Jump to content

Menu Search


Recommended Posts

The previously released menu search workflow has been universally panned due to the poor performance of the AppleScript that dumps menu contents. The caching of results worked very poorly as a stop-gap. So, I've re-written the menu extraction in Objective-C. It's much faster. The source is here: https://github.com/ctwise/alfred-workflows

 

You can download the workflow directly from http://tedwi.se/u/db

 

To recap, this workflow lets you trigger an application's menu's from Alfred. For example, if you're in iTerm and trigger Alfred, you can type 'm view' to get a list of all menu items with 'view' in the name or that belong to the 'view' menu. Selecting one of the entries triggers the corresponding menu entry in iTerm. In one sense it gives you a command-line to control your applications.

 

The workflow has the beginnings of shortcut key display as well but it's currently disabled due to numerous bugs.

 

Update: 

 

v1.3 - Provide error message when assistive devices isn't checked.

v1.2 - Skip the Safari History and Bookmarks menus. They take too long.

v1.1 - I fixed the bug with Alfred not remembering selections and added AlleyOop support. Download from the same link.

 

Requires OS/X 10.7+.

 

---

 

You need to turn on OS/X assistive device support to allow this workflow to operate. You can find the checkbox in Settings. The settings page looks very different in recent versions of OS/X but the wording for providing access for assistive devices is very similar no matter what OS/X version you're using. Here's an image of the settings from the latest version of Mountain Lion.

 

Accessibility-2.jpg

Edited by ctwise
Link to comment

I did a quick run and so far I have only one word: impressive.

 

I kind of use the same menu items in some applications and sometimes I don’t remember the hotkey or I don’t want to set up a hotkey. Now this leads to my suggestion: add favorites/history menu items per application. For example: I’m in Byword and instead of search for the menu item I would bring Alfred and type mf or mh and get a list of favorites or last used menu items for Byword.

 

Well, at least you could consider for Menu Search 2.0 :)

 

Anyway, thank you for this great version.

Link to comment

Sounds terrific but for some reason it didn't work for me.  It just got stuck saying it was loading.  I'm on 10.6.8 - maybe the workflow only works for 10.7+?  Maybe it's just me?

 

 

It's 10.7+. It uses an API call that didn't exist before 10.7. 

Link to comment

thanks for this, it is indeed a lot faster and very useful! there is one thing that was mentioned before that still does not work. some menu items are dynamic and change depending on the "mode" of the application. for example in lightroom, depending on which module i am in, the items in the View menu change and some do not show up in Alfred. Would you possibly have some time to investigate if there is way to make these show up? thank you.

Link to comment

History in Safari may slow down indeed.

 

Maybe the workflow could display results in steps, like 20 results. In addition, if I type something and get 100 items it will hard to browse all those items in Alfred anyway.

 

You have to walk the whole menu to be able to search it. Dumping is the slow point. On my computer it takes 1.6-1.7 seconds to dump the menu structure for Safari. Contrast that with iTerm, which takes 0.07 seconds.

 

I _could_ special case Safari and exclude History and Bookmarks but then, of course, you can't search them. :-)

 

It doesn't look like it's just a case of menu size either. The Chrome menu dumps in 0.25 seconds. Safari just doesn't like to give up its History and Bookmarks menus. If I exclude those two in Safari the time drops to Chrome territory.

Link to comment

You have to walk the whole menu to be able to search it. Dumping is the slow point. On my computer it takes 1.6-1.7 seconds to dump the menu structure for Safari. Contrast that with iTerm, which takes 0.07 seconds.

 

I _could_ special case Safari and exclude History and Bookmarks but then, of course, you can't search them. :-)

 

It doesn't look like it's just a case of menu size either. The Chrome menu dumps in 0.25 seconds. Safari just doesn't like to give up its History and Bookmarks menus. If I exclude those two in Safari the time drops to Chrome territory.

 

Considering there are already other workflows to search Safari's history, it may not be a bad idea to exclude them.

 

Another idea is to do the searching in Objective-C, and limit the results from there. Not sure how feasible that would be though, or how much that would actually affect performance.

Edited by Clinton Strong
Link to comment

Embarrassed to say, but it doesn't work on my machine. Result is always loading, for all apps I have tried (safari, terminal, finder). I have osx 10.8.3.

 

Not sure how to debug the workflow, wish I could provide more info.

Link to comment

Good job keeping the workflow alive. I modified my original post to point to this new topic, hopefully that will help people find this newer version.

 

Is the source code to your menudump executable as well on your github? I would prefer for things to work without any form of cache, which could possibly be achieved by limiting the recursion depth of the menus (assuming that you are recursing). That would probably also allow handling (probably hiding) of disabled menu items. Disabling caching would also make toggle menu items (such as Safari's "Show Web Inspector"/"Hide Web Inspector") work properly.

 

The goal would be to get the entire workflow to execute in less than 200 milliseconds. 100ms would be better, as it has that instant feel to it, but 200ms would still feel semi-instant.

Link to comment

Embarrassed to say, but it doesn't work on my machine. Result is always loading, for all apps I have tried (safari, terminal, finder). I have osx 10.8.3.

 

Not sure how to debug the workflow, wish I could provide more info.

 

1. Right click the workflow and choose 'Show in Finder'.

2. Double-click on the 'menudump' file.

3. A terminal window should open and it should spit out a bunch of text. It should end in something like this:

 

            "menuPath": "Help",
            "children": []
          },
          {
            "name": "Search man Page Index for Selection",
            "shortcut": "⌃⌥⌘/",
            "locator": "menu item \"Search man Page Index for Selection\" of menu \"Help\" of menu bar item \"Help\" of menu bar 1",
            "menuPath": "Help",
            "children": []
          },
        ]

      },
    ]
}
[Process completed]

 

If it doesn't, and it looks like an error message, please post it. If it does look like the above, then the Ruby script might be the problem.

 

4. To test the Ruby script, you need to open a Terminal and go to the directory it's installed in. That's the directory that Finder is open on. It will be something like: /Users/<youruser>/Library/Application Support/Alfred 2/Alfred.alfredpreferences/workflows/user.workflow.67E62A93-785A-49BA-8B22-EAAEA3FA735A. So type 'cd <the path to the workflow>'.

 

5. Now run the Ruby script, 'ruby main.rb sh'. You should see text like this:

 

<items><item arg='menu item "Page Up" of menu "View" of menu bar item "View" of menu bar 1' autocomplete='Page Up' uid='Terminal: View > Page Up' valid='yes'><title>Page Up</title><subtitle>Terminal: View</subtitle><icon type='fileicon'>/Applications/Utilities/Terminal.app</icon></item><item arg='menu item "Line Up" of menu "View" of menu bar item "View" of m

 

 

If you don't, post the result.

Link to comment

If you don't, post the result.

 

Thanks for the quick reply.

 

menudump outputs a json with "menu" being an empty array, so I guess it's the ruby script.

{
  "name": "Terminal"
  "bundleIdentifier": "com.apple.Terminal"
  "bundlePath": "/Applications/Utilities/Terminal.app"
  "executablePath": "/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal"
  "menus": [
    ]
}
[Process completed]

 

 

The output of the ruby script is

./menu_items.rb:10:in `gather_leaves': undefined method `each' for nil:NilClass (NoMethodError)
	from ./menu_items.rb:28:in `generate_items'
	from main.rb:7

 

my ruby version is 1.8.7, it's the system ruby.

Edited by curvedmark
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...