phase 16: diary path conventions + nav commands
CI / cargo fmt --check (push) Successful in 27s
CI / cargo clippy (push) Successful in 1m14s
CI / cargo test (push) Successful in 1m20s

Hand-rolled date primitive (no chrono/time dep) plus the diary
command surface that closes the `:VimwikiMakeDiaryNote` ergonomics gap.

nuwiki-core/src/date.rs:
- `DiaryDate { year, month, day }` with strict `YYYY-MM-DD` parsing
  (rejects missing zero-padding, alternate separators, whitespace,
  impossible calendar dates including the leap-year exceptions).
- `next_day` / `prev_day` via Howard Hinnant's days-from-civil
  algorithm — proleptic Gregorian, walks across month/year/leap-day
  boundaries.
- `today_utc()` from `SystemTime::now()`. UTC-only by design: a
  local-tz implementation would need a tz database we don't ship.
- `Ord` by epoch days, `Display`/`format` round-trip with `parse`.

WikiConfig (P15 resolution):
- `diary_rel_path: String` (default `"diary"`) — mirrors vimwiki's
  `g:vimwiki_diary_rel_path`.
- `diary_index: String` (default `"diary"`) — the stem inside the
  diary subdir.
- `diary_dir()`, `diary_index_path()`, `diary_path_for(date)` —
  centralise the path math so commands stay declarative.
- `RawWiki` (init-options wire format) accepts both fields, so users
  with `g:vimwiki_diary_rel_path = "journal"` migrate cleanly.

WorkspaceIndex:
- New `diary_rel_path: Option<String>` field set by `Wiki::new`.
- `IndexedPage.diary_date: Option<DiaryDate>` — populated in `upsert`
  when the URI is under `<root>/<diary_rel_path>/` and the stem
  parses. `diary_date_for_uri` is the standalone classifier.
- The classifier *requires* the URI to be inside the diary subdir
  when a root is known; with no root it accepts any file whose stem
  is a date (kept for the ad-hoc test/scratch case).

nuwiki-lsp/src/diary.rs:
- `uri_for_date` / `index_uri` — bridge from `DiaryDate` and config
  to `file://` URIs.
- `list_entries(index) → Vec<DiaryEntry>` — ascending, plus
  `list_entries_filtered(year, month)` for calendar hooks.
- `next_entry` / `prev_entry` — strict less-than/greater-than
  comparison so navigating from a non-diary page (uses today as
  pivot) still moves to the right entry.
- `build_index_body` — newest-first, grouped under `== YYYY ==` /
  `=== Month ===` subheadings, emits `- [[diary/YYYY-MM-DD]]`. Matches
  `:VimwikiDiaryGenerateLinks`.
- `DiaryEntry` JSON shape: `{ date: "YYYY-MM-DD", uri }`. Manual
  serde impl so DiaryDate stays serde-free in nuwiki-core.

Commands (9 new):
- `nuwiki.diary.openToday` / `openYesterday` / `openTomorrow` →
  `{ uri, date }`.
- `nuwiki.diary.openIndex` → `{ uri }`.
- `nuwiki.diary.generateIndex` → WorkspaceEdit. Three paths:
  live document in `backend.documents` → full-doc replace; on-disk
  index → read + full-doc replace; missing → CreateFile + insert.
- `nuwiki.diary.next` / `prev` → pivots on the current page's
  `diary_date`, falls back to today.
- `nuwiki.diary.listEntries` → optional `year` / `month` filter.
- `nuwiki.diary.openForDate` → strict `YYYY-MM-DD` arg.

All commands accept an optional `uri` to scope to a particular wiki
when multi-wiki lands; the dispatcher falls back to `default_wiki()`.

Tests: 35 new in `phase16_diary.rs` (date parser exhaustively,
calendar arithmetic across boundaries + leaps, path conventions,
upsert classification including the "date filename outside diary dir"
no-op case, list/filter/nav, index body grouping, serde shape, command
list completeness). Total 309 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-11 21:04:55 +00:00
parent ce3ac8c4f8
commit e75ad6ca89
10 changed files with 1089 additions and 2 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ See [`SPEC.md`](./SPEC.md) for the full project specification.
| 13 | Workspace edits + executeCommand | ✅ done |
| 14 | List & table edit commands | ✅ done (focused subset; table/list-renumber/colorize deferred) |
| 15 | Link health + TOC/index generation | ✅ done |
| 16 | Diary | |
| 16 | Diary | ✅ done |
| 17 | HTML export commands | ⏳ |
| 18 | Multi-wiki | ⏳ |
| 19 | Editor glue v2 (`:Vimwiki*` compat, keymaps, text objects, folding) | ⏳ |