The following script opens the AppleScript dictionary of the frontmost app; I run it by way of FastScripts.
tell application "Finder"
set frontApp to first application process whose frontmost is true
end tell
tell application "Script Editor"
activate
open file of frontApp as alias
end tell
The script works fine as long as the dictionary exists. Otherwise, the following error results and Script Editor opens an unknown document:
I added error correction to the script but that doesn’t help:
tell application "Finder"
set frontApp to first application process whose frontmost is true
set appName to name of frontApp
end tell
try
tell application "Script Editor"
open file of frontApp as alias
activate
end tell
on error
display dialog "There is not an AppleScript dictionary for " & appName buttons {"OK"} cancel button 1 default button 1 with icon stop
end try
The source of the error appears to be the following line, but I don’t understand how Script Editor can open the file of an application process.
open file of frontApp as alias
How can I get the error correction to work? Thanks.
It just occurred to me that the following script might be a more reliable approach, although I’d prefer not to have to specify every scriptable app.
set scriptableApps to {"Finder", "Script Editor"} -- add other app names
tell application "Finder"
set frontApp to first application process whose frontmost is true
set appName to name of frontApp
end tell
if appName is not in scriptableApps then
display dialog "There is not an AppleScript dictionary for " & appName buttons {"OK"} cancel button 1 default button 1 with icon stop
end if
tell application "Script Editor"
open file of frontApp as alias
activate
end tell
I guess that this fake script will help you to understand what you get :
tell application "Finder"
set frontApp to first application process whose frontmost is true
--> application process "Script Editor" of application "Finder"
end tell
tell application "Script Editor"
activate
set maybe to file of frontApp
log result --> (*alias SSD 1000:Applications:Utilities:Script Editor.app:*)
open maybe -- does nothing if the front app is Script Editor
end tell
set frontApp to (path to application "TextEdit") as alias
log result --> (*alias SSD 1000:Applications:TextEdit.app:*)
tell application "Script Editor"
activate
try
open frontApp -- as alias
on error errMsg number errNbr
display dialog "Error # " & errNumber & ", " & errMsg
end try
end tell
set frontApp to (path to application "LibreOffice") as alias
log result --> (*alias SSD 1000:Applications:Applications perso:LibreOffice.app:*)
tell application "Script Editor"
activate
try
open frontApp -- as alias
on error errMsg number errNbr
display dialog "Error # " & errNumber & ", " & errMsg
end try
end tell
My understanding is that the Editor doesn’t send its own error to the script itself.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 7 janvier 2020 17:55:10
Thanks Yvan. I now understand the code line I didn’t previously understand.
If Script Editor won’t send an error to the script itself, then that would explain why the try statement is not catching the error. So perhaps specifying scriptable apps in my second post is the way to go.
Maybe you may insert a piece of code scanning the package of the app:
----------------------------------------------------------------
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
use script "FileManagerLib" version "2.3.3"
----------------------------------------------------------------
script o
property theURLs : {}
end script
set theApp to path to application "Pages"
set o's theURLs to objects of theApp result type urls array with searching subfolders without include folders and include invisible items
set hasDictionary to false
repeat with aURL in o's theURLs
set theExtension to (aURL's pathExtension()) as text
if theExtension is in {"scriptTerminology", "scriptSuite", "sdef"} then
set hasDictionary to true
exit repeat
end if
end repeat
hasDictionary
I used FileManagerLib for this first draft but you may trigger the NSFileManager directly.
----------------------------------------------------------------
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
----------------------------------------------------------------
script o
property theURLs : {}
end script
set theApp to path to application "Pages"
set folderPath to POSIX path of theApp
set theURL to current application's class "NSURL"'s fileURLWithPath:folderPath
set fileManager to a reference to current application's NSFileManager's defaultManager()
set keysToRequest to {}
set theOptions to {current application's NSDirectoryEnumerationSkipsHiddenFiles}
set theEnumerator to fileManager's enumeratorAtURL:theURL includingPropertiesForKeys:keysToRequest options:theOptions errorHandler:(missing value)
set o's theURLs to (theEnumerator's allObjects())
set hasDictionary to false
repeat with aURL in o's theURLs
set theExtension to (aURL's pathExtension()) as text
if theExtension is in {"scriptTerminology", "scriptSuite", "sdef"} then
set hasDictionary to true
exit repeat
end if
end repeat
hasDictionary
In Pages we have a “sdef” file.
In TextEdit we have “scriptTerminology” and “scriptSuite” files but no “sdef” one.
I didn’t made more extensive search.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 7 janvier 2020 19:22:32
tell application id "com.apple.systemevents" -- System Events.app
set scriptable to has scripting terminology of (get first application process whose frontmost is true)
end tell
Thanks Shane. I incorporated your suggestion in my script and it works great.
tell application id "com.apple.systemevents"
set frontApp to first application process whose frontmost is true
set appDictionary to has scripting terminology of frontApp
set appName to name of frontApp
end tell
if appDictionary then
tell application "Script Editor"
open file of frontApp as alias
activate
end tell
else
display dialog appName & " does not have a dictionary." buttons {"OK"} ¬
cancel button 1 default button 1 with icon stop
end if
If you wanted to avoid system Events as well, you could use this:
use AppleScript version "2.5" -- macOS 10.11 or later
use framework "Foundation"
use framework "AppKit"
use scripting additions
set activeApp to current application's NSWorkspace's sharedWorkspace()'s frontmostApplication()
set theBundle to current application's NSBundle's bundleWithURL:(activeApp's bundleURL())
return ((theBundle's objectForInfoDictionaryKey:"NSAppleScriptEnabled") is not missing value)
On my Mac, that’s about 50 times quicker than System Events, which takes more than 0.1 seconds.
While working on this topic, I wrote a simple script which is functionally little different than selecting Open Dictionary from the File menu of Script Editor. The very-slight advantages of this script are 1) it contains only the dictionaries the user wants, and 2) it can be run just about any way a script can be run, which is not the case with my script included above. I tested this with most applications that have a dictionary but there may be a few that won’t work.
property defaultItem : missing value
set appList to {"Finder", "Mail", "Preview", "Safari", "Script Editor", "StandardAdditions", "System Events", "TextEdit"}
choose from list appList default items {defaultItem} with prompt "Select a Dictionary:"
if result = false then
error number -128
else
set selectedApp to item 1 of result
end if
if selectedApp = "StandardAdditions" then
set appPath to "Macintosh HD:System:Library:ScriptingAdditions:StandardAdditions.osax:" as alias
else
set appPath to path to application selectedApp
end if
tell application "Script Editor"
if selectedApp is in (name of every window) then
my raiseWindow(selectedApp)
else
activate
open appPath
end if
end tell
set defaultItem to selectedApp
on raiseWindow(selectedApp)
tell application "System Events" to tell process "Script Editor"
perform action "AXRaise" of window selectedApp
end tell
end raiseWindow
“Erreur dans Script Editor : Il est impossible d’obtenir alias (alias "SSD 1000:Applications:Safari.app:").” number -1728 from alias (alias “SSD 1000:Applications:Safari.app:”)
A small edit is required
tell application "Script Editor"
activate
open appPath -- EDITED because appPath is already an alias
end tell
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mercredi 8 janvier 2020 15:58:59
If you want simplicity and speed, Script Debugger’s OpenDictionary command is your answer. Separate lists of running, recent and favorite apps and script libraries, as well as Standard Additions and a general open command. As a bonus, you get a much more detailed presentation of the dictionary.
My script works fine and I’ll use it a lot, but I did encounter one small issue. To replicate:
Copy and paste the script contained below into Script Editor.
Run the script, which loads the Script Editor dictionary.
Without closing the dictionary, activate Script Editor and run the script again. This brings the Script Editor dictionary to the front but Script Editor continues to show “running” for about 5 seconds.
I wondered if anyone knew how to prevent my script from running as described in 3 above. This does have a practical consequence during normal use in that FastScripts is not responsive during the 5-second period. Thanks.
tell application "System Events"
set appProcess to first application process whose frontmost is true
set appName to name of appProcess
set appDictionary to has scripting terminology of appProcess
end tell
set appFile to path to application appName
if appDictionary then
tell application "Script Editor"
activate
open appFile
end tell
else
display dialog appName & " does not have a dictionary." buttons {"OK"} ¬
cancel button 1 default button 1 with icon stop
end if
I get the same result on my Mac with Script editor.
Even more interesting is: if I run it with SD with the Debugging option active, I get an error at: open file of activeApp as alias
This is the error:
Can’t make alias “iMac_HD:Applications:Script Debugger.app:” of application “System Events” into type alias.
This might help you in fix this strange behaviour.
L.
This is the script I used in SD:
tell application "System Events"
set activeApp to first application process whose frontmost is true
set appName to name of activeApp
set appDictionary to has scripting terminology of activeApp
end tell
if appDictionary then
tell application "Script Debugger"
open file of activeApp as alias
activate
end tell
else
display dialog appName & " does not have a dictionary." buttons {"OK"} ¬
cancel button 1 default button 1 with icon stop
end if
tell application "System Events"
set activeApp to first application process whose frontmost is true
set appName to name of activeApp
set appDictionary to has scripting terminology of activeApp
set thePath to path of (file of activeApp)
end tell
if appDictionary then
set maybe to appName & ".sdef"
tell application "System Events" to tell process "Script Editor"
tell menu bar 1 to tell menu bar item 9 to tell menu 1
set menuItems to name of menu items
--> {"Placer dans le Dock", "Placer toutes les fenêtres dans le Dock", "Réduire/agrandir", "Réduire/agrandir toutes les fenêtres", missing value, "Afficher l’onglet précédent", "Afficher l’onglet suivant", "Placer l’onglet dans une nouvelle fenêtre", "Fusionner toutes les fenêtres", missing value, "Tout ramener au premier plan", "Mettre au premier plan", missing value, "Historique", "Bibliothèque", missing value, "Enregistrer comme réglage par défaut", missing value, "get language code.scpt", "Pages.sdef", "Sans titre", "Sans titre 2", "System Events.sdef"}
if menuItems contains maybe then -- if Finder show extensions
click menu item maybe
return -- exit the script
end if
if menuItems contains appName then -- if Finder doesn't show extensions
click menu item appName
return -- exit the script
end if
end tell
end tell
tell application "Script Editor"
open file thePath
activate
end tell
else
display dialog appName & " does not have a dictionary." buttons {"OK"} ¬
cancel button 1 default button 1 with icon stop
end if
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) jeudi 9 janvier 2020 19:10:39