vim: Fix count handling to allow pre/post counts
Fixes 2yy, d3d, etc. For zed-industries/community#970 For zed-industries/community#1496
This commit is contained in:
parent
e8a6ecd6ac
commit
cee549e1ef
13 changed files with 175 additions and 54 deletions
|
@ -40,9 +40,12 @@ pub struct SwitchMode(pub Mode);
|
|||
pub struct PushOperator(pub Operator);
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
struct Number(u8);
|
||||
struct Number(usize);
|
||||
|
||||
actions!(vim, [Tab, Enter]);
|
||||
actions!(
|
||||
vim,
|
||||
[Tab, Enter, Object, InnerObject, FindForward, FindBackward]
|
||||
);
|
||||
impl_actions!(vim, [Number, SwitchMode, PushOperator]);
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
@ -70,7 +73,7 @@ pub fn init(cx: &mut AppContext) {
|
|||
},
|
||||
);
|
||||
cx.add_action(|_: &mut Workspace, n: &Number, cx: _| {
|
||||
Vim::update(cx, |vim, cx| vim.push_number(n, cx));
|
||||
Vim::update(cx, |vim, _| vim.push_count_digit(n.0));
|
||||
});
|
||||
|
||||
cx.add_action(|_: &mut Workspace, _: &Tab, cx| {
|
||||
|
@ -236,12 +239,7 @@ impl Vim {
|
|||
if !self.workspace_state.replaying {
|
||||
self.workspace_state.recording = true;
|
||||
self.workspace_state.recorded_actions = Default::default();
|
||||
self.workspace_state.recorded_count =
|
||||
if let Some(Operator::Number(number)) = self.active_operator() {
|
||||
Some(number)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.workspace_state.recorded_count = None;
|
||||
|
||||
let selections = self
|
||||
.active_editor
|
||||
|
@ -352,6 +350,36 @@ impl Vim {
|
|||
});
|
||||
}
|
||||
|
||||
fn push_count_digit(&mut self, number: usize) {
|
||||
if self.active_operator().is_some() {
|
||||
self.update_state(|state| {
|
||||
state.post_count = Some(state.post_count.unwrap_or(0) * 10 + number)
|
||||
})
|
||||
} else {
|
||||
self.update_state(|state| {
|
||||
state.pre_count = Some(state.pre_count.unwrap_or(0) * 10 + number)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn take_count(&mut self) -> Option<usize> {
|
||||
if self.workspace_state.replaying {
|
||||
return self.workspace_state.recorded_count;
|
||||
}
|
||||
|
||||
let count = if self.state().post_count == None && self.state().pre_count == None {
|
||||
return None;
|
||||
} else {
|
||||
Some(self.update_state(|state| {
|
||||
state.post_count.take().unwrap_or(1) * state.pre_count.take().unwrap_or(1)
|
||||
}))
|
||||
};
|
||||
if self.workspace_state.recording {
|
||||
self.workspace_state.recorded_count = count;
|
||||
}
|
||||
count
|
||||
}
|
||||
|
||||
fn push_operator(&mut self, operator: Operator, cx: &mut WindowContext) {
|
||||
if matches!(
|
||||
operator,
|
||||
|
@ -363,15 +391,6 @@ impl Vim {
|
|||
self.sync_vim_settings(cx);
|
||||
}
|
||||
|
||||
fn push_number(&mut self, Number(number): &Number, cx: &mut WindowContext) {
|
||||
if let Some(Operator::Number(current_number)) = self.active_operator() {
|
||||
self.pop_operator(cx);
|
||||
self.push_operator(Operator::Number(current_number * 10 + *number as usize), cx);
|
||||
} else {
|
||||
self.push_operator(Operator::Number(*number as usize), cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_pop_operator(&mut self) -> Option<Operator> {
|
||||
self.update_state(|state| state.operator_stack.pop())
|
||||
}
|
||||
|
@ -382,21 +401,6 @@ impl Vim {
|
|||
self.sync_vim_settings(cx);
|
||||
popped_operator
|
||||
}
|
||||
|
||||
fn pop_number_operator(&mut self, cx: &mut WindowContext) -> Option<usize> {
|
||||
if self.workspace_state.replaying {
|
||||
if let Some(number) = self.workspace_state.recorded_count {
|
||||
return Some(number);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(Operator::Number(number)) = self.active_operator() {
|
||||
self.pop_operator(cx);
|
||||
return Some(number);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn clear_operator(&mut self, cx: &mut WindowContext) {
|
||||
self.update_state(|state| state.operator_stack.clear());
|
||||
self.sync_vim_settings(cx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue