From 7eb009e259a3879a3c7016cc373477bba7a4ed65 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Thu, 12 Mar 2026 23:16:02 -0600 Subject: [PATCH] editor: Make underscores and newlines subword boundaries (#50552) Updates #21054 Authored-By: @ngauder Release Notes: - Added _ and newline to subword boundaries --------- Co-authored-by: Nikolas Gauder --- crates/editor/src/movement.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/crates/editor/src/movement.rs b/crates/editor/src/movement.rs index 01f7d0064e6f5ecd0d4d9c1760386102e9ce16e0..6bf6449506f1c1eb2a71270546ad3b063f7e9022 100644 --- a/crates/editor/src/movement.rs +++ b/crates/editor/src/movement.rs @@ -408,7 +408,7 @@ pub fn previous_subword_start(map: &DisplaySnapshot, point: DisplayPoint) -> Dis let classifier = map.buffer_snapshot().char_classifier_at(raw_point); find_preceding_boundary_display_point(map, point, FindRange::MultiLine, &mut |left, right| { - is_subword_start(left, right, &classifier) || left == '\n' + is_subword_start(left, right, &classifier) || left == '\n' || right == '\n' }) } @@ -431,6 +431,7 @@ pub fn is_subword_start(left: char, right: char, classifier: &CharClassifier) -> let is_word_start = classifier.kind(left) != classifier.kind(right) && !right.is_whitespace(); let is_subword_start = classifier.is_word('-') && left == '-' && right != '-' || left == '_' && right != '_' + || left != '_' && right == '_' || left.is_lowercase() && right.is_uppercase(); is_word_start || is_subword_start } @@ -484,7 +485,7 @@ pub fn next_subword_end(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPo let classifier = map.buffer_snapshot().char_classifier_at(raw_point); find_boundary(map, point, FindRange::MultiLine, &mut |left, right| { - is_subword_end(left, right, &classifier) || right == '\n' + is_subword_end(left, right, &classifier) || left == '\n' || right == '\n' }) } @@ -519,6 +520,7 @@ pub fn is_subword_end(left: char, right: char, classifier: &CharClassifier) -> b fn is_subword_boundary_end(left: char, right: char, classifier: &CharClassifier) -> bool { classifier.is_word('-') && left != '-' && right == '-' || left != '_' && right == '_' + || left == '_' && right != '_' || left.is_lowercase() && right.is_uppercase() } @@ -973,10 +975,10 @@ mod tests { } // Subword boundaries are respected - assert("lorem_ˇipˇsum", cx); + assert("loremˇ_ˇipsum", cx); assert("lorem_ˇipsumˇ", cx); - assert("ˇlorem_ˇipsum", cx); - assert("lorem_ˇipsum_ˇdolor", cx); + assert("ˇloremˇ_ipsum", cx); + assert("lorem_ˇipsumˇ_dolor", cx); assert("loremˇIpˇsum", cx); assert("loremˇIpsumˇ", cx); @@ -1156,10 +1158,10 @@ mod tests { } // Subword boundaries are respected - assert("loˇremˇ_ipsum", cx); + assert("loremˇ_ˇipsum", cx); assert("ˇloremˇ_ipsum", cx); - assert("loremˇ_ipsumˇ", cx); - assert("loremˇ_ipsumˇ_dolor", cx); + assert("loremˇ_ˇipsum", cx); + assert("lorem_ˇipsumˇ_dolor", cx); assert("loˇremˇIpsum", cx); assert("loremˇIpsumˇDolor", cx); @@ -1172,7 +1174,7 @@ mod tests { assert("loremˇ ipsumˇ ", cx); assert("loremˇ-ˇipsum", cx); assert("loremˇ#$@-ˇipsum", cx); - assert("loremˇ_ipsumˇ", cx); + assert("loremˇ_ˇipsum", cx); assert(" ˇbcˇΔ", cx); assert(" abˇ——ˇcd", cx); }