Skip to content

Commit c9c1fbf

Browse files
committed
optimize formatting keybindings and memoize the result
1 parent bed9540 commit c9c1fbf

File tree

2 files changed

+53
-35
lines changed

2 files changed

+53
-35
lines changed

crates/mds-tui/src/keybindings.rs

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,71 +14,86 @@ use mds_keybindings::{KeyBindings, key_event_to_string};
1414

1515
use crate::util;
1616

17-
pub struct KeybindingsPopup<'km> {
18-
keymap: &'km KeyBindings,
17+
pub struct FormattedBindings {
18+
pub data: Vec<(String, Vec<String>)>,
19+
pub max_action_width: u16,
1920
}
2021

21-
impl<'km> KeybindingsPopup<'km> {
22-
pub fn new(keybindings: &'km KeyBindings) -> Self {
23-
Self {
24-
keymap: keybindings,
25-
}
26-
}
27-
28-
pub fn get_formatted_bindings(keybindings: &KeyBindings) -> Vec<(String, Vec<String>)> {
22+
impl FormattedBindings {
23+
pub fn from_keybindings(keybindings: &KeyBindings) -> Self {
2924
let mut grouped_bindings: HashMap<String, Vec<String>> = HashMap::new();
3025

3126
for bindings in keybindings.values() {
3227
for (key_event, action) in bindings {
3328
let action_name = action.to_string();
3429
let key_string = key_event_to_string(key_event);
35-
3630
grouped_bindings
3731
.entry(action_name)
3832
.or_default()
3933
.push(key_string);
4034
}
4135
}
4236

37+
let mut max_action_width: u16 = 10;
4338
let mut rows_data: Vec<(String, Vec<String>)> = grouped_bindings
4439
.into_iter()
4540
.map(|(action, mut keys)| {
46-
keys.sort();
41+
max_action_width = max_action_width.max(action.len() as u16);
42+
keys.sort_unstable();
4743
(action, keys)
4844
})
4945
.collect();
5046

51-
rows_data.sort_by(|(a, _), (b, _)| a.cmp(b));
52-
rows_data
47+
rows_data.sort_unstable_by(|(a, _), (b, _)| a.cmp(b));
48+
49+
Self {
50+
data: rows_data,
51+
max_action_width,
52+
}
53+
}
54+
}
55+
56+
pub struct KeybindingsPopup<'km> {
57+
keymap: &'km KeyBindings,
58+
formatted: Option<FormattedBindings>,
59+
}
60+
61+
impl<'km> KeybindingsPopup<'km> {
62+
pub fn new(keybindings: &'km KeyBindings) -> Self {
63+
Self {
64+
keymap: keybindings,
65+
formatted: None,
66+
}
5367
}
5468
}
5569

5670
impl<'a> StatefulWidget for KeybindingsPopup<'a> {
5771
type State = TableState;
5872

59-
fn render(self, area: Rect, buf: &mut ratatui::buffer::Buffer, state: &mut Self::State) {
60-
let data = Self::get_formatted_bindings(self.keymap);
61-
let total_items = data.len();
62-
let max_action_width = data.iter().map(|(a, _)| a.len()).max().unwrap_or(10) as u16;
73+
fn render(mut self, area: Rect, buf: &mut ratatui::buffer::Buffer, state: &mut Self::State) {
74+
let formatted = self
75+
.formatted
76+
.get_or_insert_with(|| FormattedBindings::from_keybindings(self.keymap));
6377

64-
let rows: Vec<Row> = data
65-
.into_iter()
66-
.map(|(action, keys)| {
67-
let mut key_spans = Vec::new();
68-
for (i, key) in keys.iter().enumerate() {
69-
if i > 0 {
70-
key_spans.push(Span::raw(", "));
71-
}
72-
key_spans.push(Span::styled(key.clone(), Style::default().fg(Color::Blue)));
78+
let total_items = formatted.data.len();
79+
let max_action_width = formatted.max_action_width;
80+
81+
let mut rows = Vec::with_capacity(total_items);
82+
for (action, keys) in &formatted.data {
83+
let mut key_spans = Vec::with_capacity(keys.len() * 2);
84+
85+
for (i, key) in keys.iter().enumerate() {
86+
if i > 0 {
87+
key_spans.push(Span::raw(", "));
7388
}
74-
let keys_line = Line::from(key_spans);
89+
key_spans.push(Span::styled(key.as_str(), Style::default().fg(Color::Blue)));
90+
}
7591

76-
Row::new(vec![
77-
Cell::from(Text::from(action).style(Style::default().fg(Color::Green))),
78-
Cell::from(keys_line),
79-
])
80-
})
81-
.collect();
92+
rows.push(Row::new(vec![
93+
Cell::from(Text::from(action.as_str()).style(Style::default().fg(Color::Green))),
94+
Cell::from(Line::from(key_spans)),
95+
]));
96+
}
8297

8398
let block = Block::default()
8499
.title(" Keybindings ")

docs/default_keymap.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,12 @@
4848
"<ctrl-c>" = "copy-to-clipboard"
4949
"<ctrl-shift-c>" = "copy-to-clipboard"
5050

51-
5251
# Other Actions
5352
"<ctrl-r>" = "refresh"
5453
"<ctrl-f>" = "search"
5554
"<shift-c>" = "config"
5655
"<ctrl-s>" = "save-config"
56+
57+
# Logging verbosity
58+
"<v>" = "increase-verbosity"
59+
"<g>" = "decrease-verbosity"

0 commit comments

Comments
 (0)