on master help sign in
DynamicPicker: Recalculate column widths for new options (#6004)
0c6d25aMichael Davis
helix-term/src/ui/picker.rs+37−25
@@ -435,26 +435,6 @@ impl<T: Item> Picker<T> {
435 |_editor: &mut Context, _pattern: &str, _event: PromptEvent| {},
435 |_editor: &mut Context, _pattern: &str, _event: PromptEvent| {},
436 );
436 );
437
437
438− let n = options
439− .first()
440− .map(|option| option.format(&editor_data).cells.len())
441− .unwrap_or_default();
442− let max_lens = options.iter().fold(vec![0; n], |mut acc, option| {
443− let row = option.format(&editor_data);
444− // maintain max for each column
445− for (acc, cell) in acc.iter_mut().zip(row.cells.iter()) {
446− let width = cell.content.width();
447− if width > *acc {
448− *acc = width;
449− }
450− }
451− acc
452− });
453− let widths = max_lens
454− .into_iter()
455− .map(|len| Constraint::Length(len as u16))
456− .collect();
457−
458 let mut picker = Self {
438 let mut picker = Self {
459 options,
439 options,
460 editor_data,
440 editor_data,
@@ -467,10 +447,12 @@ impl<T: Item> Picker<T> {
467 show_preview: true,
447 show_preview: true,
468 callback_fn: Box::new(callback_fn),
448 callback_fn: Box::new(callback_fn),
469 completion_height: 0,
449 completion_height: 0,
470− widths,
450+ widths: Vec::new(),
471 };
451 };
472
452
453+ picker.calculate_column_widths();
454+
473− // scoring on empty input:
455+ // scoring on empty input
474 // TODO: just reuse score()
456 // TODO: just reuse score()
475 picker
457 picker
476 .matches
458 .matches
@@ -486,6 +468,38 @@ impl<T: Item> Picker<T> {
486 picker
468 picker
487 }
469 }
488
470
471+ pub fn set_options(&mut self, new_options: Vec<T>) {
472+ self.options = new_options;
473+ self.cursor = 0;
474+ self.force_score();
475+ self.calculate_column_widths();
476+ }
477+
478+ /// Calculate the width constraints using the maximum widths of each column
479+ /// for the current options.
480+ fn calculate_column_widths(&mut self) {
481+ let n = self
482+ .options
483+ .first()
484+ .map(|option| option.format(&self.editor_data).cells.len())
485+ .unwrap_or_default();
486+ let max_lens = self.options.iter().fold(vec![0; n], |mut acc, option| {
487+ let row = option.format(&self.editor_data);
488+ // maintain max for each column
489+ for (acc, cell) in acc.iter_mut().zip(row.cells.iter()) {
490+ let width = cell.content.width();
491+ if width > *acc {
492+ *acc = width;
493+ }
494+ }
495+ acc
496+ });
497+ self.widths = max_lens
498+ .into_iter()
499+ .map(|len| Constraint::Length(len as u16))
500+ .collect();
501+ }
502+
489 pub fn score(&mut self) {
503 pub fn score(&mut self) {
490 let pattern = self.prompt.line();
504 let pattern = self.prompt.line();
491
505
@@ -931,9 +945,7 @@ impl<T: Item + Send + 'static> Component for DynamicPicker<T> {
931 Some(overlay) => &mut overlay.content.file_picker.picker,
945 Some(overlay) => &mut overlay.content.file_picker.picker,
932 None => return,
946 None => return,
933 };
947 };
934− picker.options = new_options;
948+ picker.set_options(new_options);
935− picker.cursor = 0;
936− picker.force_score();
937 editor.reset_idle_timer();
949 editor.reset_idle_timer();
938 }));
950 }));
939 anyhow::Ok(callback)
951 anyhow::Ok(callback)