Skip to content

Commit

Permalink
refactor(term): avoid rendering during key event handling if possible
Browse files Browse the repository at this point in the history
  • Loading branch information
ymgyt committed May 30, 2024
1 parent bd428f1 commit db42f5c
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 17 deletions.
15 changes: 10 additions & 5 deletions crates/synd_term/src/application/event/key_handlers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{cell::RefCell, rc::Rc};
use std::{cell::RefCell, ops::ControlFlow, rc::Rc};

use crossterm::event::KeyEvent;

Expand Down Expand Up @@ -49,11 +49,16 @@ impl KeyHandlers {
}

pub fn handle(&mut self, event: KeyEvent) -> KeyEventResult {
for handler in self.handlers.iter_mut().rev() {
if let KeyEventResult::Consumed(r) = handler.handle(&event) {
return KeyEventResult::Consumed(r);
match self.handlers.iter_mut().rev().try_for_each(|h| {
let result = h.handle(&event);
if result.is_consumed() {
ControlFlow::Break(result)
} else {
ControlFlow::Continue(())
}
}) {
ControlFlow::Break(consumed) => consumed,
ControlFlow::Continue(()) => KeyEventResult::Ignored,
}
KeyEventResult::Ignored
}
}
28 changes: 27 additions & 1 deletion crates/synd_term/src/application/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@ mod key_handlers;
pub use key_handlers::{KeyHandler, KeyHandlers};

pub(crate) enum KeyEventResult {
Consumed(Option<Command>),
Consumed {
command: Option<Command>,
should_render: bool,
},
Ignored,
}

impl KeyEventResult {
pub(super) fn is_consumed(&self) -> bool {
matches!(self, KeyEventResult::Consumed { .. })
}

pub(crate) fn consumed(command: Command) -> Self {
KeyEventResult::Consumed {
command: Some(command),
should_render: false,
}
}

pub(crate) fn should_render(self, should_render: bool) -> Self {
match self {
KeyEventResult::Consumed { command, .. } => KeyEventResult::Consumed {
command,
should_render,
},
KeyEventResult::Ignored => KeyEventResult::Ignored,
}
}
}
9 changes: 6 additions & 3 deletions crates/synd_term/src/application/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,9 +619,12 @@ impl Application {
self.reset_idle_timer();

match self.key_handlers.handle(key) {
KeyEventResult::Consumed(cmd) => {
self.should_render();
cmd
KeyEventResult::Consumed {
command,
should_render,
} => {
should_render.then(|| self.should_render());
command
}
KeyEventResult::Ignored => None,
}
Expand Down
20 changes: 14 additions & 6 deletions crates/synd_term/src/keymap/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::{collections::HashMap, ops::ControlFlow};

use anyhow::{anyhow, bail};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
Expand Down Expand Up @@ -129,12 +129,20 @@ impl Keymaps {
}

pub fn search(&mut self, event: &KeyEvent) -> KeyEventResult {
for keymap in self.keymaps.iter_mut().rev().filter(|k| k.enable) {
if let Some(cmd) = keymap.search(event) {
return KeyEventResult::Consumed(Some(cmd));
}
match self
.keymaps
.iter_mut()
.rev()
.filter(|k| k.enable)
.try_for_each(|keymap| match keymap.search(event) {
Some(command) => {
ControlFlow::Break(KeyEventResult::consumed(command).should_render(true))
}
None => ControlFlow::Continue(()),
}) {
ControlFlow::Break(r) => r,
ControlFlow::Continue(()) => KeyEventResult::Ignored,
}
KeyEventResult::Ignored
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/synd_term/src/ui/widgets/prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ impl Prompt {
let pos = self.move_cursor(Move::BackwardChar(1));
self.line.replace_range(pos..self.cursor, "");
self.cursor = pos;
KeyEventResult::Consumed(Some(Command::PromptChanged))
KeyEventResult::consumed(Command::PromptChanged).should_render(true)
}
KeyEvent {
code: KeyCode::Char(c),
..
} => {
self.insert_char(*c);
KeyEventResult::Consumed(Some(Command::PromptChanged))
KeyEventResult::consumed(Command::PromptChanged).should_render(true)
}
_ => KeyEventResult::Ignored,
}
Expand Down

0 comments on commit db42f5c

Please sign in to comment.