on master help sign in
Refactor infobox rendering and parsing (#579)
commit14c08e855f6d0ebfbf1d7cb5d7010507ad3a5db6 authorGokul Soumya <gokulps15@gmail.com> dateTue 17 Aug 2021, 05:55 (5 years ago) parent2761615
3 files changed+35−47
helix-term/src/keymap.rs+1−1 helix-term/src/ui/info.rs+12−12 helix-view/src/info.rs+22−34
helix-term/src/keymap.rs+1−1
@@ -145,7 +145,7 @@ impl From<KeyTrieNode> for Info {
145145 .map(|(desc, keys)| (desc.strip_prefix(&prefix).unwrap(), keys))
146146 .collect();
147147 }
148− Info::key(node.name(), body)
148+ Info::new(node.name(), body)
149149 }
150150}
151151
helix-term/src/ui/info.rs+12−12
@@ -1,8 +1,8 @@
11use crate::compositor::{Component, Context};
2−use helix_view::graphics::Rect;
2+use helix_view::graphics::{Margin, Rect};
33use helix_view::info::Info;
44use tui::buffer::Buffer as Surface;
5−use tui::widgets::{Block, Borders, Widget};
5+use tui::widgets::{Block, Borders, Paragraph, Widget};
66
77impl Component for Info {
88 fn render(&mut self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
@@ -11,10 +11,11 @@ impl Component for Info {
1111 // Calculate the area of the terminal to modify. Because we want to
1212 // render at the bottom right, we use the viewport's width and height
1313 // which evaluate to the most bottom right coordinate.
14− let (width, height) = (self.width + 2, self.height + 2);
14+ let width = self.width + 2 + 2; // +2 for border, +2 for margin
15+ let height = self.height + 2; // +2 for border
1516 let area = viewport.intersection(Rect::new(
1617 viewport.width.saturating_sub(width),
17− viewport.height.saturating_sub(height + 2),
18+ viewport.height.saturating_sub(height + 2), // +2 for statusline
1819 width,
1920 height,
2021 ));
@@ -24,15 +25,14 @@ impl Component for Info {
2425 .title(self.title.as_str())
2526 .borders(Borders::ALL)
2627 .border_style(style);
27− let inner = block.inner(area);
28+
29+ let margin = Margin {
30+ vertical: 0,
31+ horizontal: 1,
32+ };
33+ let inner = block.inner(area).inner(&margin);
2834 block.render(area, surface);
2935
30− // Only write as many lines as there are rows available.
31− for (y, line) in (inner.y..)
32− .zip(self.text.lines())
33− .take(inner.height as usize)
34− {
35− surface.set_string(inner.x, y, line, style);
36− }
36+ Paragraph::new(self.text.as_str()).render(inner, surface);
3737 }
3838}
helix-view/src/info.rs+22−34
@@ -16,45 +16,33 @@ pub struct Info {
1616}
1717
1818impl Info {
19− // body is a BTreeMap instead of a HashMap because keymaps are represented
20− // with nested hashmaps with no ordering, and each invocation of infobox would
21− // show different orders of items
22− pub fn key(title: &str, body: Vec<(&str, Vec<KeyEvent>)>) -> Info {
23− let (lpad, mpad, rpad) = (1, 2, 1);
24− let keymaps_width: u16 = body
25− .iter()
26− .map(|r| r.1.iter().map(|e| e.width() as u16 + 2).sum::<u16>() - 2)
27− .max()
28− .unwrap();
19+ pub fn new(title: &str, body: Vec<(&str, Vec<KeyEvent>)>) -> Info {
20+ let body = body
21+ .into_iter()
22+ .map(|(desc, events)| {
23+ let events = events.iter().map(ToString::to_string).collect::<Vec<_>>();
24+ (desc, events.join(", "))
25+ })
26+ .collect::<Vec<_>>();
27+
28+ let keymaps_width = body.iter().map(|r| r.1.len()).max().unwrap();
2929 let mut text = String::new();
30− let mut width = 0;
31− let height = body.len() as u16;
32− for (desc, keyevents) in body {
33− let keyevent = keyevents[0];
34− let mut left = keymaps_width - keyevent.width() as u16;
35− for _ in 0..lpad {
36− text.push(' ');
37− }
38− write!(text, "{}", keyevent).ok();
39− for keyevent in &keyevents[1..] {
40− write!(text, ", {}", keyevent).ok();
41− left -= 2 + keyevent.width() as u16;
42− }
43− for _ in 0..left + mpad {
44− text.push(' ');
45− }
46− let desc = desc.trim();
47− let w = lpad + keymaps_width + mpad + (desc.width() as u16) + rpad;
48− if w > width {
49− width = w;
50− }
51− writeln!(text, "{}", desc).ok();
30+
31+ for (desc, keyevents) in &body {
32+ let _ = writeln!(
33+ text,
34+ "{:width$} {}",
35+ keyevents,
36+ desc,
37+ width = keymaps_width
38+ );
5239 }
40+
5341 Info {
5442 title: title.to_string(),
43+ width: text.lines().map(|l| l.width()).max().unwrap() as u16,
44+ height: body.len() as u16,
5545 text,
56− width,
57− height,
5846 }
5947 }
6048}