Aqui está uma postagem recente no blog que foca nessa missão:
Michael Tsai - Blog - Processando o texto selecionado via script
Uma maneira de obter o texto atualmente selecionado em um AppleScript, sem sobrescrever o conteúdo da área de transferência, é simplesmente salvar the clipboard
conteúdo para uma nova variável antes o texto selecionado é copiado. Então, no final do script, coloque o conteúdo original da área de transferência de volta the clipboard
.
Aqui está o que isso pode parecer:
-- Back up clipboard contents:
set savedClipboard to the clipboard
-- Copy selected text to clipboard:
tell application "System Events" to keystroke "c" using {command down}
delay 1 -- Without this, the clipboard may have stale data.
set theSelectedText to the clipboard
-- Makes the selected text all uppercase:
-- From: http://apple.stackexchange.com/a/171196/184907
set theModifiedSelectedText to (do shell script ("echo " & theSelectedText & " | tr a-z A-Z;"))
-- Overwrite the old selection with the desired text:
set the clipboard to theModifiedSelectedText
tell application "System Events" to keystroke "v" using {command down}
delay 0.1 -- Without this delay, may restore clipboard before pasting.
-- Instead of the above three lines, you could instead use:
-- tell application "System Events" to keystroke theModifiedSelectedText
-- But this way is a little slower.
-- Restore clipboard:
set the clipboard to savedClipboard
Mas esse método é imperfeito, como Michael observa:
Isso é feio e tem algumas desvantagens: há atrasos exigidos pelo script da GUI e certos tipos de dados da área de transferência não são preservados.
Contudo, Shane Stanley deixou um comentário na postagem do blog com um método para manter a formatação original do conteúdo da área de transferência.
Se estiver usando o exemplo anterior, substitua a primeira linha por:
set savedClipboard to my fetchStorableClipboard()
Substitua a última linha por:
my putOnClipboard:savedClipboard
E adicione o seguinte código ao final:
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
on fetchStorableClipboard()
set aMutableArray to current application's NSMutableArray's array() -- used to store contents
-- get the pasteboard and then its pasteboard items
set thePasteboard to current application's NSPasteboard's generalPasteboard()
-- loop through pasteboard items
repeat with anItem in thePasteboard's pasteboardItems()
-- make a new pasteboard item to store existing item's stuff
set newPBItem to current application's NSPasteboardItem's alloc()'s init()
-- get the types of data stored on the pasteboard item
set theTypes to anItem's types()
-- for each type, get the corresponding data and store it all in the new pasteboard item
repeat with aType in theTypes
set theData to (anItem's dataForType:aType)'s mutableCopy()
if theData is not missing value then
(newPBItem's setData:theData forType:aType)
end if
end repeat
-- add new pasteboard item to array
(aMutableArray's addObject:newPBItem)
end repeat
return aMutableArray
end fetchStorableClipboard
on putOnClipboard:theArray
-- get pasteboard
set thePasteboard to current application's NSPasteboard's generalPasteboard()
-- clear it, then write new contents
thePasteboard's clearContents()
thePasteboard's writeObjects:theArray
end putOnClipboard:
Eu testei essa solução fornecida por Shane, e ela realmente retém toda a formatação original do conteúdo da área de transferência se você tiver rich text na área de transferência.
Shane depois deixou um segundo comentário , desta vez com a intenção de minimizar o tempo de execução do script.
Substitua este código:
-- Copy selected text to clipboard:
tell application "System Events" to keystroke "c" using {command down}
delay 1 -- Without this, the clipboard may have stale data.
com este código:
set thePasteboard to current application's NSPasteboard's generalPasteboard()
set theCount to thePasteboard's changeCount()
-- Copy selected text to clipboard:
tell application "System Events" to keystroke "c" using {command down}
-- Check for changed clipboard:
repeat 20 times
if thePasteboard's changeCount() is not theCount then exit repeat
delay 0.1
end repeat
Eu testei esse novo código e descobri que o roteiro era de fato notavelmente mais rápido, apenas por um fio de cabelo.
No geral, isso não é uma solução ruim. O conteúdo da área de transferência é preservado e o atraso é muito menos perceptível se você empregar o código fornecido no segundo comentário de Shane.
Eu testei a solução contra um serviço criado no Automator.app que recebe o texto selecionado como o input
. O Serviço e a solução AppleScript pura levaram praticamente o mesmo tempo para serem concluídos (ou seja, cerca de um segundo).
Se alguém quiser um método para obter e substituir o texto selecionado sem ter que tocar na área de transferência, Michael sugere em seu blog que alguém pode utilizar um software de terceiros chamado Barra de Lançamento . No entanto, isso é "trapaça", porque, nesse ponto, fomos além do escopo da minha pergunta original, que é estritamente relacionada ao AppleScript.