A Neovim plugin for integrating Taskwarrior task management directly into Markdown files.
- π Embed Taskwarrior queries in Markdown headers
- π Automatic task list updates on file open/save
- β
Task status indicators:
[ ]pending,[S]started,[x]completed,[-]deleted - π― Priority, dependency, reverse dependency, and annotation icons
- βοΈ Configurable blank lines after task lists
- β¨οΈ Interactive task management with keybindings
- π Local timezone display for dates and times
- ποΈ Multiple Taskwarrior workspaces support with
@workspacesyntax - π¨ Smart autocomplete for projects, tags, dates, workspaces, and priorities
Using lazy.nvim
{
"yourusername/frontline.nvim",
config = function()
require('frontline').setup({
newlines_after_tasks = 2, -- Number of blank lines after tasks (default: 2)
})
end,
}Using packer.nvim
use {
"yourusername/frontline.nvim",
config = function()
require('frontline').setup()
end,
}Add Taskwarrior queries to your Markdown headers using the pipe | separator:
# My Pending Tasks | status:pending
# High Priority Work | project:work priority:H
# Due This Week | due.before:eowFrontline supports multiple Taskwarrior databases (workspaces) using the @workspace syntax in your queries:
# Personal Tasks | @personal status:pending
# Work Tasks | @work project:myproject status:pending
# Default Workspace Tasks | status:pendingConfiguration:
require('frontline').setup({
workspaces = {
personal = "~/.config/taskwarrior/personal/.taskrc",
work = "~/.config/taskwarrior/work/.taskrc",
},
default_workspace = "personal", -- Used when no @workspace specified
})Key Points:
- Use
@workspace_namein your query to specify which workspace to use - If no workspace is specified, the
default_workspaceis used - If
default_workspaceisnil, the system's default Taskwarrior database is used - A notification displays the current workspace when opening a file
- All task operations (create, modify, toggle, etc.) use the current workspace context
- Override workspace in task operations: Include
@workspacein task creation input to override the current buffer's workspace
Workspace Override Examples:
When creating a task, you can override the current workspace:
# In a buffer with @personal workspace
# Press <leader>tn to create a new task
# Create in current workspace (personal):
New task: Fix bug in app project:mobile
# Override to create in work workspace:
New task: @work Review PR project:backend priority:H
This allows you to quickly create tasks in different workspaces without switching buffers.
Tasks are displayed as Markdown list items:
* [status] description (scheduled) [due] [icons] (hash)Examples:
* [ ] Fix authentication bug (2025-11-15 10:00) [2025-11-20 17:00] [!!!,π] (abcd1234)
* [ ] Simple task (abcd1234)
* [ ] Task with due date only [2025-11-20 17:00] (abcd1234)Where:
[status]:[ ]pending,[S]started,[x]completed,[-]deleteddescription: Task description from Taskwarrior(scheduled): Scheduled date in rounded parenthesis (if set)[due]: Due date in squared brackets (if set)[icons]: Priority (π΄ high, π medium, π‘ low), Dependencies (π), Reverse Dependencies (β), Annotations (ποΈ)(hash): Short task UUID (first 8 characters)
The plugin automatically refreshes task lists:
- When you open a Markdown file (
BufReadPost) - Before you save a Markdown file (
BufWritePost)
Use the command to manually trigger a refresh:
:FrontlineRefreshPlace your cursor on any task line and use these default keybindings:
| Keybinding | Action | Description |
|---|---|---|
<leader>td |
Toggle Done | Mark task as complete or reopen it |
<leader>ts |
Toggle Started | Start or stop working on task |
<leader>tm |
Modify Task | Modify task properties (prompts for input) |
<leader>ta |
Add Annotation | Add a note to the task |
<leader>te |
Edit Task | Open task in Taskwarrior's interactive editor |
<leader>tn |
Create Task | Create new task with smart context-aware pre-fill |
<leader>tB |
Add Dependency | Create new task as dependency of current task |
<leader>tu |
Undo Task | Undo last action on task |
<leader>tb |
Show Dependencies | Show task dependencies and reverse dependencies |
The plugin provides intelligent autocomplete when creating tasks (<leader>tn) or adding dependencies (<leader>tB).
Autocomplete Features:
- Projects (
project:): Suggests existing projects from your Taskwarrior database - Tags (
+): Suggests existing tags (excluding virtual tags like PENDING, COMPLETED) - Dates (
due:,scheduled:): Suggests common date shortcuts (today, tomorrow, eow, 1w, etc.) - Workspaces (
@): Suggests configured workspaces - Priority (
priority:): Suggests H (High), M (Medium), L (Low)
How to Use Autocomplete:
- Press
<leader>tnto create a new task (opens command-line mode with:FrontlineCreateTask) - The command line will be pre-filled with context-aware attributes if available
- Type your task description and/or attributes (e.g.,
project:,+,due:,@) - Press
<Tab>to trigger autocomplete suggestions - Use
<Tab>and<Shift-Tab>to cycle through suggestions, or continue typing to filter - Press
<Enter>to execute the command and create the task - Press
<Ctrl-c>or<Esc>to cancel
Examples:
# After pressing <leader>tn:
:FrontlineCreateTask Fix bug project:<Tab>
β Suggests: backend, frontend, mobile, web
:FrontlineCreateTask Update docs +<Tab>
β Suggests: bug, feature, documentation, urgent
:FrontlineCreateTask Review PR due:<Tab>
β Suggests: today, tomorrow, eow, 1w, 2w, 1m
:FrontlineCreateTask @<Tab>
β Suggests: personal, work
Alternative: Use Commands Directly
You can also type the commands directly in command mode:
:FrontlineCreateTask Fix authentication bug project:backend priority:H due:tomorrow
:FrontlineCreateDependency Setup database project:backendSmart Context-Aware Pre-fill:
- When creating from a task line: inherits workspace, project, due date, and scheduled date
- When creating from a header: inherits all filters from the header query
- The command line opens pre-filled with these context attributes
- Project and tags are cached for 5 minutes to improve performance
Examples:
" On a task line, press <leader>td to mark it done
" Press <leader>td again to reopen it
" Press <leader>ts to start working on a task
" Press <leader>ts again to stop
" Press <leader>tm and enter: priority:H due:tomorrow
" Press <leader>ta and enter: "Started working on this"
" Press <leader>te to open the full Taskwarrior editor in a split
" Edit all task properties, save and close to updateAfter any modification, the task list automatically refreshes to show the updated state.
require('frontline').setup({
newlines_after_tasks = 2, -- Number of blank lines after task lists (default: 2)
workspaces = {
personal = "~/.config/taskwarrior/personal/.taskrc",
work = "~/.config/taskwarrior/work/.taskrc",
},
default_workspace = "personal", -- Default workspace when none specified (nil = system taskwarrior)
enable_reverse_dependencies = true, -- Show anchor icon for tasks blocking others (default: true)
reverse_dependencies_warn_threshold = 1000, -- Warn if queries take > 1000ms (default: 1000)
mappings = {
toggle_done = "<leader>td", -- Toggle task done/undone
toggle_started = "<leader>ts", -- Toggle task started/unstarted
modify_task = "<leader>tm", -- Modify task properties
add_annotation = "<leader>ta", -- Add task annotation
edit_task = "<leader>te", -- Edit task in Taskwarrior editor
show_blocking_dependencies = "<leader>tb", -- Show dependencies
add_dependency = "<leader>tB", -- Add task as dependency
undo_task = "<leader>tu", -- Undo last action
create_task = "<leader>tn", -- Create new task
},
})| Option | Type | Default | Description |
|---|---|---|---|
newlines_after_tasks |
number | 2 | Number of blank lines to add after each task list |
workspaces |
table | {} |
Map of workspace names to Taskwarrior rc file paths |
default_workspace |
string | nil |
Default workspace name (nil uses system taskwarrior) |
enable_reverse_dependencies |
boolean | true | Enable reverse dependency tracking (β icon and "tasks this task is blocking" view) |
reverse_dependencies_warn_threshold |
number | 1000 | Warn if reverse dependency queries take longer than this (in milliseconds). Set to 0 to disable warnings. |
mappings.toggle_done |
string | "<leader>td" |
Keybinding to toggle task done/undone |
mappings.toggle_started |
string | "<leader>ts" |
Keybinding to toggle task started/unstarted |
mappings.modify_task |
string | "<leader>tm" |
Keybinding to modify task |
mappings.add_annotation |
string | "<leader>ta" |
Keybinding to add annotation |
mappings.edit_task |
string | "<leader>te" |
Keybinding to edit task in Taskwarrior editor |
mappings.show_blocking_dependencies |
string | "<leader>tb" |
Keybinding to show dependencies (forward and reverse) |
mappings.add_dependency |
string | "<leader>tB" |
Keybinding to add task as dependency |
mappings.undo_task |
string | "<leader>tu" |
Keybinding to undo last action |
mappings.create_task |
string | "<leader>tn" |
Keybinding to create new task |
Note: Set any mapping to false to disable it:
require('frontline').setup({
mappings = {
toggle_done = "<leader>td",
toggle_started = false, -- Disable this mapping
modify_task = "<leader>tm",
add_annotation = "<leader>ta",
},
})- Neovim 0.5+
- Taskwarrior installed and configured
- Tasks in your Taskwarrior database
Test the plugin without installing it:
cd /path/to/frontline.nvim
nvim -u test_config.lua test.md# Today's Tasks | +today status:pending
# Work Project | project:work
# High Priority | priority:H status:pendingWhen opened in Neovim, each section will automatically populate with matching tasks.
This plugin aims for compatibility with Taskwiki's header query format.
nvim --headless -c "PlenaryBustedDirectory tests/"All tests should pass (30/30):
- Integration tests: 5
- Parser tests: 3
- Task Client tests: 4
- Renderer tests: 18
MIT
Contributions welcome! Please feel free to submit a Pull Request.