From 6fce6d18841ba2851667d5c04e84c0b21e84cb55 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sun, 1 Nov 2026 01:27:20 -0700 Subject: [PATCH] Type: text.startList names the bullet each typed trigger starts The command catalog said "* ", "# ", "> " and "+ " all start a list with the filled dot. It now names the filled dot, hollow circle, filled square and dash. The text.startList test checks each of the four triggers and the marker the layout draws. --- crates/engine/src/cmd/textedit.rs | 2 +- crates/engine/src/tests/textedit.rs | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/crates/engine/src/cmd/textedit.rs b/crates/engine/src/cmd/textedit.rs index 29d1de28f..d8514ef56 100644 --- a/crates/engine/src/cmd/textedit.rs +++ b/crates/engine/src/cmd/textedit.rs @@ -31,7 +31,7 @@ pub fn specs() -> Vec { "Bullets and Numbering", [], None, - "{id, at?: byte (default: the end of the text)} start a list from typed characters, what the Type tool runs when a space is typed on its own: when the text from the start of the paragraph that `at` is in up to `at` is \"1. \" or \"1) \" (a numbered list in 1, 2, 3), \"A. \" or \"A) \" (a numbered list in A, B, C), or \"* \", \"# \", \"> \" or \"+ \" (a bulleted list with the filled dot), and the paragraph is in no list, those characters are removed and the paragraph joins that list as one undo step (left and first-line indents of 0 become 18 and -18, as text.setFormat sets them); otherwise nothing changes → {id, started: bool, caret: byte (the paragraph's start when started, else `at`)}", + "{id, at?: byte (default: the end of the text)} start a list from typed characters, what the Type tool runs when a space is typed on its own: when the text from the start of the paragraph that `at` is in up to `at` is \"1. \" or \"1) \" (a numbered list in 1, 2, 3), \"A. \" or \"A) \" (a numbered list in A, B, C), \"* \" (a bulleted list with the filled dot), \"+ \" (the hollow circle), \"# \" (the filled square) or \"> \" (the dash), and the paragraph is in no list, those characters are removed and the paragraph joins that list as one undo step (left and first-line indents of 0 become 18 and -18, as text.setFormat sets them); otherwise nothing changes → {id, started: bool, caret: byte (the paragraph's start when started, else `at`)}", has_doc, start_list ), diff --git a/crates/engine/src/tests/textedit.rs b/crates/engine/src/tests/textedit.rs index 4d0ade073..a895655b9 100644 --- a/crates/engine/src/tests/textedit.rs +++ b/crates/engine/src/tests/textedit.rs @@ -1258,10 +1258,16 @@ fn start_list_command_removes_the_typed_characters_and_starts_the_list() { assert_eq!(list_markers(&s, id), ["1."]); s.execute("edit.undo", &json!({})).unwrap(); assert_eq!((obj(&s, id).plain_text().as_str(), obj(&s, id).para_at(1).list), ("Fruit\n1) Apples", None)); - let id = text(&mut s, "x\n# "); - let r = s.execute("text.startList", &json!({"id": id.0})).unwrap(); - assert_eq!((r["started"].clone(), obj(&s, id).plain_text()), (json!(true), "x\n".to_string())); - assert_eq!(obj(&s, id).para_at(1).list, Some(ParaList::bulleted(Bullet::Square))); + for (typed, bullet, marker) in + [("* ", Bullet::Dot, "\u{2022}"), ("+ ", Bullet::Circle, "\u{25E6}"), ("# ", Bullet::Square, "\u{25AA}"), ("> ", Bullet::Dash, "\u{2013}")] + { + let id = text(&mut s, &format!("x\n{typed}")); + let r = s.execute("text.startList", &json!({"id": id.0})).unwrap(); + assert_eq!((r["started"].clone(), obj(&s, id).plain_text()), (json!(true), "x\n".to_string()), "{typed:?}"); + assert_eq!(obj(&s, id).para_at(1).list, Some(ParaList::bulleted(bullet)), "{typed:?}"); + s.execute("text.editRange", &json!({"id": id.0, "start": 2, "end": 2, "insert": "Item"})).unwrap(); + assert_eq!(list_markers(&s, id), [marker], "{typed:?}"); + } let steps = undo_labels(&s).len(); let id = text(&mut s, "1.x"); assert_eq!(s.execute("text.startList", &json!({"id": id.0, "at": 3})).unwrap()["started"], json!(false));