Jump to content

Tips for "Choose existing item or create new item" pattern?


Recommended Posts

I'm writing a workflow to start task timers based on todos. The idea is, if I type "task fix the", it queries my todo app for todos that start with "fix the" and returns them as options. I can either select one of the options or hit enter without choosing an option, which creates a new todo called "fix the". My current script basically does the right thing, but it has a few problems I can't figure out. I haven't been able to find a discussion of this exact problem.

 

The current script is a python script that calls an Applescript to get the todos. It is slow, and there's probably nothing to be done about that because Applescript is slow. The python script filters the todos based on the query, and also outputs a "Create new" option whos "arg" value is the query itself, so that if the user picks that option, the query they entered becomes the return value of the script.

 

This is a great candidate for "Alfred filters results". I don't need to run the slow script on every keystroke, except with "Alfred filters results" there seems to be no way to tell it "if the user doesn't pick an option, return whatever they typed in". Is there?

 

Another option is for the python script to store the Applescript todo results in a tempfile or something. Or maybe pass all the results back to Alfred as a variable, and then Alfred passes the results into the script the next time it runs, so that all Python has to do is filter it. That seems messy but fine. Does anyone have any suggestions about it?

 

Finally: I often run into a race condition:

1. I start typing a new todo called "fix bug", and the python script runs for the first time after I've typed "fi".

2. While the script is running, I'm still typing out the todo text.

3. It returns a bunch of options, the first of which says "Start a new todo", but the hidden value of that option is "fi"

4. By that time I've typed out "fix bug" and it runs again with that text, but before it can return, I press Enter, which selects the top option whose value is "fi".

 

Similar to the first problem, I think I want a way for the script filter to return an option that tells Alfred "the value of 'arg' for this option is whatever the user has typed in". Is there a way to do that? Thanks!

Link to comment
3 hours ago, incidentist said:

This is a great candidate for "Alfred filters results". I don't need to run the slow script on every keystroke, except with "Alfred filters results" there seems to be no way to tell it "if the user doesn't pick an option, return whatever they typed in". Is there?

 

No, there isn't. To do what you want (which is the right way to do it, imo), you'll have to do your own filtering.

 

3 hours ago, incidentist said:

Another option is for the python script to store the Applescript todo results in a tempfile or something. Or maybe pass all the results back to Alfred as a variable, and then Alfred passes the results into the script the next time it runs, so that all Python has to do is filter it. That seems messy but fine. Does anyone have any suggestions about it?

 

Caching is the proper way to do it if you can't or don't want to use "Alfred filters results". My Python workflow library has a bunch of functions for (temporarily) caching data.

 

4 hours ago, incidentist said:

I think I want a way for the script filter to return an option that tells Alfred "the value of 'arg' for this option is whatever the user has typed in". Is there a way to do that?

 

Again, no (but I'm sure there has been a feature request). That problem will largely disappear when you start caching the data, though (except on the first run). You can fiddle with the "Queue Delay" setting in your Script Filter's "Run Behaviour" options to get slightly better behaviour, but that won't make the problem go away entirely.

 

If you want to completely eliminate the issue, you’ll have to do the caching in the background (see my library above), so your Script Filter isn’t waiting for data directly from the application. In your Script Filter, you can either load stale data from the cache or show a "Loading todos…"  item. Use the rerun field of the Script Filter JSON feedback to tell Alfred to keep re-running your Script Filter until the background job has finished updating the cache.

 

Here's an example workflow that works that way. It's in Go, not Python, but it should be easy enough to follow.

 

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