vim: Add basic mark support (#11507)

Release Notes:
- vim: Added support for buffer-local marks (`'a-'z`) and some builtin
marks `'<`,`'>`,`'[`,`']`, `'{`, `'}` and `^`. Global marks (`'A-'Z`),
and other builtin marks (`'0-'9`, `'(`, `')`, `''`, `'.`, `'"`) are not
yet implemented. (#5122)

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
Zachiah Sawyer 2024-05-09 17:51:19 -07:00 committed by GitHub
parent 9cef0ac869
commit 901cb8b3d2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 471 additions and 6 deletions

View file

@ -30,7 +30,10 @@ use gpui::{
use language::{CursorShape, Point, SelectionGoal, TransactionId};
pub use mode_indicator::ModeIndicator;
use motion::Motion;
use normal::normal_replace;
use normal::{
mark::{create_mark, create_mark_after, create_mark_before},
normal_replace,
};
use replace::multi_replace;
use schemars::JsonSchema;
use serde::Deserialize;
@ -194,7 +197,9 @@ fn observe_keystrokes(keystroke_event: &KeystrokeEvent, cx: &mut WindowContext)
| Operator::Replace
| Operator::AddSurrounds { .. }
| Operator::ChangeSurrounds { .. }
| Operator::DeleteSurrounds,
| Operator::DeleteSurrounds
| Operator::Mark
| Operator::Jump { .. },
) => {}
Some(_) => {
vim.clear_operator(cx);
@ -418,6 +423,10 @@ impl Vim {
// Sync editor settings like clip mode
self.sync_vim_settings(cx);
if mode != Mode::Insert && last_mode == Mode::Insert {
create_mark_after(self, "^".into(), cx)
}
if leave_selections {
return;
}
@ -614,6 +623,7 @@ impl Vim {
let is_multicursor = editor.read(cx).selections.count() > 1;
let state = self.state();
let mut is_visual = state.mode.is_visual();
if state.mode == Mode::Insert && state.current_tx.is_some() {
if state.current_anchor.is_none() {
self.update_state(|state| state.current_anchor = Some(newest));
@ -630,11 +640,18 @@ impl Vim {
} else {
self.switch_mode(Mode::Visual, false, cx)
}
is_visual = true;
} else if newest.start == newest.end
&& !is_multicursor
&& [Mode::Visual, Mode::VisualLine, Mode::VisualBlock].contains(&state.mode)
{
self.switch_mode(Mode::Normal, true, cx)
self.switch_mode(Mode::Normal, true, cx);
is_visual = false;
}
if is_visual {
create_mark_before(self, ">".into(), cx);
create_mark(self, "<".into(), true, cx)
}
}
@ -706,6 +723,10 @@ impl Vim {
}
_ => Vim::update(cx, |vim, cx| vim.clear_operator(cx)),
},
Some(Operator::Mark) => Vim::update(cx, |vim, cx| {
normal::mark::create_mark(vim, text, false, cx)
}),
Some(Operator::Jump { line }) => normal::mark::jump(text, line, cx),
_ => match Vim::read(cx).state().mode {
Mode::Replace => multi_replace(text, cx),
_ => {}