Script which may change your AppleScripting Life

Hello.

“Script which may change your AppleScripting Life”
It sounds like an ambitous title doesn’t it, but it is true. I wrote this since:
:mad:
¢ Navigating through folder to get the path of the scripts again and again was boring.
¢ And even more boring is finding the right paths to the load script statement.
¢ Still more boring and time consuming is navigating and finding the right file to stuff that fancy handler into.
¢ It is also boring to have to switch to the Finder and navigate to that folder some library script or snippet is stored in.
:mad:

Its main strength is providing easy access to resources you may need while writing a script.

Epilogue
I have assigned ScriptLibraryLoader to the global short cut control cmd L in the short cut utility I use. Spark is a great free shortcut manager that stores the properties of the script upon exit. Spark can be downloaded here. This makes it easy to me to open files while for instance browsing on MacScripter.net and add stuff to my collections, as well as handy when I want to create a library loader during scripting. -I use this a lot more than I usually do after the period where I was thrilled about having written it is over. At the end of the day: II find very useful as a sidekick when AppleScripting.

Comments
It is a little localized so you will get button names etc. in your local language, and I have strived for making it compatible with Tiger. Should you localize the rest of the text of the script, then it would be very nice if you contacted me, as I have plans for a fully localized version.

Finally
I hope you find ScriptLibraryLoader useful too.
Enjoy!

:smiley: (If you find it cool, or that it generally sucks, don’t hesitate to tell me!) :smiley:

Best Regards

McUsr

Documentation of ScriptLibraryLoader

[b]Abstract

This script helps you to:

¢ Achieve a smoother workflow when scripting, because you don’t have to visit other folders
¢ Makes it a lot easier to “stuff in” the handlers in the Library files where they belong.
¢ A lot faster access to your library folders and files by getting there automatically.
¢ Gets “load script” statements instantaneously by only choosing file to create statement from.
¢ Differentiates standard
load library statements from AppleMods: can be downloaded from here.
¢ It is easy to implement
special support for your own ScriptServers.
¢ These factors lead to a much more organized and easy to navigate scripting environment.
[/b]

Facts

¢ The script now uses [b][color=blue]Allan Craig's[/color] [url=http://allancraig.net/index.php?option=com_docman&task=cat_view&Itemid=100&gid=51&orderby=dmdate_published&ascdesc=DESC/]getModKey[/url][/b] when the script is run. [b][color=red]You need to install [/color][color=blue]getModKey[/color][color=red] in order to
   make the script work properly Instructions follow below[/color][color=blue] (**)[/color][/b].
  
¢ It creates [b]load script statments[/b] and copies the to the clipboard so that you can paste them straight
  into the code as property statements.
¢ It remembers the path to the folder from the last [b][color=blue]choose file dialog[/color][/b] so that you can continue where
  you left off. Should you surpass the realms of the library, it will remember the last path within the library path.[b]
¢ Standard Modus operandi[/b] is to display a [b][color=blue]choose from list[/color] dialog[/b] with the operations:

    [b]¢Load File in Editor
    ¢Reveal in Finder
    ¢Create Load Statmenent[/b]
    
¢ There are shortcuts to bypass this dialog and and perform the preferred action directly, while
   pressing a predfined [b]key modifier[/b] while selecting a file in the [b][color=blue]choose file [/color] dialog:

    ¢Press [color=blue]cmd[/color] key while confirming to just open the file.
    ¢Press [color=blue]control[/color] key while confirming to Reveal File in Finder.
    ¢Press [color=blue]control cmd[/color] to make Load  Statement for the Library - if it is.[/b]

¢ The script reacts to which script editor is currently active and loads the file into it.
¢ If you hit Esc when choosing files, you are taken to a list of your predefined libraries.
¢ The script is localized thanks to [b][color=blue]Yvan KOENIG[/color][/b]

[b]About the user interface.[/b]

Great care have been taken to provide an as smooth as possible experience of using this script while retaining the necessary functionality.

¢ You may choose a file from anywhere you want in one the [b][color=blue]choose file[/color] dialog[/b] -it will only remember paths and create load
   statements from within a specified Library path.
¢ You may get a question the first time you cancel a dialog, but after the second time, it just quits.
¢ You can get back to the initial [b][color=blue]choose file[/color] dialog[/b] from the input of library name dialog, should you so wish, so you don't have
  to start over again if you picked the wrong library.

Installation

The script is to be installed from somewhere it can be reached from your script-editors that is.
Not in any script editors application folder, unless you create aliases to the others should you use more than one. -The idea is to always retain the last path to the libraries, so that you don’t have to “re navigate” like you would if you should open them from script editor. And having access to the script from other apps is also nice!

You must of course also perform the initial configuration:[b]

¢ Provide your library paths and other paths, and strings to specify them in the dialogs. Library paths must
  come before paths to clippings and snippets folders.

¢ You must also update the list of booleans which specify wether this path is AppleMods compatible or not.
  If you want the script to provide support for your own script servers, you will have to figure out the necessary tests
  for your self.[/b]

[b]color=blue Installation of Alan Craig’s getModKey[/color]

When you have downloaded getModKey, you should open up a Terminal window;

Enter the following commands or copy from here and past into terminal window.

[code] cd ~/Downloads # (Enter)
ls getModKey # (Enter) This verifies that the file is actually there.
sudo cp getModKey /usr/local/bin # (Enter) !! assuming this is were your store your extra unix utilities.

(you are asked to enter your password, and that is perfectly normal.)

echo “You have now successfully installed Alan Craig's getModKey:”
ls -l /usr/local/bin/getModKey[/code]
You must also edit the do shell script line in the script which uses getModKey so that it has the correct path

[b]Examples of load Statements

The generated load statements is pasted to the clipboard, and you have to take over from there.[/b]

Example of a regular library loader script library statement


property thePribLib : ( load script alias "Macintosh HD:Library:Scripts:Modules:priorityLib.scpt")

Example of created AppleMods loader statement.


property _Loader : run application "LoaderServer"
property listLib : missing value
on __load__(loader)
    set my listLib to loader's loadLib("List ")
end __load__

The Script which is ScriptLibraryLoader



-- The Idea and implementation and any faults is totally mine. © McUsr 2010 and put in the Public Domain.
-- The usually guarrantees about nothing what so ever applies, use it at your own risk.
-- Read the documentation.
-- You are not allowed to post this code elsewhere, but may of course refer to the post at macscripter.net.
-- macscripter.net/viewtopic.php?id=33487
(*
TERMS OF USE. 
This applies only to posting code, as long as you don't post it, you are welcome to do
whatever you want to do with it without any further permission. 
Except for the following: Selling the code as is, or removing copyright statmentents and the embedded link in the code (without the http:// part) from the code. 

You must also state what you eventually have done with the original source. This obviously doesn't matter if you  distribure AppleScript as read only. I do not require you to embed any properties helding copyright notice for the code.

Credit for having contributed to your product would in all cases be nice!

If you use this code as part of script of yours you are of course welcome to post that code with my code in it here at macscripter.net. If you then wish to post your code elsewhere after having uploaded it to MacScripter.net please email me and ask for permission.

The ideal situation is however that you then refer to your code by a link to MacScripter.net
The sole reason for this, is that it is so much better for all of us to have a centralized codebase which are updated, than having to roam the net to find any usable snippets. Which some of us probabaly originated in the first hand.

I'm picky about this. If I find you to have published parts of my code on any other site without previous permission, I'll do what I can to have the site remove the code, ban you, and sue you under the jurisdiction of AGDER LAGMANNSRETT of Norway. Those are the terms you silently agree too by using this code. 

The above paragraphs are also valid if you violate any of my terms.

If you use this or have advantage of this code in a professional setting, where professional setting means that you use this code to earn money by keeping yourself more productive. Or if you as an employee share the resulting script with other coworkers, enhancing the productivity of your company, then a modest donation to MacScripter.net would be appreciated.
*)
-- script for localizing the dialogs were kindly given to my by KOENIG,Yvan.
-- The call chain and any problems that may cause is solely a responsibility of mine.

script localButtons -- ©  KOENIG,Yvan
    property parent : AppleScript
    property Cancel_loc : missing value
    --    property Save_loc : missing value
    property Continue_loc : missing value
    property Ok_loc : missing value
    --    property Authenticate_loc : missing value
    -- property Skip_loc : missing value
    -- property Delete_loc : missing value
    --    property Eject_loc : missing value
    on initializeLocalizationValues()
        set localButtons's Cancel_loc to localButtons's getLocalizedString("Finder", "AL1") -- Annuler
        -- set localButtons's Save_loc to localButtons's getLocalizedString("Finder", "AL2") -- Enregistrer
        set localButtons's Continue_loc to localButtons's getLocalizedString("Finder", "AL3") -- Continuer
        set localButtons's Ok_loc to my getLocalizedString("Finder", "AL4") -- OK
        --set localButtons's Authenticate_loc to localButtons's getLocalizedString("Finder", "AL5") -- Authentifier
        -- set localButtons's Skip_loc to my getLocalizedString("Finder", "AL6") -- Ignorer
        --set localButtons's Delete_loc to localButtons's getLocalizedString("Finder", "AL7") -- Supprimer
        --set localButtons's Eject_loc to localButtons's getLocalizedString("Finder", "AL8") -- Éjecter
    end initializeLocalizationValues
    on getLocalizedString(a, x)
        tell application a to return localized string x
    end getLocalizedString
end script

property parent : my localButtons
property isDegugging : true
property Scriptversion : "0.3"
property LibraryTitles : {"AppleMods", "Local Modules", "User Modules", "Snippets 1", "Harvest", "Clippings"}

-- Snippets 1 is a standard name, it will take you to your applescript snippets folder. remember the last path here also
-- but loads the file without any option of pasting a load script statement, naturally.
-- Snippets 2 is a nother snippets folder.
-- wants to add a save path part so that I easily can make a new file in some predef structure, scripts only
-- then have it open automatically. -- choose folder give up a filename, create, open.

property LastRealLibraryIndex : 3 -- Controls wether there will be created load statements or opened files automatically By the type of library.
property LibraryPaths : {} -- holds a list of paths to library and script folder sub-trees.
property AppleModsCompatible : {} -- helds boolean values controlling if there will be generated statements for applemods libraries or not
property AsEditors : {"Script Debugger 4.5", "AppleScript Editor", "Smile"}
property script_title : "ScriptLibraryLoader"
property activePath : {}
property ActiveLibIndex : 0
property LastCommandIndex : 0
property commandMenu : {}
property scriptObjectName : ""
on run
    local ctrContinueAskFromChooseLibrary, ctrContinueAskFromChooseCommand, blnIsWithinRealm, intkeyPress
    set ctrContinueAskFromChooseLibrary to 0
    set ctrContinueAskFromChooseCommand to 0
    set ctrContinueAskFromCreateLoadStatement to 0 -- these two prevents silly second time questions if wants to continue.
    set intkeyPress to 0
    
    if LibraryPaths is {} then -- initial initializing.
        initializeLocalizationValues() -- values for localized buttons.
        set AsLibraries to my smartPathParadigm's initiateSmartPath({}, "Macintosh HD:Library:Scripts:ASLibraries:")
        set LocalModules to my smartPathParadigm's initiateSmartPath({}, "Macintosh HD:Library:Scripts:Modules:")
        set UserModules to my smartPathParadigm's initiateSmartPath({}, "Macintosh HD:Users:You:Library:Scripts:Modules:")
        
        
        -- those are not real libraries, the contain clippings, snippets and such, shall allways be opened a file when 
        -- a file from any of those libraries are chosen
        set Snippets1 to my smartPathParadigm's initiateSmartPath({}, "Macintosh HD:Users:You:Documents:AppleScriptSnippets:")
        set Snippets2 to my smartPathParadigm's initiateSmartPath({}, "Macintosh HD:Users:You:Documents:AppleScript Harvest:")
        set clippings to my smartPathParadigm's initiateSmartPath({}, "Macintosh HD:Users:You:Documents:AppleScriptSnippets:Clippings:")
        set my LibraryPaths to {AsLibraries, LocalModules, UserModules, Snippets1, Snippets2, clippings}
        set my AppleModsCompatible to {true, false, false} -- controls whether there will be generated load statement for applemods    
        set my ActiveLibIndex to 1
        set activePath to a reference to item (my ActiveLibIndex) of my LibraryPaths -- because that suits me best.
        set questionMark to a reference to file "Macintosh HD:System:Library:CoreServices:CoreTypes.bundle:Contents:Resources:GenericQuestionMarkIcon.icns"
        set libraryIcon to a reference to file "Macintosh HD:System:Library:CoreServices:CoreTypes.bundle:Contents:Resources:ToolbarLibraryFolderIcon.icns"
        set alertNoteIcon to a reference to file "Macintosh HD:System:Library:CoreServices:CoreTypes.bundle:Contents:Resources:AlertNoteIcon.icns"
        set unsupportedIcon to a reference to file "Macintosh HD:System:Library:CoreServices:CoreTypes.bundle:Contents:Resources:Unsupported.icns"
        -- Amendments
        set my LastCommandIndex to 1
        set commandMenu to {"Load in Editor", "Reveal in Finder", "Create Load Statmenent"}
    end if
    set currentApp to getFrontApp() as list
    set done to false
    set changedMind to true
    set firstEntry to true
    
    -- INITIAL STAGES
    repeat while changedMind is true
        pop()
        if changedMind is true and firstEntry is true then
            set changedMind to false -- so we can get out of here again.
        end if
        repeat while done is false -- DONE IS BAADER THAN changedMind
            -- the test which is implemented here is or should not be necessary but still is in a real world.
            -- it should be done the every time the path is changed.
            -- we test if the path still exists, if it does then every thing is fine.
            
            -- FACTOR THIS ONE OUT
            try
                activePath's getPrevPath() as alias
            on error
                -- could have traveled on step above here and will do.
                activePath's setPrevPath(activePath's getInitialPath())
                -- a restore to or resetToInitialPath() is much smoother.
                try
                    activePath's getPrevPath() as alias
                on error
                    -- the whole librarypath is gone, do you wish to edit the script?
                    tell me
                        activate
                        basso()
                        display alert (my script_title & ": the path of " & (item ActiveLibIndex of LibraryTitles) & " doesn't exist. Loads script")
                    end tell
                    
                    if AsEditors contains currentApp then
                        tell application (currentApp as text) to open (path to me as text)
                    else
                        tell application "Finder" to open (path to me as text)
                    end if
                    pop()
                    return -- no reason to save any properties now!
                end try
            end try
            -- END FACTORING.
            -- if it is not , then we "fall back to the initial path silently,  and if that doesn't exist then we must 
            -- alert the user, the user will then be given the ability to edit the script within the current editor if any.
            
            -- Sound changes, I basically tried to use sound to make it kind of rewarding, - well those sounds were a failiure,
            -- I have tried to change that by issuing a lesser number of sounds, and a different sound, I have changed that to 
            -- more happy system sound..
            repeat -- CHOOSE FILE - CHOOOSE LIBRARY IF DISSATISFIED WITH PATH
                tell application "System Events"
                    tell application process "Finder"
                        activate
                        try
                            set theScriptLibrary to choose file with prompt (script_title & " : choose  Library, Snippet or Clippings file  to Open in The Editor, Reveal in Finder, or Create a Load statement onto the Clipboard for.
    Available  shortcuts for bypassing next action menu:
    Press CMD  key while selecting to just OPEN the file.
    Press CONTROL key while selecting to REVEAL File in Finder.
    CONTROL cmd to make LOAD  Statement for the Library.") default location (activePath's getPrevPath()) as alias
                            -- my pop()
                            --    display dialog "Path to parent folder er : " & activePath's getPathToParentFolder(theScriptLibrary as text)
                            activePath's updatePrevPath(theScriptLibrary as text)
                            -- display dialog "Prev path er nå : " & activePath's getPrevPath()
                            -- display dialog "Smart path's prev path er nå " & my smartPathParadigm's prevPath
                            set done to true
                            exit repeat -- Exits the choice of library location and  file from here
                        on error e number n
                            my morse()
                            -- FALL BACK PATTERN ??? -- should only be invoked if the same library are chosen the next time.
                            -- display dialog e & " : " & n
                            -- We just "falls through" (falls back) to the next menu if user cancels choose file.
                        end try
                    end tell
                end tell
                
                tell me
                    activate
                    set prevLibIndex to (my ActiveLibIndex)
                    set theResult to choose from list my LibraryTitles default items (item (my ActiveLibIndex) of my LibraryTitles) with title "Choose the active libraryPath" OK button name Ok_loc cancel button name Cancel_loc
                end tell
                
                if theResult is not false then
                    pop() -- skal gjøre et filvalg
                    -- FALL BACK PATTERN: spesielt her fordi vi trenger å sjekke om forrige lib-index er den samme som den neste.
                    -- Ett vellykket filvalg stanser fall back pattern, da setter vi forrige index lik denne index.
                    -- hva vi gjør når vi igjen går tilbake er litt uvisst, jeg har 
                    -- hvis counteren som var 0 nå er 1 så bytter vi, (kanskje til parent ) 
                    -- dette avhenger jo av om vi har noe å gå på når det gjelder forskjell på path lengde.
                    -- hvis parent så kan vi bytte dist nr med foldere tilbake, når vi treffer counter er det stopp.
                    
                    
                    set my ActiveLibIndex to my IndexOfItem(theResult as text, LibraryTitles)
                    -- FALL BACK PATTERN:
                    if prevLibIndex is equal to ActiveLibIndex then
                        -- et clou her er at vi ikke fikk noe path i forrige omgang siden vi ikke åpnet noen fil
                        if activePath's getPrevPath() is not activePath's getInitialPath() then
                            tell activePath to setPrevPath(getPathToParentFolder(getPrevPath()))
                            -- activePath's setPrevPath(activePath's getPathToParentFolder(activePath's getPrevPath()))
                        end if
                    end if
                    set my activePath to a reference to item (my ActiveLibIndex) of my LibraryPaths
                    (*
                    metode:
                    Tar alltid vare på forrige library path, som er activeLibIndex,
                    har en verdi hvis vi defaulter på en eller annen måte.
                    
                    *)
                    exit repeat -- Reenters the outer loop and chooses a file from that location.
                else
                    set ctrContinueAskFromChooseLibrary to ctrContinueAskFromChooseLibrary + 1
                    if ctrContinueAskFromChooseLibrary < 2 then
                        tell me
                            activate
                            try
                                morse()
                                display dialog "" & my Continue_loc & "?" with title my script_title with icon my questionMark
                                exit repeat
                            on error
                                withDraw(currentApp as text)
                            end try
                        end tell
                    else
                        withDraw(currentApp as text) -- we die directly upon question for the second time.
                    end if
                    
                end if
            end repeat
        end repeat -- HAVE CHOSEN A FILE WE WE WANTED TO DO "STUFF" WITH.
        
        -- we do a "realm check" here and only updates the prev path, if current path
        -- is within the realm. This also controls wether there will be generated an appleMods 
        -- of course it does.
        
        set libraryBaseName to txtHfsBaseName(theScriptLibrary as text)
        
        set blnIsWithinRealm to my activePath's withinRealm(theScriptLibrary as text)
        -- this tells us if the user has surpassed the inital realm of the library path.
        -- this indirectly controls wheter there will be generated a load statement or not.
        
        if blnIsWithinRealm is true then my activePath's updatePrevPath(theScriptLibrary as text) -- saves the path for next time
        
        if changedMind is false then -- some variables to define the logic here. only sets them the first time
            -- sets these statements to their initial values, they are later to be changed. internally.
            set willOpenTheFileOnly to false
            set willRevalInFolder to false
            set willMakeLoadStatement to false
        end if
        
        repeat -- EXECUTING COMMANDS  ON THAT SINGLE FILE UNTIL WE ARE SATISFIED.
            -- The logic of this script is rather strange as we look for commands first
            -- then looks for the commands to execute, but this implemented as an event loop
            -- and this has so far led to the least complex solution. 
            -- The solution will necessarily be complex, when a high degree of user interaction is feasible.
            -- ** ONE SINGLE POLL FOR KEYBOARD HERE.
            -- sets the state accordingly
            -- ** tests for state
            set intkeyPress to do shell script "/usr/local/opt/getModKey"
            set intkeyPress to intkeyPress as integer
            if ((intkeyPress is equal to 4352) or willMakeLoadStatement is true) then -- ctrl cmd is pressed 
                
                if changedMind is true then set changedMind to false -- because we want to exit the outer loop when we are done
                
                if my ActiveLibIndex ≤ my LastRealLibraryIndex and blnIsWithinRealm is true then -- only creates load statements from library paths.
                    set doneWithLoadStatement to false
                    repeat while doneWithLoadStatement is false
                        repeat
                            tell me
                                activate
                                try
                                    display dialog "Enter a name for property you want  the script object : " & libraryBaseName & " to be loaded into" default answer "" with title my script_title with icon libraryIcon
                                    set my scriptObjectName to text returned of result
                                    ping()
                                on error
                                    set my scriptObjectName to ""
                                end try
                            end tell
                            if not my scriptObjectName is "" then
                                set doneWithLoadStatement to true
                                exit repeat
                            else
                                set ctrContinueAskFromCreateLoadStatement to ctrContinueAskFromCreateLoadStatement + 1
                                if ctrContinueAskFromCreateLoadStatement < 2 then
                                    tell me
                                        try
                                            set theRes to display dialog "" & my Continue_loc & "?" with title my script_title with icon my questionMark buttons {"Other Action", Cancel_loc, Continue_loc} cancel button 2 default button 1
                                            set uChoice to button returned of theRes
                                            if uChoice is "Other Action" then
                                                morse()
                                                set changedMind to true
                                                set willMakeLoadStatement to false
                                                set doneWithLoadStatement to true
                                                exit repeat
                                            else
                                                pop()
                                                -- falls through and redisplays the commands
                                            end if
                                            exit repeat
                                        on error
                                            withDraw(currentApp as text)
                                        end try
                                    end tell
                                else
                                    withDraw(currentApp as text) -- we die directly upon question for the second time. -- we die directly rather than new question for the second  time. **
                                end if
                                
                            end if
                        end repeat
                    end repeat
                    
                    if changedMind is false then
                        -- time to construct the load script object handler
                        -- must figure if we shall create an APPLEmods load statement or an usual load statement.
                        if (item (my ActiveLibIndex) of AppleModsCompatible) is true and libraryBaseName is "Library.scpt" then -- create for AppleMods
                            
                            -- must get the parent folder of the file we want to load.
                            set actualLibraryName to getTextItemOfHFS(theScriptLibrary as text, -2)
                            -- should add a check for the name of the file, should be library.
                            -- preliminary check if the filename is correct.
                            
                            set the incantation to "property _Loader : run application \"LoaderServer\"
"
                            set the incantation to the incantation & "property " & scriptObjectName & " : missing value 
    on __load__(loader)
        set  my " & scriptObjectName & " to loader's loadLib(\"" & actualLibraryName & " \")
    end __load__"
                            -- SHOULD YOU HAVE YOUR OWN SCRIPTSERVERS, HERE IS THE PLACE TO ADD THEM
                            -- YOU SHOULD CREATE A LIST WITH THE BOOLEAN VALUES FOR WHICH LIBRARIES FOR YOUR SCRIPT SERVER.
                        else
                            if (item (my ActiveLibIndex) of AppleModsCompatible) is true then
                                display dialog "I only generate AppleMods loader statements for \"Library.scpt\" files.
I will however create a \"normal\" loader statement for the library you choosed." with title script_title with icon unsupportedIcon buttons {Ok_loc}
                                --                                do shell script "/usr/bin/afplay /System/Library/Sounds/Basso.aiff"
                                basso()
                                
                            end if
                            set the incantation to "property  " & scriptObjectName & " : ( load script alias \"" & theScriptLibrary & "\")"
                            
                        end if
                        set the clipboard to the incantation
                        ping()
                        
                        tell me
                            activate
                            display dialog "All done
You can get your loader statement from the clipboard!" giving up after 1 with title script_title with icon alertNoteIcon buttons {Ok_loc}
                        end tell
                        
                        tell application ("" & currentApp) to activate
                    end if
                else -- Couldn't make load statement, loads the file
                    -- subroutine
                    ping()
                    if AsEditors contains currentApp then
                        tell application (currentApp as text)
                            activate
                            open theScriptLibrary
                            tell its window 1 to activate
                        end tell
                    else
                        tell application "Finder" to open theScriptLibrary -- her kommer det noe mere!
                    end if
                end if
                exit repeat -- changedMind
            end if -- CREATING LIBRARY STATEMENT.
            -- ** State changed
            
            if ((intkeyPress is equal to 256) or willOpenTheFileOnly is true) then -- cmd were pressed
                -- THIS IS THE "OPEN FILE" CHOICE
                if changedMind is true then set changedMind to false -- because we want to exit the outer loop when we are done
                if AsEditors contains currentApp then
                    tell application (currentApp as text)
                        activate
                        open theScriptLibrary
                        tell its window 1 to activate
                    end tell
                else
                    tell application "Finder" to open theScriptLibrary
                end if
                ping()
                
                exit repeat -- changedMind 
            end if
            -- ** state changed 
            
            if ((intkeyPress is equal to 4096) or willRevalInFolder is true) then -- control were pressed 
                -- WILL SHOW FILES IN THE FOLDER
                if changedMind is true then set changedMind to false -- because we want to exit the outer loop when we are done
                tell application "Finder"
                    try
                        reveal theScriptLibrary
                    on error e number n
                        display dialog e & " : " & n
                    end try
                end tell
                ping()
                exit repeat -- changedMind
            end if
            
            repeat -- parsing commands 
                if changedMind is true then set changedMind to false
                tell me
                    activate
                    if my ActiveLibIndex ≤ my LastRealLibraryIndex then -- only creates load statements from library paths.
                        -- THIS IS THE REALM OF THE LIBRARY LISTER
                        
                        set theResult to choose from list my commandMenu default items (item (my LastCommandIndex) of (my commandMenu)) with title (script_title & " - Current File " & libraryBaseName) OK button name Ok_loc cancel button name Cancel_loc
                    else
                        if my LastCommandIndex > my LastRealLibraryIndex then set my LastCommandIndex to 1
                        set theResult to choose from list items 1 thru (my LastRealLibraryIndex) of my commandMenu default items (item (my LastCommandIndex) of (my commandMenu)) with title (script_title & " - Current File " & libraryBaseName) OK button name Ok_loc cancel button name Cancel_loc
                    end if
                end tell
                if theResult is not false then
                    set my LastCommandIndex to my IndexOfItem(theResult as text, my commandMenu)
                    if LastCommandIndex is 1 then
                        set willOpenTheFileOnly to true
                    else if LastCommandIndex is 2 then
                        set willRevalInFolder to true
                    else
                        set willMakeLoadStatement to true
                    end if
                    exit repeat
                else
                    morse()
                    set ctrContinueAskFromChooseCommand to ctrContinueAskFromChooseCommand + 1
                    if ctrContinueAskFromChooseCommand < 2 then
                        tell me
                            activate
                            try
                                set theRes to display dialog "" & my Continue_loc & "?" with title my script_title with icon my questionMark buttons {"Re Elect file", Cancel_loc, Continue_loc} cancel button 2 default button 1
                                set uChoice to button returned of theRes
                                if uChoice is "Re elect file" then
                                    set changedMind to true
                                    exit repeat
                                else
                                    -- falls through and redisplays the commands
                                    pop()
                                end if
                            on error e number n
                                withDraw(currentApp as text) -- user hit cancel so we die.
                            end try
                        end tell
                    else
                        withDraw(currentApp as text) -- we die directly upon question for the second time.
                    end if
                end if
                
            end repeat -- parsing commands.
            if changedMind is true then
                set done to false
                exit repeat
            end if
        end repeat -- executing commands.
    end repeat -- changed mind
    return "0"
end run

on withDraw(theCurrentApp)
    basso()
    tell application (theCurrentApp as text)
        activate
        tell me to error number -128
    end tell
end withDraw


on checkForValidOsVersion()
    local Major
    set Major to ((system attribute "sysv") mod 256 div 16) -- Thanks again to Nigel Garvey
    if Major < 4 then
        tell me
            activate
            display alert "Versions of Mac Os X earlier than 10.4.0 is unsupported: your version is 10." & Major & "xx"
            error number -128
        end tell
    end if
end checkForValidOsVersion

on getFrontApp()
    -- macscripter.net/viewtopic.php?id=22375 Regulus6633 /Nigel Garvey 
    set colon to ":" as Unicode text
    set dot to "." as Unicode text
    set appPath to (path to frontmost application as Unicode text)
    considering case
        if (appPath ends with colon) then
            set n to -2
        else
            set n to -1
        end if
        set astid to AppleScript's text item delimiters
        set AppleScript's text item delimiters to colon
        set appname to text item n of appPath
        if (appname contains dot) then
            set AppleScript's text item delimiters to dot
            set appname to text 1 thru text item -2 of appname
        end if
        set AppleScript's text item delimiters to astid
    end considering
    
    return appname
end getFrontApp

on IndexOfItem(theItem, theList) -- credit to Emmanuel Levy but I modified it with the considering case statements
    considering case
        set text item delimiters to return
        set theList to return & theList & return
        set text item delimiters to {""}
        try
            -1 + (count (paragraphs of (text 1 thru (offset of (return & theItem & return) in theList) of theList)))
        on error
            0
        end try
    end considering
end IndexOfItem

on getTextItemOfHFS(theText, theItemNUmber)
    local theTids
    set theTids to AppleScript's text item delimiters
    set AppleScript's text item delimiters to {":"}
    if theItemNUmber ≤ (count of text items of theText) then
        set theText to text item theItemNUmber of theText
        set theText to theText as text
    else
        set theText to ""
    end if
    set AppleScript's text item delimiters to theTids
    return theText
end getTextItemOfHFS

on txtHfsBaseName(hfsFileNameAsText)
    local tedim, hfsbasename
    set tedim to text item delimiters
    set text item delimiters to ":"
    set hfsbasename to text item -1 of hfsFileNameAsText as text
    set text item delimiters to tedim
    return hfsbasename
end txtHfsBaseName

on txtHfsParentPath(hfsFileNameAsText)
    local tedim, hfsParentPath
    set tedim to text item delimiters
    set text item delimiters to ":"
    set hfsParentPath to text items 1 thru -2 of hfsFileNameAsText as text
    set text item delimiters to tedim
    return hfsParentPath
end txtHfsParentPath

on pop()
    ignoring application responses
        tell application "SoundServer" to pop(50)
    end ignoring
end pop

on ping()
    ignoring application responses
        tell application "SoundServer" to ping(50)
    end ignoring
end ping

on basso()
    ignoring application responses
        tell application "SoundServer" to basso(50)
    end ignoring
end basso

on morse()
    ignoring application responses
        tell application "SoundServer" to morse(50)
    end ignoring
end morse



-- See macscripter.net/viewtopic.php?pid=129895#p129895 For Documentation
-- © McUsr 2010 and put in the public domain.
script smartPathParadigm
    property McUsr : "1.0"
    property initialPath : ""
    property prevPath : ""
    -- maybe remake the object model a little as well.
    on makeSmartPath(hfsInitialPathAsText)
        script o
            property parent : smartPathParadigm
            property initialPath : "" & hfsInitialPathAsText -- doesn't harm
            property prevPath : ""
        end script
        o
    end makeSmartPath
    
    on getInitialPath()
        -- gets the initial path from the last initialization
        my initialPath
    end getInitialPath
    
    on getPrevPath()
        -- gets the previous path. - there is no current.
        if my prevPath is "" then
            my initialPath
        else
            my prevPath
        end if
    end getPrevPath
    
    on updatePrevPath(hfsReturnedPathAsText)
        -- sets the previous path to this parent folder of the path delivered.
        local newPath
        --    set hfsReturnedPathAsText to "" & hfsReturnedPathAsText
        set newPath to smartPathParadigm's getPathToParentFolder(hfsReturnedPathAsText)
        
        if my prevPath is not newPath then
            set my prevPath to newPath
        end if
    end updatePrevPath
    
    on withinRealm(hfsFilePathAsText)
        -- check to see if a path is in within the realm of the initial path.
        --    set hfsFilePathAsText to "" & hfsFilePathAsText
        if hfsFilePathAsText contains my initialPath then
            return true
        else
            return false
        end if
    end withinRealm
    
    on setPrevPath(hfsNewPrevPathAsText)
        -- sets a path literally
        --        set hfsNewPrevPathAsText to "" & hfsNewPrevPathAsText -- doesn't harm
        set my prevPath to hfsNewPrevPathAsText
    end setPrevPath
    
    on initiateSmartPath(scoForPath, hfsIntialPathAsText)
        -- constructor which allows reuse.
        script o
            property pathobj : scoForPath
        end script
        --    set hfsIntialPathAsText to "" & hfsIntialPathAsText
        if scoForPath is {} then
            set o's pathobj to smartPathParadigm's makeSmartPath(hfsIntialPathAsText)
        else
            set o's pathobj's initialPath to hfsIntialPathAsText
            set o's pathobj's prevPath to ""
        end if
        o's pathobj
    end initiateSmartPath
    
    on getPathToParentFolder(hfsFileOrFolderPathAsText)
        -- return sparehtn folder.
        local tids, theFile
        --set hfsFileOrFolderPathAsText to "" & hfsFileOrFolderPathAsText -- doesn't harm.
        set tids to AppleScript's text item delimiters
        set AppleScript's text item delimiters to ":"
        if character (length of hfsFileOrFolderPathAsText) of hfsFileOrFolderPathAsText is ":" then
            set hfsFileOrFolderPathAsText to text items 1 thru -3 of hfsFileOrFolderPathAsText
        else
            set hfsFileOrFolderPathAsText to text items 1 thru -2 of hfsFileOrFolderPathAsText
        end if
        set hfsFileOrFolderPathAsText to "" & hfsFileOrFolderPathAsText -- necessary here.
        set AppleScript's text item delimiters to tids
        return hfsFileOrFolderPathAsText
    end getPathToParentFolder
end script

The Sound Server (SoundServer.App)
Takes care of sound management in order to save cycles in the script, without rendering the script without a sound lest the chime or beep.

Save this in an Application folder as an stay open application.
It uses 0% cpu on my machine, and 13.Mb of virtiual memory (real mem) and 2 threads, it is not that resource hog.
It has an idle handler that kicks in every 24 hours, you shouldn’t notice if it were there even if you have only 0,5 GB of memory.

Use Dock Dogder to make it an invisible app when you saved it in your applications folder. Dock Dodger can be downloaded from here.



on pop(intNewVolume)
    local originalOutput, originalMuted
    set {output volume:originalOutput, output muted:originalMuted} to (get volume settings)
    set volume output volume intNewVolume without output muted
    do shell script "/usr/bin/afplay /System/Library/Sounds/Pop.aiff"
    set volume output volume originalOutput output muted originalMuted
end pop

on morse(intNewVolume)
    local originalOutput, originalMuted
    set {output volume:originalOutput, output muted:originalMuted} to (get volume settings)
    set volume output volume 20 without output muted
    do shell script "/usr/bin/afplay /System/Library/Sounds/Morse.aiff"
    set volume output volume originalOutput output muted originalMuted
end morse

on ping(intNewVolume)
    local originalOutput, originalMuted
    set {output volume:originalOutput, output muted:originalMuted} to (get volume settings)
    set volume output volume intNewVolume without output muted
    do shell script "/usr/bin/afplay /System/Library/Sounds/Ping.aiff"
    set volume output volume originalOutput output muted originalMuted
end ping

on basso(intNewVolume)
    local originalOutput, originalMuted
    set {output volume:originalOutput, output muted:originalMuted} to (get volume settings)
    set volume output volume intNewVolume without output muted
    do shell script "/usr/bin/afplay /System/Library/Sounds/Basso.aiff"
    set volume output volume originalOutput output muted originalMuted
end basso


-- runs periodically the time intervals it returns.
-- called as soon as the run handler has finished
-- What happens if an applet is just launched with its idle handler?
on idle
    return 86400
end idle

-- this routine is provided for centralized cleanup like setting back AppleScript's text item delimiters.
on quit
    -- error number -128 -- comment this wen saved as a stay open handler
    -- uncomment line below when saved as a stay open applet.
    continue quit
end quit

Hello.

Updated documentation

Best Regards

McUsr

Hello.

Added support for Localization thanks to Yvan Koenig.

Added a fallback pattern, so that if you hit escape while choosing files you are taken to a choose from list to
choose another library tree to select files from.

Added a LastLibraryIndex variable. I use it to get easily to predefined paths, which contains snippets and clippings and such. Those are stored in the list after lastLibraryIndex. This makes it just load the file and not create a load script statement.

Documentation needs and update

Best Regards

McUsr

Hello.

I recently removed a couple of minor glitches.

It is left to make 100% compatible with Tiger.

Best Regards

McUsr

Hello

First version is finished!

I have hardened into the extent that it can be hardened, because there is a close button in upper left corner
which goes straight into System Events no matter what.

Added a nice question mark icon where that was appropriate.

changed code in smartPath to make it run flawless with Tiger.

Best Regards

McUsr

Hello.

Updated a left over line in smartPathParadigm to make it run flawlessly under Tiger

Best Regards

McUsr

Hello.

MInor update:

Yvan Koenig asked me why I had wrapped the display dialog into a SystemEvents / Finder construct.
My answer to this was that sometimes Exposé or Spaces seemed to move that dialog into another space when there were no Finder windows in that space in the first place.

The reason for doing it through Finder in the first place was errantly to keep the dialogs localized, I didn’t have to to that when having access to Yvan’s localized code.

The construct is however necessary in order to keep the choose file and choose from list dialogs localized with buttons named in the local language.

The unnecessary constructs is now removed. Thanks! :slight_smile:

Other bugs and errors of me that were removed:
¢ Since I end the script with a tell block, some properties sometimes at least, were not saved back into the script. Fixed that with a return “0” statement.

¢ And there were a superfluous function call which made the grand parent path to be saved instead of the parent path.

Further work:

I will rewrite the program logic to make the script more intuitive to use. If I for instance forget to press the control key, when I want to open a script in the editor and instead are asked to make a loader statement, I want the option to get back and redo that choice.
That implies a total rewrite of the logic.

Comments:

This is a script I as matter of fact use a lot, more than what I usually do when just having written something and is thrilled by that in the moment.

Best Regards

McUsr

Hello.

The script and its documentation has gotten a substantial update.

Reworked the whole logic behind the ui-interaction.
It should be a lot easier to use, and feel much better to use now.

Added support for loading AppleMods libraries.
Added support for opening a folder containing scripts, for purposes as to maintain files.

Updated the documentation.

All feedback is very welcome.

Best Regards

McUsr

Hello.

I have been able to remove some calls to System Events, and added new shorter sounds.
Pop, Morse,Ping and Basso are both shorter and more international.

* It is by all means far more responsive now.

Yes, it sounds like and old arcade game :smiley: I haven’t added “Bonus soundtracks” for hitting the shortcut keys just now, but if my idea about a SoundServer is practical then :smiley:

If you want to have a go on your own with a parallel (almost) Sound server: I will create an Applet, which takes either, the standard tunes and the number of times it is to be played, or text to be spoken and with which voice.
The idea is to do this within an “ignoring application responses block” and that the sound server dies after five minutes of inactivity.
And the code is updated in post #1

Hello.

I delegated all the sound to a SoundServer in order to make the UI faster. I have also changed the way I read the modifier keys, replacing 3 do shell script commands by one.
I have also changed the modifier keys, so that cmd now opens a file, which is the natural key, since one then get the natural response of hitting cmd - o in a file open dialog. Thanks goes to oldmaneagan for that for this post

This edition has made it as more responsive to the previous as the previous was to the former.

I will now use this for a while, there has come a new edition of AppleMods, with simpler load statements, I have also learned of John Pugh how to reload script libraries based on their modification date.

I think that this ScriptLibraryLoader have started to mature, to provide a decent form of functionality, and with the responsiveness an Apple Scripter deserves.

Enjoy.

Hello.

This is an update. I have implemented a fall back pattern so that you will be taken to the initial folder for that predetermined path if you choose that library path again, after first having defaulted to choose a file. (Fallback pattern).

This is the last release with this level of functionality. I’m working on an installer, since that is necessary in order to support different applications natively; AppleScript Editor, Script Debugger 4.5 and Smile.

It will also start using the LIbrary Lister, so that you can list the functions, of either the current file, or the libraries.

This functionality will include getting handler signatures pasted to the clipboard (resolved to a certain level). and copied handlers to the clipboard. This is useful when you have clippings embedded in handlers with descriptive names.

All the configuration of library paths will also be taken care of by the installer and stored in a property list file, in order for the script to be really easy to install. So that people will leverage on this tool as early as possible in their scripting career.

Don’t assume that the name of the start up disk is “Macintosh HD”.

Obtain user’s home directory using “path to” command.

Hello.

All of that is coming with the property list file. :slight_smile: I will wait a little bit with doing any updates, because I’m starting to intergrating a lot.