Skip to content

feat(tasks): add markdown task lists and context badges - #405

Open
JuanFerber wants to merge 12 commits into
folke:mainfrom
JuanFerber:feat/markdown-todos
Open

JuanFerber wants to merge 12 commits into
folke:mainfrom
JuanFerber:feat/markdown-todos

Conversation

@JuanFerber

@JuanFerber JuanFerber commented Aug 26, 2026 •

Copy link
Copy Markdown

feat: add markdown task lists, multiline context badges and interactive toggling

🚀 Overview

This Pull Request addresses the longstanding -- TODO: add support for markdown todos comment in config.lua and enhances todo-comments.nvim with:

  • Markdown Task Lists ([ ], [/], [x]) within TODO blocks with live completion ratio ( 1/3 (33%)).
  • Full Inline Comment Task Support: Accurately detects, highlights, and tracks tasks appearing after code statements (const x = 1; // TODO: [ ] task, x = 1 # TODO: [/], int y = 2; // TODO: [x]) with zero false positives on code identifiers or types (T[ ], any[]).
  • Multiline Context Indicators & Folding (:TodoToggleFold) with smart line counting ((+3 lines) shown when folded/hidden) and atomic block lifecycle management.
  • Interactive Checkbox Toggling (:TodoToggle) to cycle task states ([ ] ➔ [/] ➔ [x] ➔ [ ]) with clean single-space insertion on plain headers and zero extmark jitter.
  • Global Search & Picker Badges (Telescope, Trouble, Snacks, Quickfix, LocList) displaying unified task completion ratios and context line counters.
  • Smart Telescope Formatting: Dynamic width calculation with smooth ellipsis truncation (...) ensuring badges are always fully visible on the right edge.
  • Health Check Integration (:checkhealth todo-comments): Audits dependencies, search tool availability, optional plugin integrations, and feature statuses.

todo_toggle_and_fold

✨ Features & Architecture

1. Multiline Context & Folding (highlight.context & highlight.folding)

  • Universal Scope: Applies to all comment keywords (TODO, WARN, NOTE, PERF, FIX, etc.).
  • Smart Folding-Aware Display: Omits redundant line counters when child lines are expanded/visible in the buffer, and automatically appends (+N lines) when the block is folded (▶).
  • Folding Command: :TodoToggleFold folds/unfolds context lines with instant visual indicator updates (▼ / ▶).
  • Atomic Block Expansion: Prevents partial viewport rendering from truncating block counts or flickering when scrolling.

2. Task Management & Subtasks (tasks)

  • Dedicated Scope: Specifically targets TODO blocks to avoid false positives on warning or performance notes.
  • Visual Checkbox Highlights:
    • [ ] (Todo) ➔ TodoCheckboxTodo (DiagnosticInfo)
    • [/] (Doing) ➔ TodoCheckboxDoing (DiagnosticWarn)
    • [x] / [X] (Done) ➔ TodoCheckboxDone (DiagnosticHint)
  • Live Progress Virtual Text: Injects real-time status at EOL:  2/4 (50%).
  • Sign Column Prioritization: Automatically places todo-sign-task-<state> on any line with an active checkbox, seamlessly falling back to todo-sign-TODO for checkboxless headers.
  • Interactive Toggling: :TodoToggle cycles task states on the current line (supporting inline and standalone comments) and cleanly inserts [ ] on plain comment lines inside a TODO block without double spaces (-- TODO: [ ] task).

3. Global Search & Picker Integration

  • search.lua extracts task and context metrics for QuickFix, LocList, Trouble, and Snacks in a single pass via Tasks.get_block_stats().
  • Telescope displays highlighted badges: TODO: Implement auth [2/4 (50%)] [+4 lines].
  • Optional: Can be toggled globally via search.badges = false.
  • Protected against code strings: Ignores matches inside quotes or backtick code spans (e.g. print("TEST: ...") or assert(x == "TODO:")).

4. Health Check (:checkhealth todo-comments)

  • Audits Neovim version, ripgrep executable path, plenary.nvim, telescope.nvim, trouble.nvim, fzf-lua, and nvim-treesitter.
  • Reports active configuration statuses and provides actionable remediation steps if an enabled feature is missing its dependency.

⚙️ Configuration Defaults

require("todo-comments").setup({
  highlight = {
    multiline = true,
    multiline_pattern = "^.",
    multiline_context = 10,
    context = {
      enabled = true,
      show_lines = "folded", -- "folded" (only when lines are hidden), true (always), or false
      lines_format = " (+%d lines)",
    },
    folding = {
      enabled = true,
      open_icon = "▼ ",
      closed_icon = "▶ ",
    },
  },
  search = {
    command = "rg",
    args = {
      "--color=never",
      "--no-heading",
      "--with-filename",
      "--line-number",
      "--column",
    },
    pattern = [[\b(KEYWORDS):]],
    badges = true, -- show task progress and context line badges in search pickers
  },
  tasks = {
    enabled = true, -- enable markdown checkbox detection in TODO blocks
    signs = true, -- show checkbox icons in the sign column
    checkboxes = {
      todo = { icon = "󰄱 ", color = "info", pattern = "%[ %]" }, -- [ ]
      doing = { icon = "󰡖 ", color = "warning", pattern = "%[%/%]" }, -- [/]
      done = { icon = "󰄵 ", color = "hint", pattern = "%[[xX]%]" }, -- [x] or [X]
    },
    progress = {
      enabled = true, -- show progress ratio in virtual text
      show_count = true, -- show "1/3"
      show_percent = true, -- show "(33%)"
      icon = "",
      count_format = "%d/%d",
      percent_format = "(%d%%)",
    },
  },
})

⌨️ Commands & Keymaps

-- Toggle checkbox task status under cursor ([ ] -> [/] -> [x] -> [ ])
vim.keymap.set("n", "<leader>tt", "<cmd>TodoToggle<CR>", { desc = "Toggle TODO task status" })

-- Toggle multiline context folding
vim.keymap.set("n", "<leader>tf", "<cmd>TodoToggleFold<CR>", { desc = "Toggle TODO multiline fold" })

🧪 Testing & Reliability

  • 100% Backward Compatible: If no checkboxes are used, all existing behavior remains completely unaffected.
  • Zero False Positives: Rigorous anti-collision safeguards ([%w_]$ boundary check and Util.is_inside_string) ensure types, arrays, index access expressions (T[ ], any[], arr[ ] = x) and code print statements are never misinterpreted as tasks.
  • Graceful Degradation: All file operations, module loaders, and integrations are wrapped in safe guards (pcall). Missing optional plugins will never crash or disrupt editor operations.
  • Automated Test Suite Included:
    • tests/test_highlight.lua: Validates extmarks, checkbox highlight groups, sign column priority, and virtual text formatting on standalone and inline tasks.
    • tests/test_tasks.lua: Validates state cycle transitions, header spacing normalization, inline task toggles, and block boundary detection.
    • tests/test_folding.lua: Validates folding execution, multi-block atomicity, and dynamic arrow rotation (▼ ➔ ▶).
    • tests/test_search.lua: Validates search result processing and unified badge calculation across Lua, Python, and C inline task patterns.

…teractive toggling

- Add markdown checkbox detection ([ ], [/], [x]) and live progress
virtual text for TODOs.
- Add multiline context line indicators and folding (:TodoToggleFold).
- Add interactive task toggling command (:TodoToggle).
- Add task progress and context line badges in search pickers
(Telescope, Trouble, Quickfix).
- Add healthcheck module (:checkhealth todo-comments) and defensive
error handling.
- Add comprehensive automated test suite.
@github-actions github-actions Bot added the size/xl Extra large PR (100+ lines changed) label Aug 26, 2026
@JuanFerber JuanFerber changed the title feat: add markdown task lists, multiline context badges and interactive toggling feat(tasks): add markdown task lists and context badges Aug 26, 2026
JuanFerber and others added 11 commits August 27, 2026 15:26
…d fix eof hang

- Canonical checkbox detection for inline comments.
- Prevent string literal collisions in print/assert statements.
- Atomic block expansion preventing truncated ratio calculations.
- Clamped window bounds resolving infinite loop at EOF.
- Synchronous re-highlighting eliminating extmark toggle jitter.
- Add regression test suites for multi-block stability.
- Add ordered Showcase section with interactive, inline, and search demos.
- Include optimized GIF recordings in assets/.
…te badges in quickfix

- Add backtick (code span) delimiter tracking to Util.is_inside_string.
- Locate matched keyword preceding colon in Highlight.match instead of leftmost unpunctuated substring.
- Prevent current_block tracking and virtual text emission on quickfix buffers, eliminating double badges ([N/M] + virt_text).
…s on continuation lines

- Clamp finish and start column offsets to line length for multiline continuation lines.
- Set start and finish to the matched column on the current line instead of inheriting previous header column.
- Safeguard add_highlight against negative offsets and wrap nvim_buf_set_extmark in pcall.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xl Extra large PR (100+ lines changed)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant