fix(parity): close the 2026-06-02 re-audit config/command findings
Implements the remaining fourth-pass findings (gap doc updated):
- list_margin: rework to upstream's buffer-side meaning. Drop the
nuwiki-only HTML em-margin (renderer field/method + render_page_html
param removed) and prepend max(0, list_margin) leading spaces to every
generated bullet in build_toc_text / build_links_text /
build_tag_links_text / diary::build_index_body; headings stay at col 0.
From<RawWiki> derives 0 for markdown wikis when unset. Negatives can't
resolve 'shiftwidth' server-side, so they collapse to zero indent
(documented divergence).
- diary_months: per-wiki Vec<String> (default 12 English names), threaded
into the diary-index month labels; missing/empty slots fall back to the
English name.
- diary_caption_level: widen u8 -> i8 so vimwiki's -1 (min: -1) parses;
build_index_body clamps < 0 to base tree level 0.
- VimwikiRemoveDone: regain upstream's -range. All four defs are now
-bang -range, dispatched via remove_done(bang, range, l1, l2) in both
clients: ! -> whole buffer, explicit range -> new list_remove_done_range
({range:[l1-1,l2-1]}), else current list. Server remove_done_edit gained
an Option<(u32,u32)> range that filters whole-doc victims by start line.
markdown_header_style is deferred: the generators emit vimwiki syntax only
(caption_line never writes markdown headers), so there's no markdown header
to attach the style to. Logged as the "generated-content is vimwiki-only"
intentional divergence pending a later markdown generated-content effort.
Tests: list_margin indent, markdown list_margin-0 default, diary_months
custom + fallback, negative caption_level clamp/parse, ranged remove-done
(server + both keymap harnesses). 553 lsp/core tests pass; clippy clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -49,13 +49,21 @@ pub struct WikiConfig {
|
||||
/// 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,
|
||||
/// Caption level for the diary index page headings (1 = h1). vimwiki's
|
||||
/// `diary_caption_level` (`min: -1`). nuwiki uses it as the base level of
|
||||
/// the year/month index tree; values `< 0` clamp to `0` (upstream's `-1`
|
||||
/// "read no per-page captions" mode isn't modelled — nuwiki builds the
|
||||
/// tree from dates, not page headers).
|
||||
pub diary_caption_level: i8,
|
||||
/// Newest-first (`desc`) or oldest-first (`asc`) in the diary
|
||||
/// index.
|
||||
pub diary_sort: String,
|
||||
/// H1 text for the diary index page.
|
||||
pub diary_header: String,
|
||||
/// vimwiki `diary_months`: month-number → display name for the diary
|
||||
/// index tree. Twelve entries (January..December) by default; a custom
|
||||
/// list falls back to the English name for any missing/out-of-range slot.
|
||||
pub diary_months: Vec<String>,
|
||||
/// Vimwiki's `g:vimwiki_listsyms`. A progression of checkbox glyphs
|
||||
/// from "empty" (first) to "done" (last); the lexer recognises these
|
||||
/// glyphs and the toggle/cycle commands walk them. Any length ≥ 2 is
|
||||
@@ -66,8 +74,12 @@ pub struct WikiConfig {
|
||||
pub listsym_rejected: String,
|
||||
/// When toggling a parent list item, also cascade to descendants.
|
||||
pub listsyms_propagate: bool,
|
||||
/// `-1` keeps tight lists; positive integers indent list items by
|
||||
/// that many extra columns. Layout hint for the renderer.
|
||||
/// vimwiki `list_margin`: number of leading spaces before bullets in
|
||||
/// **buffer-side generated lists** — `:VimwikiGenerateLinks`, the TOC, the
|
||||
/// tags index, and the diary index. `>= 0` indents by that many spaces;
|
||||
/// `< 0` means "no margin" (default `-1`; `0` for markdown wikis).
|
||||
/// Divergence: upstream resolves `< 0` to the buffer's `'shiftwidth'`,
|
||||
/// which the server can't observe, so negatives collapse to zero indent.
|
||||
pub list_margin: i32,
|
||||
/// Character used in place of literal spaces inside wikilink
|
||||
/// targets when writing to disk (a single space `" "` by default,
|
||||
@@ -229,6 +241,7 @@ impl WikiConfig {
|
||||
diary_caption_level: d.diary_caption_level,
|
||||
diary_sort: d.diary_sort,
|
||||
diary_header: d.diary_header,
|
||||
diary_months: d.diary_months,
|
||||
listsyms: d.listsyms,
|
||||
listsym_rejected: d.listsym_rejected,
|
||||
listsyms_propagate: d.listsyms_propagate,
|
||||
@@ -268,6 +281,7 @@ impl WikiConfig {
|
||||
diary_caption_level: d.diary_caption_level,
|
||||
diary_sort: d.diary_sort,
|
||||
diary_header: d.diary_header,
|
||||
diary_months: d.diary_months,
|
||||
listsyms: d.listsyms,
|
||||
listsym_rejected: d.listsym_rejected,
|
||||
listsyms_propagate: d.listsyms_propagate,
|
||||
@@ -371,6 +385,27 @@ fn default_diary_header() -> String {
|
||||
"Diary".to_string()
|
||||
}
|
||||
|
||||
/// vimwiki's default `diary_months` — the English month names, January..December.
|
||||
fn default_diary_months() -> Vec<String> {
|
||||
[
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December",
|
||||
]
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn default_listsyms() -> String {
|
||||
" .oOX".to_string()
|
||||
}
|
||||
@@ -411,6 +446,7 @@ fn wiki_defaults() -> WikiDefaults {
|
||||
diary_caption_level: 0,
|
||||
diary_sort: default_diary_sort(),
|
||||
diary_header: default_diary_header(),
|
||||
diary_months: default_diary_months(),
|
||||
listsyms: default_listsyms(),
|
||||
listsym_rejected: default_listsym_rejected(),
|
||||
listsyms_propagate: true,
|
||||
@@ -436,9 +472,10 @@ struct WikiDefaults {
|
||||
diary_frequency: String,
|
||||
diary_weekly_style: String,
|
||||
diary_start_week_day: String,
|
||||
diary_caption_level: u8,
|
||||
diary_caption_level: i8,
|
||||
diary_sort: String,
|
||||
diary_header: String,
|
||||
diary_months: Vec<String>,
|
||||
listsyms: String,
|
||||
listsym_rejected: String,
|
||||
listsyms_propagate: bool,
|
||||
@@ -673,12 +710,14 @@ struct RawWiki {
|
||||
#[serde(default)]
|
||||
diary_start_week_day: Option<String>,
|
||||
#[serde(default)]
|
||||
diary_caption_level: Option<u8>,
|
||||
diary_caption_level: Option<i8>,
|
||||
#[serde(default)]
|
||||
diary_sort: Option<String>,
|
||||
#[serde(default)]
|
||||
diary_header: Option<String>,
|
||||
#[serde(default)]
|
||||
diary_months: Option<Vec<String>>,
|
||||
#[serde(default)]
|
||||
listsyms: Option<String>,
|
||||
#[serde(default)]
|
||||
listsym_rejected: Option<String>,
|
||||
@@ -764,11 +803,19 @@ impl From<RawWiki> for WikiConfig {
|
||||
html.html_header_numbering_sym = s;
|
||||
}
|
||||
let d = wiki_defaults();
|
||||
let syntax = r.syntax.unwrap_or_else(|| "vimwiki".into());
|
||||
// vimwiki derives `list_margin = 0` for markdown wikis when the key is
|
||||
// unset (vars.vim:651); other syntaxes keep the `-1` default.
|
||||
let list_margin = r.list_margin.unwrap_or(if syntax == "markdown" {
|
||||
0
|
||||
} else {
|
||||
d.list_margin
|
||||
});
|
||||
WikiConfig {
|
||||
name: r.name.unwrap_or(derived_name),
|
||||
root,
|
||||
file_extension: r.file_extension.unwrap_or_else(|| ".wiki".into()),
|
||||
syntax: r.syntax.unwrap_or_else(|| "vimwiki".into()),
|
||||
syntax,
|
||||
index: r.index.unwrap_or(d.index),
|
||||
diary_rel_path: r.diary_rel_path.unwrap_or(d.diary_rel_path),
|
||||
diary_index: r.diary_index.unwrap_or(d.diary_index),
|
||||
@@ -778,10 +825,11 @@ impl From<RawWiki> for WikiConfig {
|
||||
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),
|
||||
diary_months: r.diary_months.unwrap_or(d.diary_months),
|
||||
listsyms: r.listsyms.unwrap_or(d.listsyms),
|
||||
listsym_rejected: r.listsym_rejected.unwrap_or(d.listsym_rejected),
|
||||
listsyms_propagate: r.listsyms_propagate.unwrap_or(d.listsyms_propagate),
|
||||
list_margin: r.list_margin.unwrap_or(d.list_margin),
|
||||
list_margin,
|
||||
links_space_char: r.links_space_char.unwrap_or(d.links_space_char),
|
||||
auto_toc: r.auto_toc.unwrap_or(d.auto_toc),
|
||||
auto_generate_links: r.auto_generate_links.unwrap_or(d.auto_generate_links),
|
||||
|
||||
Reference in New Issue
Block a user