NA has always had its own search syntax for navigating TaskPaper files, but it didn’t understand TaskPaper’s actual search syntax. I thought it might be time to change that.

For years, na has focused on a simple idea: when you sit down to work, you should be able to see your next actions for a project with a single, fast command (or even a prompt hook when you cd into a folder). It started as a thin wrapper around TaskPaper-style todo files, but its own filtering language slowly grew more powerful and less obvious. Recently, I decided to turn that around and lean into something that already exists: TaskPaper’s own search syntax.

TaskPaper search is surprisingly rich. You can filter by plain text on the action line, query tags and their values, and even combine multiple conditions with logical operators. Instead of reinventing all of that, na now understands most of the same syntax. You can drop a TaskPaper query like @priority <= 2 and not @done straight into na next "@search(@priority <= 2 and not @done)" and get exactly what you expect: high-priority, incomplete actions for the current project.

Under the hood, na maps TaskPaper-style predicates into its own query engine. Bare words become text searches on the action line. Tag predicates like @tag, @tag = value, or @tag contains foo are parsed into comparison operators that na already knew how to handle. Special handling for @done keeps the UX sane: @done alone means “include completed tasks,” while not @done or combinations with other predicates flip the filter to only show what is still active. It even understands nested comparisons and item path syntax like //Bugs/* and not @done.

The nicest part, in my own usage, is that TaskPaper queries are now first-class citizens in todo files themselves. If you drop a line like:

Today's focus @search(@na and @priority <= 2 and not @done)

into your TaskPaper document, na can treat that as a saved search. Running something like na saved "Today's focus" will execute the embedded @search(...) expression and show you only the actions that match. Your TaskPaper document becomes both a list of tasks and a library of reusable, named filters you can run from the command line.

TaskPaper queries are not limited to inline @search(...) lines in your TaskPaper files. na also recognizes @search syntax in ~/.local/share/na/saved_searches.yml, so you can define named searches there using pure TaskPaper syntax and reuse them everywhere. That means the same query language works in your editor, inside your todo documents, and in your global saved searches, giving you one universal way to describe how you want your TaskPaper tasks filtered.

This change does not replace na’s existing search language; it layers a familiar syntax on top of it. You can still use the more compact na-style filters when you want, but if you already live in TaskPaper, you do not have to context-switch. The same search expressions work in the editor and in the terminal, against the same files, using the same mental model.

If you’ve been using na as a quick way to see @na-tagged items, TaskPaper search support might seem like a small detail. But it opens up a lot of expressive power without extra configuration: you can slice your todos by project, tags, dates, and priorities using a language that is already documented and battle-tested. And if you are just getting started, you can learn one syntax and use it everywhere.

See the na project page for more details on the supported TaskPaper syntax. And, as always, you can get the latest version with gem install na.