Come ottenere il testo selezionato in un AppleScript, senza copiare il testo negli Appunti?

6

Ho studiato i metodi su come ottenere la selezione come variabile di testo in un AppleScript. Ma questi metodi si basano sulla copia della selezione negli appunti (ad esempio, digitando il comando di copia nella parte superiore dello script) per introdurre questo testo nell'AppleScript (utilizzando the clipboard ).

Ovviamente non è l'ideale, perché il testo degli appunti reali viene sovrascritto.

C'è un altro modo per ottenere il testo selezionato, a livello di sistema, in AppleScript, senza disturbare gli appunti?

Ovviamente, è possibile ottenere facilmente il testo selezionato senza toccare gli appunti in Automator. Tuttavia, in questo caso, non voglio usare Automator; Ho bisogno di una soluzione AppleScript pura.

    
posta rubik's sphere 01.02.2017 - 03:14
fonte

1 risposta

4

Ecco un recente post sul blog che si concentra su questa stessa missione:

Michael Tsai - Blog - Elaborazione del testo selezionato tramite script

Un modo per ottenere il testo selezionato in un AppleScript, senza sovrascrivere il contenuto degli appunti, è semplicemente salvare the clipboard contenuti in una nuova variabile prima il testo selezionato viene copiato. Quindi, alla fine dello script, posiziona nuovamente il contenuto degli appunti originali su the clipboard .

Ecco come potrebbe essere:

-- 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

Ma questo metodo è imperfetto, come nota Michael:

This is ugly and has some downsides: there are delays necessitated by the GUI scripting, and certain types of clipboard data are not preserved.

Tuttavia, Shane Stanley ha lasciato un commento sul post del blog con un metodo per mantenere la formattazione originale dei contenuti degli appunti.

Se si utilizza l'esempio precedente, sostituire la prima riga con:

set savedClipboard to my fetchStorableClipboard()

Sostituisci l'ultima riga con:

my putOnClipboard:savedClipboard

E aggiungi il seguente codice alla fine:

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:

Ho provato questa soluzione fornita da Shane, e in effetti mantiene tutta la formattazione originale dei contenuti degli appunti se hai un testo ricco negli appunti.

Shane in seguito ha lasciato un secondo commento , questa volta con l'intento di ridurre al minimo il runtime dello script.

Sostituisci questo codice:

-- 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.

con questo codice:

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

Ho provato questo nuovo codice e ho scoperto che la sceneggiatura era in effetti notevolmente più veloce, solo per i capelli.

Nel complesso, non si tratta di una soluzione alternativa. Il contenuto degli appunti è conservato e il ritardo è molto meno evidente se si utilizza il codice fornito nel secondo commento di Shane.

Ho testato la soluzione su un servizio creato in Automator.app che riceve il testo selezionato come input . Il Service e la pura soluzione AppleScript hanno richiesto parecchio tempo per completare (cioè circa un secondo).

Se si vuole un metodo per ottenere e sostituire il testo selezionato senza dover toccare gli appunti, Michael suggerisce nel suo post sul blog che si può utilizzare un software di terze parti intitolato LaunchBar . Tuttavia, questo è "imbroglio", perché, a quel punto, siamo andati oltre lo scopo della mia domanda originale, che è strettamente legata a AppleScript.

    
risposta data 06.02.2017 - 03:54
fonte

Leggi altre domande sui tag