11 votes

Comment récupérer le texte sélectionné dans un AppleScript, sans copier le texte dans le presse-papiers ?

J'ai fait des recherches sur les méthodes permettant d'obtenir la sélection en tant que variable texte dans un AppleScript. Mais ces méthodes reposent sur la copie de la sélection dans le presse-papiers (par exemple, en tapant sur la commande copy en haut du script) afin d'introduire ce texte dans l'AppleScript (en utilisant la commande the clipboard ).

Ce n'est pas idéal, bien sûr, car le texte du presse-papiers est écrasé.

Existe-t-il un autre moyen d'obtenir le texte sélectionné, à l'échelle du système, dans AppleScript, sans perturber le presse-papiers ?

Évidemment, on peut facilement obtenir le texte sélectionné sans toucher au presse-papiers dans Automator. Cependant, dans ce cas, je ne veux pas utiliser Automator ; j'ai besoin d'une solution purement AppleScript.

9voto

rubik's sphere Points 4760

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.

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X