Merge pull request #5523 from dotCooCoo/fix/continued-paragraph-typed-list

Type: typing a list's start in a continued paragraph starts no list
This commit is contained in:
BFlat
2026-11-04 14:30:14 +07:00
committed by GitHub
2 changed files with 17 additions and 2 deletions
+4 -2
View File
@@ -200,14 +200,16 @@ impl TextObject {
}
/// The list that the characters before byte `at` start ([`ParaList::typed`]) with the byte
/// where their paragraph starts: when the plain text from the start of the paragraph up to
/// `at` is a list's start followed by a space, and the paragraph is in no list. None otherwise.
/// `at` is a list's start followed by a space, and the paragraph is in no list. None otherwise,
/// and for a first paragraph that continues from the frame before
/// ([`TextObject::first_para_continues`]).
pub fn typed_list_at(&self, at: usize) -> Option<(usize, ParaList)> {
let text = self.plain_text();
let before = text.get(..at)?;
let start = before.rfind('\n').map_or(0, |i| i + 1);
let list = ParaList::typed(before[start..].strip_suffix(' ')?)?;
let index = before.bytes().filter(|&b| b == b'\n').count();
self.para_at(index).list.is_none().then_some((start, list))
(!(index == 0 && self.first_para_continues) && self.para_at(index).list.is_none()).then_some((start, list))
}
/// Apply `f` to the attributes of paragraphs `range` (indices; None = every paragraph).
pub fn edit_paras(&mut self, range: Option<std::ops::Range<usize>>, mut f: impl FnMut(&mut ParaStyle)) {
+13
View File
@@ -239,6 +239,19 @@ fn typed_list_starts_are_found_at_a_paragraphs_start() {
assert_eq!(t.typed_list_at(19), Some((16, letters)));
}
/// In a threaded frame whose first paragraph continues from the frame before, the text at the
/// frame's start is not the start of a paragraph, so typing a list's start there starts nothing.
/// The paragraphs after it still start lists.
#[test]
fn typed_list_starts_skip_a_continued_paragraph() {
let dot = ParaList::bulleted(Bullet::Dot);
let mut t = TextObject::point(Point::ZERO, "* Pears\n# ", CharStyle::default());
assert_eq!(t.typed_list_at(2), Some((0, dot)));
t.first_para_continues = true;
assert_eq!(t.typed_list_at(2), None, "a continued paragraph starts no list");
assert_eq!(t.typed_list_at(10), Some((8, dot)));
}
#[test]
fn character_controls_reject_collapsed_and_nonfinite_transforms() {
let mut t = TextObject::point(Point::ZERO, "Text", CharStyle::default());