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:
@@ -61,7 +61,7 @@ fn render_marker_handles_each_symbol() {
|
||||
fn remove_done_strips_done_and_rejected_items() {
|
||||
let src = "- [ ] todo\n- [X] done\n- [-] rejected\n- [ ] also todo\n";
|
||||
let ast = parse(src);
|
||||
let edit = ops::remove_done_edit(src, &ast, &uri(), None, true).expect("edit");
|
||||
let edit = ops::remove_done_edit(src, &ast, &uri(), None, None, true).expect("edit");
|
||||
let changes = edit.changes.expect("changes");
|
||||
let edits = &changes[&uri()];
|
||||
assert_eq!(edits.len(), 2, "expected 2 deletions");
|
||||
@@ -75,14 +75,14 @@ fn remove_done_strips_done_and_rejected_items() {
|
||||
fn remove_done_leaves_open_items_alone() {
|
||||
let src = "- [ ] todo\n- [.] partial\n- [o] more\n";
|
||||
let ast = parse(src);
|
||||
assert!(ops::remove_done_edit(src, &ast, &uri(), None, true).is_none());
|
||||
assert!(ops::remove_done_edit(src, &ast, &uri(), None, None, true).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_done_returns_none_when_no_lists() {
|
||||
let src = "= heading =\nparagraph\n";
|
||||
let ast = parse(src);
|
||||
assert!(ops::remove_done_edit(src, &ast, &uri(), None, true).is_none());
|
||||
assert!(ops::remove_done_edit(src, &ast, &uri(), None, None, true).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -96,7 +96,7 @@ fn remove_done_scoped_by_position_to_current_list() {
|
||||
line: 0,
|
||||
character: 0,
|
||||
});
|
||||
let edit = ops::remove_done_edit(src, &ast, &uri(), pos, true).expect("edit");
|
||||
let edit = ops::remove_done_edit(src, &ast, &uri(), pos, None, true).expect("edit");
|
||||
let edits = &edit.changes.unwrap()[&uri()];
|
||||
assert_eq!(edits.len(), 2, "both done items in the current list match");
|
||||
}
|
||||
@@ -112,7 +112,7 @@ fn remove_done_position_leaves_other_lists_untouched() {
|
||||
line: 0,
|
||||
character: 0,
|
||||
});
|
||||
let edit = ops::remove_done_edit(src, &ast, &uri(), pos, true).expect("edit");
|
||||
let edit = ops::remove_done_edit(src, &ast, &uri(), pos, None, true).expect("edit");
|
||||
let edits = &edit.changes.unwrap()[&uri()];
|
||||
assert_eq!(edits.len(), 1, "only the first list's done item is removed");
|
||||
}
|
||||
@@ -126,11 +126,32 @@ fn remove_done_position_cascades_into_sublists() {
|
||||
line: 0,
|
||||
character: 0,
|
||||
});
|
||||
let edit = ops::remove_done_edit(src, &ast, &uri(), pos, true).expect("edit");
|
||||
let edit = ops::remove_done_edit(src, &ast, &uri(), pos, None, true).expect("edit");
|
||||
let edits = &edit.changes.unwrap()[&uri()];
|
||||
assert_eq!(edits.len(), 1, "the nested done child is removed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_done_ranged_restricts_to_selected_lines() {
|
||||
// The `:'<,'>VimwikiRemoveDone` form: a 0-indexed inclusive line range
|
||||
// sweeps the whole doc but only deletes done/rejected items inside it.
|
||||
// Lines: 0 `[X]`, 1 `[ ]`, 2 `[X]`, 3 `[-]`. Range 0..=1 keeps only the
|
||||
// line-0 done item; the line-2/3 done+rejected items survive.
|
||||
let src = "- [X] a\n- [ ] b\n- [X] c\n- [-] d\n";
|
||||
let ast = parse(src);
|
||||
let edit = ops::remove_done_edit(src, &ast, &uri(), None, Some((0, 1)), true).expect("edit");
|
||||
let edits = &edit.changes.unwrap()[&uri()];
|
||||
assert_eq!(edits.len(), 1, "only the done item on line 0 is in range");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_done_ranged_returns_none_when_range_has_no_done() {
|
||||
// Range covering only open items → nothing to delete.
|
||||
let src = "- [X] a\n- [ ] b\n- [ ] c\n";
|
||||
let ast = parse(src);
|
||||
assert!(ops::remove_done_edit(src, &ast, &uri(), None, Some((1, 2)), true).is_none());
|
||||
}
|
||||
|
||||
// ===== renumber =====
|
||||
|
||||
#[test]
|
||||
@@ -280,6 +301,6 @@ fn commands_list_includes_cluster_a() {
|
||||
fn one_edit_text_round_trip() {
|
||||
let src = "- [X] done\n";
|
||||
let ast = parse(src);
|
||||
let edit = ops::remove_done_edit(src, &ast, &uri(), None, true).unwrap();
|
||||
let edit = ops::remove_done_edit(src, &ast, &uri(), None, None, true).unwrap();
|
||||
let _ = one_edit_text(edit);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user