I've written an AppleScript to iterate through an app's menu choices, doing something with each item (e.g., get its keyboard shortcut). It works, though (being AppleScript) it's very slow, but I'm unsatisfied with it.

As you can see from the skeleton below, I've used a brute force nesting of repeat loops to work down through the menu tree. It gets particularly ugly when the skeleton is fleshed out to do actual work, requiring repetition of instructions so brief that putting them into their own handlers doesn't really help.

It seems like a recursive algorithm would be a more elegant solution, but I've been unable to implement one. I've foundered on AppleScript's lack of dynamic variable assignment.

Is there a more elegant solution?

-- Iterates through an app's menus, performing an action on each item

--list of apps to process
set theApps to {"Stickies"}

repeat with thisProc in theApps

    --wake up
    launch application thisProc

    --process this process
    tell application "System Events" to tell process thisProc

        --iterate through submenus, ignoring anything beyond three levels

        --there are always menu bar items
        repeat with levelOne in menu bar items 2 through -1 of menu bar 1
            Get_Something of me from levelOne
            --there are always level 1 menu items contained in a menu 1
            repeat with levelTwo in (menu items of menu 1) of levelOne
                Get_Something of me from levelTwo
                --fail silently if there's no level 3
                    repeat with levelThree in (menu items of menu 1)
                        Get_Something of me from levelThree given indent:3
                        --fail silently if there's no level 4
                            repeat with levelFour in (menu items of menu 1) of levelThree
                                Get_Something of me from levelFour
                            end repeat
                        end try
                    end repeat
                end try
            end repeat
        end repeat
    end tell
end repeat

to Get_Something from thisItem

    tell application "System Events" to set theName to title of thisItem

    --ignore menu separators
    if theName is not missing value and theName is not "" then
        say theName
    end if

end Get_Something

You must log in to answer this question.

Browse other questions tagged .