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));