Fix 0 used in a count

This commit is contained in:
Conrad Irwin 2023-09-12 09:56:23 -06:00
parent c2c521015a
commit 7daed1b2c3
15 changed files with 73 additions and 29 deletions

View File

@ -12,7 +12,7 @@ pub fn init(cx: &mut AppContext) {
fn normal_before(_: &mut Workspace, action: &NormalBefore, cx: &mut ViewContext<Workspace>) {
let should_repeat = Vim::update(cx, |vim, cx| {
let count = vim.take_count().unwrap_or(1);
let count = vim.take_count(cx).unwrap_or(1);
vim.stop_recording_immediately(action.boxed_clone());
if count <= 1 || vim.workspace_state.replaying {
vim.update_active_editor(cx, |editor, cx| {

View File

@ -229,7 +229,7 @@ pub(crate) fn motion(motion: Motion, cx: &mut WindowContext) {
Vim::update(cx, |vim, cx| vim.pop_operator(cx));
}
let count = Vim::update(cx, |vim, _| vim.take_count());
let count = Vim::update(cx, |vim, cx| vim.take_count(cx));
let operator = Vim::read(cx).active_operator();
match Vim::read(cx).state().mode {
Mode::Normal => normal_motion(motion, operator, count, cx),

View File

@ -68,21 +68,21 @@ pub fn init(cx: &mut AppContext) {
cx.add_action(|_: &mut Workspace, _: &DeleteLeft, cx| {
Vim::update(cx, |vim, cx| {
vim.record_current_action(cx);
let times = vim.take_count();
let times = vim.take_count(cx);
delete_motion(vim, Motion::Left, times, cx);
})
});
cx.add_action(|_: &mut Workspace, _: &DeleteRight, cx| {
Vim::update(cx, |vim, cx| {
vim.record_current_action(cx);
let times = vim.take_count();
let times = vim.take_count(cx);
delete_motion(vim, Motion::Right, times, cx);
})
});
cx.add_action(|_: &mut Workspace, _: &ChangeToEndOfLine, cx| {
Vim::update(cx, |vim, cx| {
vim.start_recording(cx);
let times = vim.take_count();
let times = vim.take_count(cx);
change_motion(
vim,
Motion::EndOfLine {
@ -96,7 +96,7 @@ pub fn init(cx: &mut AppContext) {
cx.add_action(|_: &mut Workspace, _: &DeleteToEndOfLine, cx| {
Vim::update(cx, |vim, cx| {
vim.record_current_action(cx);
let times = vim.take_count();
let times = vim.take_count(cx);
delete_motion(
vim,
Motion::EndOfLine {
@ -110,7 +110,7 @@ pub fn init(cx: &mut AppContext) {
cx.add_action(|_: &mut Workspace, _: &JoinLines, cx| {
Vim::update(cx, |vim, cx| {
vim.record_current_action(cx);
let mut times = vim.take_count().unwrap_or(1);
let mut times = vim.take_count(cx).unwrap_or(1);
if vim.state().mode.is_visual() {
times = 1;
} else if times > 1 {

View File

@ -8,7 +8,7 @@ use crate::{normal::ChangeCase, state::Mode, Vim};
pub fn change_case(_: &mut Workspace, _: &ChangeCase, cx: &mut ViewContext<Workspace>) {
Vim::update(cx, |vim, cx| {
vim.record_current_action(cx);
let count = vim.take_count().unwrap_or(1) as u32;
let count = vim.take_count(cx).unwrap_or(1) as u32;
vim.update_active_editor(cx, |editor, cx| {
let mut ranges = Vec::new();
let mut cursor_positions = Vec::new();

View File

@ -60,7 +60,7 @@ pub(crate) fn repeat(cx: &mut WindowContext, from_insert_mode: bool) {
let Some(editor) = vim.active_editor.clone() else {
return None;
};
let count = vim.take_count();
let count = vim.take_count(cx);
let selection = vim.workspace_state.recorded_selection.clone();
match selection {
@ -253,7 +253,7 @@ mod test {
deterministic.run_until_parked();
cx.simulate_shared_keystrokes(["."]).await;
deterministic.run_until_parked();
cx.set_shared_state("THE QUICK ˇbrown fox").await;
cx.assert_shared_state("THE QUICK ˇbrown fox").await;
}
#[gpui::test]

View File

@ -48,7 +48,7 @@ pub fn init(cx: &mut AppContext) {
fn scroll(cx: &mut ViewContext<Workspace>, by: fn(c: Option<f32>) -> ScrollAmount) {
Vim::update(cx, |vim, cx| {
let amount = by(vim.take_count().map(|c| c as f32));
let amount = by(vim.take_count(cx).map(|c| c as f32));
vim.update_active_editor(cx, |editor, cx| scroll_editor(editor, &amount, cx));
})
}

View File

@ -52,7 +52,7 @@ fn search(workspace: &mut Workspace, action: &Search, cx: &mut ViewContext<Works
Direction::Next
};
Vim::update(cx, |vim, cx| {
let count = vim.take_count().unwrap_or(1);
let count = vim.take_count(cx).unwrap_or(1);
pane.update(cx, |pane, cx| {
if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::<BufferSearchBar>() {
search_bar.update(cx, |search_bar, cx| {
@ -119,7 +119,7 @@ pub fn move_to_internal(
) {
Vim::update(cx, |vim, cx| {
let pane = workspace.active_pane().clone();
let count = vim.take_count().unwrap_or(1);
let count = vim.take_count(cx).unwrap_or(1);
pane.update(cx, |pane, cx| {
if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::<BufferSearchBar>() {
let search = search_bar.update(cx, |search_bar, cx| {

View File

@ -11,7 +11,7 @@ pub(crate) fn init(cx: &mut AppContext) {
cx.add_action(|_: &mut Workspace, _: &Substitute, cx| {
Vim::update(cx, |vim, cx| {
vim.start_recording(cx);
let count = vim.take_count();
let count = vim.take_count(cx);
substitute(vim, count, vim.state().mode == Mode::VisualLine, cx);
})
});
@ -22,7 +22,7 @@ pub(crate) fn init(cx: &mut AppContext) {
if matches!(vim.state().mode, Mode::VisualBlock | Mode::Visual) {
vim.switch_mode(Mode::VisualLine, false, cx)
}
let count = vim.take_count();
let count = vim.take_count(cx);
substitute(vim, count, true, cx)
})
});

View File

@ -186,6 +186,7 @@ impl EditorState {
if self.active_operator().is_none() && self.pre_count.is_some()
|| self.active_operator().is_some() && self.post_count.is_some()
{
dbg!("VimCount");
context.add_identifier("VimCount");
}

View File

@ -587,9 +587,34 @@ async fn test_clear_counts(cx: &mut gpui::TestAppContext) {
cx.simulate_shared_keystrokes(["4", "escape", "3", "d", "l"])
.await;
cx.set_shared_state(indoc! {"
cx.assert_shared_state(indoc! {"
The quick brown
fox juˇ over
the lazy dog"})
.await;
}
#[gpui::test]
async fn test_zero(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx).await;
cx.set_shared_state(indoc! {"
The quˇick brown
fox jumps over
the lazy dog"})
.await;
cx.simulate_shared_keystrokes(["0"]).await;
cx.assert_shared_state(indoc! {"
ˇThe quick brown
fox jumps over
the lazy dog"})
.await;
cx.simulate_shared_keystrokes(["1", "0", "l"]).await;
cx.assert_shared_state(indoc! {"
The quick ˇbrown
fox jumps over
the lazy dog"})
.await;
}

View File

@ -68,6 +68,8 @@ pub struct NeovimBackedTestContext<'a> {
last_set_state: Option<String>,
recent_keystrokes: Vec<String>,
is_dirty: bool,
}
impl<'a> NeovimBackedTestContext<'a> {
@ -81,6 +83,7 @@ impl<'a> NeovimBackedTestContext<'a> {
last_set_state: None,
recent_keystrokes: Default::default(),
is_dirty: false,
}
}
@ -128,6 +131,7 @@ impl<'a> NeovimBackedTestContext<'a> {
self.last_set_state = Some(marked_text.to_string());
self.recent_keystrokes = Vec::new();
self.neovim.set_state(marked_text).await;
self.is_dirty = true;
context_handle
}
@ -153,6 +157,7 @@ impl<'a> NeovimBackedTestContext<'a> {
}
pub async fn assert_shared_state(&mut self, marked_text: &str) {
self.is_dirty = false;
let marked_text = marked_text.replace("", " ");
let neovim = self.neovim_state().await;
let editor = self.editor_state();
@ -258,6 +263,7 @@ impl<'a> NeovimBackedTestContext<'a> {
}
pub async fn assert_state_matches(&mut self) {
self.is_dirty = false;
let neovim = self.neovim_state().await;
let editor = self.editor_state();
let initial_state = self
@ -383,6 +389,14 @@ impl<'a> DerefMut for NeovimBackedTestContext<'a> {
}
}
impl<'a> Drop for NeovimBackedTestContext<'a> {
fn drop(&mut self) {
if self.is_dirty {
panic!("Test context was dropped after set_shared_state before assert_shared_state")
}
}
}
#[cfg(test)]
mod test {
use gpui::TestAppContext;

View File

@ -73,7 +73,7 @@ pub fn init(cx: &mut AppContext) {
},
);
cx.add_action(|_: &mut Workspace, n: &Number, cx: _| {
Vim::update(cx, |vim, _| vim.push_count_digit(n.0));
Vim::update(cx, |vim, cx| vim.push_count_digit(n.0, cx));
});
cx.add_action(|_: &mut Workspace, _: &Tab, cx| {
@ -228,13 +228,7 @@ impl Vim {
let editor = self.active_editor.clone()?.upgrade(cx)?;
Some(editor.update(cx, update))
}
// ~, shift-j, x, shift-x, p
// shift-c, shift-d, shift-i, i, a, o, shift-o, s
// c, d
// r
// TODO: shift-j?
//
pub fn start_recording(&mut self, cx: &mut WindowContext) {
if !self.workspace_state.replaying {
self.workspace_state.recording = true;
@ -309,7 +303,7 @@ impl Vim {
state.operator_stack.clear();
});
if mode != Mode::Insert {
self.take_count();
self.take_count(cx);
}
cx.emit_global(VimEvent::ModeChanged { mode });
@ -363,7 +357,7 @@ impl Vim {
});
}
fn push_count_digit(&mut self, number: usize) {
fn push_count_digit(&mut self, number: usize, cx: &mut WindowContext) {
if self.active_operator().is_some() {
self.update_state(|state| {
state.post_count = Some(state.post_count.unwrap_or(0) * 10 + number)
@ -373,9 +367,11 @@ impl Vim {
state.pre_count = Some(state.pre_count.unwrap_or(0) * 10 + number)
})
}
// update the keymap so that 0 works
self.sync_vim_settings(cx)
}
fn take_count(&mut self) -> Option<usize> {
fn take_count(&mut self, cx: &mut WindowContext) -> Option<usize> {
if self.workspace_state.replaying {
return self.workspace_state.recorded_count;
}
@ -390,6 +386,7 @@ impl Vim {
if self.workspace_state.recording {
self.workspace_state.recorded_count = count;
}
self.sync_vim_settings(cx);
count
}
@ -415,7 +412,7 @@ impl Vim {
popped_operator
}
fn clear_operator(&mut self, cx: &mut WindowContext) {
self.take_count();
self.take_count(cx);
self.update_state(|state| state.operator_stack.clear());
self.sync_vim_settings(cx);
}

View File

@ -4,4 +4,4 @@
{"Key":"3"}
{"Key":"d"}
{"Key":"l"}
{"Put":{"state":"The quick brown\nfox juˇ over\nthe lazy dog"}}
{"Get":{"state":"The quick brown\nfox juˇ over\nthe lazy dog","mode":"Normal"}}

View File

@ -35,4 +35,4 @@
{"Key":"."}
{"Put":{"state":"THE QUIˇck brown fox"}}
{"Key":"."}
{"Put":{"state":"THE QUICK ˇbrown fox"}}
{"Get":{"state":"THE QUICK ˇbrown fox","mode":"Normal"}}

View File

@ -0,0 +1,7 @@
{"Put":{"state":"The quˇick brown\nfox jumps over\nthe lazy dog"}}
{"Key":"0"}
{"Get":{"state":"ˇThe quick brown\nfox jumps over\nthe lazy dog","mode":"Normal"}}
{"Key":"1"}
{"Key":"0"}
{"Key":"l"}
{"Get":{"state":"The quick ˇbrown\nfox jumps over\nthe lazy dog","mode":"Normal"}}