Converting to one line AppleScript
Asked Answered
A

2

18

I have a series of AppleScript commands I need to implement into a single line of AppleScript. The code is below.

delay 2
tell application "System Events" to keystroke "foo"
tell application "System Events" to keystroke return
Alceste answered 13/3, 2011 at 7:51 Comment(5)
Out of curiosity: why do they need to be one-liners? Also: could you say which application is receiving the "foo" and "return"? This would make it easier to test your script. Beyond that, I´m assuming the second and third line can be joined to tell app "System Events" to keystroke {"foo",return}.Cornflower
It needs to be one line because I am going to implement this AppleScript into a Cocoa application.Alceste
Couldn´t you handle the delay in Cocoa then?Cornflower
I also do not see why that needs to be a single line. You can either use an escaped line break inside an NSString literal @"foo\nbar". You could also use a literal line break in the NSString literal. Or if it is not a literal, you should still be able to manage to add a suitable line break character as a part of your string building.Aground
@Cornflower @Chris Johnsen Good point, I think I will handle the delay in Cocoa.Alceste
A
27

You can combine the two keystroke commands into a single one by concatenating your strings together:

tell app "System Events" to keystroke "foo" & return

But that still leaves you with one command and a statement (delay and tell … to …).

Effectively, AppleScript’s statement separator is a line break. In modern AppleScript the line breaks can be either CR, LF, or CRLF (respectively: old-Mac-, Unix-, or DOS-style). There is no convenient way write a multi-statement line (like foo; bar; baz; in C, Perl, Ruby, et cetera).

For your specific request, you can combine the two in a really ugly way by using delay as a part of an expression.

tell application "System Events" to keystroke "" & (delay 2) & "foo" & return

This is ugly because delay technically returns no value, but we are able to concatenate it with an empty string without causing an error.

The problem is that such a construction is not very “general purpose”. You may not always be able to turn any command into an expression in the same way (and you can not use statements like tell as a part of an expression1). For a bit more brevity (and obfuscation), you can write the last bit as "foo" & return & (delay 2). It still runs in the same order (delay first) because each part of the concatenation expression must be evaluated before it can be built into a single value for the keystroke command.

1 Short of putting them in a string given to run script that is. Even then, some statements (loops, try/catch, etc.) are always multi-line; though you can get around that by using escaped line breaks or concatenation and one of the line break constants (as follows).

You could use run script with a string argument and use the backslash2 escapes to represent the line breaks.

run script "delay 0.1\ntell app \"System Events\" to keystroke \"foo\" & return"

AppleScript Editor may translate the escape notation into a literal unless you have “Escape tabs and line break in string” enabled in its Editing preferences (available in 10.5 and later). You could always use the return constant and concatenation instead of the in-string-literal/escape-notation.

run script "delay 0.1" & return & "tell app \"System Events\" to keystroke \"foo\" & return"

2 If you are going to represent such strings inside an Objective C string literal (as one of your comments might imply), then you will have to escape the backslashes and double quotes for Objective C, also (…& \"tell app \\\"System…).

Or, if you are ultimately trying to run the code with osascript, then you can use the fact that each instance of -e will become a separate line to put it all on a single shell command line.

osascript -e 'delay 2' -e 'tell app "System Events" to keystroke "foo" & return'
Aground answered 13/3, 2011 at 8:47 Comment(0)
E
4

osascript -e 'line1' -e 'line2' …

The manpage for osascript suggests to use several -e to build up a multi-line script:

-e statement
Enter one line of a script. If -e is given, osascript will not look for a filename in the argument list.
Multiple -e options may be given to build up a multi-line script.
Because most scripts use characters that are special to many shell programs (for example, AppleScript uses single and double quote marks, “(”, “)”, and “*”), the statement will have to be correctly quoted and escaped to get it past the shell intact.

Answer already given by Chris Johnsen, but is contained in a longer answer and therefore can be overlooked.

Escurial answered 28/12, 2022 at 9:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.