From adb12ad4a7e64526581ffe2cd4672448654d7468 Mon Sep 17 00:00:00 2001 From: mWalrus Date: Wed, 22 Mar 2023 15:38:34 +0100 Subject: [PATCH 1/5] Truncate paths in the file picker --- helix-term/src/ui/menu.rs | 1 + helix-term/src/ui/picker.rs | 1 + helix-tui/src/buffer.rs | 25 +++++++++++++++++++++ helix-tui/src/widgets/table.rs | 41 ++++++++++++++++++++++++---------- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index 30625acee60c..bdad2e408392 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -347,6 +347,7 @@ impl Component for Menu { offset: scroll, selected: self.cursor, }, + false, ); if let Some(cursor) = self.cursor { diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 3294a2a1d23a..e73088e528fa 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -885,6 +885,7 @@ impl Component for Picker { offset: 0, selected: Some(cursor), }, + self.truncate_start, ); } diff --git a/helix-tui/src/buffer.rs b/helix-tui/src/buffer.rs index b1fd44787f78..2c212b125c3a 100644 --- a/helix-tui/src/buffer.rs +++ b/helix-tui/src/buffer.rs @@ -433,6 +433,31 @@ impl Buffer { (x_offset as u16, y) } + pub fn set_spans_truncated(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) { + let mut remaining_width = width; + let mut alt_x = x; + let (text, styles) = + spans + .0 + .iter() + .fold((String::new(), vec![]), |(mut s, mut h), span| { + s.push_str(span.content.as_ref()); + let mut styles = span + .styled_graphemes(span.style) + .map(|grapheme| grapheme.style) + .collect(); + h.append(&mut styles); + + let w = span.width() as u16; + alt_x = alt_x + w; + remaining_width = remaining_width.saturating_sub(w); + + (s, h) + }); + self.set_string_truncated(x, y, &text, width.into(), |idx| styles[idx], true, true); + (x, y) + } + pub fn set_spans(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) { let mut remaining_width = width; let mut x = x; diff --git a/helix-tui/src/widgets/table.rs b/helix-tui/src/widgets/table.rs index 400f65e0ad98..164d9146300f 100644 --- a/helix-tui/src/widgets/table.rs +++ b/helix-tui/src/widgets/table.rs @@ -354,7 +354,13 @@ impl TableState { impl<'a> Table<'a> { // type State = TableState; - pub fn render_table(mut self, area: Rect, buf: &mut Buffer, state: &mut TableState) { + pub fn render_table( + mut self, + area: Rect, + buf: &mut Buffer, + state: &mut TableState, + truncate_rows: bool, + ) { if area.area() == 0 { return; } @@ -448,22 +454,33 @@ impl<'a> Table<'a> { if is_selected { buf.set_style(table_row_area, self.highlight_style); } - render_cell( - buf, - cell, - Rect { - x: col, - y: row, - width: *width, - height: table_row.height, - }, - ); + let rect = Rect { + x: col, + y: row, + width: *width, + height: table_row.height, + }; + if truncate_rows { + render_cell_truncated(buf, cell, rect); + } else { + render_cell(buf, cell, rect); + } col += *width + self.column_spacing; } } } } +fn render_cell_truncated(buf: &mut Buffer, cell: &Cell, area: Rect) { + buf.set_style(area, cell.style); + for (i, spans) in cell.content.lines.iter().enumerate() { + if i as u16 >= area.height { + break; + } + buf.set_spans_truncated(area.x, area.y + i as u16, spans, area.width); + } +} + fn render_cell(buf: &mut Buffer, cell: &Cell, area: Rect) { buf.set_style(area, cell.style); for (i, spans) in cell.content.lines.iter().enumerate() { @@ -477,7 +494,7 @@ fn render_cell(buf: &mut Buffer, cell: &Cell, area: Rect) { impl<'a> Widget for Table<'a> { fn render(self, area: Rect, buf: &mut Buffer) { let mut state = TableState::default(); - Table::render_table(self, area, buf, &mut state); + Table::render_table(self, area, buf, &mut state, false); } } From 772fd461929d9fe8e9c8139e9a1f7432a1ab3623 Mon Sep 17 00:00:00 2001 From: mWalrus Date: Wed, 22 Mar 2023 18:35:52 +0100 Subject: [PATCH 2/5] Skip truncation of single character cells in `Table` Here we assume that spans with content that is 1 in length will not need to be truncated. This solves an issue with my previous commit that made the buffer picker truncate the "prefix" cells. --- helix-tui/src/buffer.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/helix-tui/src/buffer.rs b/helix-tui/src/buffer.rs index 2c212b125c3a..27fa3f2ab5ad 100644 --- a/helix-tui/src/buffer.rs +++ b/helix-tui/src/buffer.rs @@ -434,6 +434,20 @@ impl Buffer { } pub fn set_spans_truncated(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) { + // if the spans contains only 1 span and the + // content length of that span is 1, we can + // assume that we dont need to truncate the + // string. + if spans.0.len() == 1 { + match spans.0.first() { + Some(s) if s.content.len() == 1 => { + return self.set_stringn(x, y, s.content.as_ref(), width as usize, s.style) + } + // if we pass the above checks, we continue as normal + _ => {} + } + } + let mut remaining_width = width; let mut alt_x = x; let (text, styles) = From 978e1a4e59b7b6bcd1215c774bcb5c47992051a8 Mon Sep 17 00:00:00 2001 From: mWalrus Date: Wed, 22 Mar 2023 19:17:39 +0100 Subject: [PATCH 3/5] Move truncate check into `render_cell` This removes the need for `render_cell_truncated`. We now check if we should truncate in `render_cell` which allows us to skip the additional checks in `Buffer::set_spans_truncated`. --- helix-tui/src/buffer.rs | 14 -------------- helix-tui/src/widgets/table.rs | 25 ++++++++----------------- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/helix-tui/src/buffer.rs b/helix-tui/src/buffer.rs index 27fa3f2ab5ad..2c212b125c3a 100644 --- a/helix-tui/src/buffer.rs +++ b/helix-tui/src/buffer.rs @@ -434,20 +434,6 @@ impl Buffer { } pub fn set_spans_truncated(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) { - // if the spans contains only 1 span and the - // content length of that span is 1, we can - // assume that we dont need to truncate the - // string. - if spans.0.len() == 1 { - match spans.0.first() { - Some(s) if s.content.len() == 1 => { - return self.set_stringn(x, y, s.content.as_ref(), width as usize, s.style) - } - // if we pass the above checks, we continue as normal - _ => {} - } - } - let mut remaining_width = width; let mut alt_x = x; let (text, styles) = diff --git a/helix-tui/src/widgets/table.rs b/helix-tui/src/widgets/table.rs index 164d9146300f..82504915f561 100644 --- a/helix-tui/src/widgets/table.rs +++ b/helix-tui/src/widgets/table.rs @@ -359,7 +359,7 @@ impl<'a> Table<'a> { area: Rect, buf: &mut Buffer, state: &mut TableState, - truncate_rows: bool, + truncate: bool, ) { if area.area() == 0 { return; @@ -407,6 +407,7 @@ impl<'a> Table<'a> { width: *width, height: max_header_height, }, + false, ); col += *width + self.column_spacing; } @@ -460,34 +461,24 @@ impl<'a> Table<'a> { width: *width, height: table_row.height, }; - if truncate_rows { - render_cell_truncated(buf, cell, rect); - } else { - render_cell(buf, cell, rect); - } + render_cell(buf, cell, rect, truncate); col += *width + self.column_spacing; } } } } -fn render_cell_truncated(buf: &mut Buffer, cell: &Cell, area: Rect) { +fn render_cell(buf: &mut Buffer, cell: &Cell, area: Rect, truncate: bool) { buf.set_style(area, cell.style); for (i, spans) in cell.content.lines.iter().enumerate() { if i as u16 >= area.height { break; } - buf.set_spans_truncated(area.x, area.y + i as u16, spans, area.width); - } -} - -fn render_cell(buf: &mut Buffer, cell: &Cell, area: Rect) { - buf.set_style(area, cell.style); - for (i, spans) in cell.content.lines.iter().enumerate() { - if i as u16 >= area.height { - break; + if cell.content.width() > 1 && truncate { + buf.set_spans_truncated(area.x, area.y + i as u16, spans, area.width); + } else { + buf.set_spans(area.x, area.y + i as u16, spans, area.width); } - buf.set_spans(area.x, area.y + i as u16, spans, area.width); } } From b23024ac43c3cccc305ab5701179100069acead6 Mon Sep 17 00:00:00 2001 From: mWalrus Date: Wed, 22 Mar 2023 19:21:21 +0100 Subject: [PATCH 4/5] Move `Rect` definition into call to `render_cell` --- helix-tui/src/widgets/table.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/helix-tui/src/widgets/table.rs b/helix-tui/src/widgets/table.rs index 82504915f561..11ee165a18ac 100644 --- a/helix-tui/src/widgets/table.rs +++ b/helix-tui/src/widgets/table.rs @@ -455,13 +455,17 @@ impl<'a> Table<'a> { if is_selected { buf.set_style(table_row_area, self.highlight_style); } - let rect = Rect { - x: col, - y: row, - width: *width, - height: table_row.height, - }; - render_cell(buf, cell, rect, truncate); + render_cell( + buf, + cell, + Rect { + x: col, + y: row, + width: *width, + height: table_row.height, + }, + truncate, + ); col += *width + self.column_spacing; } } From 49924298a705fee76d5bdd2198d9737caacf201c Mon Sep 17 00:00:00 2001 From: mWalrus Date: Wed, 22 Mar 2023 21:22:47 +0100 Subject: [PATCH 5/5] Simplify `Buffer::set_spans_truncated` --- helix-tui/src/buffer.rs | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/helix-tui/src/buffer.rs b/helix-tui/src/buffer.rs index 2c212b125c3a..a4fd6beed131 100644 --- a/helix-tui/src/buffer.rs +++ b/helix-tui/src/buffer.rs @@ -434,28 +434,16 @@ impl Buffer { } pub fn set_spans_truncated(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) { - let mut remaining_width = width; - let mut alt_x = x; - let (text, styles) = - spans - .0 - .iter() - .fold((String::new(), vec![]), |(mut s, mut h), span| { - s.push_str(span.content.as_ref()); - let mut styles = span - .styled_graphemes(span.style) - .map(|grapheme| grapheme.style) - .collect(); - h.append(&mut styles); - - let w = span.width() as u16; - alt_x = alt_x + w; - remaining_width = remaining_width.saturating_sub(w); - - (s, h) - }); - self.set_string_truncated(x, y, &text, width.into(), |idx| styles[idx], true, true); - (x, y) + let mut text = String::new(); + let mut styles = vec![]; + + for span in &spans.0 { + text.push_str(span.content.as_ref()); + span.styled_graphemes(span.style) + .for_each(|grapheme| styles.push(grapheme.style)); + } + + self.set_string_truncated(x, y, &text, width.into(), |idx| styles[idx], true, true) } pub fn set_spans(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) {