mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
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:
parent
9cef0ac869
commit
901cb8b3d2
@ -117,6 +117,9 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"m": ["vim::PushOperator", "Mark"],
|
||||
"'": ["vim::PushOperator", { "Jump": { "line": true } }],
|
||||
"`": ["vim::PushOperator", { "Jump": { "line": false } }],
|
||||
";": "vim::RepeatFind",
|
||||
",": "vim::RepeatFindReversed",
|
||||
"ctrl-o": "pane::GoBack",
|
||||
|
@ -13,7 +13,7 @@ use std::ops::Range;
|
||||
use workspace::Workspace;
|
||||
|
||||
use crate::{
|
||||
normal::normal_motion,
|
||||
normal::{mark, normal_motion},
|
||||
state::{Mode, Operator},
|
||||
surrounds::SurroundsType,
|
||||
utils::coerce_punctuation,
|
||||
@ -105,6 +105,10 @@ pub enum Motion {
|
||||
prior_selections: Vec<Range<Anchor>>,
|
||||
new_selections: Vec<Range<Anchor>>,
|
||||
},
|
||||
Jump {
|
||||
anchor: Anchor,
|
||||
line: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
@ -469,6 +473,7 @@ impl Motion {
|
||||
| WindowTop
|
||||
| WindowMiddle
|
||||
| WindowBottom
|
||||
| Jump { line: true, .. }
|
||||
| EndOfParagraph => true,
|
||||
EndOfLine { .. }
|
||||
| Matching
|
||||
@ -492,6 +497,7 @@ impl Motion {
|
||||
| FindBackward { .. }
|
||||
| RepeatFind { .. }
|
||||
| RepeatFindReversed { .. }
|
||||
| Jump { line: false, .. }
|
||||
| ZedSearchResult { .. } => false,
|
||||
}
|
||||
}
|
||||
@ -531,7 +537,8 @@ impl Motion {
|
||||
| WindowMiddle
|
||||
| WindowBottom
|
||||
| NextLineStart
|
||||
| ZedSearchResult { .. } => false,
|
||||
| ZedSearchResult { .. }
|
||||
| Jump { .. } => false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -570,6 +577,7 @@ impl Motion {
|
||||
| PreviousSubwordStart { .. }
|
||||
| FirstNonWhitespace { .. }
|
||||
| FindBackward { .. }
|
||||
| Jump { .. }
|
||||
| ZedSearchResult { .. } => false,
|
||||
RepeatFind { last_find: motion } | RepeatFindReversed { last_find: motion } => {
|
||||
motion.inclusive()
|
||||
@ -761,6 +769,7 @@ impl Motion {
|
||||
WindowTop => window_top(map, point, &text_layout_details, times - 1),
|
||||
WindowMiddle => window_middle(map, point, &text_layout_details),
|
||||
WindowBottom => window_bottom(map, point, &text_layout_details, times - 1),
|
||||
Jump { line, anchor } => mark::jump_motion(map, *anchor, *line),
|
||||
ZedSearchResult { new_selections, .. } => {
|
||||
// There will be only one selection, as
|
||||
// Search::SelectNextMatch selects a single match.
|
||||
|
@ -2,6 +2,7 @@ mod case;
|
||||
mod change;
|
||||
mod delete;
|
||||
mod increment;
|
||||
pub(crate) mod mark;
|
||||
mod paste;
|
||||
pub(crate) mod repeat;
|
||||
mod scroll;
|
||||
|
147
crates/vim/src/normal/mark.rs
Normal file
147
crates/vim/src/normal/mark.rs
Normal file
@ -0,0 +1,147 @@
|
||||
use std::{ops::Range, sync::Arc};
|
||||
|
||||
use editor::{
|
||||
display_map::{DisplaySnapshot, ToDisplayPoint},
|
||||
movement,
|
||||
scroll::Autoscroll,
|
||||
Anchor, Bias, DisplayPoint,
|
||||
};
|
||||
use gpui::WindowContext;
|
||||
use language::SelectionGoal;
|
||||
|
||||
use crate::{
|
||||
motion::{self, Motion},
|
||||
Vim,
|
||||
};
|
||||
|
||||
pub fn create_mark(vim: &mut Vim, text: Arc<str>, tail: bool, cx: &mut WindowContext) {
|
||||
let Some(anchors) = vim.update_active_editor(cx, |_, editor, _| {
|
||||
editor
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.iter()
|
||||
.map(|s| if tail { s.tail() } else { s.head() })
|
||||
.collect::<Vec<_>>()
|
||||
}) else {
|
||||
return;
|
||||
};
|
||||
vim.update_state(|state| state.marks.insert(text.to_string(), anchors));
|
||||
vim.clear_operator(cx);
|
||||
}
|
||||
|
||||
pub fn create_mark_after(vim: &mut Vim, text: Arc<str>, cx: &mut WindowContext) {
|
||||
let Some(anchors) = vim.update_active_editor(cx, |_, editor, cx| {
|
||||
let (map, selections) = editor.selections.all_display(cx);
|
||||
selections
|
||||
.into_iter()
|
||||
.map(|selection| {
|
||||
let point = movement::saturating_right(&map, selection.tail());
|
||||
map.buffer_snapshot
|
||||
.anchor_before(point.to_offset(&map, Bias::Left))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}) else {
|
||||
return;
|
||||
};
|
||||
|
||||
vim.update_state(|state| state.marks.insert(text.to_string(), anchors));
|
||||
vim.clear_operator(cx);
|
||||
}
|
||||
|
||||
pub fn create_mark_before(vim: &mut Vim, text: Arc<str>, cx: &mut WindowContext) {
|
||||
let Some(anchors) = vim.update_active_editor(cx, |_, editor, cx| {
|
||||
let (map, selections) = editor.selections.all_display(cx);
|
||||
selections
|
||||
.into_iter()
|
||||
.map(|selection| {
|
||||
let point = movement::saturating_left(&map, selection.head());
|
||||
map.buffer_snapshot
|
||||
.anchor_before(point.to_offset(&map, Bias::Left))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}) else {
|
||||
return;
|
||||
};
|
||||
|
||||
vim.update_state(|state| state.marks.insert(text.to_string(), anchors));
|
||||
vim.clear_operator(cx);
|
||||
}
|
||||
|
||||
pub fn jump(text: Arc<str>, line: bool, cx: &mut WindowContext) {
|
||||
let anchors = match &*text {
|
||||
"{" | "}" => Vim::update(cx, |vim, cx| {
|
||||
vim.update_active_editor(cx, |_, editor, cx| {
|
||||
let (map, selections) = editor.selections.all_display(cx);
|
||||
selections
|
||||
.into_iter()
|
||||
.map(|selection| {
|
||||
let point = if &*text == "{" {
|
||||
movement::start_of_paragraph(&map, selection.head(), 1)
|
||||
} else {
|
||||
movement::end_of_paragraph(&map, selection.head(), 1)
|
||||
};
|
||||
map.buffer_snapshot
|
||||
.anchor_before(point.to_offset(&map, Bias::Left))
|
||||
})
|
||||
.collect::<Vec<Anchor>>()
|
||||
})
|
||||
}),
|
||||
_ => Vim::read(cx).state().marks.get(&*text).cloned(),
|
||||
};
|
||||
|
||||
Vim::update(cx, |vim, cx| {
|
||||
vim.pop_operator(cx);
|
||||
});
|
||||
|
||||
let Some(anchors) = anchors else { return };
|
||||
|
||||
let is_active_operator = Vim::read(cx).state().active_operator().is_some();
|
||||
if is_active_operator {
|
||||
if let Some(anchor) = anchors.last() {
|
||||
motion::motion(
|
||||
Motion::Jump {
|
||||
anchor: *anchor,
|
||||
line,
|
||||
},
|
||||
cx,
|
||||
)
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
Vim::update(cx, |vim, cx| {
|
||||
vim.update_active_editor(cx, |_, editor, cx| {
|
||||
let map = editor.snapshot(cx);
|
||||
let mut ranges: Vec<Range<Anchor>> = Vec::new();
|
||||
for mut anchor in anchors {
|
||||
if line {
|
||||
let mut point = anchor.to_display_point(&map.display_snapshot);
|
||||
point = motion::first_non_whitespace(&map.display_snapshot, false, point);
|
||||
anchor = map
|
||||
.display_snapshot
|
||||
.buffer_snapshot
|
||||
.anchor_before(point.to_point(&map.display_snapshot));
|
||||
}
|
||||
if ranges.last() != Some(&(anchor..anchor)) {
|
||||
ranges.push(anchor..anchor);
|
||||
}
|
||||
}
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.select_anchor_ranges(ranges)
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jump_motion(
|
||||
map: &DisplaySnapshot,
|
||||
anchor: Anchor,
|
||||
line: bool,
|
||||
) -> (DisplayPoint, SelectionGoal) {
|
||||
let mut point = anchor.to_display_point(map);
|
||||
if line {
|
||||
point = motion::first_non_whitespace(map, false, point)
|
||||
}
|
||||
|
||||
(point, SelectionGoal::None)
|
||||
}
|
@ -59,6 +59,8 @@ pub enum Operator {
|
||||
AddSurrounds { target: Option<SurroundsType> },
|
||||
ChangeSurrounds { target: Option<Object> },
|
||||
DeleteSurrounds,
|
||||
Mark,
|
||||
Jump { line: bool },
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
@ -74,6 +76,8 @@ pub struct EditorState {
|
||||
pub operator_stack: Vec<Operator>,
|
||||
pub replacements: Vec<(Range<editor::Anchor>, String)>,
|
||||
|
||||
pub marks: HashMap<String, Vec<Anchor>>,
|
||||
|
||||
pub current_tx: Option<TransactionId>,
|
||||
pub current_anchor: Option<Selection<Anchor>>,
|
||||
pub undo_modes: HashMap<TransactionId, Mode>,
|
||||
@ -172,7 +176,10 @@ impl EditorState {
|
||||
}
|
||||
matches!(
|
||||
self.operator_stack.last(),
|
||||
Some(Operator::FindForward { .. }) | Some(Operator::FindBackward { .. })
|
||||
Some(Operator::FindForward { .. })
|
||||
| Some(Operator::FindBackward { .. })
|
||||
| Some(Operator::Mark)
|
||||
| Some(Operator::Jump { .. })
|
||||
)
|
||||
}
|
||||
|
||||
@ -254,6 +261,9 @@ impl Operator {
|
||||
Operator::AddSurrounds { .. } => "ys",
|
||||
Operator::ChangeSurrounds { .. } => "cs",
|
||||
Operator::DeleteSurrounds => "ds",
|
||||
Operator::Mark => "m",
|
||||
Operator::Jump { line: true } => "'",
|
||||
Operator::Jump { line: false } => "`",
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,6 +271,8 @@ impl Operator {
|
||||
match self {
|
||||
Operator::Object { .. } | Operator::ChangeSurrounds { target: None } => &["VimObject"],
|
||||
Operator::FindForward { .. }
|
||||
| Operator::Mark
|
||||
| Operator::Jump { .. }
|
||||
| Operator::FindBackward { .. }
|
||||
| Operator::Replace
|
||||
| Operator::AddSurrounds { target: Some(_) }
|
||||
|
@ -1073,3 +1073,133 @@ async fn test_mouse_selection(cx: &mut TestAppContext) {
|
||||
|
||||
cx.assert_state("one «ˇtwo» three", Mode::Visual)
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_lowercase_marks(cx: &mut TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
cx.set_shared_state("line one\nline ˇtwo\nline three").await;
|
||||
cx.simulate_shared_keystrokes(["m", "a", "l", "'", "a"])
|
||||
.await;
|
||||
cx.assert_shared_state("line one\nˇline two\nline three")
|
||||
.await;
|
||||
cx.simulate_shared_keystrokes(["`", "a"]).await;
|
||||
cx.assert_shared_state("line one\nline ˇtwo\nline three")
|
||||
.await;
|
||||
|
||||
cx.simulate_shared_keystrokes(["^", "d", "`", "a"]).await;
|
||||
cx.assert_shared_state("line one\nˇtwo\nline three").await;
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_lt_gt_marks(cx: &mut TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
cx.set_shared_state(indoc!(
|
||||
"
|
||||
Line one
|
||||
Line two
|
||||
Line ˇthree
|
||||
Line four
|
||||
Line five
|
||||
"
|
||||
))
|
||||
.await;
|
||||
|
||||
cx.simulate_shared_keystrokes(["v", "j", "escape", "k", "k"])
|
||||
.await;
|
||||
|
||||
cx.simulate_shared_keystrokes(["'", "<"]).await;
|
||||
cx.assert_shared_state(indoc!(
|
||||
"
|
||||
Line one
|
||||
Line two
|
||||
ˇLine three
|
||||
Line four
|
||||
Line five
|
||||
"
|
||||
))
|
||||
.await;
|
||||
|
||||
cx.simulate_shared_keystrokes(["`", "<"]).await;
|
||||
cx.assert_shared_state(indoc!(
|
||||
"
|
||||
Line one
|
||||
Line two
|
||||
Line ˇthree
|
||||
Line four
|
||||
Line five
|
||||
"
|
||||
))
|
||||
.await;
|
||||
|
||||
cx.simulate_shared_keystrokes(["'", ">"]).await;
|
||||
cx.assert_shared_state(indoc!(
|
||||
"
|
||||
Line one
|
||||
Line two
|
||||
Line three
|
||||
ˇLine four
|
||||
Line five
|
||||
"
|
||||
))
|
||||
.await;
|
||||
|
||||
cx.simulate_shared_keystrokes(["`", ">"]).await;
|
||||
cx.assert_shared_state(indoc!(
|
||||
"
|
||||
Line one
|
||||
Line two
|
||||
Line three
|
||||
Line ˇfour
|
||||
Line five
|
||||
"
|
||||
))
|
||||
.await;
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_caret_mark(cx: &mut TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
cx.set_shared_state(indoc!(
|
||||
"
|
||||
Line one
|
||||
Line two
|
||||
Line three
|
||||
ˇLine four
|
||||
Line five
|
||||
"
|
||||
))
|
||||
.await;
|
||||
|
||||
cx.simulate_shared_keystrokes([
|
||||
"c", "w", "shift-s", "t", "r", "a", "i", "g", "h", "t", " ", "t", "h", "i", "n", "g",
|
||||
"escape", "j", "j",
|
||||
])
|
||||
.await;
|
||||
|
||||
cx.simulate_shared_keystrokes(["'", "^"]).await;
|
||||
cx.assert_shared_state(indoc!(
|
||||
"
|
||||
Line one
|
||||
Line two
|
||||
Line three
|
||||
ˇStraight thing four
|
||||
Line five
|
||||
"
|
||||
))
|
||||
.await;
|
||||
|
||||
cx.simulate_shared_keystrokes(["`", "^"]).await;
|
||||
cx.assert_shared_state(indoc!(
|
||||
"
|
||||
Line one
|
||||
Line two
|
||||
Line three
|
||||
Straight thingˇ four
|
||||
Line five
|
||||
"
|
||||
))
|
||||
.await;
|
||||
}
|
||||
|
@ -39,6 +39,24 @@ fn copy_selections_content_internal(
|
||||
let mut text = String::new();
|
||||
let mut clipboard_selections = Vec::with_capacity(selections.len());
|
||||
let mut ranges_to_highlight = Vec::new();
|
||||
|
||||
vim.update_state(|state| {
|
||||
state.marks.insert(
|
||||
"[".to_string(),
|
||||
selections
|
||||
.iter()
|
||||
.map(|s| buffer.anchor_before(s.start))
|
||||
.collect(),
|
||||
);
|
||||
state.marks.insert(
|
||||
"]".to_string(),
|
||||
selections
|
||||
.iter()
|
||||
.map(|s| buffer.anchor_after(s.end))
|
||||
.collect(),
|
||||
)
|
||||
});
|
||||
|
||||
{
|
||||
let mut is_first = true;
|
||||
for selection in selections.iter() {
|
||||
|
@ -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),
|
||||
_ => {}
|
||||
|
36
crates/vim/test_data/test_builtin_marks.json
Normal file
36
crates/vim/test_data/test_builtin_marks.json
Normal file
@ -0,0 +1,36 @@
|
||||
{"Put":{"state":"Line one\nLine two\nLine ˇthree\nLine four\nLine five\n"}}
|
||||
{"Key":"v"}
|
||||
{"Key":"j"}
|
||||
{"Key":"escape"}
|
||||
{"Key":"k"}
|
||||
{"Key":"k"}
|
||||
{"Key":"'"}
|
||||
{"Key":"<"}
|
||||
{"Get":{"state":"Line one\nLine two\nˇLine three\nLine four\nLine five\n","mode":"Normal"}}
|
||||
{"Key":"`"}
|
||||
{"Key":"<"}
|
||||
{"Get":{"state":"Line one\nLine two\nLine ˇthree\nLine four\nLine five\n","mode":"Normal"}}
|
||||
{"Key":"'"}
|
||||
{"Key":">"}
|
||||
{"Get":{"state":"Line one\nLine two\nLine three\nˇLine four\nLine five\n","mode":"Normal"}}
|
||||
{"Key":"`"}
|
||||
{"Key":">"}
|
||||
{"Get":{"state":"Line one\nLine two\nLine three\nLine ˇfour\nLine five\n","mode":"Normal"}}
|
||||
{"Key":"g"}
|
||||
{"Key":"g"}
|
||||
{"Key":"^"}
|
||||
{"Key":"j"}
|
||||
{"Key":"j"}
|
||||
{"Key":"l"}
|
||||
{"Key":"l"}
|
||||
{"Key":"c"}
|
||||
{"Key":"e"}
|
||||
{"Key":"k"}
|
||||
{"Key":"e"}
|
||||
{"Key":"escape"}
|
||||
{"Key":"'"}
|
||||
{"Key":"."}
|
||||
{"Get":{"state":"Line one\nLine two\nˇLike three\nLine four\nLine five\n","mode":"Normal"}}
|
||||
{"Key":"`"}
|
||||
{"Key":"."}
|
||||
{"Get":{"state":"Line one\nLine two\nLiˇke three\nLine four\nLine five\n","mode":"Normal"}}
|
26
crates/vim/test_data/test_caret_mark.json
Normal file
26
crates/vim/test_data/test_caret_mark.json
Normal file
@ -0,0 +1,26 @@
|
||||
{"Put":{"state":"Line one\nLine two\nLine three\nˇLine four\nLine five\n"}}
|
||||
{"Key":"c"}
|
||||
{"Key":"w"}
|
||||
{"Key":"shift-s"}
|
||||
{"Key":"t"}
|
||||
{"Key":"r"}
|
||||
{"Key":"a"}
|
||||
{"Key":"i"}
|
||||
{"Key":"g"}
|
||||
{"Key":"h"}
|
||||
{"Key":"t"}
|
||||
{"Key":" "}
|
||||
{"Key":"t"}
|
||||
{"Key":"h"}
|
||||
{"Key":"i"}
|
||||
{"Key":"n"}
|
||||
{"Key":"g"}
|
||||
{"Key":"escape"}
|
||||
{"Key":"j"}
|
||||
{"Key":"j"}
|
||||
{"Key":"'"}
|
||||
{"Key":"^"}
|
||||
{"Get":{"state":"Line one\nLine two\nLine three\nˇStraight thing four\nLine five\n","mode":"Normal"}}
|
||||
{"Key":"`"}
|
||||
{"Key":"^"}
|
||||
{"Get":{"state":"Line one\nLine two\nLine three\nStraight thingˇ four\nLine five\n","mode":"Normal"}}
|
15
crates/vim/test_data/test_lowercase_marks.json
Normal file
15
crates/vim/test_data/test_lowercase_marks.json
Normal file
@ -0,0 +1,15 @@
|
||||
{"Put":{"state":"line one\nline ˇtwo\nline three"}}
|
||||
{"Key":"m"}
|
||||
{"Key":"a"}
|
||||
{"Key":"l"}
|
||||
{"Key":"'"}
|
||||
{"Key":"a"}
|
||||
{"Get":{"state":"line one\nˇline two\nline three","mode":"Normal"}}
|
||||
{"Key":"`"}
|
||||
{"Key":"a"}
|
||||
{"Get":{"state":"line one\nline ˇtwo\nline three","mode":"Normal"}}
|
||||
{"Key":"^"}
|
||||
{"Key":"d"}
|
||||
{"Key":"`"}
|
||||
{"Key":"a"}
|
||||
{"Get":{"state":"line one\nˇtwo\nline three","mode":"Normal"}}
|
18
crates/vim/test_data/test_lt_gt_marks.json
Normal file
18
crates/vim/test_data/test_lt_gt_marks.json
Normal file
@ -0,0 +1,18 @@
|
||||
{"Put":{"state":"Line one\nLine two\nLine ˇthree\nLine four\nLine five\n"}}
|
||||
{"Key":"v"}
|
||||
{"Key":"j"}
|
||||
{"Key":"escape"}
|
||||
{"Key":"k"}
|
||||
{"Key":"k"}
|
||||
{"Key":"'"}
|
||||
{"Key":"<"}
|
||||
{"Get":{"state":"Line one\nLine two\nˇLine three\nLine four\nLine five\n","mode":"Normal"}}
|
||||
{"Key":"`"}
|
||||
{"Key":"<"}
|
||||
{"Get":{"state":"Line one\nLine two\nLine ˇthree\nLine four\nLine five\n","mode":"Normal"}}
|
||||
{"Key":"'"}
|
||||
{"Key":">"}
|
||||
{"Get":{"state":"Line one\nLine two\nLine three\nˇLine four\nLine five\n","mode":"Normal"}}
|
||||
{"Key":"`"}
|
||||
{"Key":">"}
|
||||
{"Get":{"state":"Line one\nLine two\nLine three\nLine ˇfour\nLine five\n","mode":"Normal"}}
|
15
crates/vim/test_data/test_marks.json
Normal file
15
crates/vim/test_data/test_marks.json
Normal file
@ -0,0 +1,15 @@
|
||||
{"Put":{"state":"line one\nline ˇtwo\nline three"}}
|
||||
{"Key":"m"}
|
||||
{"Key":"a"}
|
||||
{"Key":"l"}
|
||||
{"Key":"'"}
|
||||
{"Key":"a"}
|
||||
{"Get":{"state":"line one\nˇline two\nline three","mode":"Normal"}}
|
||||
{"Key":"`"}
|
||||
{"Key":"a"}
|
||||
{"Get":{"state":"line one\nline ˇtwo\nline three","mode":"Normal"}}
|
||||
{"Key":"^"}
|
||||
{"Key":"d"}
|
||||
{"Key":"`"}
|
||||
{"Key":"a"}
|
||||
{"Get":{"state":"line one\nˇtwo\nline three","mode":"Normal"}}
|
14
crates/vim/test_data/test_period_mark.json
Normal file
14
crates/vim/test_data/test_period_mark.json
Normal file
@ -0,0 +1,14 @@
|
||||
{"Put":{"state":"Line one\nLine two\nLiˇne three\nLine four\nLine five\n"}}
|
||||
{"Key":"c"}
|
||||
{"Key":"e"}
|
||||
{"Key":"k"}
|
||||
{"Key":"e"}
|
||||
{"Key":"escape"}
|
||||
{"Key":"j"}
|
||||
{"Key":"j"}
|
||||
{"Key":"'"}
|
||||
{"Key":"."}
|
||||
{"Get":{"state":"Line one\nLine two\nˇLike three\nLine four\nLine five\n","mode":"Normal"}}
|
||||
{"Key":"`"}
|
||||
{"Key":"."}
|
||||
{"Get":{"state":"Line one\nLine two\nLiˇke three\nLine four\nLine five\n","mode":"Normal"}}
|
Loading…
Reference in New Issue
Block a user