Skip to content

Commit 6b4126e

Browse files
committed
incomplete key sequences should be completed first
1 parent 02f551d commit 6b4126e

File tree

1 file changed

+51
-5
lines changed

1 file changed

+51
-5
lines changed

src/edit_mode/vi/mod.rs

+51-5
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,20 +67,21 @@ 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
@@ -93,6 +96,8 @@ impl EditMode for Vi {
9396
} else {
9497
ReedlineEvent::None
9598
}
99+
} else if let Some(event) = binding {
100+
event
96101
} else {
97102
ReedlineEvent::None
98103
}
@@ -277,4 +282,45 @@ mod test {
277282

278283
assert_eq!(result, ReedlineEvent::None);
279284
}
285+
286+
#[test]
287+
fn find_custom_keybinding_test() {
288+
let mut keybindings = default_vi_normal_keybindings();
289+
keybindings.add_binding(
290+
KeyModifiers::SHIFT,
291+
KeyCode::Char('B'),
292+
ReedlineEvent::Edit(vec![EditCommand::MoveBigWordLeft { select: false }]),
293+
);
294+
let mut vi = Vi {
295+
insert_keybindings: default_vi_insert_keybindings(),
296+
normal_keybindings: keybindings,
297+
mode: ViMode::Normal,
298+
..Default::default()
299+
};
300+
301+
let _ = vi.parse_event(
302+
ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
303+
KeyCode::Char('f'),
304+
KeyModifiers::NONE,
305+
)))
306+
.unwrap(),
307+
);
308+
let res = vi.parse_event(
309+
ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
310+
KeyCode::Char('B'),
311+
KeyModifiers::SHIFT,
312+
)))
313+
.unwrap(),
314+
);
315+
316+
assert_eq!(
317+
res,
318+
ReedlineEvent::Multiple(vec![ReedlineEvent::Edit(vec![
319+
EditCommand::MoveRightUntil {
320+
c: 'B',
321+
select: false
322+
}
323+
])])
324+
);
325+
}
280326
}

0 commit comments

Comments
 (0)