feat(diary): restore diary_start_week_day via configurable weekly naming
c63ec67 dropped diary_start_week_day, hardwiring the weekly diary to ISO
(Monday) weeks. Upstream vimwiki instead names a weekly note by the
week-start day's date (YYYY-MM-DD) and honours diary_start_week_day. Rather
than force one scheme, make it a per-wiki choice so migrators keep upstream
behaviour while existing nuwiki weekly files keep working:
- New per-wiki key `diary_weekly_style`: `iso` (default — `YYYY-Www`,
Monday-based, nuwiki's original) or `date`/`vimwiki` (`YYYY-MM-DD` of the
week-start day, upstream parity).
- Restored per-wiki key `diary_start_week_day` (`monday`..`sunday`, default
monday); applies only in `date` mode.
Implementation:
- nuwiki-core::date gains WeeklyStyle, WeekStart, and DiaryCalendar (owns
today/next/prev — date-mode snaps to the week-start and steps ±7 days;
iso/daily/monthly/yearly defer to the existing DiaryPeriod logic).
- WikiConfig gains the two fields (+ defaults, RawWiki, From) and a
diary_calendar() builder; commands.rs diary_open_relative and the
next/prev pivot use it.
Defaults preserve current behaviour (iso/monday), so no breaking change.
Tests: DiaryCalendar cases in nuwiki-core/tests/diary.rs (snap, ±7, sunday
start, iso delegation, daily) + config round-trip in
nuwiki-lsp/tests/index_and_config.rs. README + doc/nuwiki.txt + lua config
comment updated. fmt + clippy clean; all crate tests + config-parity green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -219,6 +219,8 @@ require('nuwiki').setup({
|
||||
diary_rel_path = 'diary',
|
||||
diary_index = 'diary',
|
||||
diary_frequency = 'daily', -- 'daily' | 'weekly' | 'monthly' | 'yearly'
|
||||
diary_weekly_style = 'iso', -- 'iso' (YYYY-Www) | 'date' (week-start YYYY-MM-DD, vimwiki)
|
||||
diary_start_week_day = 'monday', -- week start for diary_weekly_style='date'
|
||||
diary_sort = 'desc', -- 'desc' | 'asc'
|
||||
diary_header = 'Diary',
|
||||
-- HTML export
|
||||
@@ -319,7 +321,9 @@ Each is a boolean. All default to `true` except `mouse`.
|
||||
| `diary_rel_path` | string | `'diary'` | path relative to `root` |
|
||||
| `diary_index` | string | `'diary'` | diary index page stem |
|
||||
| `diary_frequency` | string | `'daily'` | `'daily'` \| `'weekly'` \| `'monthly'` \| `'yearly'` |
|
||||
| `diary_caption_level` | int | `1` | `1`–`6` (level of the index caption) |
|
||||
| `diary_weekly_style` | string | `'iso'` | `'iso'` (`YYYY-Www`) \| `'date'`/`'vimwiki'` (week-start `YYYY-MM-DD`). Weekly only |
|
||||
| `diary_start_week_day` | string | `'monday'` | `'monday'`–`'sunday'`; week start when `diary_weekly_style = 'date'` |
|
||||
| `diary_caption_level` | int | `0` | `0`–`6` (level of the index caption) |
|
||||
| `diary_sort` | string | `'desc'` | `'desc'` \| `'asc'` |
|
||||
| `diary_header` | string | `'Diary'` | any heading text |
|
||||
| `listsyms` | string | `' .oOX'` | checkbox progression chars |
|
||||
|
||||
@@ -358,6 +358,132 @@ impl fmt::Display for DiaryPeriod {
|
||||
}
|
||||
}
|
||||
|
||||
/// How a *weekly* diary entry is named.
|
||||
///
|
||||
/// `Iso` — ISO-week label `YYYY-Www` (nuwiki's original scheme; the week
|
||||
/// always begins on Monday, `week_start` is ignored).
|
||||
/// `Date` — the week-start day's calendar date `YYYY-MM-DD`, matching
|
||||
/// upstream vimwiki; honours `week_start`.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum WeeklyStyle {
|
||||
Iso,
|
||||
Date,
|
||||
}
|
||||
|
||||
impl WeeklyStyle {
|
||||
/// Parse the config string. `date`/`vimwiki` → `Date`; anything else
|
||||
/// (including `iso`/`week`/empty) → `Iso`.
|
||||
pub fn parse(s: &str) -> Self {
|
||||
match s.trim().to_ascii_lowercase().as_str() {
|
||||
"date" | "vimwiki" | "day" => Self::Date,
|
||||
_ => Self::Iso,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Day a week begins on, in ISO numbering (Monday = 1 … Sunday = 7).
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct WeekStart(u8);
|
||||
|
||||
impl WeekStart {
|
||||
/// Parse a weekday name (`monday`..`sunday`); unknown → Monday.
|
||||
pub fn parse(s: &str) -> Self {
|
||||
let n = match s.trim().to_ascii_lowercase().as_str() {
|
||||
"tuesday" => 2,
|
||||
"wednesday" => 3,
|
||||
"thursday" => 4,
|
||||
"friday" => 5,
|
||||
"saturday" => 6,
|
||||
"sunday" => 7,
|
||||
_ => 1, // monday (default)
|
||||
};
|
||||
Self(n)
|
||||
}
|
||||
|
||||
pub fn monday() -> Self {
|
||||
Self(1)
|
||||
}
|
||||
|
||||
fn iso(self) -> i64 {
|
||||
self.0 as i64
|
||||
}
|
||||
}
|
||||
|
||||
/// Diary navigation policy: frequency plus, for weekly diaries, the naming
|
||||
/// scheme and week-start day. Built from a wiki's `diary_*` config so the
|
||||
/// LSP commands can compute today / next / prev without re-deriving the
|
||||
/// rules. `Daily`/`Monthly`/`Yearly` ignore the weekly fields.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DiaryCalendar {
|
||||
pub freq: DiaryFrequency,
|
||||
pub weekly_style: WeeklyStyle,
|
||||
pub week_start: WeekStart,
|
||||
}
|
||||
|
||||
impl DiaryCalendar {
|
||||
pub fn new(freq: DiaryFrequency, weekly_style: WeeklyStyle, week_start: WeekStart) -> Self {
|
||||
Self {
|
||||
freq,
|
||||
weekly_style,
|
||||
week_start,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_weekly_date(&self) -> bool {
|
||||
self.freq == DiaryFrequency::Weekly && self.weekly_style == WeeklyStyle::Date
|
||||
}
|
||||
|
||||
/// "Now" as a diary period for this calendar. Date-mode weekly snaps
|
||||
/// today back to the most recent week-start day (a plain `Day`, so the
|
||||
/// file is `YYYY-MM-DD` like upstream); everything else defers to
|
||||
/// [`DiaryPeriod::today_utc`].
|
||||
pub fn today(&self) -> DiaryPeriod {
|
||||
if self.is_weekly_date() {
|
||||
DiaryPeriod::Day(self.week_start_of(DiaryDate::today_utc()))
|
||||
} else {
|
||||
DiaryPeriod::today_utc(self.freq)
|
||||
}
|
||||
}
|
||||
|
||||
/// The period one cadence-step after `p`.
|
||||
pub fn next(&self, p: DiaryPeriod) -> DiaryPeriod {
|
||||
self.step(p, 1)
|
||||
}
|
||||
|
||||
/// The period one cadence-step before `p`.
|
||||
pub fn prev(&self, p: DiaryPeriod) -> DiaryPeriod {
|
||||
self.step(p, -1)
|
||||
}
|
||||
|
||||
fn step(&self, p: DiaryPeriod, dir: i64) -> DiaryPeriod {
|
||||
// Date-mode weekly: the period is a `Day` on a week-start; a step is
|
||||
// ±7 days (re-snapped so an off-week-start pivot still lands cleanly).
|
||||
if self.is_weekly_date() {
|
||||
if let DiaryPeriod::Day(d) = p {
|
||||
let start = self.week_start_of(d);
|
||||
return DiaryPeriod::Day(add_days(start, 7 * dir));
|
||||
}
|
||||
}
|
||||
if dir >= 0 {
|
||||
p.next()
|
||||
} else {
|
||||
p.prev()
|
||||
}
|
||||
}
|
||||
|
||||
/// The most recent `week_start` weekday on or before `d`.
|
||||
fn week_start_of(&self, d: DiaryDate) -> DiaryDate {
|
||||
let wd = iso_weekday(&d) as i64; // 1..=7
|
||||
let back = (wd - self.week_start.iso()).rem_euclid(7);
|
||||
add_days(d, -back)
|
||||
}
|
||||
}
|
||||
|
||||
/// Shift a calendar date by `delta` days (may be negative).
|
||||
fn add_days(d: DiaryDate, delta: i64) -> DiaryDate {
|
||||
from_days(to_days(d.year, d.month, d.day) + delta)
|
||||
}
|
||||
|
||||
/// Day-of-week with Monday=1 … Sunday=7 (ISO 8601).
|
||||
fn iso_weekday(d: &DiaryDate) -> u8 {
|
||||
// Zeller-style via days-from-epoch: 1970-01-01 was a Thursday.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
//! Cluster 4 — diary frequency / period primitives.
|
||||
//! Tests the date math for ISO weeks, monthly, yearly periods.
|
||||
|
||||
use nuwiki_core::date::{DiaryDate, DiaryFrequency, DiaryPeriod};
|
||||
use nuwiki_core::date::{
|
||||
DiaryCalendar, DiaryDate, DiaryFrequency, DiaryPeriod, WeekStart, WeeklyStyle,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn frequency_parses_canonical_strings() {
|
||||
@@ -182,3 +184,95 @@ fn day_next_and_prev_still_work() {
|
||||
DiaryPeriod::Day(DiaryDate::from_ymd(2026, 5, 11).unwrap())
|
||||
);
|
||||
}
|
||||
|
||||
// ===== DiaryCalendar — weekly naming styles + week-start =====
|
||||
// 2026-05-25 is a Monday (so 2026-05-27 is a Wednesday, 2026-05-24 a Sunday).
|
||||
|
||||
fn day(y: i32, m: u8, d: u8) -> DiaryPeriod {
|
||||
DiaryPeriod::Day(DiaryDate::from_ymd(y, m, d).unwrap())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn weekly_style_and_week_start_parse() {
|
||||
assert_eq!(WeeklyStyle::parse("date"), WeeklyStyle::Date);
|
||||
assert_eq!(WeeklyStyle::parse("vimwiki"), WeeklyStyle::Date);
|
||||
assert_eq!(WeeklyStyle::parse("iso"), WeeklyStyle::Iso);
|
||||
assert_eq!(WeeklyStyle::parse(""), WeeklyStyle::Iso); // default
|
||||
assert_eq!(WeeklyStyle::parse("WEEK"), WeeklyStyle::Iso);
|
||||
// WeekStart::parse is exercised via the calendar tests below; unknown
|
||||
// names fall back to Monday.
|
||||
assert_eq!(WeekStart::parse("sunday"), WeekStart::parse("SUNDAY"));
|
||||
assert_eq!(WeekStart::parse("nonsense"), WeekStart::monday());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn date_mode_weekly_today_is_a_day() {
|
||||
let cal = DiaryCalendar::new(
|
||||
DiaryFrequency::Weekly,
|
||||
WeeklyStyle::Date,
|
||||
WeekStart::monday(),
|
||||
);
|
||||
assert!(matches!(cal.today(), DiaryPeriod::Day(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iso_mode_weekly_today_is_a_week() {
|
||||
let cal = DiaryCalendar::new(
|
||||
DiaryFrequency::Weekly,
|
||||
WeeklyStyle::Iso,
|
||||
WeekStart::monday(),
|
||||
);
|
||||
assert!(matches!(cal.today(), DiaryPeriod::Week { .. }));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn date_mode_weekly_steps_seven_days_from_the_week_start_monday() {
|
||||
let cal = DiaryCalendar::new(
|
||||
DiaryFrequency::Weekly,
|
||||
WeeklyStyle::Date,
|
||||
WeekStart::monday(),
|
||||
);
|
||||
// From a Wednesday: snap back to Mon 05-25, then ±7.
|
||||
assert_eq!(cal.next(day(2026, 5, 27)), day(2026, 6, 1));
|
||||
assert_eq!(cal.prev(day(2026, 5, 27)), day(2026, 5, 18));
|
||||
// From the Monday itself: no snap, just ±7.
|
||||
assert_eq!(cal.next(day(2026, 5, 25)), day(2026, 6, 1));
|
||||
assert_eq!(cal.prev(day(2026, 5, 25)), day(2026, 5, 18));
|
||||
// Stem is the plain date, like upstream.
|
||||
assert_eq!(cal.next(day(2026, 5, 27)).format(), "2026-06-01");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn date_mode_weekly_honours_a_sunday_week_start() {
|
||||
let cal = DiaryCalendar::new(
|
||||
DiaryFrequency::Weekly,
|
||||
WeeklyStyle::Date,
|
||||
WeekStart::parse("sunday"),
|
||||
);
|
||||
// Wed 05-27 snaps back to Sun 05-24, +7 = Sun 05-31.
|
||||
assert_eq!(cal.next(day(2026, 5, 27)), day(2026, 5, 31));
|
||||
assert_eq!(cal.prev(day(2026, 5, 27)), day(2026, 5, 17));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iso_mode_weekly_delegates_to_iso_week_stepping() {
|
||||
let cal = DiaryCalendar::new(
|
||||
DiaryFrequency::Weekly,
|
||||
WeeklyStyle::Iso,
|
||||
WeekStart::monday(),
|
||||
);
|
||||
let wk = DiaryPeriod::week_containing(DiaryDate::from_ymd(2026, 5, 27).unwrap());
|
||||
assert_eq!(cal.next(wk), wk.next());
|
||||
assert_eq!(cal.prev(wk), wk.prev());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn daily_calendar_steps_one_day_regardless_of_weekly_fields() {
|
||||
let cal = DiaryCalendar::new(
|
||||
DiaryFrequency::Daily,
|
||||
WeeklyStyle::Date,
|
||||
WeekStart::parse("sunday"),
|
||||
);
|
||||
assert_eq!(cal.next(day(2026, 5, 27)), day(2026, 5, 28));
|
||||
assert_eq!(cal.prev(day(2026, 5, 27)), day(2026, 5, 26));
|
||||
}
|
||||
|
||||
@@ -402,11 +402,12 @@ fn diary_open_relative(
|
||||
return Ok(None);
|
||||
};
|
||||
let freq = wiki.config.frequency();
|
||||
let today_period = nuwiki_core::date::DiaryPeriod::today_utc(freq);
|
||||
let calendar = wiki.config.diary_calendar();
|
||||
let today_period = calendar.today();
|
||||
let period = match rel {
|
||||
RelativeDay::Today => today_period,
|
||||
RelativeDay::Yesterday => today_period.prev(),
|
||||
RelativeDay::Tomorrow => today_period.next(),
|
||||
RelativeDay::Yesterday => calendar.prev(today_period),
|
||||
RelativeDay::Tomorrow => calendar.next(today_period),
|
||||
};
|
||||
let Some(uri) = crate::diary::uri_for_period(&wiki.config, &period) else {
|
||||
return Ok(None);
|
||||
@@ -469,7 +470,7 @@ fn diary_step(backend: &Backend, args: Vec<Value>, forward: bool) -> Result<Opti
|
||||
.map_err(|_| "index lock poisoned".to_string())?;
|
||||
idx.page(&p.uri)
|
||||
.and_then(|page| page.diary_period)
|
||||
.unwrap_or_else(|| nuwiki_core::date::DiaryPeriod::today_utc(wiki.config.frequency()))
|
||||
.unwrap_or_else(|| wiki.config.diary_calendar().today())
|
||||
};
|
||||
let next = {
|
||||
let idx = wiki
|
||||
|
||||
@@ -41,6 +41,14 @@ pub struct WikiConfig {
|
||||
/// diary commands use. `daily` is supported; the others fall through
|
||||
/// to vimwiki-style names but the commands are no-ops for them.
|
||||
pub diary_frequency: String,
|
||||
/// Weekly-diary naming: `iso` (nuwiki default — `YYYY-Www` labels,
|
||||
/// always Monday-based) or `date`/`vimwiki` (the week-start day's date
|
||||
/// `YYYY-MM-DD`, honouring `diary_start_week_day`). Only affects
|
||||
/// `diary_frequency = weekly`.
|
||||
pub diary_weekly_style: String,
|
||||
/// Weekday the diary week begins on (`monday`..`sunday`, vimwiki's
|
||||
/// `diary_start_week_day`). Used only when `diary_weekly_style = date`.
|
||||
pub diary_start_week_day: String,
|
||||
/// Caption level for the diary index page headings (1 = h1).
|
||||
pub diary_caption_level: u8,
|
||||
/// Newest-first (`desc`) or oldest-first (`asc`) in the diary
|
||||
@@ -174,6 +182,8 @@ impl WikiConfig {
|
||||
diary_rel_path: d.diary_rel_path,
|
||||
diary_index: d.diary_index,
|
||||
diary_frequency: d.diary_frequency,
|
||||
diary_weekly_style: d.diary_weekly_style,
|
||||
diary_start_week_day: d.diary_start_week_day,
|
||||
diary_caption_level: d.diary_caption_level,
|
||||
diary_sort: d.diary_sort,
|
||||
diary_header: d.diary_header,
|
||||
@@ -201,6 +211,8 @@ impl WikiConfig {
|
||||
diary_rel_path: d.diary_rel_path,
|
||||
diary_index: d.diary_index,
|
||||
diary_frequency: d.diary_frequency,
|
||||
diary_weekly_style: d.diary_weekly_style,
|
||||
diary_start_week_day: d.diary_start_week_day,
|
||||
diary_caption_level: d.diary_caption_level,
|
||||
diary_sort: d.diary_sort,
|
||||
diary_header: d.diary_header,
|
||||
@@ -245,6 +257,16 @@ impl WikiConfig {
|
||||
pub fn frequency(&self) -> nuwiki_core::date::DiaryFrequency {
|
||||
nuwiki_core::date::DiaryFrequency::parse(&self.diary_frequency)
|
||||
}
|
||||
|
||||
/// The diary navigation policy (frequency + weekly naming/week-start),
|
||||
/// used by the diary commands to compute today / next / prev.
|
||||
pub fn diary_calendar(&self) -> nuwiki_core::date::DiaryCalendar {
|
||||
nuwiki_core::date::DiaryCalendar::new(
|
||||
self.frequency(),
|
||||
nuwiki_core::date::WeeklyStyle::parse(&self.diary_weekly_style),
|
||||
nuwiki_core::date::WeekStart::parse(&self.diary_start_week_day),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn default_diary_rel_path() -> String {
|
||||
@@ -263,6 +285,15 @@ fn default_diary_frequency() -> String {
|
||||
"daily".to_string()
|
||||
}
|
||||
|
||||
fn default_diary_weekly_style() -> String {
|
||||
// nuwiki's original ISO-week labels; opt into `date` for vimwiki parity.
|
||||
"iso".to_string()
|
||||
}
|
||||
|
||||
fn default_diary_start_week_day() -> String {
|
||||
"monday".to_string()
|
||||
}
|
||||
|
||||
fn default_diary_sort() -> String {
|
||||
"desc".to_string()
|
||||
}
|
||||
@@ -288,6 +319,8 @@ fn wiki_defaults() -> WikiDefaults {
|
||||
diary_rel_path: default_diary_rel_path(),
|
||||
diary_index: default_diary_index(),
|
||||
diary_frequency: default_diary_frequency(),
|
||||
diary_weekly_style: default_diary_weekly_style(),
|
||||
diary_start_week_day: default_diary_start_week_day(),
|
||||
// Match upstream vimwiki's `diary_caption_level` default of 0 (year
|
||||
// captions at the top level, months one below). Users override per-wiki.
|
||||
diary_caption_level: 0,
|
||||
@@ -306,6 +339,8 @@ struct WikiDefaults {
|
||||
diary_rel_path: String,
|
||||
diary_index: String,
|
||||
diary_frequency: String,
|
||||
diary_weekly_style: String,
|
||||
diary_start_week_day: String,
|
||||
diary_caption_level: u8,
|
||||
diary_sort: String,
|
||||
diary_header: String,
|
||||
@@ -519,6 +554,10 @@ struct RawWiki {
|
||||
#[serde(default)]
|
||||
diary_frequency: Option<String>,
|
||||
#[serde(default)]
|
||||
diary_weekly_style: Option<String>,
|
||||
#[serde(default)]
|
||||
diary_start_week_day: Option<String>,
|
||||
#[serde(default)]
|
||||
diary_caption_level: Option<u8>,
|
||||
#[serde(default)]
|
||||
diary_sort: Option<String>,
|
||||
@@ -584,6 +623,8 @@ impl From<RawWiki> for WikiConfig {
|
||||
diary_rel_path: r.diary_rel_path.unwrap_or(d.diary_rel_path),
|
||||
diary_index: r.diary_index.unwrap_or(d.diary_index),
|
||||
diary_frequency: r.diary_frequency.unwrap_or(d.diary_frequency),
|
||||
diary_weekly_style: r.diary_weekly_style.unwrap_or(d.diary_weekly_style),
|
||||
diary_start_week_day: r.diary_start_week_day.unwrap_or(d.diary_start_week_day),
|
||||
diary_caption_level: r.diary_caption_level.unwrap_or(d.diary_caption_level),
|
||||
diary_sort: r.diary_sort.unwrap_or(d.diary_sort),
|
||||
diary_header: r.diary_header.unwrap_or(d.diary_header),
|
||||
|
||||
@@ -284,6 +284,8 @@ fn raw_wiki_parses_every_new_key() {
|
||||
"root": "/tmp/w",
|
||||
"index": "home",
|
||||
"diary_frequency": "weekly",
|
||||
"diary_weekly_style": "date",
|
||||
"diary_start_week_day": "sunday",
|
||||
"diary_caption_level": 2,
|
||||
"diary_sort": "asc",
|
||||
"diary_header": "Journal",
|
||||
@@ -297,6 +299,8 @@ fn raw_wiki_parses_every_new_key() {
|
||||
let w = &cfg.wikis[0];
|
||||
assert_eq!(w.index, "home");
|
||||
assert_eq!(w.diary_frequency, "weekly");
|
||||
assert_eq!(w.diary_weekly_style, "date");
|
||||
assert_eq!(w.diary_start_week_day, "sunday");
|
||||
assert_eq!(w.diary_caption_level, 2);
|
||||
assert_eq!(w.diary_sort, "asc");
|
||||
assert_eq!(w.diary_header, "Journal");
|
||||
@@ -305,6 +309,23 @@ fn raw_wiki_parses_every_new_key() {
|
||||
assert_eq!(w.list_margin, 2);
|
||||
assert_eq!(w.links_space_char, "_");
|
||||
assert!(w.auto_toc);
|
||||
|
||||
// The parsed keys drive a date-mode, Sunday-start diary calendar:
|
||||
// a weekly note is the week-start date (YYYY-MM-DD), stepping ±7 days.
|
||||
use nuwiki_core::date::{DiaryDate, DiaryPeriod};
|
||||
let cal = w.diary_calendar();
|
||||
let wed = DiaryPeriod::Day(DiaryDate::from_ymd(2026, 5, 27).unwrap());
|
||||
assert_eq!(
|
||||
cal.next(wed),
|
||||
DiaryPeriod::Day(DiaryDate::from_ymd(2026, 5, 31).unwrap())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn diary_calendar_defaults_to_iso_weeks() {
|
||||
let cfg = WikiConfig::empty();
|
||||
assert_eq!(cfg.diary_weekly_style, "iso");
|
||||
assert_eq!(cfg.diary_start_week_day, "monday");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -109,13 +109,18 @@ fix site.
|
||||
upstream `0`. _Fix:_ `wiki_defaults()` in `crates/nuwiki-lsp/src/config.rs` now
|
||||
defaults `diary_caption_level: 0` (year captions top-level, months one below),
|
||||
still per-wiki overridable. Test `defaults_carry_vimwiki_per_wiki_keys` updated.
|
||||
- [ ] **`diary_start_week_day`** — **wrongly removed** in `c63ec67`. The removal
|
||||
treated it as a server concern and hardwired the weekly diary to ISO-Monday
|
||||
(`crates/nuwiki-core/src/date.rs` `monday_of_iso_week`), but choosing which
|
||||
weekday the diary week begins on is a **client-side concern** and it **matters
|
||||
for parity** — non-Monday users lose the upstream option entirely. _Fix:_
|
||||
restore the config key client-side (`lua/nuwiki/config.lua`) and thread the
|
||||
week-start through to the diary date logic instead of hardcoding Monday.
|
||||
- [x] **`diary_start_week_day`** — removed in `c63ec67` (weekly diary hardwired
|
||||
to ISO-Monday). Restored as a **configurable choice** so migrators keep
|
||||
upstream behaviour while new wikis can use ISO weeks. New per-wiki key
|
||||
`diary_weekly_style`: `iso` (default — `YYYY-Www`, Monday-based, nuwiki's
|
||||
original) or `date`/`vimwiki` (`YYYY-MM-DD` of the week-start day, upstream
|
||||
parity, honouring the restored `diary_start_week_day` = `monday`..`sunday`).
|
||||
_Impl:_ `nuwiki_core::date::{WeeklyStyle, WeekStart, DiaryCalendar}` own the
|
||||
today/next/prev logic; `WikiConfig::diary_calendar()` builds it from config;
|
||||
the diary commands (`commands.rs` `diary_open_relative` + next/prev pivot) use
|
||||
it. Defaults keep existing nuwiki weekly files working (no breaking change).
|
||||
Covered by calendar tests in `crates/nuwiki-core/tests/diary.rs` and the
|
||||
config round-trip in `crates/nuwiki-lsp/tests/index_and_config.rs`.
|
||||
|
||||
## P3 — Niche / low impact
|
||||
|
||||
|
||||
+12
-1
@@ -182,7 +182,11 @@ match upstream vimwiki.
|
||||
`diary_rel_path` `'diary'`
|
||||
`diary_index` `'diary'` — stem of the diary index page.
|
||||
`diary_frequency` `'daily'` | `'weekly'` | `'monthly'` | `'yearly'`
|
||||
`diary_caption_level` `1`
|
||||
`diary_weekly_style` `'iso'` (YYYY-Www) | `'date'`/`'vimwiki'` (week-start
|
||||
YYYY-MM-DD). Weekly diaries only.
|
||||
`diary_start_week_day` `'monday'`..`'sunday'`; week start used when
|
||||
`diary_weekly_style = 'date'`.
|
||||
`diary_caption_level` `0`
|
||||
`diary_sort` `'desc'` | `'asc'`
|
||||
`diary_header` `'Diary'`
|
||||
`html_path` Path for `:Vimwiki2HTML` output.
|
||||
@@ -582,6 +586,13 @@ The `diary_frequency` per-wiki option controls the cadence:
|
||||
monthly YYYY-MM e.g. `2026-05.wiki`
|
||||
yearly YYYY e.g. `2026.wiki`
|
||||
|
||||
For weekly diaries, `diary_weekly_style` chooses the file name: the default
|
||||
`'iso'` uses the ISO-week label above (always Monday-based); `'date'` (a.k.a.
|
||||
`'vimwiki'`) names the file after the week-start day's date — e.g. with
|
||||
`diary_start_week_day = 'monday'`, the week of 2026-05-27 is `2026-05-25.wiki`
|
||||
— matching upstream vimwiki. `diary_start_week_day` (`'monday'`..`'sunday'`)
|
||||
only applies in `'date'` mode.
|
||||
|
||||
`:NuwikiMakeDiaryNote` opens the entry for the current period at the
|
||||
configured cadence; the yesterday / tomorrow commands step back and
|
||||
forward by one period. `<C-Down>` / `<C-Up>` walk between indexed
|
||||
|
||||
@@ -21,6 +21,7 @@ M.defaults = {
|
||||
-- `doc/nuwiki.txt`):
|
||||
-- name, root, file_extension, syntax, index
|
||||
-- diary_rel_path, diary_index, diary_frequency,
|
||||
-- diary_weekly_style, diary_start_week_day,
|
||||
-- diary_caption_level, diary_sort, diary_header
|
||||
-- html_path, template_path, template_default, template_ext,
|
||||
-- template_date_format, css_name, auto_export, auto_toc,
|
||||
|
||||
Reference in New Issue
Block a user