refactor(ui): remove the unused list helpers from Edit text

is_bulleted, is_numbered, toggle_bullet_list and toggle_numbered_list had no
caller outside their own tests: Format text shows bulleted and numbered lists
as planned. Removed with their tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
FredApps
2026-11-01 12:34:54 +01:00
co-authored by Claude Opus 5.5
parent 1a2f7b2a34
commit 2ef192b7cd
-158
View File
@@ -46,124 +46,6 @@ enum TextTarget {
/// hit-testing still covers every image, so nothing becomes unselectable.
pub(crate) const MAX_OUTLINES: usize = 250;
pub fn is_bulleted(text: &str) -> bool {
let mut lines = text.lines();
let Some(first) = lines.next() else { return false };
first.trim_start().starts_with("• ") || first.trim_start().starts_with("- ")
}
pub fn is_numbered(text: &str) -> bool {
let mut lines = text.lines();
let Some(first) = lines.next() else { return false };
let t = first.trim_start();
let num_end = t.find('.').unwrap_or(0);
num_end > 0 && t[..num_end].chars().all(|c| c.is_ascii_digit()) && t[num_end..].starts_with(". ")
}
pub fn toggle_bullet_list(text: &mut String) -> bool {
let has_trailing_crlf = text.ends_with("\r\n");
let has_trailing_newline = text.ends_with('\n');
let lines: Vec<&str> = text.lines().collect();
if lines.is_empty() {
return false;
}
let all_bulleted = lines.iter().all(|l| {
let t = l.trim_start();
t.is_empty() || t.starts_with("• ") || t.starts_with("- ")
});
let mut new_text = String::with_capacity(text.len() + 16);
for (i, line) in lines.iter().enumerate() {
if i > 0 {
new_text.push('\n');
}
let trimmed = line.trim_start();
let indent = &line[..line.len() - trimmed.len()];
if all_bulleted {
if let Some(rest) = trimmed.strip_prefix("• ").or_else(|| trimmed.strip_prefix("- ")) {
new_text.push_str(indent);
new_text.push_str(rest);
} else {
new_text.push_str(line);
}
} else if trimmed.is_empty() || trimmed.starts_with("• ") {
new_text.push_str(line);
} else {
new_text.push_str(indent);
new_text.push_str("• ");
new_text.push_str(trimmed);
}
}
if has_trailing_crlf {
new_text.push_str("\r\n");
} else if has_trailing_newline {
new_text.push('\n');
}
if new_text != *text {
*text = new_text;
true
} else {
false
}
}
pub fn toggle_numbered_list(text: &mut String) -> bool {
let has_trailing_crlf = text.ends_with("\r\n");
let has_trailing_newline = text.ends_with('\n');
let lines: Vec<&str> = text.lines().collect();
if lines.is_empty() {
return false;
}
let is_num_line = |l: &str| {
let t = l.trim_start();
if t.is_empty() {
return true;
}
let dot_idx = t.find('.').unwrap_or(0);
dot_idx > 0 && t[..dot_idx].chars().all(|c| c.is_ascii_digit()) && t[dot_idx..].starts_with(". ")
};
let all_numbered = lines.iter().all(|l| is_num_line(l));
let mut new_text = String::with_capacity(text.len() + 16);
let mut num = 1;
for (i, line) in lines.iter().enumerate() {
if i > 0 {
new_text.push('\n');
}
let t = line.trim_start();
let indent = &line[..line.len() - t.len()];
if all_numbered {
if let Some(dot_idx) = t.find('.')
&& dot_idx > 0
&& t[..dot_idx].chars().all(|c| c.is_ascii_digit())
&& t[dot_idx..].starts_with(". ")
{
new_text.push_str(indent);
new_text.push_str(t.get(dot_idx + 2..).unwrap_or(""));
continue;
}
new_text.push_str(line);
} else if t.is_empty() {
new_text.push_str(line);
} else {
use std::fmt::Write as _;
new_text.push_str(indent);
let _ = write!(new_text, "{num}. ");
new_text.push_str(t);
num += 1;
}
}
if has_trailing_crlf {
new_text.push_str("\r\n");
} else if has_trailing_newline {
new_text.push('\n');
}
if new_text != *text {
*text = new_text;
true
} else {
false
}
}
pub fn char_to_superscript(c: char) -> char {
match c {
'0' => '⁰',
@@ -1730,46 +1612,6 @@ C", &picked
assert_eq!(caret_color_on(DARK_EDITOR_FILL), Color32::WHITE);
}
#[test]
fn bullet_list_toggles_and_preserves_content() {
let mut text = "First line\nSecond line\n\nThird line".to_string();
assert!(!is_bulleted(&text));
assert!(toggle_bullet_list(&mut text));
assert!(is_bulleted(&text));
assert_eq!(text, "• First line\n• Second line\n\n• Third line");
// Toggling again removes bullets
assert!(toggle_bullet_list(&mut text));
assert!(!is_bulleted(&text));
assert_eq!(text, "First line\nSecond line\n\nThird line");
let mut indented = " First line\n Second line".to_string();
assert!(toggle_bullet_list(&mut indented));
assert_eq!(indented, " • First line\n • Second line");
assert!(toggle_bullet_list(&mut indented));
assert_eq!(indented, " First line\n Second line");
}
#[test]
fn numbered_list_toggles_and_preserves_content() {
let mut text = "Item A\nItem B\n\nItem C".to_string();
assert!(!is_numbered(&text));
assert!(toggle_numbered_list(&mut text));
assert!(is_numbered(&text));
assert_eq!(text, "1. Item A\n2. Item B\n\n3. Item C");
// Toggling again removes numbering
assert!(toggle_numbered_list(&mut text));
assert!(!is_numbered(&text));
assert_eq!(text, "Item A\nItem B\n\nItem C");
let mut indented = " Item A\n Item B".to_string();
assert!(toggle_numbered_list(&mut indented));
assert_eq!(indented, " 1. Item A\n 2. Item B");
assert!(toggle_numbered_list(&mut indented));
assert_eq!(indented, " Item A\n Item B");
}
#[test]
fn superscript_and_subscript_conversion() {
let mut ed = LineEditor {