use {
reovim_driver_input::{
ExtensionMap, KeyCode, KeyEvent, KeyLookupState, KeySequence, ModeKeyResolver, ModeState,
Modifiers, ResolveContext, ResolveInput, ResolveResult,
},
reovim_kernel::api::v1::ModeId,
};
use crate::{VimSessionState, modes::VimMode};
pub struct VimInsertResolver {
mode_id: ModeId,
}
impl VimInsertResolver {
#[must_use]
pub const fn new() -> Self {
Self {
mode_id: VimMode::INSERT_ID,
}
}
const fn is_insertable(key: &KeyEvent) -> Option<char> {
if key.modifiers.contains(Modifiers::CTRL) || key.modifiers.contains(Modifiers::ALT) {
return None;
}
match key.code {
KeyCode::Char(c) => Some(c),
KeyCode::Tab => Some('\t'),
KeyCode::Enter => Some('\n'),
_ => None,
}
}
}
impl Default for VimInsertResolver {
fn default() -> Self {
Self::new()
}
}
impl ModeKeyResolver for VimInsertResolver {
#[cfg_attr(coverage_nightly, coverage(off))]
fn resolve_with_keymap(
&self,
key: &KeyEvent,
_state: &mut ModeState,
input: &ResolveInput<'_>,
) -> ResolveResult {
if let Some(c) = Self::is_insertable(key) {
return ResolveResult::insert_char(c);
}
let keys = KeySequence::from_keys(&[*key]);
let lookup_state = input.keymap.query(input.mode, &keys);
match lookup_state {
KeyLookupState::ExactOnly(cmd) | KeyLookupState::ExactWithLonger { exact: cmd, .. } => {
ResolveResult::Execute(cmd, ResolveContext::new())
}
KeyLookupState::PrefixOnly => {
ResolveResult::Pending
}
KeyLookupState::NotFound => {
ResolveResult::NotHandled
}
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
fn resolve_with_extensions(
&self,
key: &KeyEvent,
state: &mut ModeState,
input: &ResolveInput<'_>,
_shared_extensions: &mut ExtensionMap,
client_extensions: &mut ExtensionMap,
) -> ResolveResult {
if let Some(vim) = client_extensions.get_mut::<VimSessionState>() {
vim.record_repeat_key(*key);
}
if let Some(c) = Self::is_insertable(key) {
if let Some(vim) = client_extensions.get_mut::<VimSessionState>() {
vim.insert_buffer.push(c);
}
return ResolveResult::insert_char(c);
}
self.resolve_with_keymap(key, state, input)
}
fn mode_id(&self) -> &ModeId {
&self.mode_id
}
fn inherits_from(&self) -> Option<&ModeId> {
None
}
fn reset(&mut self) {
}
}