A lightweight, floating window todo plugin for Neovim that manages markdown-based todo lists with advanced sorting and bulk operations.
- Floating Window Interface - Opens todos in a beautiful floating window that doesn't disrupt your workflow
- Dual Display Modes - Choose between floating window or regular buffer
- Smart Todo Creation - Press Enter in insert mode to auto-create new todo checkboxes with proper indentation
- Priority Syntax Highlighting - Visual highlighting for
[HIGH],[MEDIUM],[LOW]priority tags and completed tasks - Quick Date Insertion - Fast insertion of today's date, tomorrow's date, or full date with day name
- Custom Window Width - Configure floating window width to your preference
- Auto-Sorting - Automatically sorts todos with incomplete items first
- Bulk Operations - Mark all todos as done/undone, clear completed items
- Smart Persistence - Auto-saves changes when closing floating window (supports
q,Esc,ZZ) - Customizable - Configure file path and all keybindings
- Markdown Format - Uses standard markdown checkbox format
- [ ]and- [x]
Add this to your Neovim configuration:
-- In lua/plugins/todo-md.lua or your plugin configuration
return {
{
"zaffron/todo-md.nvim",
opts = {
todo_file_path = vim.fn.expand("~/todo.md"), -- Customize your todo file location
auto_sort = true, -- Auto-sort todos by completion status
floating_width = 80, -- Custom width for floating window (in columns)
keybindings = {
open_todo_floating = "<leader>to",
open_todo_buffer = "<leader>tO",
add_todo = "<leader>ta",
toggle_todo = "<leader>tt",
delete_todo = "<leader>td",
sort_todos = "<leader>ts",
clear_todos = "<leader>tc",
mark_all_done = "<leader>tD",
mark_all_undone = "<leader>tU",
insert_today = "<leader>tdt",
insert_tomorrow = "<leader>tdm",
insert_full_date = "<leader>tdf",
},
},
config = function(_, opts)
require("zaffron.todo-md").setup(opts)
end,
keys = {
{ "<leader>to", desc = "Open Todo (Floating)" },
{ "<leader>tO", desc = "Open Todo (Buffer)" },
{ "<leader>ta", desc = "Add Todo Item" },
{ "<leader>tt", desc = "Toggle Todo Item" },
{ "<leader>td", desc = "Delete Todo Item" },
{ "<leader>ts", desc = "Sort Todos" },
{ "<leader>tc", desc = "Clear Todos" },
{ "<leader>tD", desc = "Mark All Done" },
{ "<leader>tU", desc = "Mark All Undone" },
{ "<leader>tdt", desc = "Insert Today's Date" },
{ "<leader>tdm", desc = "Insert Tomorrow's Date" },
{ "<leader>tdf", desc = "Insert Full Date" },
},
},
}- Add the plugin configuration to your
lua/plugins/directory - Restart Neovim and run
:Lazy syncto install the plugin
| Key | Action | Description |
|---|---|---|
<leader>to |
Open Todo (Floating) | Open todo list in floating window |
<leader>tO |
Open Todo (Buffer) | Open todo list in regular buffer |
<leader>ta |
Add Todo Item | Add new todo via input prompt |
<leader>tt |
Toggle Todo Item | Toggle completion status of current line |
<leader>td |
Delete Todo Item | Delete todo item on current line |
<leader>ts |
Sort Todos | Manually sort todos by completion status |
<leader>tc |
Clear Todos | Clear todos with options (all/completed only) |
<leader>tD |
Mark All Done | Mark all todos as completed |
<leader>tU |
Mark All Undone | Mark all todos as incomplete |
<leader>tdt |
Insert Today's Date | Insert current date at cursor position |
<leader>tdm |
Insert Tomorrow's Date | Insert tomorrow's date at cursor position |
<leader>tdf |
Insert Full Date | Insert full date with day name |
For users who prefer commands over keybindings, all functions are available as Neovim commands:
| Command | Equivalent Key | Description |
|---|---|---|
:TodoOpen |
<leader>to |
Open todo list in floating window |
:TodoBuffer |
<leader>tO |
Open todo list in regular buffer |
:TodoAdd |
<leader>ta |
Add new todo item via input prompt |
:TodoToggle |
<leader>tt |
Toggle completion status of current line |
:TodoDelete |
<leader>td |
Delete todo item on current line |
:TodoSort |
<leader>ts |
Sort todos by completion status |
:TodoClear |
<leader>tc |
Clear todos with interactive options |
:TodoMarkAllDone |
<leader>tD |
Mark all todos as completed |
:TodoMarkAllUndone |
<leader>tU |
Mark all todos as incomplete |
:TodoInsertToday |
<leader>tdt |
Insert today's date at cursor position |
:TodoInsertTomorrow |
<leader>tdm |
Insert tomorrow's date at cursor position |
:TodoInsertFullDate |
<leader>tdf |
Insert full date with day name |
:TodoClose |
q or Esc |
Close floating todo window |
Note: Commands work the same as keybindings. You can use either method or mix both approaches based on your preference.
When in the floating window:
q,Esc, orZZ- Close and saveEnter(in insert mode) - Auto-create new todo checkbox with same indentationCtrl+d t(in insert mode) - Insert today's dateCtrl+d m(in insert mode) - Insert tomorrow's dateCtrl+d f(in insert mode) - Insert full date with day name- Normal vim editing commands work
- Auto-saves on
:w(write)
- Quick Todo Entry: Press
<leader>taor use:TodoAddanywhere to add a new todo - Review & Edit: Press
<leader>toor use:TodoOpento open floating todo window - Fast Todo Creation: In floating window insert mode, press
Enteron any todo line to auto-create new checkboxes - Priority & Dates: Add
[HIGH],[MEDIUM],[LOW]tags for visual highlighting, use<leader>tdtto insert dates - Toggle Completion: Navigate to any todo line and press
<leader>ttor use:TodoToggle - Bulk Operations: Use
<leader>tD(:TodoMarkAllDone) to mark all as done,<leader>tc(:TodoClear) to clear completed - Organization:
<leader>ts(:TodoSort) to sort todos, or enableauto_sortfor automatic sorting
opts = {
todo_file_path = vim.fn.expand("~/Documents/my-todos.md"), -- Custom location
}opts = {
auto_sort = false, -- Disable automatic sorting
}opts = {
floating_width = 120, -- Set custom width (default: 80% of screen width)
}opts = {
keybindings = {
open_todo_floating = "<C-t>", -- Use Ctrl+t instead
add_todo = "<leader>+",
-- ... customize any keybinding
},
}The plugin uses standard markdown checkbox format:
# Todo List
- [ ] Incomplete todo item
- [x] Completed todo item
- [ ] [HIGH] Important task with high priority
- [ ] [MEDIUM] Medium priority task 2024-06-17
- [ ] [LOW] Low priority task
- [ ] Meeting with team 2024-06-18 Tuesday
## Work Tasks
- [ ] Review pull request
- [ ] Update documentationThe plugin automatically highlights priority tags in your todos:
[HIGH]- Red color with bold text for urgent tasks[MEDIUM]- Orange/yellow color with bold text for important tasks[LOW]- Blue color with bold text for less urgent tasks- Completed tasks - Gray with strikethrough for finished items
Syntax highlighting updates in real-time as you type, making it easy to visually scan your todo priorities.
Insert dates quickly using these methods:
Global keybindings (work anywhere):
<leader>tdt- Insert today's date (e.g.,2024-06-17)<leader>tdm- Insert tomorrow's date (e.g.,2024-06-18)<leader>tdf- Insert full date with day name (e.g.,2024-06-17 Monday)
Floating window shortcuts (insert mode only):
Ctrl+d t- Insert today's dateCtrl+d m- Insert tomorrow's dateCtrl+d f- Insert full date with day name
Commands:
:TodoInsertToday,:TodoInsertTomorrow,:TodoInsertFullDate
When enabled, todos are automatically sorted with:
- Non-todo content (headers, text) at the top
- Incomplete todos
- [ ]next - Completed todos
- [x]at the bottom
The clear function (<leader>tc) provides three options:
- Clear all todos - Removes all todo items
- Clear completed todos only - Removes only completed items
- Cancel - No action
- Floating window automatically updates when using bulk operations
- File changes are saved immediately when closing floating window
- All operations provide user feedback via notifications
- Ensure the plugin directory structure is correct
- Run
:Lazy syncto install - Check
:Lazyfor any error messages
- Verify your leader key is set:
vim.g.mapleader = " " - Check for keybinding conflicts with
:map <your-key> - Customize keybindings in the configuration if needed
- Check that the todo file path exists and is writable
- The plugin will create the file automatically if the directory exists
This is a personal plugin, but feel free to fork and modify for your needs. The code is structured to be easily extensible for additional features.
