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:
@@ -202,17 +202,27 @@ fn heading(level: u8, text: &str) -> String {
|
||||
/// subheadings so the rendered page mirrors `:VimwikiDiaryGenerateLinks`.
|
||||
///
|
||||
/// `caption_level` sets the level of the top caption; the year and month
|
||||
/// subheadings nest one and two levels below it. `sort` controls whether
|
||||
/// the flat list runs newest- or oldest-first.
|
||||
/// subheadings nest one and two levels below it. A `caption_level < 0`
|
||||
/// clamps to `0` (nuwiki builds the tree from dates, so upstream's `-1`
|
||||
/// "no per-page captions" mode doesn't apply). `months` supplies the
|
||||
/// month-number → display name table; an empty slice (or a short list)
|
||||
/// falls back to the English `month_name` for any missing slot. `sort`
|
||||
/// controls whether the flat list runs newest- or oldest-first. `margin`
|
||||
/// is the number of leading spaces before each entry bullet (vimwiki's
|
||||
/// `list_margin`).
|
||||
pub fn build_index_body(
|
||||
entries: &[DiaryEntry],
|
||||
diary_rel_path: &str,
|
||||
index_heading: &str,
|
||||
sort: DiarySort,
|
||||
caption_level: u8,
|
||||
caption_level: i8,
|
||||
months: &[String],
|
||||
margin: usize,
|
||||
) -> String {
|
||||
let base_level = caption_level.max(0) as u8;
|
||||
let pad = " ".repeat(margin);
|
||||
let mut out = String::new();
|
||||
out.push_str(&heading(caption_level, index_heading));
|
||||
out.push_str(&heading(base_level, index_heading));
|
||||
out.push('\n');
|
||||
|
||||
if entries.is_empty() {
|
||||
@@ -225,8 +235,8 @@ pub fn build_index_body(
|
||||
DiarySort::Asc => a.date.cmp(&b.date),
|
||||
});
|
||||
|
||||
let year_level = caption_level.saturating_add(1);
|
||||
let month_level = caption_level.saturating_add(2);
|
||||
let year_level = base_level.saturating_add(1);
|
||||
let month_level = base_level.saturating_add(2);
|
||||
let mut current_year: Option<i32> = None;
|
||||
let mut current_month: Option<u8> = None;
|
||||
for e in sorted {
|
||||
@@ -238,12 +248,17 @@ pub fn build_index_body(
|
||||
current_month = None;
|
||||
}
|
||||
if current_month != Some(e.date.month) {
|
||||
out.push_str(&heading(month_level, month_name(e.date.month)));
|
||||
let label = months
|
||||
.get((e.date.month.saturating_sub(1)) as usize)
|
||||
.map(String::as_str)
|
||||
.filter(|s| !s.is_empty())
|
||||
.unwrap_or_else(|| month_name(e.date.month));
|
||||
out.push_str(&heading(month_level, label));
|
||||
out.push('\n');
|
||||
current_month = Some(e.date.month);
|
||||
}
|
||||
out.push_str(&format!(
|
||||
"- [[{}/{}]]\n",
|
||||
"{pad}- [[{}/{}]]\n",
|
||||
diary_rel_path.trim_end_matches('/'),
|
||||
e.date.format()
|
||||
));
|
||||
@@ -253,7 +268,8 @@ pub fn build_index_body(
|
||||
|
||||
/// Render the diary-index body for the given wiki's currently-indexed
|
||||
/// entries. Convenience wrapper around [`build_index_body`] that honours
|
||||
/// the wiki's `diary_header`, `diary_sort`, and `diary_caption_level`.
|
||||
/// the wiki's `diary_header`, `diary_sort`, `diary_caption_level`, and
|
||||
/// `diary_months`.
|
||||
pub fn render_index_body(cfg: &WikiConfig, index: &WorkspaceIndex) -> String {
|
||||
build_index_body(
|
||||
&list_entries(index),
|
||||
@@ -261,6 +277,8 @@ pub fn render_index_body(cfg: &WikiConfig, index: &WorkspaceIndex) -> String {
|
||||
&cfg.diary_header,
|
||||
DiarySort::parse(&cfg.diary_sort),
|
||||
cfg.diary_caption_level,
|
||||
&cfg.diary_months,
|
||||
cfg.list_margin.max(0) as usize,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user