aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/ui
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-07-19 02:28:29 +0000
committerBlaž Hrastnik2021-07-19 02:29:51 +0000
commit5292fe0f7df9f1a420744007aa9dd67e7a5a6610 (patch)
tree1a7c6d7268a623163eb74e81079ae8d7fa92c20c /helix-term/src/ui
parentbf43fabf65fe4062f582e59fe21e92a0b0f48cb8 (diff)
Calculate completion popup sizing
Fixes #220
Diffstat (limited to 'helix-term/src/ui')
-rw-r--r--helix-term/src/ui/menu.rs34
1 files changed, 31 insertions, 3 deletions
diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs
index 226c1135..8681e5b1 100644
--- a/helix-term/src/ui/menu.rs
+++ b/helix-term/src/ui/menu.rs
@@ -8,6 +8,7 @@ use fuzzy_matcher::skim::SkimMatcherV2 as Matcher;
use fuzzy_matcher::FuzzyMatcher;
use helix_view::{graphics::Rect, Editor};
+use tui::layout::Constraint;
pub trait Item {
// TODO: sort_text
@@ -26,6 +27,8 @@ pub struct Menu<T: Item> {
/// (index, score)
matches: Vec<(usize, i64)>,
+ widths: Vec<Constraint>,
+
callback_fn: Box<dyn Fn(&mut Editor, Option<&T>, MenuEvent)>,
scroll: usize,
@@ -44,6 +47,7 @@ impl<T: Item> Menu<T> {
matcher: Box::new(Matcher::default()),
matches: Vec::new(),
cursor: None,
+ widths: Vec::new(),
callback_fn: Box::new(callback_fn),
scroll: 0,
size: (0, 0),
@@ -218,8 +222,33 @@ impl<T: Item + 'static> Component for Menu<T> {
EventResult::Ignored
}
+ // TODO: completion sorting
+
fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> {
- let width = std::cmp::min(30, viewport.0);
+ let n = self
+ .options
+ .first()
+ .map(|option| option.row().cells.len())
+ .unwrap_or_default();
+ let max_lens = self.options.iter().fold(vec![0; n], |mut acc, option| {
+ let row = option.row();
+ // maintain max for each column
+ for (i, cell) in row.cells.iter().enumerate() {
+ let width = cell.content.width();
+ if width > acc[i] {
+ acc[i] = width;
+ }
+ }
+
+ acc
+ });
+ let len = (max_lens.iter().sum::<usize>()) + n + 1; // +1: reserve some space for scrollbar
+ let width = len.min(viewport.0 as usize);
+
+ self.widths = max_lens
+ .into_iter()
+ .map(|len| Constraint::Length(len as u16))
+ .collect();
const MAX: usize = 10;
let height = std::cmp::min(self.options.len(), MAX);
@@ -263,13 +292,12 @@ impl<T: Item + 'static> Component for Menu<T> {
let scroll_line = (win_height - scroll_height) * scroll
/ std::cmp::max(1, len.saturating_sub(win_height));
- use tui::layout::Constraint;
let rows = options.iter().map(|option| option.row());
let table = Table::new(rows)
.style(style)
.highlight_style(selected)
.column_spacing(1)
- .widths(&[Constraint::Percentage(50), Constraint::Percentage(50)]);
+ .widths(&self.widths);
use tui::widgets::TableState;