Skip to content

Mitra98t/TodoPile

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Todo Pile

A Neovim plugin that manages a LIFO stack of todos anchored to code positions to keep in mind the stack of task at hand.

Each todo remembers the file and line where it was created and displays a marker in the sign column whenever that file is open.

Inline todos showcase

List of todos showcase

Requirements

Installation

lazy.nvim

{
  "Mitra98t/TodoPile",
  -- optional: add snacks or telescope for a richer picker UI
  dependencies = { "folke/snacks.nvim" },
  config = function()
    require("todo_pile").setup()
  end,
}

Configuration

Call setup() once, optionally passing a config table. All fields are optional.

require("todo_pile").setup({
  -- Symbol displayed in the sign column next to a todo's line.
  -- Any string up to 2 characters works (single emoji included).
  sign_text = "",              -- default: "●"

  -- Highlight applied to the sign column marker.
  -- Accepts a highlight group name or a hex color string.
  sign_hl = "DiagnosticHint",   -- default: "DiagnosticHint"
  -- sign_hl = "#ff8800",        -- hex color alternative

  -- When true, each todo's first letter is used as its sign column marker
  -- instead of sign_text. Mutually exclusive with sign_text — a warning is
  -- shown at startup if both are set.
  sign_first_letter = false,    -- default: false

  -- When true, popping the top todo automatically jumps to the new top.
  jump_after_pop = true,        -- default: true

  -- When true, the todo text is shown as ghost (virtual) text at the end of
  -- its line.
  ghost_text = false,           -- default: false

  -- Prefix displayed before the todo text when ghost_text is enabled.
  --   true   → the sign column marker glyph (sign_text or first letter) — default
  --   false  → no prefix, only the todo text
  --   string → literal prefix, e.g. "TODO:" or "FIXME:"
  ghost_text_prefix = true,     -- default: true (marker glyph)

  -- Highlight applied to the ghost text.
  -- Accepts a highlight group name or a hex color string.
  -- Defaults to the TodoPileGhostText group, which is linked to Comment.
  ghost_text_hl = "Comment",    -- default: links to "Comment"
  -- ghost_text_hl = "#ff8800", -- hex color alternative
})

Commands

Command Description
:TodoPileAdd [text] Add a todo at the cursor position. If text is omitted a prompt is shown.
:TodoPilePop Remove the most recent todo. Jumps to the new top if jump_after_pop is enabled.
:TodoPileJump Jump to the file and line of the most recent todo without removing it.
:TodoPileList Open a picker with todos in the current project. Select one to navigate to it.
:TodoPileList! Same as above but shows todos from all projects.
:TodoPileClose Open a picker with todos in the current project. Select one to delete it.
:TodoPileClose! Same as above but shows todos from all projects.
:TodoPileQuickfix Populate the quickfix list with todos in the current project and open it.
:TodoPileReorder Open a floating window to manually reorder the stack.
:TodoPileClearProject Delete all todos whose files belong to the current working directory (asks for confirmation).

Reorder window keymaps

Key Action
<C-k> / <C-Up> Move item up
<C-j> / <C-Down> Move item down
<CR> Save new order
q / <Esc> Cancel without saving

Example keymap configuration

-- Suggested keymaps (adjust to your preference)
local map = vim.keymap.set

-- Add a todo at the current position (prompts for text)
map("n", "<leader>ta", "<cmd>TodoPileAdd<cr>",     { desc = "Todo: add" })

-- Close (pop) the top todo and jump to the new top
map("n", "<leader>tx", "<cmd>TodoPilePop<cr>",     { desc = "Todo: pop top" })

-- Jump to the top todo without removing it
map("n", "<leader>tj", "<cmd>TodoPileJump<cr>",    { desc = "Todo: jump to top" })

-- Browse and navigate all todos
map("n", "<leader>tl", "<cmd>TodoPileList<cr>",    { desc = "Todo: list" })

-- Browse and selectively close a todo
map("n", "<leader>tc", "<cmd>TodoPileClose<cr>",   { desc = "Todo: close one" })

-- Reorder the stack
map("n", "<leader>tr", "<cmd>TodoPileReorder<cr>", { desc = "Todo: reorder" })

-- Browse todos from all projects
map("n", "<leader>tL", "<cmd>TodoPileList!<cr>",       { desc = "Todo: list all projects" })

-- Send todos to the quickfix list
map("n", "<leader>tq", "<cmd>TodoPileQuickfix<cr>",    { desc = "Todo: quickfix list" })

-- Clear all todos for the current project
map("n", "<leader>tX", "<cmd>TodoPileClearProject<cr>", { desc = "Todo: clear project" })

Full lazy.nvim spec with keymaps

{
  "Mitra98t/TodoPile",
  dependencies = { "folke/snacks.nvim" },
  keys = {
    { "<leader>ta", "<cmd>TodoPileAdd<cr>",          desc = "Todo: add" },
    { "<leader>tx", "<cmd>TodoPilePop<cr>",          desc = "Todo: pop top" },
    { "<leader>tj", "<cmd>TodoPileJump<cr>",         desc = "Todo: jump to top" },
    { "<leader>tl", "<cmd>TodoPileList<cr>",         desc = "Todo: list" },
    { "<leader>tc", "<cmd>TodoPileClose<cr>",        desc = "Todo: close one" },
    { "<leader>tr", "<cmd>TodoPileReorder<cr>",      desc = "Todo: reorder" },
    { "<leader>tL", "<cmd>TodoPileList!<cr>",         desc = "Todo: list all projects" },
    { "<leader>tq", "<cmd>TodoPileQuickfix<cr>",      desc = "Todo: quickfix list" },
    { "<leader>tX", "<cmd>TodoPileClearProject<cr>",  desc = "Todo: clear project" },
  },
  config = function()
    require("todo_pile").setup({
      sign_text      = "",
      sign_hl        = "DiagnosticHint",
      jump_after_pop = true,
    })
  end,
}

Statusline integration

TodoPile exposes a few functions you can embed in any statusline plugin:

Function Returns
require("todo_pile").count() Total number of todos across all projects
require("todo_pile").project_count() Number of todos in the current working directory
require("todo_pile").top_text() Text of the top todo in the current project, or ""

lualine example:

-- in your lualine sections
{
  function()
    local n = require("todo_pile").project_count()
    return n > 0 and ("" .. n) or ""
  end,
}

Data storage

Todos are persisted as JSON at:

$XDG_DATA_HOME/nvim/todo_pile.json

(vim.fn.stdpath("data") on your system — typically ~/.local/share/nvim/todo_pile.json.)

The file is rewritten on every change. Deleting it resets the pile.

About

Simple TODOs pluign for NVIM to open TODOs in a stack!

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages