I’ve added some stuff to Doing lately. Like, a lot of stuff. To be fair, I’ve also done a lot of jobby job stuff. And worked with Fletcher on nvUltra. And started a rewrite of Gather as a menu bar clipboard web Markdownifier with integration with multiple apps (that one’s going to be cool if I finish it). And some time on Bunch. But as I’ve said before, the one thing I use when working on all of these is Doing. And I always want it to do something new or better, so it gets some attention.

Oh, and looking at my doing recent output reminds me that I also tried my hand at creating my first oh-my-fish plugin yesterday. It has some dependencies and I don’t think it’s right for the main packages repo, so you have to add the repository manually to try it out, but I think it’s fully functional. If you want intelligent directory navigation with bookmarks, fuzzy matching, and fasd/fzf integration in Fish, all in your cd command, check it out.

Anyway, what were we talking about? Hang on:

doing last...

Right. Doing updates. To get the latest version, just run gem install doing, which as of this writing should get you at least version 2.1.34. (If you get an error, run the same command with sudo.)

A Built-in Changelog Viewer

I’m not going to go through the whole changelog, but I did add a thing for that. This is a tool I made mostly for me, exactly for things like writing a post such as this one, but if you want to see what’s changed next time you update, it’s handy.

`doing changes` output on the command line

You can now run doing changes to see the latest changes, and use doing changes --lookup "QUERY" (or -l) to search for a version or a range of versions (or --all for the whole kit and caboodle). To see all of the changes since the last time I blogged about Doing, you would run doing changes -l "> 2.1.0". That will give you a rendered version of all version entries since 2.1.0, and you can output just the change lines (without version numbers and dates) by adding --changes. Multiple comparisons can be combined, e.g. "> 2.1 <= 2.1.20".

You can also search for changes related to something you’re curious about using --search, e.g. doing changes --search "autotag". A good way to keep track of a feature you care about and ignore the rest of my very frequent updates.

Shell Completion

The shell completion scripts have improved, especially for Fish. (I put some more effort into Zsh, but I don’t use it regularly and I’m sure it could use further improvements. If you’re a Zsh pro and a Doing user, please feel free to create a GitHub Issue with any suggestions/fixes.)

Tab completion in Zsh

doing completion now uses subcommands: install and generate. The install command copies the built-in scripts that are generated with every deploy into ~/.local/share/doing/completion and then offers to symlink them into an appropriate auto-load folder for your shell. Just run doing completion install SHELL, where shell is zsh, bash, or fish.

(I know I got the fish autoload folders right, but I went with StackOverflow answers to guess the right ones for Zsh and Bash, and haven’t thoroughly tested yet. I also don’t know what changes there might be between platforms. Plus, I know a lot of people use tools like oh-my-zsh or bash-it and have their own ways of loading completions, so if you answer “n” when it asks to create a link, it will instead output the path of the script so you can source it however you like. If you know of better folders to test for and copy to, please let me know.)

The generate command runs through every command and generates completion for subcommands, flags, and switches. It takes a minute or more to run (it’s very thorough), and is only necessary if you’ve added your own custom commands or plugins using the new plugin architecture, or if you’ve used the new doing commands command to modify what commands are available. If you have custom stuff, though, doing completion generate SHELL will create completions for everything, including custom commands and plugins. Takes some time, but it’s worth it to have all available commands and their options just a tab away.

In Fish you now get section and view name completion, as well as tag completion.

Tab completing tag names in Fish

Search Improvements

There have been a lot of general search improvements, including case sensitivity options, exact matching flags, and better regular expression handling.

I added pattern matching for tag filters and searches: use + and - symbols to create simple boolean searches, e.g. --tag '+doing -writing' (“contains ‘doing’ and NOT ‘writing’”) or --search 'oracle +webdev -docs' “contains ‘oracle’ AND ‘webdev’ but NOT ‘docs’”. A string without any +/- is interpreted as an AND string but will match the words in any order. This is now the default way search and tag filters are parsed. You can still use --bool AND or --bool NOT to create simpler boolean searches, or use --exact with searches to force exact string matching.

doing search with pattern matching

All commands that accept a --tag filter can now handle wildcards in the tag names. * to match any number of characters, ? to match a single character. You can also use wildcards in synonym settings for autotagging.

