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(
|
self.push_to_nav_history(
|
||||||
*old_cursor_position,
|
*old_cursor_position,
|
||||||
Some(new_cursor_position.to_point(buffer)),
|
Some(new_cursor_position.to_point(buffer)),
|
||||||
|
false,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -10809,10 +10810,15 @@ impl Editor {
|
||||||
self.nav_history.as_ref()
|
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(
|
fn push_to_nav_history(
|
||||||
&mut self,
|
&mut self,
|
||||||
cursor_anchor: Anchor,
|
cursor_anchor: Anchor,
|
||||||
new_position: Option<Point>,
|
new_position: Option<Point>,
|
||||||
|
is_deactivate: bool,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
if let Some(nav_history) = self.nav_history.as_mut() {
|
if let Some(nav_history) = self.nav_history.as_mut() {
|
||||||
|
@ -10838,6 +10844,10 @@ impl Editor {
|
||||||
}),
|
}),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
cx.emit(EditorEvent::PushedToNavHistory {
|
||||||
|
anchor: cursor_anchor,
|
||||||
|
is_deactivate,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18617,6 +18627,10 @@ pub enum EditorEvent {
|
||||||
},
|
},
|
||||||
Reloaded,
|
Reloaded,
|
||||||
CursorShapeChanged,
|
CursorShapeChanged,
|
||||||
|
PushedToNavHistory {
|
||||||
|
anchor: Anchor,
|
||||||
|
is_deactivate: bool,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter<EditorEvent> for Editor {}
|
impl EventEmitter<EditorEvent> for Editor {}
|
||||||
|
|
|
@ -737,7 +737,7 @@ impl Item for Editor {
|
||||||
|
|
||||||
fn deactivated(&mut self, _: &mut Window, cx: &mut Context<Self>) {
|
fn deactivated(&mut self, _: &mut Window, cx: &mut Context<Self>) {
|
||||||
let selection = self.selections.newest_anchor();
|
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>) {
|
fn workspace_deactivated(&mut self, _: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
|
|
@ -210,6 +210,9 @@ impl Vim {
|
||||||
|
|
||||||
let Some(mut anchors) = anchors else { return };
|
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();
|
let is_active_operator = self.active_operator().is_some();
|
||||||
if is_active_operator {
|
if is_active_operator {
|
||||||
if let Some(anchor) = anchors.last() {
|
if let Some(anchor) = anchors.last() {
|
||||||
|
@ -264,7 +267,7 @@ impl Vim {
|
||||||
|
|
||||||
pub fn set_mark(
|
pub fn set_mark(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: String,
|
mut name: String,
|
||||||
anchors: Vec<Anchor>,
|
anchors: Vec<Anchor>,
|
||||||
buffer_entity: &Entity<MultiBuffer>,
|
buffer_entity: &Entity<MultiBuffer>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
|
@ -273,6 +276,9 @@ impl Vim {
|
||||||
let Some(workspace) = self.workspace(window) else {
|
let Some(workspace) = self.workspace(window) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
if name == "`" {
|
||||||
|
name = "'".to_string();
|
||||||
|
}
|
||||||
let entity_id = workspace.entity_id();
|
let entity_id = workspace.entity_id();
|
||||||
Vim::update_globals(cx, |vim_globals, cx| {
|
Vim::update_globals(cx, |vim_globals, cx| {
|
||||||
let Some(marks_state) = vim_globals.marks.get(&entity_id) else {
|
let Some(marks_state) = vim_globals.marks.get(&entity_id) else {
|
||||||
|
@ -286,11 +292,14 @@ impl Vim {
|
||||||
|
|
||||||
pub fn get_mark(
|
pub fn get_mark(
|
||||||
&self,
|
&self,
|
||||||
name: &str,
|
mut name: &str,
|
||||||
editor: &mut Editor,
|
editor: &mut Editor,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Option<Mark> {
|
) -> Option<Mark> {
|
||||||
|
if name == "`" {
|
||||||
|
name = "'";
|
||||||
|
}
|
||||||
if matches!(name, "{" | "}" | "(" | ")") {
|
if matches!(name, "{" | "}" | "(" | ")") {
|
||||||
let (map, selections) = editor.selections.all_display(cx);
|
let (map, selections) = editor.selections.all_display(cx);
|
||||||
let anchors = selections
|
let anchors = selections
|
||||||
|
@ -331,3 +340,29 @@ pub fn jump_motion(
|
||||||
|
|
||||||
(point, SelectionGoal::None)
|
(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::Edited { .. } => self.push_to_change_list(window, cx),
|
||||||
EditorEvent::FocusedIn => self.sync_vim_settings(window, cx),
|
EditorEvent::FocusedIn => self.sync_vim_settings(window, cx),
|
||||||
EditorEvent::CursorShapeChanged => self.cursor_shape_changed(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