Recursively Extract Keyboard Shortcuts from Menus

As an exercise in heavily caffeinated OCD, I’ve written a script to extract menu items and their keyboard shortcuts from the current application. It’s been amusing, but there’s one aspect of it with which I’m unsatisfied.

The excerpt below shows the basic structure I’ve used to drill down through menus and menu items. It works, but is inelegant. It’s painfully ugly, not least of all because each successive level has to be manually coded. While this isn’t really a problem (sane developers limit the depth of their menu hierarchy), well. Like I said, caffeinated OCD.

A recursive approach seems called for, but I’m not familiar enough with AS to work it out. Perhaps wiser heads might care to provide an “oh, duh” moment?

tell application "System Events"
	
	tell (first process whose frontmost is true) to ¬
		set procName to name --																					get name of current application	
	set procName to "Finder" --																					DEBUG ONLY
	set prevElName to "" --																							start fresh
	tell process procName --																						tell the current application
		
		--	⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯	main menu bar for current application
		set menuBar to menu bar 1 --																			menu bar 1
		
		--	⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯	get menu bar items: , Finder, Edit, etc.
		set allMenuBarItems to UI elements of menuBar --												get all menu bar items.
		set theElements to items 2 through -1 of allMenuBarItems --								.and omit  menu
		
		
		--	⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯	menu bar item: Finder, File, Edit, etc.
		repeat with thisElement in theElements
			set theElements to Process_Item of me for ¬
				thisElement given procName:procName
			
			--	⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯	menu: Finder or File or Edit, etc.
			repeat with thisElement in theElements
				set theElements to Process_Item of me for ¬
					thisElement given procName:procName
				
				--	⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯	menu item: About Finder, Preferences., etc.
				repeat with thisElement in theElements
					set theElements to Process_Item of me for ¬
						thisElement given procName:procName
					
					--	⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯	menu: About Finder or Preferences., etc. 
					repeat with thisElement in theElements
						set theElements to Process_Item of me for ¬
							thisElement given procName:procName
						
						--	⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯	menu item: Make New Sticky, Upper Case, etc.
						repeat with thisElement in theElements
							set theElements to Process_Item of me for ¬
								thisElement given procName:procName
							
							--	⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯	menu: Make New Sticky or Upper Case, etc.
							repeat with thisElement in theElements
								set theElements to Process_Item of me for ¬
									thisElement given procName:procName
								
								--	⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯	menu item: Pink, Green, Blue, etc.
								repeat with thisElement in theElements
									set theElements to Process_Item of me for ¬
										thisElement given procName:procName
								end repeat
								
								--	⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯	enough already
								
							end repeat
						end repeat
					end repeat
				end repeat
			end repeat
		end repeat
	end tell
end tell

It may be helpful to look at :

http://macscripter.net/viewtopic.php?id=40374&p=2

Yvan KOENIG (VALLAURIS, France) mercredi 15 octobre 2014 22:37:26

Merci. Sadly, I didn’t find it until I’d reinvented the wheel.

It doesn’t answer my question, but it’s nice to know I’m not completely insane (or at least not completely alone) in pursuing this.

-Bryan