Side note, and again for my own purposes but might be of interest to someone else, you can see what commands accept any given flag by running doing commands_accepting FLAG. So doing commands_accepting search would show you all commands that have a search filter. Many of the commands of the same type share filtering/sorting/dating/etc. options, so it’s mostly a debugging tool for me. But it’s there if you’re ever curious.

You can now include a --val flag for all display commands. It allows tag value queries — tag values are contained in parenthesis after the tag, e.g. @progress(50) or @done(2022-01-15 05:00). Queries look like --val "done < two weeks ago", "project *= oracle" or "progress >= 50". Wildcards are allowed in the value, and comparators can be <, >, <=, >=, ==, *= (contains), ^= (begins with), or $= (ends with). Numeric and date comparisons are detected and handled appropriately, with natural language parsing for dates and times.

To see a list of other improvements to search and tag filtering: doing changes -s "/--(search|tag)/" -l "> 2.0.10".

Other Stuff

I said I wouldn’t include the whole changelog, but if you’ve read this far, I might as well include some highlights. The current version also includes a ton of fixes and I’ve closed out every open ticket for the time being. Please keep the reports coming!

  • Expanded the capabilities of the doing config command and its subcommands. See doing changes -s "config" -l "> 2.0.10".
  • Lots of improvements to date filtering. See doing changes -s "/--(before|after|from)/" -l "> 2.0.10"
  • Improvements to multiple entry editing. Select a bunch of entries using doing select and some fuzzy searching, choose edit from the menu, and edit them all in one go. Any dates can be replaced with natural language strings (e.g. @done(today 4pm)) and they’ll be parsed and converted when you save. Modify, tag, add notes, even delete, all from a quick Vim session affecting only the filtered selection of entries.
  • When editor is invoked, entry titles include start date, which can be modified
  • Multiple ways to update start dates and @done dates for entries. See doing help reset and doing help again for a couple of them. I’ve been trying to avoid manual editing as much as possible, so tools that can accurately query and modify entries have been a focus.
  • In addition to showing the elapsed time for a finished entry, you can now show the running duration of unfinished entries. See doing changes -s "duration" -l "> 2.0.10"
  • A bunch of improvements to undo history, including multiple undos and redos, and an interactive browser that shows you a diff of what will change when restored from the history. See doing changes -s "/(undo|redo)/" -l "> 2.0.10"
  • For anyone still using Day One, I added plugins for Day One export: export individual entries as Day One entries, create a single Day One entry from the output of any command, or split the output by day (start times) and create a digest entry for each day.
  • All template placeholders can now use the “printf” formatting that %title and %note have, allowing for padding, prefixes, etc.
  • doing tag_dir command creates/updates .doingrc files in the current directory with default_tags values. Then all entries created within that directory (or subdirectories) get tagged with that value.
  • New hooks: pre_entry_add, post_entry_added, post_entry_updated, post_entry_removed, pre_export
  • doing tag now accepts a --value flag to define a value for a single tag, e.g. @tag(value)
  • All commands that accept --note now accept --ask, which requests input via readline after creating the note. Multiple lines are allowed, hit return twice to end editing. Works alongside --note and --editor
  • When completing an entry, if the elapsed time would be greater than a (configurable) amount, doing will now ask for confirmation and allow you to enter a new duration before setting the @done date
  • doing done --from "3pm to 3:15pm" to set start and end times with natural language string
  • Improvements to command line text entry, prompted input with tab completion of tags, handling of control sequences, and better multi-line editing
  • Show preview of up to 5 items when confirming a delete operation so you actually know what you’re deleting
  • doing commands will let you enable and disable built-in and custom commands with interactive menu
  • Config setting doing_file_sort (asc or desc) determines the sort order of entries in the actual Doing file. Has no effect on other operations, just allows you to store the file with newest entries at top (desc) or bottom (asc) based on your preference.
  • If doing is run without a command but with arguments, it executes as if you’d run doing now, passing the arguments to that. So you can just write “doing this thing” instead of “doing now this thing”, as long as the first word of the arguments is not a recognized command. Natural language and all.
  • With complete examples in the help output for most commands, doing help almost always requires scrolling up. It now automatically paginates using your system $PAGER (or best detected option).