|
|
@ -1,5 +1,5 @@
|
|
|
|
use crate::{
|
|
|
|
use crate::{
|
|
|
|
commands::{self, OnKeyCallback},
|
|
|
|
commands::{self, OnKeyCallback, OnKeyCallbackKind},
|
|
|
|
compositor::{Component, Context, Event, EventResult},
|
|
|
|
compositor::{Component, Context, Event, EventResult},
|
|
|
|
events::{OnModeSwitch, PostCommand},
|
|
|
|
events::{OnModeSwitch, PostCommand},
|
|
|
|
key,
|
|
|
|
key,
|
|
|
@ -36,7 +36,7 @@ use tui::{buffer::Buffer as Surface, text::Span};
|
|
|
|
|
|
|
|
|
|
|
|
pub struct EditorView {
|
|
|
|
pub struct EditorView {
|
|
|
|
pub keymaps: Keymaps,
|
|
|
|
pub keymaps: Keymaps,
|
|
|
|
on_next_key: Option<OnKeyCallback>,
|
|
|
|
on_next_key: Option<(OnKeyCallback, OnKeyCallbackKind)>,
|
|
|
|
pseudo_pending: Vec<KeyEvent>,
|
|
|
|
pseudo_pending: Vec<KeyEvent>,
|
|
|
|
pub(crate) last_insert: (commands::MappableCommand, Vec<InsertEvent>),
|
|
|
|
pub(crate) last_insert: (commands::MappableCommand, Vec<InsertEvent>),
|
|
|
|
pub(crate) completion: Option<Completion>,
|
|
|
|
pub(crate) completion: Option<Completion>,
|
|
|
@ -917,8 +917,10 @@ impl EditorView {
|
|
|
|
if let Some(keyresult) = self.handle_keymap_event(Mode::Insert, cx, event) {
|
|
|
|
if let Some(keyresult) = self.handle_keymap_event(Mode::Insert, cx, event) {
|
|
|
|
match keyresult {
|
|
|
|
match keyresult {
|
|
|
|
KeymapResult::NotFound => {
|
|
|
|
KeymapResult::NotFound => {
|
|
|
|
if let Some(ch) = event.char() {
|
|
|
|
if !self.on_next_key(OnKeyCallbackKind::Fallback, cx, event) {
|
|
|
|
commands::insert::insert_char(cx, ch)
|
|
|
|
if let Some(ch) = event.char() {
|
|
|
|
|
|
|
|
commands::insert::insert_char(cx, ch)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeymapResult::Cancelled(pending) => {
|
|
|
|
KeymapResult::Cancelled(pending) => {
|
|
|
@ -1014,7 +1016,10 @@ impl EditorView {
|
|
|
|
// set the register
|
|
|
|
// set the register
|
|
|
|
cxt.register = cxt.editor.selected_register.take();
|
|
|
|
cxt.register = cxt.editor.selected_register.take();
|
|
|
|
|
|
|
|
|
|
|
|
self.handle_keymap_event(mode, cxt, event);
|
|
|
|
let res = self.handle_keymap_event(mode, cxt, event);
|
|
|
|
|
|
|
|
if matches!(&res, Some(KeymapResult::NotFound)) {
|
|
|
|
|
|
|
|
self.on_next_key(OnKeyCallbackKind::Fallback, cxt, event);
|
|
|
|
|
|
|
|
}
|
|
|
|
if self.keymaps.pending().is_empty() {
|
|
|
|
if self.keymaps.pending().is_empty() {
|
|
|
|
cxt.editor.count = None
|
|
|
|
cxt.editor.count = None
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -1090,7 +1095,7 @@ impl EditorView {
|
|
|
|
modifiers: KeyModifiers::empty(),
|
|
|
|
modifiers: KeyModifiers::empty(),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// dismiss any pending keys
|
|
|
|
// dismiss any pending keys
|
|
|
|
if let Some(on_next_key) = self.on_next_key.take() {
|
|
|
|
if let Some((on_next_key, _)) = self.on_next_key.take() {
|
|
|
|
on_next_key(cxt, null_key_event);
|
|
|
|
on_next_key(cxt, null_key_event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.handle_keymap_event(cxt.editor.mode, cxt, null_key_event);
|
|
|
|
self.handle_keymap_event(cxt.editor.mode, cxt, null_key_event);
|
|
|
@ -1313,6 +1318,24 @@ impl EditorView {
|
|
|
|
_ => EventResult::Ignored(None),
|
|
|
|
_ => EventResult::Ignored(None),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn on_next_key(
|
|
|
|
|
|
|
|
&mut self,
|
|
|
|
|
|
|
|
kind: OnKeyCallbackKind,
|
|
|
|
|
|
|
|
ctx: &mut commands::Context,
|
|
|
|
|
|
|
|
event: KeyEvent,
|
|
|
|
|
|
|
|
) -> bool {
|
|
|
|
|
|
|
|
if let Some((on_next_key, kind_)) = self.on_next_key.take() {
|
|
|
|
|
|
|
|
if kind == kind_ {
|
|
|
|
|
|
|
|
on_next_key(ctx, event);
|
|
|
|
|
|
|
|
true
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
self.on_next_key = Some((on_next_key, kind_));
|
|
|
|
|
|
|
|
false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Component for EditorView {
|
|
|
|
impl Component for EditorView {
|
|
|
@ -1364,10 +1387,7 @@ impl Component for EditorView {
|
|
|
|
|
|
|
|
|
|
|
|
let mode = cx.editor.mode();
|
|
|
|
let mode = cx.editor.mode();
|
|
|
|
|
|
|
|
|
|
|
|
if let Some(on_next_key) = self.on_next_key.take() {
|
|
|
|
if !self.on_next_key(OnKeyCallbackKind::PseudoPending, &mut cx, key) {
|
|
|
|
// if there's a command waiting input, do that first
|
|
|
|
|
|
|
|
on_next_key(&mut cx, key);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
match mode {
|
|
|
|
match mode {
|
|
|
|
Mode::Insert => {
|
|
|
|
Mode::Insert => {
|
|
|
|
// let completion swallow the event if necessary
|
|
|
|
// let completion swallow the event if necessary
|
|
|
@ -1417,8 +1437,8 @@ impl Component for EditorView {
|
|
|
|
|
|
|
|
|
|
|
|
self.on_next_key = cx.on_next_key_callback.take();
|
|
|
|
self.on_next_key = cx.on_next_key_callback.take();
|
|
|
|
match self.on_next_key {
|
|
|
|
match self.on_next_key {
|
|
|
|
Some(_) => self.pseudo_pending.push(key),
|
|
|
|
Some((_, OnKeyCallbackKind::PseudoPending)) => self.pseudo_pending.push(key),
|
|
|
|
None => self.pseudo_pending.clear(),
|
|
|
|
_ => self.pseudo_pending.clear(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// appease borrowck
|
|
|
|
// appease borrowck
|
|
|
|