The script below quits specified applications if they are running, changes the system spelling language to French, and restarts the app (so that the app registers the change in the spellcheck language setting).
I am triggering the script via a third party app (Shortery) that initiates the script whenever any of the apps is launched. The problem is it creates an endless loop of the app quitting and relaunching.
How do I modify the script so that it stops running once it is executed once?
on isAppRunning(appName)
tell application "System Events"
set appProcesses to name of every process
if appName is in appProcesses then
return true
else
return false
end if
end tell
end isAppRunning
-- List of apps to check and restart
set appList to {"Microsoft Word", "Pages", "TextEdit"}
-- Iterate through the app list
repeat with appName in appList
if isAppRunning(appName) then
-- Quit the app
tell application appName to quit
delay 1
-- Check the current language setting
set currentLang to do shell script "defaults read -g NSPreferredSpellServerLanguage"
if currentLang is "en" then
-- Change the language setting to "fr"
do shell script "defaults write -g NSPreferredSpellServerLanguage fr"
end if
delay 1
-- Restart the app
tell application appName to activate
delay 1
if appName is "Microsoft Word" then
tell application "Microsoft Word"
set track revisions of active document to true
end tell
display notification "Track Changes enabled" with title "Microsoft Word"
end if
display notification "Spelling language set to French"
end if
end repeat
-- Check if f4transkript is running
tell application "System Events"
if (name of processes) contains "f4transkript" then
-- force quit f4transkript
do shell script "killall f4transkript"
-- Check the current language setting
set currentLang to do shell script "defaults read -g NSPreferredSpellServerLanguage"
if currentLang is "en" then
-- Change the language setting to "fr"
do shell script "defaults write -g NSPreferredSpellServerLanguage fr"
end if
delay 1
-- Restart f4transkript
tell application "f4transkript" to launch
delay 1
display notification "Spelling language set to French"
end if
end tell
Are you only restating these apps because you want the language set to French?
If so check the language first and only loop thru the apps if the languages wasn’t already French.
My system spelling language is always set to English. It needs to be set to French when those applications are used, but before they are launched as macOS applications cannot register the new setting without being restarted, hence the script.
Here is a cleaned-up version that will only restart the apps once when the language is set to french
set appList to {"Microsoft Word", "Pages", "TextEdit", "f4transkript"} -- List of apps to check and restart
tell application "System Events"
-- Check the current language setting
set currentLang to do shell script "defaults read -g NSPreferredSpellServerLanguage"
if currentLang is "en" then
-- Change the language setting to "fr"
do shell script "defaults write -g NSPreferredSpellServerLanguage fr"
display notification "Spelling language set to French"
delay 1
restartApps()
end if
end tell
on restartApps()
-- Iterate through the app list
repeat with appName in appList
if isAppRunning(appName) then
if appName is "f4transkript" then
do shell script "killall f4transkript"
else
-- Quit the app
tell application appName to quit
end if
delay 1
-- Restart the app
tell application appName to activate
delay 1
if appName is "Microsoft Word" then
tell application "Microsoft Word"
set track revisions of active document to true
end tell
display notification "Track Changes enabled" with title "Microsoft Word"
end if
end if
end repeat
end restartApps
on isAppRunning(appName)
tell application "System Events"
set appProcesses to name of every process
if appName is in appProcesses then
return true
else
return false
end if
end tell
end isAppRunning
Did you manage to find a satisfactory solution?
Just in case, here’s a script that should work:
property appList : {"f4transkript", "TextEdit", "Pages", "Microsoft Word"}
property delayValue : 20 -- waits the app responses up to 2 seconds
-- toggle the spelling language
(do shell script "defaults write -g NSSpellCheckerAutomaticallyIdentifiesLanguages 0")
set spellingLang to (do shell script "defaults read -g NSPreferredSpellServerLanguage")
if spellingLang = "en" then
(do shell script "defaults write -g NSPreferredSpellServerLanguage 'fr'")
else
(do shell script "defaults write -g NSPreferredSpellServerLanguage 'en'")
end if
if (do shell script "defaults read -g NSPreferredSpellServerLanguage") = spellingLang then
display alert "Something went wrong and prevents spelling language to change." buttons {"Annuler"} cancel button 1
end if
-- restart apps
repeat with appName in appList
if application appName is running then
activate application appName -- in case some documents are modified
quit application appName -- try to quit the app
end if
repeat with iLoop from 1 to delayValue
if application appName is not running then exit repeat
delay 0.1
end repeat
if iLoop = delayValue then do shell script "killall " & quoted form of appName
tell application appName to activate
repeat with iLoop from 1 to delayValue
if application appName is running then exit repeat
delay 0.1
end repeat
if iLoop = delayValue then display alert ("Unable to relaunch " & appName) message "Do you want to continue ?" buttons {"Cancel", "Continue"} cancel button 1
end repeat
Thank you for taking the time to write this. I ended up making separate shortcuts for each app. I used a mix of AppleScript and Shell commands, plus a few built-in actions. I just realized the endless loop was most likely caused by a stupid oversight on my part: I had other shorcuts set to automatically run on app quit which changed the spelling language back to EN… thus causing the close-and-open loop. I think my original AppleScript was actually fine… Ugh.