It's minimal, but I'm posting things.
This page assumes you are at least familiar with Taskwarrior, a Unix task management application.
In this article, I'll refer to Taskwarrior as tw
.
Using Taskwarrior TUI is absolutely essential for me. It’s a terminal user interface for TaskWarrior that seriously speeds up task management. Plus, it uses intuitive vim-like keybindings. My whole workflow depends on tui
.
If you're running TaskWarrior 2.6.x alongside TaskWarrior-TUI 0.25 or newer, be aware of potential compatibility issues.
Taskwarrior recently upgraded to major version 3.x.x.
Tasks are now stored in a SQL database instead of JSON files. I haven’t migrated to version 3 yet. Starting with version v0.26.0, TUI becomes incompatible with Taskwarrior 2.x.
To avoid issues, I built TUI using a commit hash just before the 0.26.0 release. This version includes a useful bug-fix:
fix: allowing custom keybinding for shortcuts 0..9 by @katekorsaro in #532
.
This means you can assign shortcuts to letters on your keyboard (not just numbers) to run Taskwarrior scripts. I rely on custom bindings daily, so this fix is crucial for my workflow.
To build and install TUI at commit hash5e9c22a
, do the following:
#!/bin/bash
# Clone taskwarrior-tui repository into the /tmp dir
git clone https://github.com/kdheepak/taskwarrior-tui.git "/tmp/taskwarrior-tui"
cd "/tmp/taskwarrior-tui" || exit
git checkout 5e9c22a
# Build
cargo build --release
# Copy to install /usr/bin
sudo cp "/tmp/taskwarrior-tui/target/release/taskwarrior-tui" /usr/bin/taskwarrior-tui
sudo chmod 0755 /usr/bin/taskwarrior-tui
It's annoying and distracting to see housekeeping, work and other unrelated tasks in your todo list sequentially. As for me, I prefer to separate my tasks by view:
Separating your tasks helps you focus. You can do this using taskwarrior contexts and the task context
command. If you use the TUI1, just press c
for context, then navigate with j
or k
. Pick your context and view your task list.
My life goals have separate categories. Let's compare one of my most important life pillars, work
2, and socialization
. For these important aspects of life, I've assigned them to their own project
.
If you wonder whether a tag or a project works better, ask yourself "Would this tag or project make a good context?" If yes, it's a good fit as a project. If not, I personally lean towards using a tag.
Life pillars are put into my personal
context and share the same task view.
However, they are assigned different urgency coefficients
3. Typically, I will not deviate much from the default urgency coefficients, and assign a bonus/malus coherent which those coefficients.
For tasks I want to do but aren't a priority, I assign them to a "relaxing" context. Since they have low or near-zero priority, their urgency score is low. However, some tasks are more appealing than others. For those, I add a want
tag, which adds a small urgency boost of 0.50. This helps push those tasks closer to the top of the list.
I make sure low-priority tasks or distractions don’t show up when I need serious focus. By filtering with tags or setting a priority threshold, I can easily separate distracting tasks from important ones.
TW doesn’t natively support relative recurrence for tasks. For example, if you need to do the dishes every 2 days, TW will create a new task every 2 days regardless of whether you completed the previous ones. So, if you leave your computer off for a week, you’ll end up with 4 pending tasks...
I use custom hooks to implement custom behaviour, the first of which I call on completetion recurrence
(rcomplete
).
Do check out my git repository with my custom hooks: Kevin's Taskwarrior hooks
Now, the 'do the dishes task' will only be recreated upon completion; reducing the clutter in your todo list.
Using TUI, you can assign hotkeys to actions. Often, I need to snooze a task from my todo list. I do this using the S
key (Shift+S
).
Just add :
uda.taskwarrior-tui.shortcuts.1=~/.config/taskwarrior-tui/shortcut-scripts/snooze-task
The script content is :
#!/usr/bin/env bash
snoozed_datetime=$(task calc "tomorrow+5h")
task \
rc.bulk=0 \
rc.confirmation=off \
rc.dependency.confirmation=off \
rc.recurrence.confirmation=off \
"$@" \
modify \
due:$snoozed_datetime \
wait:$snoozed_datetime
# Note: wait datetime cannot be after due datetime.
code=$?
if [ "$code" -eq 0 ]; then
echo "Task(s) snoozed until: $snoozed_datetime : $@"
else
echo "Failed snooze."
fi
By the way, I also have other useful shortcuts.
A task is either completed or not completed. However, you may not want to delete a task, as this risks losing useful recurrence. For such tasks, I use the F
key to mark a task as failed. This action adds a failed
tag to the task and changes its status to completed.
uda.taskwarrior-tui.shortcuts.3=~/.config/taskwarrior-tui/shortcut-scripts/fail-task
uda.taskwarrior-tui.keyconfig.shortcut3=F
#!/usr/bin/env bash
# Mark task as done but failed
task rc.bulk=0 rc.confirmation=off rc.dependency.confirmation=off rc.recurrence.confirmation=off "$@" mod +failed
task rc.bulk=0 rc.confirmation=off rc.dependency.confirmation=off rc.recurrence.confirmation=off "$@" done
echo "Task(s) marked as done and tagged as failed: $@"
Often, I want to add a detailed note to a task. Annotations alone are insufficient, and I don't want to clutter the task description.
The project taskopen is excellent for this but is not natively integrated with TUI.
I have bound the E
(shift+e
) hotkey to my taskopen-task
script.
To your taskrc
, add:
uda.taskwarrior-tui.keyconfig.shortcut1=S
uda.taskwarrior-tui.shortcuts.2=~/.config/taskwarrior-tui/shortcut-scripts/taskopen-task
The taskopen-task
bash script:
#!/usr/bin/env bash
# Only add an annotation if we are operating on a single ID
if [ $# -eq 1 ]; then
# Only add a note annotation if none exist.
annotation_count=$(task _get $@.annotations.count)
match_found=false
for ((i=1; i<=$annotation_count; i++)); do
annotation_description=$(task _get $@.annotations.$i.description)
if [[ $(echo "$annotation_description" | grep -P '^\s*Notes\.md\s*$') ]]; then
match_found=true
break
fi
done
# Annotate note if none exist
if [ "$match_found" = false ]; then
task $@ annotate -- Notes.md
fi
# Append [1] to the description to signal that a note has been associated with the task.
description=$(task _get $@.description)
if [[ ! $description =~ \[1\]\s*$ ]]; then
task $1 modify description:"$description [1]"
fi
# Open the note!
taskopen $@
else
echo "Only one ID at a time can be processed by this taskopen-task hook."
exit 1
fi
And by the way, in your taskopenrc
file, make sure your editor is set according to your preference; for me, it is:
EDITOR=vim
I'm undecided about using TW for simple lists like groceries, reading lists, or items to buy. For example, I assign a specific context to a groceries
project and switch contexts just to view my groceries. This is easier than changing the task filter or exiting TUI to run an aliased command that opens TW with a groceries filter.
I have been tempted to use TW for other purposes but have since reconsidered.
While I recommend the taskopen
plugin for TW, it should not replace your note-taking system. Tasks may recur and invoke custom hooks, which can cause you to lose track of the notes associated with each task. I use taskopen
only when a note needs to be linked to a specific task; otherwise, the note goes into my regular note-taking system.
Taskwarrior is an opinionated approach to getting things done. It lists your tasks by priority and assumes you will complete those tasks first.
All your efforts to fine-tune the urgency algorithm will never lead to a perfect solution; if you rely solely on urgency to manage your life, you may miss events and meetings.
Therefore, I do not add events to Taskwarrior. One solution I have considered is adding a side panel in the TUI to display upcoming events separately from my task list. This would allow me to stay on top of both my TODO lists and meetings.
I find it difficult to see how Taskwarrior could evolve into an intuitive and comprehensive project management system, comparable to Jira. Adding metadata to tasks (such as relates to, blocks, depends on, work hours) demands significant upkeep. The primary objective remains to complete tasks efficiently. However, I have not tried this extensively with Taskwarrior; it might be feasible, but I am skeptical that it is the most suitable tool for this purpose.
Two years ago, I attempted to set up task synchronization using taskd
. I succeeded, but automating the setup proved frustrating, so I abandoned it. I remember spending a day or two trying to complete this setup.
Fast forward to 2025, I automated the taskd
setup using ansible
. I succeeded, but only on one of my computers. On my other work PC, the synchronization failed to work; I have yet to understand why4 and lost another two days realizing it wouldn't work. Moreover, taskd
mangled my tasks: I've partially recovered them, but the process is slow.
My lesson to you here is: don't use taskd. Prefer simply backing up your pending.data
and completed.data
files in any other way.
In a similar approach to note-taking systems such as Zettelkasten, I am in the process of 'flattening' my task system.
I am minimizing the number of contexts and projects in TW as much as possible.
I am also reducing the number of tags and simplifying my urgency algorithm while keeping it sufficiently accurate for my needs.
Because I don't believe TW is the most suitable tool for project management, I avoid using extensive project hierarchies.
My goal is to make TW as intuitive, fast, and accurate as possible, while minimizing the required maintenance. Of course, regular task reviews are highly recommended.