helix: Apply modification (e.g. switch case) on a single character only in helix mode (#38119)

Closes #34192

Without selection, only current character would be affected.

Also if #38117 is merged too, then transformations in SelectMode behave
correctly too and selection is not collapsed.

Release Notes:

- helix: Implemented `~`, `` ` ``, `` Alt-` `` correctly in normal and
select modes

---------

Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
This commit is contained in:
Romans Malinovskis
2025-09-18 08:47:15 +00:00
committed by GitHub
co-authored by Jakub Konka
parent d85a6db6a3
commit ed46e2ca77
2 changed files with 19 additions and 10 deletions
+2 -3
View File
@@ -442,9 +442,8 @@
">": "vim::Indent",
"<": "vim::Outdent",
"=": "vim::AutoIndent",
"g u": "vim::PushLowercase",
"g shift-u": "vim::PushUppercase",
"g ~": "vim::PushOppositeCase",
"`": "vim::ConvertToLowerCase",
"alt-`": "vim::ConvertToUpperCase",
"g q": "vim::PushRewrap",
"g w": "vim::PushRewrap",
"insert": "vim::InsertBefore",
+17 -7
View File
@@ -214,11 +214,10 @@ impl Vim {
Mode::HelixNormal | Mode::HelixSelect => {
if selection.is_empty() {
// Handle empty selection by operating on the whole word
let (word_range, _) = snapshot.surrounding_word(selection.start, false);
let word_start = snapshot.offset_to_point(word_range.start);
let word_end = snapshot.offset_to_point(word_range.end);
ranges.push(word_start..word_end);
// Handle empty selection by operating on single character
let start = selection.start;
let end = snapshot.clip_point(start + Point::new(0, 1), Bias::Right);
ranges.push(start..end);
cursor_positions.push(selection.start..selection.start);
} else {
ranges.push(selection.start..selection.end);
@@ -445,15 +444,26 @@ mod test {
cx.simulate_keystrokes("~");
cx.assert_state("«HELLO WORLDˇ»", Mode::HelixNormal);
// Cursor-only (empty) selection
// Cursor-only (empty) selection - switch case
cx.set_state("The ˇquick brown", Mode::HelixNormal);
cx.simulate_keystrokes("~");
cx.assert_state("The ˇQUICK brown", Mode::HelixNormal);
cx.assert_state("The ˇQuick brown", Mode::HelixNormal);
cx.simulate_keystrokes("~");
cx.assert_state("The ˇquick brown", Mode::HelixNormal);
// Cursor-only (empty) selection - switch to uppercase and lowercase explicitly
cx.set_state("The ˇquick brown", Mode::HelixNormal);
cx.simulate_keystrokes("alt-`");
cx.assert_state("The ˇQuick brown", Mode::HelixNormal);
cx.simulate_keystrokes("`");
cx.assert_state("The ˇquick brown", Mode::HelixNormal);
// With `e` motion (which extends selection to end of word in Helix)
cx.set_state("The ˇquick brown fox", Mode::HelixNormal);
cx.simulate_keystrokes("e");
cx.simulate_keystrokes("~");
cx.assert_state("The «QUICKˇ» brown fox", Mode::HelixNormal);
// Cursor-only
}
}