Voici un récent billet de blog qui porte précisément sur cette mission :
Michael Tsai - Blog - Traitement du texte sélectionné via script
Une façon d'intégrer le texte actuellement sélectionné dans un AppleScript, sans écraser le contenu du presse-papiers, est de simplement enregistrer the clipboard
dans une nouvelle variable avant le texte sélectionné est copié. Ensuite, à la fin du script, replacez le contenu original du presse-papier sur the clipboard
.
Voici à quoi cela pourrait ressembler :
-- 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
Mais, cette méthode est imparfaite, comme le note Michael :
C'est laid et présente quelques inconvénients : il y a des retards nécessités par le script de l'interface graphique, et certains types de données du presse-papiers ne sont pas préservés.
Cependant, Shane Stanley a laissé un commentaire sur l'article de blog avec une méthode permettant de conserver le formatage original du contenu du presse-papiers.
Si vous utilisez l'exemple précédent, remplacez la première ligne par :
set savedClipboard to my fetchStorableClipboard()
Remplacer la dernière ligne par :
my putOnClipboard:savedClipboard
Et ajoutez le code suivant à la fin :
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:
J'ai testé la solution proposée par Shane, et elle conserve effectivement tout le formatage d'origine du contenu du presse-papiers si vous avez du texte riche dans le presse-papiers.
Shane a ensuite laissé un deuxième commentaire , cette fois avec l'intention de minimiser le temps d'exécution du script.
Remplacez ce code :
-- 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.
avec ce code :
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
J'ai testé ce nouveau code et j'ai constaté que le script était en fait sensiblement plus rapide, juste d'un poil.
Globalement, ce n'est pas une mauvaise solution de contournement. Le contenu du presse-papiers est préservé et le retard est beaucoup moins perceptible si vous utilisez le code fourni dans le deuxième commentaire de Shane.
J'ai testé la solution par rapport à un service créé dans Automator.app qui reçoit le texte sélectionné comme l'élément input
. Le service et la solution AppleScript pure ont pris à peu près le même temps (c'est-à-dire environ une seconde).
Si l'on veut une méthode permettant de récupérer et de remplacer le texte sélectionné sans avoir à toucher au presse-papiers, Michael suggère dans son billet de blog d'utiliser un logiciel tiers intitulé Barre de lancement . Toutefois, il s'agit d'une "tricherie", car, à ce stade, nous avons dépassé le cadre de ma question initiale, qui concerne strictement AppleScript.