Skip to content

Commit 7673d86

Browse files
committed
incomplete key sequences should be completed first
1 parent f396223 commit 7673d86

File tree

1 file changed

+48
-5
lines changed

1 file changed

+48
-5
lines changed

src/edit_mode/vi/mod.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub struct Vi {
3030
previous: Option<ReedlineEvent>,
3131
// last f, F, t, T motion for ; and ,
3232
last_char_search: Option<ViCharSearch>,
33+
seq_completed: bool,
3334
}
3435

3536
impl Default for Vi {
@@ -41,6 +42,7 @@ impl Default for Vi {
4142
mode: ViMode::Insert,
4243
previous: None,
4344
last_char_search: None,
45+
seq_completed: true,
4446
}
4547
}
4648
}
@@ -65,23 +67,26 @@ impl EditMode for Vi {
6567
(ViMode::Normal, modifier, KeyCode::Char(c)) => {
6668
let c = c.to_ascii_lowercase();
6769

68-
if let Some(event) = self
70+
let binding = self
6971
.normal_keybindings
70-
.find_binding(modifiers, KeyCode::Char(c))
72+
.find_binding(modifiers, KeyCode::Char(c));
73+
if self.seq_completed
74+
|| binding.is_none()
75+
&& (modifier == KeyModifiers::NONE || modifier == KeyModifiers::SHIFT)
7176
{
72-
event
73-
} else if modifier == KeyModifiers::NONE || modifier == KeyModifiers::SHIFT {
7477
self.cache.push(if modifier == KeyModifiers::SHIFT {
7578
c.to_ascii_uppercase()
7679
} else {
7780
c
7881
});
7982

8083
let res = parse(&mut self.cache.iter().peekable());
81-
84+
self.seq_completed = res.is_complete();
8285
if !res.is_valid() {
8386
self.cache.clear();
8487
ReedlineEvent::None
88+
} else if let Some(event) = binding {
89+
event
8590
} else if res.is_complete() {
8691
if res.enters_insert_mode() {
8792
self.mode = ViMode::Insert;
@@ -264,4 +269,42 @@ mod test {
264269

265270
assert_eq!(result, ReedlineEvent::None);
266271
}
272+
273+
#[test]
274+
fn find_custom_keybinding_test() {
275+
let mut keybindings = default_vi_normal_keybindings();
276+
keybindings.add_binding(
277+
KeyModifiers::SHIFT,
278+
KeyCode::Char('B'),
279+
ReedlineEvent::Edit(vec![EditCommand::MoveBigWordLeft]),
280+
);
281+
let mut vi = Vi {
282+
insert_keybindings: default_vi_insert_keybindings(),
283+
normal_keybindings: keybindings,
284+
mode: ViMode::Normal,
285+
..Default::default()
286+
};
287+
288+
let _ = vi.parse_event(
289+
ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
290+
KeyCode::Char('f'),
291+
KeyModifiers::NONE,
292+
)))
293+
.unwrap(),
294+
);
295+
let res = vi.parse_event(
296+
ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
297+
KeyCode::Char('B'),
298+
KeyModifiers::SHIFT,
299+
)))
300+
.unwrap(),
301+
);
302+
303+
assert_eq!(
304+
res,
305+
ReedlineEvent::Multiple(vec![ReedlineEvent::Edit(vec![
306+
EditCommand::MoveRightUntil('B')
307+
])])
308+
);
309+
}
267310
}

0 commit comments

Comments
 (0)