Add "shift-r" and "g ." support for helix mode (#35468)
Related #4642 Compatible with #34136 Release Notes: - Helix: `Shift+R` works as Paste instead of taking you to ReplaceMode - Helix: `g .` goes to last modification place (similar to `. in vim)
This commit is contained in:
parent
633ce23ae9
commit
bb5cfe118f
2 changed files with 89 additions and 0 deletions
|
@ -428,11 +428,13 @@
|
|||
"g h": "vim::StartOfLine",
|
||||
"g s": "vim::FirstNonWhitespace", // "g s" default behavior is "space s"
|
||||
"g e": "vim::EndOfDocument",
|
||||
"g .": "vim::HelixGotoLastModification", // go to last modification
|
||||
"g r": "editor::FindAllReferences", // zed specific
|
||||
"g t": "vim::WindowTop",
|
||||
"g c": "vim::WindowMiddle",
|
||||
"g b": "vim::WindowBottom",
|
||||
|
||||
"shift-r": "editor::Paste",
|
||||
"x": "editor::SelectLine",
|
||||
"shift-x": "editor::SelectLine",
|
||||
"%": "editor::SelectAll",
|
||||
|
|
|
@ -23,6 +23,8 @@ actions!(
|
|||
HelixInsert,
|
||||
/// Appends at the end of the selection.
|
||||
HelixAppend,
|
||||
/// Goes to the location of the last modification.
|
||||
HelixGotoLastModification,
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -31,6 +33,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
|||
Vim::action(editor, cx, Vim::helix_insert);
|
||||
Vim::action(editor, cx, Vim::helix_append);
|
||||
Vim::action(editor, cx, Vim::helix_yank);
|
||||
Vim::action(editor, cx, Vim::helix_goto_last_modification);
|
||||
}
|
||||
|
||||
impl Vim {
|
||||
|
@ -430,6 +433,15 @@ impl Vim {
|
|||
});
|
||||
self.switch_mode(Mode::HelixNormal, true, window, cx);
|
||||
}
|
||||
|
||||
pub fn helix_goto_last_modification(
|
||||
&mut self,
|
||||
_: &HelixGotoLastModification,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.jump(".".into(), false, false, window, cx);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -441,6 +453,7 @@ mod test {
|
|||
#[gpui::test]
|
||||
async fn test_word_motions(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
cx.enable_helix();
|
||||
// «
|
||||
// ˇ
|
||||
// »
|
||||
|
@ -502,6 +515,7 @@ mod test {
|
|||
#[gpui::test]
|
||||
async fn test_delete(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
cx.enable_helix();
|
||||
|
||||
// test delete a selection
|
||||
cx.set_state(
|
||||
|
@ -582,6 +596,7 @@ mod test {
|
|||
#[gpui::test]
|
||||
async fn test_f_and_t(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
cx.enable_helix();
|
||||
|
||||
cx.set_state(
|
||||
indoc! {"
|
||||
|
@ -635,6 +650,7 @@ mod test {
|
|||
#[gpui::test]
|
||||
async fn test_newline_char(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
cx.enable_helix();
|
||||
|
||||
cx.set_state("aa«\nˇ»bb cc", Mode::HelixNormal);
|
||||
|
||||
|
@ -652,6 +668,7 @@ mod test {
|
|||
#[gpui::test]
|
||||
async fn test_insert_selected(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
cx.enable_helix();
|
||||
cx.set_state(
|
||||
indoc! {"
|
||||
«The ˇ»quick brown
|
||||
|
@ -674,6 +691,7 @@ mod test {
|
|||
#[gpui::test]
|
||||
async fn test_append(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
cx.enable_helix();
|
||||
// test from the end of the selection
|
||||
cx.set_state(
|
||||
indoc! {"
|
||||
|
@ -716,6 +734,7 @@ mod test {
|
|||
#[gpui::test]
|
||||
async fn test_replace(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
cx.enable_helix();
|
||||
|
||||
// No selection (single character)
|
||||
cx.set_state("ˇaa", Mode::HelixNormal);
|
||||
|
@ -763,4 +782,72 @@ mod test {
|
|||
cx.shared_clipboard().assert_eq("worl");
|
||||
cx.assert_state("hello «worlˇ»d", Mode::HelixNormal);
|
||||
}
|
||||
#[gpui::test]
|
||||
async fn test_shift_r_paste(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
cx.enable_helix();
|
||||
|
||||
// First copy some text to clipboard
|
||||
cx.set_state("«hello worldˇ»", Mode::HelixNormal);
|
||||
cx.simulate_keystrokes("y");
|
||||
|
||||
// Test paste with shift-r on single cursor
|
||||
cx.set_state("foo ˇbar", Mode::HelixNormal);
|
||||
cx.simulate_keystrokes("shift-r");
|
||||
|
||||
cx.assert_state("foo hello worldˇbar", Mode::HelixNormal);
|
||||
|
||||
// Test paste with shift-r on selection
|
||||
cx.set_state("foo «barˇ» baz", Mode::HelixNormal);
|
||||
cx.simulate_keystrokes("shift-r");
|
||||
|
||||
cx.assert_state("foo hello worldˇ baz", Mode::HelixNormal);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_insert_mode_stickiness(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
cx.enable_helix();
|
||||
|
||||
// Make a modification at a specific location
|
||||
cx.set_state("ˇhello", Mode::HelixNormal);
|
||||
assert_eq!(cx.mode(), Mode::HelixNormal);
|
||||
cx.simulate_keystrokes("i");
|
||||
assert_eq!(cx.mode(), Mode::Insert);
|
||||
cx.simulate_keystrokes("escape");
|
||||
assert_eq!(cx.mode(), Mode::HelixNormal);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_goto_last_modification(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
cx.enable_helix();
|
||||
|
||||
// Make a modification at a specific location
|
||||
cx.set_state("line one\nline ˇtwo\nline three", Mode::HelixNormal);
|
||||
cx.assert_state("line one\nline ˇtwo\nline three", Mode::HelixNormal);
|
||||
cx.simulate_keystrokes("i");
|
||||
cx.simulate_keystrokes("escape");
|
||||
cx.simulate_keystrokes("i");
|
||||
cx.simulate_keystrokes("m o d i f i e d space");
|
||||
cx.simulate_keystrokes("escape");
|
||||
|
||||
// TODO: this fails, because state is no longer helix
|
||||
cx.assert_state(
|
||||
"line one\nline modified ˇtwo\nline three",
|
||||
Mode::HelixNormal,
|
||||
);
|
||||
|
||||
// Move cursor away from the modification
|
||||
cx.simulate_keystrokes("up");
|
||||
|
||||
// Use "g ." to go back to last modification
|
||||
cx.simulate_keystrokes("g .");
|
||||
|
||||
// Verify we're back at the modification location and still in HelixNormal mode
|
||||
cx.assert_state(
|
||||
"line one\nline modifiedˇ two\nline three",
|
||||
Mode::HelixNormal,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue