diff --git a/.planning/STATE.md b/.planning/STATE.md index 286eaa5..8c000f9 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -80,10 +80,13 @@ Recent decisions affecting current work: - [Phase 04-03]: try_recv drain loop per poll iteration — drains all queued events, debounce collapses burst into single reload - [Phase 04-03]: FileWatcher initialized in main.rs before App::new() — avoids self-referential ownership, keeps constructor pure - [Phase 04-03]: Non-fatal watcher failure — warning printed, None passed to App, app runs without live reload +- [quick-1]: Bare Left/Right match arms placed after Alt+Left/Alt+Right guards — match order ensures Alt combos consumed first +- [quick-1]: BufReader + take(20) for frontmatter parsing — avoids loading entire large files +- [quick-1]: span_len covers only [name] bracket not description — keeps Tab-cycling highlight correct ### Pending Todos -None. Project complete. +None. Project complete. Quick task 1 executed. ### Blockers/Concerns @@ -95,5 +98,5 @@ All blockers resolved: ## Session Continuity Last session: 2026-03-01 -Stopped at: PROJECT COMPLETE — Completed 04-03-PLAN.md (final plan) -Resume file: N/A — project complete +Stopped at: Completed quick-1 (arrow key navigation + directory descriptions) +Resume file: N/A — project complete, quick task 1 done diff --git a/.planning/quick/1-arrow-key-navigation-and-directory-descr/1-SUMMARY.md b/.planning/quick/1-arrow-key-navigation-and-directory-descr/1-SUMMARY.md new file mode 100644 index 0000000..8ae8c5e --- /dev/null +++ b/.planning/quick/1-arrow-key-navigation-and-directory-descr/1-SUMMARY.md @@ -0,0 +1,89 @@ +--- +phase: quick-1 +plan: "01" +subsystem: navigation, directory-listing +tags: [arrow-keys, frontmatter, directory, vault] +dependency_graph: + requires: [] + provides: [ARROW-NAV, DIR-DESC] + affects: [src/app.rs, src/vault.rs] +tech_stack: + added: [] + patterns: [yaml-frontmatter-parsing, bufreader-take] +key_files: + created: [] + modified: + - src/app.rs + - src/vault.rs +decisions: + - "Bare Left/Right go after Alt+Left/Right guards in match — Rust match guards ensure Alt+Left is consumed first" + - "Read only first 20 lines via BufReader + take(20) — avoids loading large files for metadata" + - "strip_span covers only [name] bracket, not description — keeps Tab-cycling highlight correct" + - "78-char truncation budget applied after accounting for indent and separator widths" +metrics: + duration: "5 min" + completed: "2026-03-01T10:38:54Z" + tasks_completed: 1 + files_modified: 2 +--- + +# Quick Task 1: Arrow Key Navigation and Directory Descriptions Summary + +**One-liner:** Bare Left/Right arrow keys navigate history and directory listing shows YAML frontmatter descriptions in DarkGray beside each file entry. + +## What Was Built + +### Part A — Bare arrow key navigation (src/app.rs) + +Added two new match arms to `handle_key()` immediately after the `Alt+Left`/`Alt+Right` guarded arms: + +```rust +KeyCode::Left => { + self.navigate_back(); +} +KeyCode::Right => { + self.navigate_forward(); +} +``` + +The match arm order is critical: the guarded `KeyCode::Left if key.modifiers.contains(KeyModifiers::ALT)` arms are checked first. Bare `Left`/`Right` fall through to the new unguarded arms only when `ALT` is not held. Updated the doc comment on `handle_key()` to document the new bindings. + +### Part B — Frontmatter description parsing (src/vault.rs) + +Added a `description: Option` field to `DirEntry`. + +Added `extract_frontmatter_description(path: &Path) -> Option`: +- Opens the file with `BufReader` and reads at most 20 lines (`lines().take(20)`) +- Checks first line is exactly `---` +- Scans for `description:` key, stops at closing `---` +- Strips surrounding single or double quotes if present +- Returns `Some(value)` or `None` + +Updated `list_vault_files()` to call `extract_frontmatter_description()` for each `.md` file and populate the field. Directory entries get `description: None`. + +### Part C — Description display in directory listing (src/app.rs) + +Updated `build_directory_lines()` to append description spans for file entries that have one: + +``` + [filename] description text here, truncated... +``` + +- Two-space separator (`" "`) between the bracketed name and description +- Description rendered as `Span::styled(text, Style::default().fg(Color::DarkGray))` +- Truncation budget: `78 - indent_chars - span_len - 2`, appending `"..."` if clipped +- `link_records` entry's `span_len` covers only the `[name]` bracket — description is a separate span and not part of the link highlight range + +## Deviations from Plan + +None - plan executed exactly as written. + +## Self-Check + +- [x] `src/app.rs` modified — bare Left/Right arms present, description display in `build_directory_lines()` +- [x] `src/vault.rs` modified — `description` field on `DirEntry`, `extract_frontmatter_description()` helper, `list_vault_files()` populates field +- [x] `cargo build` — clean (0 new warnings) +- [x] `cargo clippy` — clean (all warnings pre-existing in unrelated files) +- [x] Commit `f0ec2ed` exists + +## Self-Check: PASSED