I Would like to skip the user interface when I insert a text to replace. In other words, I'd like to accelerate the processes, because, as you can see on this image, I add lot of words there, very often.
Basically, when I type a word wrong, I select it and activate the macro that asks me to correct this word to insert in the text substitution of the system preferences.
Would anyone have a suggestion to shorten or speed up this macro, like via AppleScript, add directly into plist file, whatever.
As a starter, here a quick script that lets you create a new entry in the macOS text replacements:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
tell application id "com.apple.systempreferences"
reveal anchor "Text" of pane id "com.apple.preference.keyboard"
activate
end tell
tell application id "com.apple.systemevents"
tell application process "System Preferences"
tell window "Keyboard"
tell tab group 1
tell group 1
tell button 1
click
end tell
end tell
end tell
end tell
end tell
end tell
You can run the script from KM (Execute AppleScript action) or Script Editor, or whatever.
Obviously, there is still work to do (e.g. we have to bring the selected word into the field), but it should give you a rough idea how it can be done.
I don’t have much time at the moment, but probably later today I can complete the script/macro.
Yes, as a rule of thumb, I would use actions like Click at Coordinates or Find Image only if there really is no other way.
Here a more complete version:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
set theWord to the clipboard as text
tell application id "com.apple.systempreferences"
reveal anchor "Text" of pane id "com.apple.preference.keyboard"
activate
end tell
tell application id "com.apple.systemevents"
tell application process "System Preferences"
tell window "Keyboard"
tell tab group 1
tell group 1
tell button 1
click
--delay 0.5
end tell
end tell
tell scroll area 1
tell table 1
tell row -1
tell UI element 1
tell text field 1
set value to theWord
--confirm
end tell
end tell
tell UI element 2
tell text field 1
set value to theWord
set focused to true
end tell
end tell
end tell
end tell
end tell
end tell
end tell
end tell
end tell
A new entry with the selected word should be created in macOS Text Replacements
The Replacement field should be prepopulated with the same word and focused for editing
Edit the Replacement word and press Return
Of course, you can change the input method to your needs (I have seen you have used a User Prompt action in your original macro). The word must just be on the system clipboard, when the script starts.
If the script doesn’t work for you, then we probably have to add some delays in the script.
Tested from within TextEdit on macOS 10.15.3, KM 9.0.5.
I'm trying to do something very similar to what @alex.sanches was doing last February. I want to use an AppleScript to update a specific Text Replacement that contains the current date that I'll use across multiple (iOS) devices spanning the Apple ecosystem. I have leveraged the script that @Tom shared with a slight twist to update a Keyboard/Text Replacement on my Mac and allow it to propagate - I'll use Keyboard Maestro to scheduled the updates for just after midnight.
This script makes the change on a positional basis (i.e., it updates the value field of the first name:value key pair, but I can't get the change to stick. When System Preferences closes, the value reverts back to what it was before I ran the script.
Does anybody have a suggestion for how I can "save" the System Preferences/General/Keyboard/Text Replacement modification?
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
-- get the current date into today
set today to short date string of (current date)
set [_month, _day, _year] to [month, day, year] of date today
-- format today so it will look like YYYY-MM-DD
set _day to _day * 1 --> 3
set _day to text -1 thru -2 of ("0" & _day) --> "03"
set _month to _month * 1 --> 3
set _month to text -1 thru -2 of ("0" & _month) --> "03"
set _year to _year * 1 --> 5
set _year to text -1 thru -4 of ("0" & _year)
set the text item delimiters to "-"
set today to {_year, _month, _day} as string
set fullDateToday to today as string
-- swap out the "With" text field in the first value row of System Preferences/Keyboard/Text
tell application id "com.apple.systempreferences"
reveal anchor "Text" of pane id "com.apple.preference.keyboard"
activate
end tell
tell application id "com.apple.systemevents"
tell application process "System Preferences"
tell window "Keyboard"
tell tab group 1
tell scroll area 1
tell table 1
tell row 1
tell UI element 2
set value of text field 1 to today as text
end tell
end tell
end tell
end tell
end tell
end tell
end tell
end tell
I plan to refactor and do a more deliberate match of names & variables after I get the MVP going. Thanks in advance for any direction you can give me on how to make the change stick.
I figured it out and it's working like a champ with Keyboard Maestro. My AppleScript is probably pretty rough, but it's doing the trick as a minimum viable product - I'll tweak it as I go. Posting here in case it helps anybody else.
PS - the trick to making the changes stick was to treat it a bit more like I was sitting in the user's chair and including the following code (shout out to the AppleScript-Users mailing list):
set focused to true
keystroke today -- today is a variable that contains a formatted date
keystroke return
Here's the final AppleScript:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
-- get the current date into today
set today to short date string of (current date)
set [_month, _day, _year] to [month, day, year] of date today
-- format today so it will look like YYYY-MM-DD
set _day to _day * 1 --> 3
set _day to text -1 thru -2 of ("0" & _day) --> "03"
set _month to _month * 1 --> 3
set _month to text -1 thru -2 of ("0" & _month) --> "03"
set _year to _year * 1 --> 5
set _year to text -1 thru -4 of ("0" & _year)
set the text item delimiters to "-"
set today to {_year, _month, _day} as string
set fullDateToday to today as string
-- swap out the "With" text field in the first value row of System Preferences/Keyboard/Text
tell application id "com.apple.systempreferences"
reveal anchor "Text" of pane id "com.apple.preference.keyboard"
activate
end tell
tell application "System Events" to quit
set myRow to 1
set allSnippets to {}
set mySnippets to {}
set myShortcut to ""
set myReplacement to ""
tell application id "com.apple.systemevents"
tell application process "System Preferences"
tell window "Keyboard"
tell tab group 1
tell scroll area 1
tell table 1
set rc to count of rows
-- display dialog "row count is " & rc as string
repeat until myRow > rc
set mySnippets to mySnippets & {row:{myRow}}
tell row myRow
tell UI element 1
tell text field 1
set focused to true
delay 1
tell application "System Events" to quit
tell application "System Events" to keystroke "c" using {command down}
delay 0.1
-- display dialog "clipboard is " & (the clipboard)
set myShortcut to the clipboard
delay 0.1
tell application "System Events" to quit
set mySnippets to mySnippets & {shortcut:{myShortcut}}
-- display dialog "row: " & row of mySnippets & ", shortcut: " & shortcut of mySnippets
-- if myShortcut = "2021-06-20" then
set focus to {}
end tell
end tell
-- breakpoint between uiel 1 and 2 of each row
tell UI element 2
tell text field 1
set focused to true
tell application "System Events" to quit
tell application "System Events" to keystroke "c" using {command down}
delay 0.1
-- display dialog "clipboard is " & (the clipboard)
set myReplacement to the clipboard
delay 0.1
tell application "System Events" to quit
-- display dialog "myReplacement is " & myReplacement
set mySnippets to mySnippets & {replacement:{myReplacement}}
-- display dialog "row: " & row of mySnippets & ", shortcut: " & shortcut of mySnippets & ", replacement: " & replacement of mySnippets
set allSnippets to allSnippets & {mySnippets}
set mySnippets to {}
set myRow to (myRow + 1)
-- display dialog "myRow is " & myRow
set focus to {}
end tell
end tell
end tell
end repeat
end tell
end tell
end tell
end tell
end tell
set iter to 1
set today_row to 0
repeat until iter > rc
-- display dialog shortcut of item {iter} of allSnippets
if (shortcut of item {iter} of allSnippets) starts with "jgdate" then
set today_row to (row of item {iter} of allSnippets)
end if
set iter to (iter + 1)
end repeat
-- display dialog today_row
-- display dialog (replacement where (shortcut = "jgdate")) of allSnippets
tell application process "System Preferences"
tell window "Keyboard"
tell tab group 1
tell scroll area 1
tell table 1
tell row {today_row}
tell UI element 2
tell text field 1
set focused to true
keystroke today
keystroke return
end tell
end tell
end tell
end tell
end tell
end tell
end tell
end tell
end tell
-- quit System Preferences
tell application "System Events"
get name of every process whose name is "System Preferences"
if result is not {} then
tell application "System Preferences"
quit
end tell
else
tell application "System Preferences"
activate
end tell
end if
end tell
In other words you want the word to be corrected without having to type a space first? AFAIK the native text replacement feature doesn’t support that.
If you’re not married to a native feature though there is Typinator that was already mentioned. It can expand a word even before hitting the space bar (among many, many other things).