Jump to content

Recommended Posts

Fuzzy search across folder subtrees.

 

Update 10/09/2016:

  • Added Alfred 3 support and removed Alfred 2 support.
  • Added ability to self-update.

 

Update 10/04/2014:

  • Added support for glob-style excludes. Unfortunately, these have to be added manually to the settings file at the moment.

Update 05/04/2014:

  • Now supports searching files as well as/instead of folders
  • You can now adjust the minimum query length to improve search performance.

demo.gif

This Workflow provides partial matching of path components, allowing you to drill down into your filesystem with a space-separated query. Each "word" of the query will be matched against the components of a directory or file's path, so a three-word query will only match at least three levels down from the specified root directory.

You can use a File Action to intiate a fuzzy search on a folder or to assign a keyword to perform a fuzzy search on that folder.

Download

Get the Workflow from GitHub or Packal.

Commands

  • fuzzy — List your Fuzzy Folders
  • — Edit Fuzzy Folder settings
  • ⌘+↩ — Start a Fuzzy Folder search with the associated keyword
  • ⌥+↩ — Delete the keyword–Fuzzy Folder combination
  • fzyup — Recreate the Script Filters from your saved configuration (useful after an update)
  • fzyhelp — Open the help file in your browser

Settings

You can specify these settings globally as defaults for all Fuzzy Folders or on a per-folder basis. For ad-hoc searches via the Fuzzy Search Here file action, the default settings always apply.

Use keyword fuzzy to view and edit settings.

  • Minimum query length — The last "word" of a query must be this long to trigger a search. Default is 1, but increase this number if the search is too slow. This is very often the case if you're searching a large subtree and/or also choose to search files.
  • Search scope — Choose to search only for folders, files or both. Note: In most cases, searches including files are significantly slower. Consider increasing the minimum query length to speed up slow searches.

File Actions

  • Fuzzy Search Here — Fuzzy search this folder
  • Add Fuzzy Folder — Set a keyword for this folder for faster fuzzy searching

Search result actions

  • — Open folder in Finder
  • ⌘+↩ — Browse folder in Alfred

Bugs, questions, feedback

You can open an issue on GitHub, or post in this thread.

Licensing, other stuff

This Workflow is made available under the MIT Licence.

The icon was made by Jono Hunt.

It uses docopt and Alfred-Workflow.

Edited by deanishe
Workflow updated
Link to comment

Ta. I'm going to have to refactor out the code that manages the saved settings and adds Script Filters to info.plist based on them.

That could be very handy in a lot of workflows.

That would be very handy. I'll keep my eyes on that code...

Link to comment

:)

The code that generates the Script Filters is pretty straightforward, just scattered around a bit.

I must admit, I think there's something deeply cool about a Workflow that can rewrite itself. I want to upgrade my Smart Folders workflow to the same "technology". I use that one a lot, and one of the things that puts me off fiddling with the code is having to recreate my custom Script Filters all the time.

Link to comment

:)

The code that generates the Script Filters is pretty straightforward, just scattered around a bit.

I must admit, I think there's something deeply cool about a Workflow that can rewrite itself. I want to upgrade my Smart Folders workflow to the same "technology". I use that one a lot, and one of the things that puts me off fiddling with the code is having to recreate my custom Script Filters all the time.

Nice! Only issue I ran in to was that it seems to take a while to load the initial results. For example, when I typed 'e', it returned over 6,000 results and took a couple of seconds before any other characters were processed.

Unfortunately it doesn't look like you can limit the number of results with mdfind without dipping in to the C/Objective-C APIs. I suppose a quick and easy fix could be to ignore the search if the query's only one character long, since it'll likely be too noisy to find anything anyway.

 

Could you elaborate any on the methodology of such code? What does it look for in the settings? What does it add to the Script Filter info in the info.plist based on that data?

Basically, each script, keyword, action, etc. is stored as an object in a workflow’s info.plist. You can see them listed under <key>objects</key>. The important part is the uid field; Alfred associates each object with a unique ID (I believe it uses UUIDv4).

Alfred uses these UUIDs to keep track of each object’s relationship to another, which you can see below <key>connections</key>. Each of these relationships also has a unique ID, stored in the key field.

