feat(config): P3 config batch — group 3 (cycle_bullets)
cycle_bullets (default off): when an unordered list item changes indent level (gll/glh), rotate its glyph through the configured bullet_types as a depth-keyed ring buffer — change_level_edit gains cycle_bullets + bullet_types params, locates the marker via find_marker_span, and rewrites the glyph to bullet_types[new_depth % len] for single-char unordered markers. Ordered markers are untouched. list_change_level reads both from the wiki config. Tests: cycle_bullets_rotates_glyph_on_indent + cycle_bullets_off_leaves_glyph. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -254,7 +254,7 @@ fn remove_checkbox_none_without_checkbox() {
|
||||
fn change_level_indents_single_item() {
|
||||
let src = "- one\n- two\n";
|
||||
let ast = parse(src);
|
||||
let edit = ops::change_level_edit(src, &ast, &uri(), 1, 1, false, true).expect("edit");
|
||||
let edit = ops::change_level_edit(src, &ast, &uri(), 1, 1, false, true, false, &[]).expect("edit");
|
||||
let edits = &edit.changes.unwrap()[&uri()];
|
||||
assert_eq!(edits.len(), 1);
|
||||
// delta=1 → +2 spaces
|
||||
@@ -265,16 +265,48 @@ fn change_level_indents_single_item() {
|
||||
fn change_level_dedents_clamps_to_zero() {
|
||||
let src = "- root\n";
|
||||
let ast = parse(src);
|
||||
let edit = ops::change_level_edit(src, &ast, &uri(), 0, -1, false, true);
|
||||
let edit = ops::change_level_edit(src, &ast, &uri(), 0, -1, false, true, false, &[]);
|
||||
// Already at column 0 — dedent is a no-op.
|
||||
assert!(edit.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cycle_bullets_rotates_glyph_on_indent() {
|
||||
// With cycle_bullets + bullet_types [-,*,#], indenting a `-` item (depth 0
|
||||
// → 1) rotates the glyph to `*` (and dedenting back to `-`).
|
||||
let bullets: Vec<String> = ["-", "*", "#"].iter().map(|s| s.to_string()).collect();
|
||||
let src = "- one\n- two\n";
|
||||
let ast = parse(src);
|
||||
let edit =
|
||||
ops::change_level_edit(src, &ast, &uri(), 1, 1, false, true, true, &bullets).expect("edit");
|
||||
let texts: Vec<String> = edit.changes.unwrap()[&uri()]
|
||||
.iter()
|
||||
.map(|e| e.new_text.clone())
|
||||
.collect();
|
||||
assert!(texts.contains(&" ".to_string()), "indent edit: {texts:?}");
|
||||
assert!(texts.contains(&"*".to_string()), "glyph rotated to *: {texts:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cycle_bullets_off_leaves_glyph() {
|
||||
let bullets: Vec<String> = ["-", "*", "#"].iter().map(|s| s.to_string()).collect();
|
||||
let src = "- one\n- two\n";
|
||||
let ast = parse(src);
|
||||
let edit = ops::change_level_edit(src, &ast, &uri(), 1, 1, false, true, false, &bullets)
|
||||
.expect("edit");
|
||||
let texts: Vec<String> = edit.changes.unwrap()[&uri()]
|
||||
.iter()
|
||||
.map(|e| e.new_text.clone())
|
||||
.collect();
|
||||
// Only the indent edit; no glyph rewrite.
|
||||
assert!(!texts.iter().any(|t| t == "*"), "no glyph change: {texts:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn change_level_whole_subtree_walks_descendants() {
|
||||
let src = "- parent\n - child a\n - child b\n- sibling\n";
|
||||
let ast = parse(src);
|
||||
let edit = ops::change_level_edit(src, &ast, &uri(), 0, 1, true, true).expect("edit");
|
||||
let edit = ops::change_level_edit(src, &ast, &uri(), 0, 1, true, true, false, &[]).expect("edit");
|
||||
let edits = &edit.changes.unwrap()[&uri()];
|
||||
// Parent + 2 children get indented. Sibling stays.
|
||||
assert!(edits.len() >= 3, "got {} edits", edits.len());
|
||||
|
||||
Reference in New Issue
Block a user