mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-25 02:46:17 +04:00
No need for KeymapResult anymore since we can query .sticky()
This commit is contained in:
parent
7909d6f05e
commit
a7ee9f74f7
@ -300,7 +300,7 @@ pub fn search(&self, keys: &[KeyEvent]) -> Option<&KeyTrie> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum KeymapResultKind {
|
pub enum KeymapResult {
|
||||||
/// Needs more keys to execute a command. Contains valid keys for next keystroke.
|
/// Needs more keys to execute a command. Contains valid keys for next keystroke.
|
||||||
Pending(KeyTrieNode),
|
Pending(KeyTrieNode),
|
||||||
Matched(MappableCommand),
|
Matched(MappableCommand),
|
||||||
@ -313,20 +313,6 @@ pub enum KeymapResultKind {
|
|||||||
Cancelled(Vec<KeyEvent>),
|
Cancelled(Vec<KeyEvent>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returned after looking up a key in [`Keymap`]. The `sticky` field has a
|
|
||||||
/// reference to the sticky node if one is currently active.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct KeymapResult<'a> {
|
|
||||||
pub kind: KeymapResultKind,
|
|
||||||
pub sticky: Option<&'a KeyTrieNode>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> KeymapResult<'a> {
|
|
||||||
pub fn new(kind: KeymapResultKind, sticky: Option<&'a KeyTrieNode>) -> Self {
|
|
||||||
Self { kind, sticky }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct Keymap {
|
pub struct Keymap {
|
||||||
@ -437,11 +423,8 @@ pub fn get(&mut self, mode: Mode, key: KeyEvent) -> KeymapResult {
|
|||||||
|
|
||||||
if key!(Esc) == key {
|
if key!(Esc) == key {
|
||||||
if !self.state.is_empty() {
|
if !self.state.is_empty() {
|
||||||
return KeymapResult::new(
|
|
||||||
// Note that Esc is not included here
|
// Note that Esc is not included here
|
||||||
KeymapResultKind::Cancelled(self.state.drain(..).collect()),
|
return KeymapResult::Cancelled(self.state.drain(..).collect());
|
||||||
self.sticky(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self.sticky = None;
|
self.sticky = None;
|
||||||
}
|
}
|
||||||
@ -454,15 +437,12 @@ pub fn get(&mut self, mode: Mode, key: KeyEvent) -> KeymapResult {
|
|||||||
|
|
||||||
let trie = match trie_node.search(&[*first]) {
|
let trie = match trie_node.search(&[*first]) {
|
||||||
Some(KeyTrie::Leaf(ref cmd)) => {
|
Some(KeyTrie::Leaf(ref cmd)) => {
|
||||||
return KeymapResult::new(KeymapResultKind::Matched(cmd.clone()), self.sticky())
|
return KeymapResult::Matched(cmd.clone());
|
||||||
}
|
}
|
||||||
Some(KeyTrie::Sequence(ref cmds)) => {
|
Some(KeyTrie::Sequence(ref cmds)) => {
|
||||||
return KeymapResult::new(
|
return KeymapResult::MatchedSequence(cmds.clone());
|
||||||
KeymapResultKind::MatchedSequence(cmds.clone()),
|
|
||||||
self.sticky(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
None => return KeymapResult::new(KeymapResultKind::NotFound, self.sticky()),
|
None => return KeymapResult::NotFound,
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -473,23 +453,17 @@ pub fn get(&mut self, mode: Mode, key: KeyEvent) -> KeymapResult {
|
|||||||
self.state.clear();
|
self.state.clear();
|
||||||
self.sticky = Some(map.clone());
|
self.sticky = Some(map.clone());
|
||||||
}
|
}
|
||||||
KeymapResult::new(KeymapResultKind::Pending(map.clone()), self.sticky())
|
KeymapResult::Pending(map.clone())
|
||||||
}
|
}
|
||||||
Some(&KeyTrie::Leaf(ref cmd)) => {
|
Some(&KeyTrie::Leaf(ref cmd)) => {
|
||||||
self.state.clear();
|
self.state.clear();
|
||||||
return KeymapResult::new(KeymapResultKind::Matched(cmd.clone()), self.sticky());
|
KeymapResult::Matched(cmd.clone())
|
||||||
}
|
}
|
||||||
Some(&KeyTrie::Sequence(ref cmds)) => {
|
Some(&KeyTrie::Sequence(ref cmds)) => {
|
||||||
self.state.clear();
|
self.state.clear();
|
||||||
KeymapResult::new(
|
KeymapResult::MatchedSequence(cmds.clone())
|
||||||
KeymapResultKind::MatchedSequence(cmds.clone()),
|
|
||||||
self.sticky(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
None => KeymapResult::new(
|
None => KeymapResult::Cancelled(self.state.drain(..).collect()),
|
||||||
KeymapResultKind::Cancelled(self.state.drain(..).collect()),
|
|
||||||
self.sticky(),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -901,19 +875,19 @@ fn merge_partial_keys() {
|
|||||||
|
|
||||||
let keymap = &mut merged_config.keys;
|
let keymap = &mut merged_config.keys;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
keymap.get(Mode::Normal, key!('i')).kind,
|
keymap.get(Mode::Normal, key!('i')),
|
||||||
KeymapResultKind::Matched(MappableCommand::normal_mode),
|
KeymapResult::Matched(MappableCommand::normal_mode),
|
||||||
"Leaf should replace leaf"
|
"Leaf should replace leaf"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
keymap.get(Mode::Normal, key!('无')).kind,
|
keymap.get(Mode::Normal, key!('无')),
|
||||||
KeymapResultKind::Matched(MappableCommand::insert_mode),
|
KeymapResult::Matched(MappableCommand::insert_mode),
|
||||||
"New leaf should be present in merged keymap"
|
"New leaf should be present in merged keymap"
|
||||||
);
|
);
|
||||||
// Assumes that z is a node in the default keymap
|
// Assumes that z is a node in the default keymap
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
keymap.get(Mode::Normal, key!('z')).kind,
|
keymap.get(Mode::Normal, key!('z')),
|
||||||
KeymapResultKind::Matched(MappableCommand::jump_backward),
|
KeymapResult::Matched(MappableCommand::jump_backward),
|
||||||
"Leaf should replace node"
|
"Leaf should replace node"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
commands,
|
commands,
|
||||||
compositor::{Component, Context, EventResult},
|
compositor::{Component, Context, EventResult},
|
||||||
key,
|
key,
|
||||||
keymap::{KeymapResult, KeymapResultKind, Keymaps},
|
keymap::{KeymapResult, Keymaps},
|
||||||
ui::{Completion, ProgressSpinners},
|
ui::{Completion, ProgressSpinners},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -694,7 +694,7 @@ pub fn render_statusline(
|
|||||||
|
|
||||||
/// Handle events by looking them up in `self.keymaps`. Returns None
|
/// Handle events by looking them up in `self.keymaps`. Returns None
|
||||||
/// if event was handled (a command was executed or a subkeymap was
|
/// if event was handled (a command was executed or a subkeymap was
|
||||||
/// activated). Only KeymapResultKind::{NotFound, Cancelled} is returned
|
/// activated). Only KeymapResult::{NotFound, Cancelled} is returned
|
||||||
/// otherwise.
|
/// otherwise.
|
||||||
fn handle_keymap_event(
|
fn handle_keymap_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -704,36 +704,36 @@ fn handle_keymap_event(
|
|||||||
) -> Option<KeymapResult> {
|
) -> Option<KeymapResult> {
|
||||||
cxt.editor.autoinfo = None;
|
cxt.editor.autoinfo = None;
|
||||||
let key_result = self.keymaps.get(mode, event);
|
let key_result = self.keymaps.get(mode, event);
|
||||||
cxt.editor.autoinfo = key_result.sticky.map(|node| node.infobox());
|
cxt.editor.autoinfo = self.keymaps.sticky().map(|node| node.infobox());
|
||||||
|
|
||||||
match &key_result.kind {
|
match &key_result {
|
||||||
KeymapResultKind::Matched(command) => command.execute(cxt),
|
KeymapResult::Matched(command) => command.execute(cxt),
|
||||||
KeymapResultKind::Pending(node) => cxt.editor.autoinfo = Some(node.infobox()),
|
KeymapResult::Pending(node) => cxt.editor.autoinfo = Some(node.infobox()),
|
||||||
KeymapResultKind::MatchedSequence(commands) => {
|
KeymapResult::MatchedSequence(commands) => {
|
||||||
for command in commands {
|
for command in commands {
|
||||||
command.execute(cxt);
|
command.execute(cxt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KeymapResultKind::NotFound | KeymapResultKind::Cancelled(_) => return Some(key_result),
|
KeymapResult::NotFound | KeymapResult::Cancelled(_) => return Some(key_result),
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_mode(&mut self, cx: &mut commands::Context, event: KeyEvent) {
|
fn insert_mode(&mut self, cx: &mut commands::Context, event: KeyEvent) {
|
||||||
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.kind {
|
match keyresult {
|
||||||
KeymapResultKind::NotFound => {
|
KeymapResult::NotFound => {
|
||||||
if let Some(ch) = event.char() {
|
if let Some(ch) = event.char() {
|
||||||
commands::insert::insert_char(cx, ch)
|
commands::insert::insert_char(cx, ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KeymapResultKind::Cancelled(pending) => {
|
KeymapResult::Cancelled(pending) => {
|
||||||
for ev in pending {
|
for ev in pending {
|
||||||
match ev.char() {
|
match ev.char() {
|
||||||
Some(ch) => commands::insert::insert_char(cx, ch),
|
Some(ch) => commands::insert::insert_char(cx, ch),
|
||||||
None => {
|
None => {
|
||||||
if let KeymapResultKind::Matched(command) =
|
if let KeymapResult::Matched(command) =
|
||||||
self.keymaps.get(Mode::Insert, ev).kind
|
self.keymaps.get(Mode::Insert, ev)
|
||||||
{
|
{
|
||||||
command.execute(cx);
|
command.execute(cx);
|
||||||
}
|
}
|
||||||
@ -1182,8 +1182,8 @@ fn handle_event(
|
|||||||
// how we entered insert mode is important, and we should track that so
|
// how we entered insert mode is important, and we should track that so
|
||||||
// we can repeat the side effect.
|
// we can repeat the side effect.
|
||||||
|
|
||||||
self.last_insert.0 = match self.keymaps.get(mode, key).kind {
|
self.last_insert.0 = match self.keymaps.get(mode, key) {
|
||||||
KeymapResultKind::Matched(command) => command,
|
KeymapResult::Matched(command) => command,
|
||||||
// FIXME: insert mode can only be entered through single KeyCodes
|
// FIXME: insert mode can only be entered through single KeyCodes
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user