Copy Concatenation in AppleScript as a command - macos

so I have a quick question for anyone willing to help. When I am programming in a regular text editor, I often find myself wanting to copy multiple lines of code, concatenating them on the fly and then being able to paste their contents just like I would normally use Command+c/Command+v.
I think this would be done in Applescript and then assigned a custom shortcut with Quicksilver but I am not too familiar with either. Below is an example to illustrate the desired behavior.
Copy-Concatenate with Command+C+X Paste with Command+V Clear Clipboard when regular Command+C is used
so...
Command+C+X "First line" ... Command+C+x"Second line" ... Command+V pastes "First lineSecond line"
and Command+C"Third line"... Command+V pastes "Third line"
Can someone help me accomplish this or set me on the right path? Thank you in advance.

Select the text in your editor and try this:
tell application "System Events" to keystroke "x" using command down
set myText to the clipboard as «class utf8»
set {TID, text item delimiters} to {text item delimiters, {return, linefeed, character id 8233, character id 8232}}
set myText to text items of myText
set AppleScript's text item delimiters to space
set the clipboard to myText as text
set text item delimiters to TID
tell application "System Events" to keystroke "v" using command down

Related

Removing a word from a variable in Applescript

I'm pretty newbie at Applescript and I can't work out how to remove a word from a variable if the word contains a “#” in it.
My script gets this error -> "Can’t make word into type integer." number -1700 from word to integer
Here's my script so far:
activate application "Grids"
delay 2
tell application "System Events"
keystroke "a" using command down
delay 0.25
keystroke "c" using command down
delay 0.25
set Description to the clipboard
if any word in Description contains "#" then delete that word
return Description
end tell
Any pointers?
Cheers,
Chris
To get text out of the clipboard, use (clipboard as text). The clipboard can contain almost anything, even multiple objects, in multiple formats, so as text gives you a string to work with.
And watch out: 'Description' appears to be part of some existing appleScript 'terminology', at least on the Mac I have right here, so I am changing your identifier to desc here:
activate application "Grids"
delay 2
tell application "System Events"
keystroke "a" using command down
delay 0.25
keystroke "c" using command down
delay 0.25
set desc to the clipboard as text
end tell
set out to {}
set tids to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "
repeat with anItem in (text items of desc)
set str to (anItem as string)
if (str does not contain "#") then
set end of out to str
end if
end repeat
set outStr to out as string
set AppleScript's text item delimiters to tids
return outStr
This code just returns the text you are looking for. It does not re-insert the groomed string, or do anything else interesting.
I assume you're going to tell System Events to paste it via cmd-v. (Remember to set the clipboard to outStr before you paste!)
AppleScript's text item delimiters allows the string to be split and reassembled using a space (or any other token you wish). For code hygiene reasons, it's wise practice to store it before changing it, then reset it to its original value afterwards, as shown here, otherwise odd things might happen in scripts which expect it to have the default value.

Applescript Paste and Tab From a Comma Delimited List

I'm trying to get an automator applescript to loop though a comma delimited list; and in doing so, paste value 1, tab, paste value 2, tab etc...
It doesn't seem to want to paste into a text field in google chrome however.
display dialog "What is the list? (Artist, Song Title, Artist, Song Title)" default answer "Frank Sinatra, My Way, Elvis, Blue Christmas"
set user_input to text returned of result
set {myTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {","}}
set myList to text items of user_input -- Gives list {"2", "69", "12"}
set AppleScript's text item delimiters to myTID -- It's considered good practice to return the TID's to their original state
repeat with myItem in myList -- Loop through the items in the list
tell application "System Events"
set the clipboard to myItem
keystroke "v" using {command down}
keystroke tab
end tell
delay 1
end repeat
display dialog "Job Done"
return
Your paste command is done on your script, not on other application (Chrome in your case). you must tell which process should receive the keystroke. Something like :
tell application "System Events"
tell process "Chrome"
Set the clipboard to myItem
keystroke "v" using {command down}
keystroke tab
end tell
end tell

Replacing words in Applescript

I'm back to writing Applescripts. I'm making a script that will Google things for you. Basically, I need to replace all of the spaces with %20. I know a little about text item delimiters, but I don't know how to implement them in this case.
Here's what I got so far:
if userInput contains "Google " then set {TID, text item delimiters} to {text item delimiters, {"Google "}}
if length of userInput is greater than or equal to 2 then set resultString to text item 2 of userInput
if userInput contains "Google " then set text item delimiters to TID
set openPage to (resultString as string)
if userInput contains "Google " then do shell script "open http://www.google.com/search?q=" & openPage
FYI, the userInput variable is the variable I use when dealing with textboxes.
Thanks
I think this script demonstrates the principle of what you’re trying to do:
tell application "Safari"
activate
display dialog "Search Google for:" default answer "" buttons {"Cancel", "OK"} default button "OK" with title (the name as text) with icon note giving up after 60
if the button returned of the result is equal to "OK" then
set theSearch to the text returned of the result
set AppleScript's text item delimiters to space
set theSearchList to every text item of theSearch
set AppleScript's text item delimiters to "+"
set theQuery to theSearchList as text
set AppleScript's text item delimiters to ""
set theLink to "http://www.google.com/search?hl=en&q=" & theQuery & "&btnG=Google+Search"
open location theLink
end if
end tell
However, it’s a lot easier if you just ask an app like BBEdit (or its free version, TextWrangler, which has the same AppleScript dictionary) to do the find and replace for you, because BBEdit is an expert at finding and replacing text, whereas AppleScript by itself is not. AppleScript is a “little language” — it deliberately lacks 95% of the functionality of most programming languages because the functionality is in the apps that you command with AppleScript. In other words, AppleScript expects you to have a text editor with which to process text, therefore AppleScript deliberately doesn’t have the built-in text processing ability of a language like Perl (which you can also use in your AppleScripts.)
So the above script gets a lot shorter, easier to write, easier to read, and easier to understand if you add BBEdit (or the free TextWrangler) into the mix:
tell application "Safari"
activate
display dialog "Search Google for:" default answer "" buttons {"Cancel", "OK"} default button "OK" with title (the name as text) with icon note giving up after 60
if the button returned of the result is equal to "OK" then
set theSearch to the text returned of the result
tell application "BBEdit"
set theQuery to replace " " using "+" searchingString theSearch
end tell
set theLink to "http://www.google.com/search?hl=en&q=" & theQuery & "&btnG=Google+Search"
open location theLink
end if
end tell
Also, notice that you don’t have to run a shell script to open a link in a browser. So this line in your script:
if userInput contains "Google " then do shell script "open http://www.google.com/search?q=" & openPage
… can be written like this:
if userInput contains "Google " then open location "http://www.google.com/search?q=" & openPage
… or like this:
if userInput contains "Google " then
open location "http://www.google.com/search?q=" & openPage
end if
… and you can use the “open location” command with any app, not just Safari. If you tell Finder to “open location” the link will open in your default browser, which might be Chrome.

Unable to manipulate text from Clipboard in Applescript

I am forced to use a piece of software that requires a lot of data entry into simple web forms, so I have designed an AppleScript to take a text file as input and then keystroke out the contents into Safari, so that tabs in the text file are used to advance to the next field in the web form. I am doing some string replacement so I can treat newlines in the text file as tabs, for readability of the text file.
I want to streamline this by keystroking from the clipboard, which works, but the string replacement is not happening the way it should, and I am unable to determine why. My workaround at this point is to manually find/replace newlines with tabs before copying, but that's basically just as slow as saving the file and pointing the script at it.
tell application "Safari"
activate
end tell
set sourceString to (the clipboard) as text
set ASTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "\n"
set the lineList to every text item of sourceString
set AppleScript's text item delimiters to "\t"
set keystrokeString to the lineList as string
set AppleScript's text item delimiters to ASTID
tell application "System Events"
keystroke keystrokeString as text
end tell
\t and \n will compile down to invisibles if you put this into AppleScript Editor. The string editing (middle) part works as advertised when I read from a file using:
set theFile to (choose file with prompt "Select a file to read:" of type {"txt"})
open for access theFile
set fileContents to (read theFile)
close access theFile
Any ideas why the string replacement might not be working when I get the text from the clipboard?
Using the ASCII Character function when setting the delimiters should work. A linefeed is ASCII character 10. So i.e.: set AppleScript's text item delimiters to ASCII character 10
Should work.
Tabbing through forms on a page is often error prone. You should identify each form by id and populate the form with javascript.
tell application "Safari"
set URL of document 1 to "http://www.google.com/"
delay 3
do JavaScript "document.getElementById('gbqfq').value = 'My Text'" in document 1
end tell
It appears as though linefeeds are translated into carriage returns upon copying text to the clipboard, and \n will not match them.
\r will, however, and they both compile down to invisible characters, which is a bit of an annoyance.
After a little bit of testing, it looks like when you save a text file to disk and then read it with AppleScript, you must match the line endings used in the file, LF or CR with \n or \r. However, when reading text copied to the clipboard, you must always match \r.
Edit:
Many of these characters have AppleScript keywords. tab, linefeed, and return can all be used as is. My script now looks like this:
set backspace to ASCII character 8
get the clipboard
set keystrokeString to (replacement of return by tab for the result)
set keystrokeString to (replacement of linefeed by tab for the result)
set keystrokeString to (replacement of tab by tab & backspace for the result)
tell application "System Events"
keystroke keystrokeString as text
end tell
on replacement of oldDelim by newDelim for sourceString
set oldTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to oldDelim
set strtoks to text items of sourceString
set text item delimiters of AppleScript to newDelim
set joinedString to strtoks as string
set text item delimiters of AppleScript to oldTIDs
joinedString
end replacement
It also now includes backspace characters that are hit after every tab, so if text is not entered into an already filled field, it is deleted after being advanced to.

Get message in compose window from Mail.app

I am trying to make a script that will get the contents of an email message that I'm composing in Mail, do something with the data, and then send the message. I know how to make and send a new message from scratch with AppleScript, but I can't find a way to get a message that I'm already writing. I don't care what language is used, and I would be open to trying a different email client. Thanks for your help!
Mail has huge limitations with regards to Applescript and dealing with its content area is a major one. The best bet is to use GUI scripting to tab to the content area, type cmd-C, and then work off the data in the clipboard.
Sadly from what I can see Applescript has not been improved at all in Lion.
It's actually pretty easy to do what you need.
If you want to run some kind of an inline processing (assigned to, say, a hotkey (in Mail, e.g. Cmd+D is not occupied), or "just" listed in the Services menu, accessible after selecting something), you can simply use Automator. A demo Automator script reading the current selection, making some changes (here, converting some ASCII char+number combinations to some accented characters) and, finally, returning the modified text is as follows:
on run {input, parameters}
set myText to replaceText("a1", "á", (input as text))
set myText to replaceText("e1", "é", myText)
set myText to replaceText("i1", "í", myText)
return myText
end run
on replaceText(find, replace, someText)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to find
set someText to text items of someText
set text item delimiters of AppleScript to replace
set someText to "" & someText
set text item delimiters of AppleScript to prevTIDs
return someText
end replaceText
Make sure you enable the "Replaces selected text", should you want to overwrite the original content with the returned one.
if you want to write an external script not invoked from the local Services menu (or via a hotkey), you'll also need to add clipboard handling. A solution similar to the above with additional clipboard copy/paste:
on replaceText(find, replace, someText)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to find
set someText to text items of someText
set text item delimiters of AppleScript to replace
set someText to "" & someText
set text item delimiters of AppleScript to prevTIDs
return someText
end replaceText
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
click menu item "Select All" of menu "Edit" of menu bar 1
click menu item "Copy" of menu "Edit" of menu bar 1
end tell
end tell
end tell
tell application "Mail"
set textclip to (the clipboard)
end tell
set myText to replaceText("a1", "á", textclip)
set myText to replaceText("e1", "é", myText)
set myText to replaceText("i1", "í", myText)
set the clipboard to myText
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
click menu item "Paste" of menu "Edit" of menu bar 1
end tell
end tell
end tell
Note that the latter script selects (and, then, overwrites) the entire window contents. It should be easy to work on the current selection only.
It's possible, but painful. Painful enough that I'm still trying to work out exactly how to do something similar but in Safari. I've gotten to the point where I can find the textarea, but the documentation I've found for getting the content isn't working. (Unfortunately, that's pretty much par for the course for AppleScript; every program does stuff just a little bit differently from the next program.)
EDIT: ok, have some horrible evil which hopefully can be adapted to work with Mail: http://www.ece.cmu.edu/~allbery/edit_textarea.script
This is striaghtforward if we make two reasonably weak assumptions: that the message you're working on is frontmost, and that the subject of all draft messages is unique. Then, before running the script, save the message you're working on; this will place it in the drafts mailbox. Then, since the subject of the message is the name of the window, we can easily access it; and since we can easily access the drafts mailbox, we can combine the two. This gives us:
tell application "Mail"
set msgs to messages of drafts mailbox ¬
whose subject is (name of window 1 as string)
if (count of msgs) = 1 then
-- Do whatever
else
-- Error, disambiguate, whatever
end if
end tell
It's probably possible to make the script save the frontmost window, and it wouldn't surprise me if a freshly-saved message is always the first item of the drafts mailbox, but these are left as an exercise for the reader :-)
So I came across this in 2020 and with this Apple Script it is (now?) possible (whenever its still a bit hacky since I have to use the clipboard for this):
activate application "Mail"
tell application "System Events"
tell process "Mail"
set initialClipboardContent to (the clipboard as text)
set composeWindow to (first window whose title does not contain "Inbox")
set value of attribute "AXFocused" of UI element 1 of scroll area 1 of composeWindow to true
delay 0.05
# CMD + A
key code 0 using command down
delay 0.1
# CMD + C
key code 8 using command down
delay 0.1
set message to (the clipboard as text) as string
log message
set the clipboard to initialClipboardContent
end tell
end tell
Here a proof of concept:

Resources