vim: Single quote mark (#27231)
Closes #22398 Release Notes: - vim: Adds `'` and `"` marks (last location jumped from in the current buffer, and location when last exiting a buffer) --------- Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
parent
d82b547596
commit
fa677bdc38
5 changed files with 88 additions and 3 deletions
|
@ -2147,6 +2147,7 @@ impl Editor {
|
|||
self.push_to_nav_history(
|
||||
*old_cursor_position,
|
||||
Some(new_cursor_position.to_point(buffer)),
|
||||
false,
|
||||
cx,
|
||||
);
|
||||
|
||||
|
@ -10809,10 +10810,15 @@ impl Editor {
|
|||
self.nav_history.as_ref()
|
||||
}
|
||||
|
||||
pub fn create_nav_history_entry(&mut self, cx: &mut Context<Self>) {
|
||||
self.push_to_nav_history(self.selections.newest_anchor().head(), None, false, cx);
|
||||
}
|
||||
|
||||
fn push_to_nav_history(
|
||||
&mut self,
|
||||
cursor_anchor: Anchor,
|
||||
new_position: Option<Point>,
|
||||
is_deactivate: bool,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if let Some(nav_history) = self.nav_history.as_mut() {
|
||||
|
@ -10838,6 +10844,10 @@ impl Editor {
|
|||
}),
|
||||
cx,
|
||||
);
|
||||
cx.emit(EditorEvent::PushedToNavHistory {
|
||||
anchor: cursor_anchor,
|
||||
is_deactivate,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18617,6 +18627,10 @@ pub enum EditorEvent {
|
|||
},
|
||||
Reloaded,
|
||||
CursorShapeChanged,
|
||||
PushedToNavHistory {
|
||||
anchor: Anchor,
|
||||
is_deactivate: bool,
|
||||
},
|
||||
}
|
||||
|
||||
impl EventEmitter<EditorEvent> for Editor {}
|
||||
|
|
|
@ -737,7 +737,7 @@ impl Item for Editor {
|
|||
|
||||
fn deactivated(&mut self, _: &mut Window, cx: &mut Context<Self>) {
|
||||
let selection = self.selections.newest_anchor();
|
||||
self.push_to_nav_history(selection.head(), None, cx);
|
||||
self.push_to_nav_history(selection.head(), None, true, cx);
|
||||
}
|
||||
|
||||
fn workspace_deactivated(&mut self, _: &mut Window, cx: &mut Context<Self>) {
|
||||
|
|
|
@ -210,6 +210,9 @@ impl Vim {
|
|||
|
||||
let Some(mut anchors) = anchors else { return };
|
||||
|
||||
self.update_editor(window, cx, |_, editor, _, cx| {
|
||||
editor.create_nav_history_entry(cx);
|
||||
});
|
||||
let is_active_operator = self.active_operator().is_some();
|
||||
if is_active_operator {
|
||||
if let Some(anchor) = anchors.last() {
|
||||
|
@ -264,7 +267,7 @@ impl Vim {
|
|||
|
||||
pub fn set_mark(
|
||||
&mut self,
|
||||
name: String,
|
||||
mut name: String,
|
||||
anchors: Vec<Anchor>,
|
||||
buffer_entity: &Entity<MultiBuffer>,
|
||||
window: &mut Window,
|
||||
|
@ -273,6 +276,9 @@ impl Vim {
|
|||
let Some(workspace) = self.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
if name == "`" {
|
||||
name = "'".to_string();
|
||||
}
|
||||
let entity_id = workspace.entity_id();
|
||||
Vim::update_globals(cx, |vim_globals, cx| {
|
||||
let Some(marks_state) = vim_globals.marks.get(&entity_id) else {
|
||||
|
@ -286,11 +292,14 @@ impl Vim {
|
|||
|
||||
pub fn get_mark(
|
||||
&self,
|
||||
name: &str,
|
||||
mut name: &str,
|
||||
editor: &mut Editor,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Option<Mark> {
|
||||
if name == "`" {
|
||||
name = "'";
|
||||
}
|
||||
if matches!(name, "{" | "}" | "(" | ")") {
|
||||
let (map, selections) = editor.selections.all_display(cx);
|
||||
let anchors = selections
|
||||
|
@ -331,3 +340,29 @@ pub fn jump_motion(
|
|||
|
||||
(point, SelectionGoal::None)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use gpui::TestAppContext;
|
||||
|
||||
use crate::test::NeovimBackedTestContext;
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_quote_mark(cx: &mut TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
cx.set_shared_state("ˇHello, world!").await;
|
||||
cx.simulate_shared_keystrokes("w m o").await;
|
||||
cx.shared_state().await.assert_eq("Helloˇ, world!");
|
||||
cx.simulate_shared_keystrokes("$ ` o").await;
|
||||
cx.shared_state().await.assert_eq("Helloˇ, world!");
|
||||
cx.simulate_shared_keystrokes("` `").await;
|
||||
cx.shared_state().await.assert_eq("Hello, worldˇ!");
|
||||
cx.simulate_shared_keystrokes("` `").await;
|
||||
cx.shared_state().await.assert_eq("Helloˇ, world!");
|
||||
cx.simulate_shared_keystrokes("$ m '").await;
|
||||
cx.shared_state().await.assert_eq("Hello, worldˇ!");
|
||||
cx.simulate_shared_keystrokes("^ ` `").await;
|
||||
cx.shared_state().await.assert_eq("Hello, worldˇ!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -822,6 +822,19 @@ impl Vim {
|
|||
EditorEvent::Edited { .. } => self.push_to_change_list(window, cx),
|
||||
EditorEvent::FocusedIn => self.sync_vim_settings(window, cx),
|
||||
EditorEvent::CursorShapeChanged => self.cursor_shape_changed(window, cx),
|
||||
EditorEvent::PushedToNavHistory {
|
||||
anchor,
|
||||
is_deactivate,
|
||||
} => {
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
let mark = if *is_deactivate {
|
||||
"\"".to_string()
|
||||
} else {
|
||||
"'".to_string()
|
||||
};
|
||||
vim.set_mark(mark, vec![*anchor], editor.buffer(), window, cx);
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
23
crates/vim/test_data/test_quote_mark.json
Normal file
23
crates/vim/test_data/test_quote_mark.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{"Put":{"state":"ˇHello, world!"}}
|
||||
{"Key":"w"}
|
||||
{"Key":"m"}
|
||||
{"Key":"o"}
|
||||
{"Get":{"state":"Helloˇ, world!","mode":"Normal"}}
|
||||
{"Key":"$"}
|
||||
{"Key":"`"}
|
||||
{"Key":"o"}
|
||||
{"Get":{"state":"Helloˇ, world!","mode":"Normal"}}
|
||||
{"Key":"`"}
|
||||
{"Key":"`"}
|
||||
{"Get":{"state":"Hello, worldˇ!","mode":"Normal"}}
|
||||
{"Key":"`"}
|
||||
{"Key":"`"}
|
||||
{"Get":{"state":"Helloˇ, world!","mode":"Normal"}}
|
||||
{"Key":"$"}
|
||||
{"Key":"m"}
|
||||
{"Key":"'"}
|
||||
{"Get":{"state":"Hello, worldˇ!","mode":"Normal"}}
|
||||
{"Key":"^"}
|
||||
{"Key":"`"}
|
||||
{"Key":"`"}
|
||||
{"Get":{"state":"Hello, worldˇ!","mode":"Normal"}}
|
Loading…
Add table
Add a link
Reference in a new issue