Fix select in Helix mode (#38117)
Hotfixes issue I have introduced in #37748. Without this, helix mode select not working at all in `main` branch. Release Notes: - N/A
This commit is contained in:
@@ -328,7 +328,7 @@
|
||||
{
|
||||
"context": "vim_mode == helix_select",
|
||||
"bindings": {
|
||||
"escape": "vim::NormalBefore",
|
||||
"v": "vim::NormalBefore",
|
||||
";": "vim::HelixCollapseSelection",
|
||||
"~": "vim::ChangeCase",
|
||||
"ctrl-a": "vim::Increment",
|
||||
|
||||
@@ -53,6 +53,35 @@ impl Vim {
|
||||
self.helix_move_cursor(motion, times, window, cx);
|
||||
}
|
||||
|
||||
pub fn helix_select_motion(
|
||||
&mut self,
|
||||
motion: Motion,
|
||||
times: Option<usize>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
let current_head = selection.head();
|
||||
|
||||
let Some((new_head, goal)) = motion.move_point(
|
||||
map,
|
||||
current_head,
|
||||
selection.goal,
|
||||
times,
|
||||
&text_layout_details,
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
|
||||
selection.set_head(new_head, goal);
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Updates all selections based on where the cursors are.
|
||||
fn helix_new_selections(
|
||||
&mut self,
|
||||
@@ -1033,4 +1062,49 @@ mod test {
|
||||
Mode::HelixNormal,
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_helix_select_mode_motion(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
assert_eq!(cx.mode(), Mode::Normal);
|
||||
cx.enable_helix();
|
||||
|
||||
cx.set_state("ˇhello", Mode::HelixNormal);
|
||||
cx.simulate_keystrokes("l v l l");
|
||||
cx.assert_state("h«ellˇ»o", Mode::HelixSelect);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_helix_select_mode_motion_multiple_cursors(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
assert_eq!(cx.mode(), Mode::Normal);
|
||||
cx.enable_helix();
|
||||
|
||||
// Start with multiple cursors (no selections)
|
||||
cx.set_state("ˇhello\nˇworld", Mode::HelixNormal);
|
||||
|
||||
// Enter select mode and move right twice
|
||||
cx.simulate_keystrokes("v l l");
|
||||
|
||||
// Each cursor should independently create and extend its own selection
|
||||
cx.assert_state("«helˇ»lo\n«worˇ»ld", Mode::HelixSelect);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_helix_select_word_motions(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
cx.set_state("ˇone two", Mode::Normal);
|
||||
cx.simulate_keystrokes("v w");
|
||||
cx.assert_state("«one tˇ»wo", Mode::Visual);
|
||||
|
||||
// In Vim, this selects "t". In helix selections stops just before "t"
|
||||
|
||||
cx.enable_helix();
|
||||
cx.set_state("ˇone two", Mode::HelixNormal);
|
||||
cx.simulate_keystrokes("v w");
|
||||
cx.assert_state("«one ˇ»two", Mode::HelixSelect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,9 +726,8 @@ impl Vim {
|
||||
self.visual_motion(motion, count, window, cx)
|
||||
}
|
||||
|
||||
Mode::HelixNormal | Mode::HelixSelect => {
|
||||
self.helix_normal_motion(motion, count, window, cx)
|
||||
}
|
||||
Mode::HelixNormal => self.helix_normal_motion(motion, count, window, cx),
|
||||
Mode::HelixSelect => self.helix_select_motion(motion, count, window, cx),
|
||||
}
|
||||
self.clear_operator(window, cx);
|
||||
if let Some(operator) = waiting_operator {
|
||||
|
||||
Reference in New Issue
Block a user