Skip to content

Commit

Permalink
incomplete key sequences should be completed first
Browse files Browse the repository at this point in the history
  • Loading branch information
crides committed Jan 2, 2024
1 parent f396223 commit 7673d86
Showing 1 changed file with 48 additions and 5 deletions.
53 changes: 48 additions & 5 deletions src/edit_mode/vi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub struct Vi {
previous: Option<ReedlineEvent>,
// last f, F, t, T motion for ; and ,
last_char_search: Option<ViCharSearch>,
seq_completed: bool,
}

impl Default for Vi {
Expand All @@ -41,6 +42,7 @@ impl Default for Vi {
mode: ViMode::Insert,
previous: None,
last_char_search: None,
seq_completed: true,
}
}
}
Expand All @@ -65,23 +67,26 @@ impl EditMode for Vi {
(ViMode::Normal, modifier, KeyCode::Char(c)) => {
let c = c.to_ascii_lowercase();

if let Some(event) = self
let binding = self
.normal_keybindings
.find_binding(modifiers, KeyCode::Char(c))
.find_binding(modifiers, KeyCode::Char(c));
if self.seq_completed
|| binding.is_none()
&& (modifier == KeyModifiers::NONE || modifier == KeyModifiers::SHIFT)
{
event
} else if modifier == KeyModifiers::NONE || modifier == KeyModifiers::SHIFT {
self.cache.push(if modifier == KeyModifiers::SHIFT {
c.to_ascii_uppercase()
} else {
c
});

let res = parse(&mut self.cache.iter().peekable());

self.seq_completed = res.is_complete();
if !res.is_valid() {
self.cache.clear();
ReedlineEvent::None
} else if let Some(event) = binding {
event
} else if res.is_complete() {
if res.enters_insert_mode() {
self.mode = ViMode::Insert;
Expand Down Expand Up @@ -264,4 +269,42 @@ mod test {

assert_eq!(result, ReedlineEvent::None);
}

#[test]
fn find_custom_keybinding_test() {
let mut keybindings = default_vi_normal_keybindings();
keybindings.add_binding(
KeyModifiers::SHIFT,
KeyCode::Char('B'),
ReedlineEvent::Edit(vec![EditCommand::MoveBigWordLeft]),
);
let mut vi = Vi {
insert_keybindings: default_vi_insert_keybindings(),
normal_keybindings: keybindings,
mode: ViMode::Normal,
..Default::default()
};

let _ = vi.parse_event(
ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
KeyCode::Char('f'),
KeyModifiers::NONE,
)))
.unwrap(),
);
let res = vi.parse_event(
ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
KeyCode::Char('B'),
KeyModifiers::SHIFT,
)))
.unwrap(),
);

assert_eq!(
res,
ReedlineEvent::Multiple(vec![ReedlineEvent::Edit(vec![
EditCommand::MoveRightUntil('B')
])])
);
}
}

0 comments on commit 7673d86

Please sign in to comment.