Ich habe Methoden recherchiert, wie man die Auswahl als Textvariable in einem AppleScript erhält. Aber diese Methoden verlassen sich darauf, die Auswahl in die Zwischenablage zu kopieren (zum Beispiel durch Tastendruck auf den Kopierbefehl am Anfang des Skripts), um diesen Text in das AppleScript einzuführen (durch Verwendung von the clipboard
).
Das ist natürlich alles andere als ideal, da der eigentliche Text aus der Zwischenablage überschrieben wird.
Gibt es eine andere Möglichkeit, den ausgewählten Text systemweit in AppleScript abzurufen, ohne die Zwischenablage zu stören?
Offensichtlich kann man den ausgewählten Text leicht abrufen, ohne die Zwischenablage in Automator zu berühren. In diesem Fall möchte ich jedoch Automator nicht verwenden. Ich brauche eine reine AppleScript-Lösung.
Hier ist ein kürzlich erschienener Blogbeitrag, der sich auf genau diese Mission konzentriert:
Michael Tsai - Blog - Verarbeitung des ausgewählten Textes per Skript
Eine Möglichkeit, den aktuell ausgewählten Text in ein AppleScript zu übertragen, ohne den Inhalt der Zwischenablage zu überschreiben, besteht darin, den the clipboard
Inhalt einfach in einer neuen Variablen zu speichern, bevor der ausgewählte Text kopiert wird. Platzieren Sie dann am Ende des Skripts den ursprünglichen Inhalt der Zwischenablage wieder in the clipboard
.
So könnte das aussehen:
-- 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
Aber diese Methode ist unvollkommen, wie Michael bemerkt:
Das ist hässlich und hat einige Nachteile: Es gibt Verzögerungen, die durch das GUI-Skripting erforderlich sind, und bestimmte Arten von Zwischenablagedaten werden nicht beibehalten.
Shane Stanley hinterließ jedoch einen Kommentar zu dem Blogbeitrag mit einer Methode, um die ursprüngliche Formatierung des Inhalts der Zwischenablage beizubehalten.
Wenn Sie das vorherige Beispiel verwenden, ersetzen Sie die erste Zeile durch:
set savedClipboard to my fetchStorableClipboard()
Ersetzen Sie die letzte Zeile durch:
my putOnClipboard:savedClipboard
Und fügen Sie am Ende den folgenden Code hinzu:
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:
Ich habe diese von Shane bereitgestellte Lösung getestet, und sie behält tatsächlich die gesamte ursprüngliche Formatierung des Inhalts der Zwischenablage bei, wenn Sie Rich-Text in der Zwischenablage haben.
Shane hinterließ später einen zweiten Kommentar , diesmal mit der Absicht, die Laufzeit des Skripts zu minimieren.
Ersetzen Sie diesen 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.
mit diesem 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
Ich habe diesen neuen Code getestet und festgestellt, dass das Skript tatsächlich merklich schneller war, nur um ein Haar.
Insgesamt ist dies kein schlechter Workaround. Der Inhalt der Zwischenablage bleibt erhalten und die Verzögerung ist viel weniger bemerkbar, wenn Sie den in Shanes zweitem Kommentar bereitgestellten Code verwenden.
Ich habe die Lösung mit einem in Automator.app erstellten Dienst getestet, der den ausgewählten Text als input
. Die Ausführung des Dienstes und der reinen AppleScript-Lösung dauerte ungefähr gleich lange (dh ungefähr eine Sekunde).
Wenn Sie eine Methode suchen, um den ausgewählten Text abzurufen und zu ersetzen, ohne die Zwischenablage berühren zu müssen, schlägt Michael in seinem Blogbeitrag vor, dass Sie eine Software eines Drittanbieters mit dem Namen LaunchBar verwenden können . Dies ist jedoch "Schummeln", weil wir an diesem Punkt über den Rahmen meiner ursprünglichen Frage hinausgegangen sind, die sich ausschließlich mit AppleScript befasst.
Benutzer3439894
Rubiks Sphäre
Benutzer3439894
Rubiks Sphäre
Benutzer3439894
Rubiks Sphäre
input
Parameter hat, wie ihn Automator bietet.Dan Eiche
getSelection().toString()
Glen Yates
Rubiks Sphäre