docs: capture v0.1 feature roadmap as backlog tasks (release-1 + release-2)
a9471ff9e4848f6c8e66f8eb3fc87f6ec9d51d42
humdrum <me@humdrum.me> · 2026-06-29 09:26
parent cff0fb47
docs: capture v0.1 feature roadmap as backlog tasks (release-1 + release-2) Release 1 (TASK-006..012): undo/redo, find-in-document, list/checkbox continuation, wrap-selection formatting, status line:col + word count, in-app help overlay, editing-polish bundle. Release 2 (TASK-013/014 + existing TASK-004/005): full-text vault search, external-change detection, large-file perf, tab/CJK display width.
9 files changed
- → Undo-redo.md +27 −0
@@ -0,0 +1,27 @@
+---
+id: TASK-006
+title: Undo / redo
+status: "\U0001F7E6 Backlog"
+assignee: []
+created_date: '2026-06-29 16:26'
+labels:
+ - feature
+ - release-1
+dependencies: []
+priority: high
+ordinal: 6000
+---
+
+## Description
+
+<!-- SECTION:DESCRIPTION:BEGIN -->
+Release 1. The biggest gap and a data-loss safety net (select-all+type or Ctrl+U is currently unrecoverable). Add an undo stack in internal/editor capturing buffer+cursor snapshots (or reversible ops). Coalesce consecutive typing into one undo group; each structural op (newline, delete, paste, cut, delete-selection, kill-line, word-delete) is its own group. Bound history (e.g. 500 entries). Keys: Ctrl+Z undo, Ctrl+Y (and Ctrl+Shift+Z) redo. Restore cursor + scroll on undo/redo. Mark Dirty appropriately.
+<!-- SECTION:DESCRIPTION:END -->
+
+## Acceptance Criteria
+<!-- AC:BEGIN -->
+- [ ] #1 Ctrl+Z reverts the last edit group; Ctrl+Y / Ctrl+Shift+Z redoes
+- [ ] #2 Typing is coalesced; structural ops are separate groups
+- [ ] #3 Cursor and selection state restored on undo/redo
+- [ ] #4 Redo stack cleared on a new edit; history bounded
+<!-- AC:END -->
- → Find-in-document.md +26 −0
@@ -0,0 +1,26 @@
+---
+id: TASK-007
+title: Find in document
+status: "\U0001F7E6 Backlog"
+assignee: []
+created_date: '2026-06-29 16:26'
+labels:
+ - feature
+ - release-1
+dependencies: []
+priority: high
+ordinal: 7000
+---
+
+## Description
+
+<!-- SECTION:DESCRIPTION:BEGIN -->
+Release 1. In-file search (Ctrl+F is the picker, so use another key e.g. Ctrl+G or '/'). A find bar (reuse the textinput) takes a query; matches are highlighted; Enter / n next, Shift+Enter / N previous, wrapping around; case-insensitive by default; Esc closes and returns to the editor; the viewport scrolls to keep the active match visible. Live-update matches as you type.
+<!-- SECTION:DESCRIPTION:END -->
+
+## Acceptance Criteria
+<!-- AC:BEGIN -->
+- [ ] #1 A keybind opens a find prompt; typing filters/highlights matches
+- [ ] #2 Next/prev cycle through matches, wrapping; view scrolls to the match
+- [ ] #3 Esc closes the find bar; case-insensitive matching
+<!-- AC:END -->
- → List-and-checkbox-continuation.md +26 −0
@@ -0,0 +1,26 @@
+---
+id: TASK-008
+title: List and checkbox continuation
+status: "\U0001F7E6 Backlog"
+assignee: []
+created_date: '2026-06-29 16:26'
+labels:
+ - feature
+ - release-1
+dependencies: []
+priority: high
+ordinal: 8000
+---
+
+## Description
+
+<!-- SECTION:DESCRIPTION:BEGIN -->
+Release 1. Markdown table-stakes. Enter on a list line ('- ', '* ', '+ ', 'N. ', '- [ ] ') starts a new item with the same marker and indentation; ordered lists increment the number; checkboxes continue as '- [ ] '. Enter on an EMPTY list item removes the marker and exits the list. Tab / Shift+Tab indent / outdent the current list item (adjust leading whitespace). Toggle a checkbox '[ ]'<->'[x]' with a key or by editing.
+<!-- SECTION:DESCRIPTION:END -->
+
+## Acceptance Criteria
+<!-- AC:BEGIN -->
+- [ ] #1 Enter continues the list marker (ordered numbers increment)
+- [ ] #2 Enter on an empty item exits the list (removes the marker)
+- [ ] #3 Tab / Shift+Tab indent and outdent list items
+<!-- AC:END -->
- → Wrap-selection-in-markdown-formatting.md +26 −0
@@ -0,0 +1,26 @@
+---
+id: TASK-009
+title: Wrap selection in markdown formatting
+status: "\U0001F7E6 Backlog"
+assignee: []
+created_date: '2026-06-29 16:26'
+labels:
+ - feature
+ - release-1
+dependencies: []
+priority: medium
+ordinal: 9000
+---
+
+## Description
+
+<!-- SECTION:DESCRIPTION:BEGIN -->
+Release 1. With a selection, a shortcut wraps it: bold (**), italic (_), inline code (backtick), and link ([sel](|)). Toggle off if already wrapped. With no selection, insert the empty pair with the cursor between. Needs free keys (Ctrl+B is new-inbox; pick non-conflicting bindings, document them). Keep the markup-visible invariant (the markers are inserted into the buffer).
+<!-- SECTION:DESCRIPTION:END -->
+
+## Acceptance Criteria
+<!-- AC:BEGIN -->
+- [ ] #1 Selection wraps in **/_/code/link via shortcuts; toggles off when already wrapped
+- [ ] #2 No selection inserts the pair with the cursor inside
+- [ ] #3 Bindings chosen to not clash with existing keys; documented
+<!-- AC:END -->
- → Status-bar-line-col-and-word-count.md +26 −0
@@ -0,0 +1,26 @@
+---
+id: TASK-010
+title: 'Status bar: line:col and word count'
+status: "\U0001F7E6 Backlog"
+assignee: []
+created_date: '2026-06-29 16:26'
+labels:
+ - feature
+ - release-1
+dependencies: []
+priority: medium
+ordinal: 10000
+---
+
+## Description
+
+<!-- SECTION:DESCRIPTION:BEGIN -->
+Release 1. The status bar shows only filename/theme/dirty. Add live cursor position (Ln:Col, 1-based) and a word count (and optionally char count / % through the document). Lay out alongside the existing left status without overflowing the bar; keep theme colors.
+<!-- SECTION:DESCRIPTION:END -->
+
+## Acceptance Criteria
+<!-- AC:BEGIN -->
+- [ ] #1 Status bar shows Ln:Col (1-based) updating live
+- [ ] #2 Status bar shows a word count
+- [ ] #3 Layout coexists with filename/dirty and respects theme colors
+<!-- AC:END -->
- → In-app-help-overlay.md +25 −0
@@ -0,0 +1,25 @@
+---
+id: TASK-011
+title: In-app help overlay
+status: "\U0001F7E6 Backlog"
+assignee: []
+created_date: '2026-06-29 16:26'
+labels:
+ - feature
+ - release-1
+dependencies: []
+priority: medium
+ordinal: 11000
+---
+
+## Description
+
+<!-- SECTION:DESCRIPTION:BEGIN -->
+Release 1. A keybind cheatsheet inside the editor (we have 'glint -h' on the CLI). A key (e.g. '?' when not typing, or a Ctrl combo) toggles a centered overlay listing all editor keys and command flags; Esc closes. Source the same content as helpText in main.go (consider sharing a single source of truth).
+<!-- SECTION:DESCRIPTION:END -->
+
+## Acceptance Criteria
+<!-- AC:BEGIN -->
+- [ ] #1 A key toggles a help overlay listing editor keys + commands
+- [ ] #2 Esc closes it; content matches the CLI help
+<!-- AC:END -->
- → Editing-polish-bundle.md +26 −0
@@ -0,0 +1,26 @@
+---
+id: TASK-012
+title: Editing polish bundle
+status: "\U0001F7E6 Backlog"
+assignee: []
+created_date: '2026-06-29 16:26'
+labels:
+ - feature
+ - release-1
+dependencies: []
+priority: low
+ordinal: 12000
+---
+
+## Description
+
+<!-- SECTION:DESCRIPTION:BEGIN -->
+Release 1 (can be split). Smaller niceties: (a) auto-close pairs — typing '[','(','backtick' inserts the closing char with the cursor inside; typing the closing char over an auto-inserted one steps over it; (b) smart Home — first press goes to the first non-whitespace column, second to column 0; (c) go-to-line command/prompt; (d) remember cursor position per file within a session (reopening returns to it); (e) paste a URL over a selection -> [selection](url).
+<!-- SECTION:DESCRIPTION:END -->
+
+## Acceptance Criteria
+<!-- AC:BEGIN -->
+- [ ] #1 Auto-close pairs for [] () and backticks (with step-over)
+- [ ] #2 Smart Home (first non-blank, then col 0)
+- [ ] #3 Go-to-line; per-file cursor memory; paste-URL-over-selection
+<!-- AC:END -->
- → Full-text-vault-search.md +25 −0
@@ -0,0 +1,25 @@
+---
+id: TASK-013
+title: Full-text vault search
+status: "\U0001F7E6 Backlog"
+assignee: []
+created_date: '2026-06-29 16:26'
+labels:
+ - feature
+ - release-2
+dependencies: []
+priority: medium
+ordinal: 13000
+---
+
+## Description
+
+<!-- SECTION:DESCRIPTION:BEGIN -->
+Release 2. The picker matches filenames only. Add a content search across the vault/working dir (ripgrep if available, else a Go walk) surfacing files + matching lines; open at the match. Was explicitly deferred in v1.1.
+<!-- SECTION:DESCRIPTION:END -->
+
+## Acceptance Criteria
+<!-- AC:BEGIN -->
+- [ ] #1 Search note contents across the vault; results show file + matching line
+- [ ] #2 Selecting a result opens the file at the match
+<!-- AC:END -->
- → External-change-detection-on-save.md +25 −0
@@ -0,0 +1,25 @@
+---
+id: TASK-014
+title: External change detection on save
+status: "\U0001F7E6 Backlog"
+assignee: []
+created_date: '2026-06-29 16:26'
+labels:
+ - feature
+ - release-2
+dependencies: []
+priority: medium
+ordinal: 14000
+---
+
+## Description
+
+<!-- SECTION:DESCRIPTION:BEGIN -->
+Release 2. If an open file changes on disk while editing (synced vault: Obsidian/iCloud), glint silently overwrites on save. Track the file's mtime/size at load; before saving, if it changed, warn and offer to overwrite/reload/diff instead of clobbering.
+<!-- SECTION:DESCRIPTION:END -->
+
+## Acceptance Criteria
+<!-- AC:BEGIN -->
+- [ ] #1 Detect when the open file changed on disk since load
+- [ ] #2 On save with an external change, warn instead of silently overwriting
+<!-- AC:END -->