feat(lsp): show workspace TODOs via LSP pull diagnostics #130

Merged
kfickel merged 6 commits from 129_lsp-workspace-todo-diagnostics into main 2026-08-06 20:08:26 +02:00
Owner

Closes #129.

Summary

  • Implements the ticket's primary approach: LSP 3.17 pull diagnostics (textDocument/diagnostic, workspace/diagnostic) so open/waiting @Task shards across all .md files in the workspace are surfaced, not just the currently open buffer. Advertises diagnosticProvider with workspaceDiagnostics: true.
  • Todos are reported as Information-severity diagnostics (message = the todo's line text, [waiting]-prefixed for waiting tasks). R15/R18 diagnostics remain push-only and unchanged; todos are exposed exclusively via the new pull methods to avoid duplicate reporting.
  • Registers a **/*.md file watcher (alongside the existing .streamd.toml one) that invalidates the affected file's cache and sends workspace/diagnostic/refresh; also refreshes after didSave so edits show up without waiting on the client's own pull heuristics.
  • Implements the ticket's secondary goal: workspace/symbol now additionally emits a symbol per open/waiting todo whose name is the todo's own text (not just the marker name), so todos are findable by content via fuzzy symbol search.
  • Fixes an existing limitation along the way: workspace/symbol, textDocument/references, and textDocument/rename previously only scanned the top-level directory (WalkDir::max_depth(1)); all three (plus the new todo index) now share one recursive file-listing helper that skips dotdirs like .git.
  • Docs: updated README's LSP feature table and REQUIREMENTS.md (new R25f, extended R25b/R25e/config-watching sections).
  • Version bumped 0.2.7 → 0.3.0 (minor) to trigger a new release on merge.

Implementation notes / scope decisions

(from the refinement plan on #129, confirmed with the reporter before implementation)

  • Both task == open and task == waiting count as todos.
  • Diagnostic severity is Information (not Hint), since Hint-level diagnostics are often filtered or underline-only in editor problem panels.
  • No resultId/unchanged-report caching in this pass — each request recomputes from current state. Acceptable for typical vault sizes; can be added later if profiling shows it's needed.
  • Out of scope (per ticket): code lens todo counts, textDocument/documentSymbol todo entries, done/open diagnostic tags, push-diagnostics fallback (only needed if pull diagnostics prove unreliable in Zed in practice).

Test plan

  • cargo test — all existing tests pass, plus new unit tests for list_markdown_files (recursive, skips dotdirs), extract_todo_items (open/waiting extraction), todo_diagnostics (severity/message/range), and collect_todo_symbols (name = todo text, query filtering).
  • cargo clippy --all-targets clean.
  • nix flake check — all checks pass (clippy, fmt, tests, pre-commit).
  • Manual verification in Zed (not performed in this session — recommend opening a workspace with .streamd.toml and multiple note files containing @Task markers in subdirectories, and confirming the diagnostics panel and workspace symbol search both surface them).
Closes #129. ## Summary - Implements the ticket's primary approach: LSP 3.17 pull diagnostics (`textDocument/diagnostic`, `workspace/diagnostic`) so open/waiting `@Task` shards across **all** `.md` files in the workspace are surfaced, not just the currently open buffer. Advertises `diagnosticProvider` with `workspaceDiagnostics: true`. - Todos are reported as `Information`-severity diagnostics (message = the todo's line text, `[waiting]`-prefixed for waiting tasks). R15/R18 diagnostics remain push-only and unchanged; todos are exposed exclusively via the new pull methods to avoid duplicate reporting. - Registers a `**/*.md` file watcher (alongside the existing `.streamd.toml` one) that invalidates the affected file's cache and sends `workspace/diagnostic/refresh`; also refreshes after `didSave` so edits show up without waiting on the client's own pull heuristics. - Implements the ticket's secondary goal: `workspace/symbol` now additionally emits a symbol per open/waiting todo whose name is the todo's own text (not just the marker name), so todos are findable by content via fuzzy symbol search. - Fixes an existing limitation along the way: `workspace/symbol`, `textDocument/references`, and `textDocument/rename` previously only scanned the top-level directory (`WalkDir::max_depth(1)`); all three (plus the new todo index) now share one recursive file-listing helper that skips dotdirs like `.git`. - Docs: updated README's LSP feature table and REQUIREMENTS.md (new R25f, extended R25b/R25e/config-watching sections). - Version bumped 0.2.7 → 0.3.0 (minor) to trigger a new release on merge. ## Implementation notes / scope decisions (from the refinement plan on #129, confirmed with the reporter before implementation) - Both `task == open` and `task == waiting` count as todos. - Diagnostic severity is `Information` (not `Hint`), since Hint-level diagnostics are often filtered or underline-only in editor problem panels. - No `resultId`/unchanged-report caching in this pass — each request recomputes from current state. Acceptable for typical vault sizes; can be added later if profiling shows it's needed. - Out of scope (per ticket): code lens todo counts, `textDocument/documentSymbol` todo entries, done/open diagnostic tags, push-diagnostics fallback (only needed if pull diagnostics prove unreliable in Zed in practice). ## Test plan - [x] `cargo test` — all existing tests pass, plus new unit tests for `list_markdown_files` (recursive, skips dotdirs), `extract_todo_items` (open/waiting extraction), `todo_diagnostics` (severity/message/range), and `collect_todo_symbols` (name = todo text, query filtering). - [x] `cargo clippy --all-targets` clean. - [x] `nix flake check` — all checks pass (clippy, fmt, tests, pre-commit). - [ ] Manual verification in Zed (not performed in this session — recommend opening a workspace with `.streamd.toml` and multiple note files containing `@Task` markers in subdirectories, and confirming the diagnostics panel and workspace symbol search both surface them).
symbol/references/rename previously only scanned the top-level
directory (WalkDir max_depth(1)), so notes in subdirectories were
invisible to workspace-wide LSP features. Introduce a shared
list_markdown_files() helper that walks the whole tree while
skipping dotdirs (e.g. .git), and use it in all three call sites.
Add textDocument/diagnostic and workspace/diagnostic support so open
and waiting @Task shards across the whole workspace are surfaced as
Information-severity diagnostics, not just in the currently open
buffer. Advertise diagnosticProvider (workspaceDiagnostics: true) in
server capabilities.

R15/R18 diagnostics remain push-only (unchanged); todos are exposed
exclusively via the new pull methods to avoid duplicate reporting.
Register a **/*.md file watcher alongside the existing .streamd.toml
one so external edits/creates/deletes invalidate the affected file's
cache and trigger workspace/diagnostic/refresh. Also refresh after
did_save, so todos added/removed in the open buffer show up in the
workspace-wide diagnostics view without waiting for the client's own
pull heuristics.
Emit an additional SymbolInformation per open/waiting @Task shard
whose name is the todo's own line text (not just the marker name),
so todos are findable by content through fuzzy workspace symbol
search. Complements the existing generic marker-name symbols rather
than replacing them.
Update README's LSP feature table and REQUIREMENTS.md (new R25f,
extended R25e/R25b/config-watching sections) to describe the new
textDocument/diagnostic + workspace/diagnostic todo support, the
recursive .md file listing, and the *.md file watcher.
chore(build): bump version to 0.3.0
All checks were successful
Continuous Integration / Build Package (push) Successful in 7s
Continuous Integration / Lint, Check & Test (push) Successful in 30s
Release / Build and Release (push) Successful in 6m1s
2a2cd099b2
kfickel deleted branch 129_lsp-workspace-todo-diagnostics 2026-08-06 20:08:26 +02:00
Sign in to join this conversation.
No reviewers
No labels
planned
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
kfickel/streamd!130
No description provided.