I am trying to create a script to take the clipboard, strip out certain characters, paste the stripped down string and finally restore the clipboard to its original state:
I have the following script:
--delay 2
set chars_to_strip to {" ", ASCII character 10, ASCII character 13, "(", ")", "-"}
set message_text to the clipboard -- get clipboard
set temp_store to message_text
repeat with cnt from 1 to count (chars_to_strip)
set the message_text to replace_chars(message_text, item cnt of chars_to_strip, "")
end repeat
--display dialog message_text
set the clipboard to message_text
--with timeout of 1 second
tell application "System Events" to tell (name of application processes whose frontmost is true) to keystroke "v" using command down -- paste stripped down text
--end timeout
delay 0.5
set the clipboard to temp_store --restore clipboard
on replace_chars(this_text, search_string, replacement_string)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set AppleScript's text item delimiters to the replacement_string
set this_text to the item_list as string
set AppleScript's text item delimiters to astid
return this_text
end replace_chars
Two issues encountered:
(1) I lose formatting after I restore the clipboard (minor issue)
(2) The clipboard does not restore until after a number of seconds have passed after running the script. The peculiar thing is that I had to introduce a delay 0.5 to get the script to work at all because without the delay, by the time System Events pasted the parsed text, the script had already restored the original clipboard.
Any ideas? And as an aside, is it possible to issue a paste command without having to use the “V” hot key, which would have to work across all applications?
Thanks
It seems to work for me, except that if I run it from the script editor, that’s where the text gets pasted, so I inserted a line to tell Text Edit to activate:
--delay 2
set chars_to_strip to {" ", ASCII character 10, ASCII character 13, "(", ")", "-"}
--set message_text to the clipboard -- get clipboard
set message_text to the clipboard font
set temp_store to message_text
repeat with cnt from 1 to count (chars_to_strip)
set the message_text to replace_chars(message_text, item cnt of chars_to_strip, "")
end repeat
set the clipboard to message_text
--with timeout of 1 second
--Insert this line:
tell application "TextEdit" to activate
tell application "System Events" to tell (name of application processes whose frontmost is true) to keystroke "v" using command down -- paste stripped down text
--end timeout
delay 0.5
set the clipboard to temp_store --restore clipboard
on replace_chars(this_text, search_string, replacement_string)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set AppleScript's text item delimiters to the replacement_string
set this_text to the item_list as string
set AppleScript's text item delimiters to astid
return this_text
end replace_chars
I have the script attached to a Hotkey with Quicksilver as it needs to work in all apps.
It seems that when the script is invoked with Quicksilver, the funny behaviour I am experiencing occurs. But if run direct from Script Editor, the script works as you would expect. You can hit command V just after running the script and the original clipboard is back in place. Not so when invoked from Quicksilver.
Not sure what to make of this…
Here is what is happening:
I add a “delay 2” to the beginning of the script so that I can run it and switch to the relevant app before it starts processing pasting. If I run from Script Editor and as soon as it pastes the parsed clipboard (into Word or Textedit) I start hitting command V manually, I get this:
Just as you would expect.
If I run the script from Quicksilver, do exactly the same thing, I get this:
As you can see, it takes some time before the clipboard is restored and the computer feels unresponsive as I hit the command Vs this time.
Curious…
… part of the problem (but not all) is that the scripted “command v” interferes with the hotkey used by Quicksilver. If I could directly command the frontmost application to paste without needing to resort to simulating keyboard presses, that would help…
I’m not sure, but I think that Quicksilver is showing up in your list “of application processes whose frontmost is true” and that is causing the delay.
Any time you use UI scripting, you’ll need to experiment with adding delays. I have the following values in my UI scripts these days:
short_delay = 0.2
medium_delay = 1
long_delay = 3
These three values seem to cover most circumstances in Tiger and Leopard using anything as fast or faster than a “mirror front” Mac. Your values may vary depending on the speed of the machine the script is running on.
I’ve yet to meet a UI script that didn’t need at least a few stretegically place delays to make it run smoother and more repeatably.
EDIT:
To be clear, I forgot to add a syntax example:
delay medium_delay
I use variables so I can globally control certain delay intervals. Comes in handy when my scripts move to a faster machine or a new OS version (like Tiger-to-Leopard), I can re-tweak the delays easier. I used to use 0.4 for short_delay and 2 for long_delay under Tiger, but Leopard changed the dynamics…things needing little delays got quicker, but the apps needing long delays (like Lotus Notes) needed longer ones. Maybe it’s a Rosetta side-effect?
Thanks for the suggestions
For those who may find it useful, final script follows below. I still use Quicksilver but the hotkey is now set in Quicksilver to run the script after it has been released. All seems to work pretty well. Have added Growl notification for visual feedback that it is working as it is not instantaneous with GUI scripting being necessary.
set frontApp to my getFrontApp() -- determine frontmost app
my notify(1, frontApp) -- Growl notify that special pasting
delay 0.3
set chars_to_strip to {" ", ASCII character 10, ASCII character 13, ASCII character 9, "(", ")", "-"}
set message_text to the clipboard -- get clipboard
set temp_store to message_text
repeat with cnt from 1 to count (chars_to_strip)
set the message_text to replace_chars(message_text, item cnt of chars_to_strip, "")
end repeat
set the clipboard to message_text
tell application "System Events" to tell (name of application processes whose frontmost is true) to keystroke "v" using command down -- paste stripped down text
delay 0.3
set the clipboard to temp_store --restore clipboard
-- various subroutines follow
on replace_chars(this_text, search_string, replacement_string)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set AppleScript's text item delimiters to the replacement_string
set this_text to the item_list as string
set AppleScript's text item delimiters to astid
return this_text
end replace_chars
on notify(messNum, appname)
tell application "GrowlHelperApp"
set the allNotificationsList to ¬
{"StripPaste"}
set the enabledNotificationsList to {"StripPaste"}
register as application ¬
"StripPaste" all notifications allNotificationsList ¬
default notifications enabledNotificationsList ¬
icon of application appname
if messNum is 1 then
notify with name ¬
"StripPaste" title ¬
appname description ¬
"Pasted stripped text" application name "StripPaste"
end if
end tell
end notify
on getFrontApp()
set colon to ":" as Unicode text
set dot to "." as Unicode text
set appPath to (path to frontmost application as Unicode text)
considering case
if (appPath ends with colon) then
set n to -2
else
set n to -1
end if
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to colon
set appname to text item n of appPath
if (appname contains dot) then
set AppleScript's text item delimiters to dot
set appname to text 1 thru text item -2 of appname
end if
set AppleScript's text item delimiters to astid
end considering
return appname
end getFrontApp
Whoops. Replace the tell “System Events” line above with:
tell application "System Events" to tell application frontApp to keystroke "v" using command down -- paste stripped down text
Seems to help with speed as well.