Alfred also keeps track of the graphical representation of the workflow’s objects under <key>uidata</key>. If you’re programmatically adding new objects, you’ll probably want to find the largest ypos of the objects, and increment it by about 120 so it aligns correctly each object is 96 px in height and typically has 26px of padding between other objects (though you can adjust this).

Link to comment

Could you elaborate any on the methodology of such code? What does it look for in the settings? What does it add to the Script Filter info in the info.plist based on that data?

info.plist is laid out just as Clinton describes it.

When you add or delete a Fuzzy Folder (or manually trigger an update with fzyup), the script deletes all the Script Filters from the objects array in info.plist it recognises as having put their itself (using a regex on the script command and a list of the Workflow's own keywords that it shouldn't delete) and the corresponding connections and positioning data.

Then it adds new Script Filters based on the Fuzzy Folders you've set up with corresponding connections to the Browse in Alfred action via its UID (which is hard-coded in the script), and gives them all a position in the UI (otherwise they'd all be in the same place). The position of the first one is hard-coded into the script.

Finally, info.plist is overwritten with the the updated version. Alfred picks up the changes after a few seconds.

 

Nice! Only issue I ran in to was that it seems to take a while to load the initial results. For example, when I typed 'e', it returned over 6,000 results and took a couple of seconds before any other characters were processed.

Unfortunately it doesn't look like you can limit the number of results with mdfind without dipping in to the C/Objective-C APIs. I suppose a quick and easy fix could be to ignore the search if the query's only one character long, since it'll likely be too noisy to find anything anyway.

I'm reluctant to require a minimum query length, as one-letter queries are something I use quite a lot (as in the demo in the OP). The thing regarding noise is that mdfind is only run with the last "word" of the query; the script then filters the results from mdfind based on the preceding words.

I see a few possibilities to improve performance:

  1. Kill the mdfind process after a few hundred results if there's only one word in the query. This won't help much, though, as most of the delay occurs before mdfind actually starts returning results.
  2. Cache the results from mdfind for a few seconds. Again, I don't think there's much to be gained by this, as mdfind caches its own results (subsequent runs with the same query are instant), and presumably knows more about how long its cache is valid.
  3. Don't send thousands of results to Alfred. This is a no-brainer, I guess.

I'll profile the code to see where most time is wasted, and add an option for the user to specify a minimum query length.

Edited by deanishe
Link to comment
  • 4 weeks later...

Nice! Only issue I ran in to was that it seems to take a while to load the initial results. For example, when I typed 'e', it returned over 6,000 results and took a couple of seconds before any other characters were processed.

Unfortunately it doesn't look like you can limit the number of results with mdfind without dipping in to the C/Objective-C APIs. I suppose a quick and easy fix could be to ignore the search if the query's only one character long, since it'll likely be too noisy to find anything anyway.

 

 

You can now specify a minimum query length to improve search performance.

Link to comment

Added a feature for power users: glob-style exclusions similar to .gitignore files.

I say power users because currently you have to add exclude patterns by hand to the settings.json file.

How to do that is documented in the README on GitHub and in the included help file (use fzyhelp in Alfred).

Just be sure to edit the file in a proper code editor and not TextEdit (which will break the file).

Edited by deanishe
Link to comment
  • 1 month later...
  • 2 weeks later...
  • 3 months later...

Hi deanishe!

 

As I was trying to make the workflow work I got this log in the console:

[ERROR: alfred.workflow.input.scriptfilter] Code 0: 21:06:40 ff.py:974 DEBUG    wf.args : [u'manage', u'']
21:06:40 ff.py:975 DEBUG    args : {u'<dir>': None,
 u'<profile>': None,
 u'<query>': u'',
 u'add': False,
 u'alfred-browse': False,
 u'alfred-search': False,
 u'choose': False,
 u'keyword': False,
 u'load-profile': False,
 u'load-settings': False,
 u'manage': True,
 u'open-help': False,
 u'remove': False,
 u'search': False,
 u'settings': False,
 u'update': False,
 u'update-setting': False}
21:06:40 ff.py:310 DEBUG    dirpath : None  query : u''

I finally can use the workflow but I thought you might be interested in this feedback.

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...