on master help sign in
Truncate the starts of file paths instead of the ends in picker (#951)
5b5d1b9Omnikar
helix-term/src/ui/picker.rs+1
@@ -483,6 +483,7 @@ impl<T: 'static> Component for Picker<T> {
483 text_style
483 text_style
484 },
484 },
485 true,
485 true,
486+ true,
486 );
487 );
487 }
488 }
488 }
489 }
helix-tui/src/buffer.rs+56−22
@@ -266,12 +266,14 @@ impl Buffer {
266 where
266 where
267 S: AsRef<str>,
267 S: AsRef<str>,
268 {
268 {
269− self.set_string_truncated(x, y, string, width, style, false)
269+ self.set_string_truncated(x, y, string, width, style, false, false)
270 }
270 }
271
271
272 /// Print at most the first `width` characters of a string if enough space is available
272 /// Print at most the first `width` characters of a string if enough space is available
273− /// until the end of the line. If `markend` is true appends a `…` at the end of
273+ /// until the end of the line. If `ellipsis` is true appends a `…` at the end of
274− /// truncated lines.
274+ /// truncated lines. If `truncate_start` is `true`, truncate the beginning of the string
275+ /// instead of the end.
276+ #[allow(clippy::too_many_arguments)]
275 pub fn set_string_truncated<S>(
277 pub fn set_string_truncated<S>(
276 &mut self,
278 &mut self,
277 x: u16,
279 x: u16,
@@ -280,6 +282,7 @@ impl Buffer {
280 width: usize,
282 width: usize,
281 style: Style,
283 style: Style,
282 ellipsis: bool,
284 ellipsis: bool,
285+ truncate_start: bool,
283 ) -> (u16, u16)
286 ) -> (u16, u16)
284 where
287 where
285 S: AsRef<str>,
288 S: AsRef<str>,
@@ -289,28 +292,59 @@ impl Buffer {
289 let width = if ellipsis { width - 1 } else { width };
292 let width = if ellipsis { width - 1 } else { width };
290 let graphemes = UnicodeSegmentation::graphemes(string.as_ref(), true);
293 let graphemes = UnicodeSegmentation::graphemes(string.as_ref(), true);
291 let max_offset = min(self.area.right() as usize, width.saturating_add(x as usize));
294 let max_offset = min(self.area.right() as usize, width.saturating_add(x as usize));
295+ if !truncate_start {
292− for s in graphemes {
296+ for s in graphemes {
293− let width = s.width();
297+ let width = s.width();
294− if width == 0 {
298+ if width == 0 {
295− continue;
299+ continue;
300+ }
301+ // `x_offset + width > max_offset` could be integer overflow on 32-bit machines if we
302+ // change dimenstions to usize or u32 and someone resizes the terminal to 1x2^32.
303+ if width > max_offset.saturating_sub(x_offset) {
304+ break;
305+ }
306+
307+ self.content[index].set_symbol(s);
308+ self.content[index].set_style(style);
309+ // Reset following cells if multi-width (they would be hidden by the grapheme),
310+ for i in index + 1..index + width {
311+ self.content[i].reset();
312+ }
313+ index += width;
314+ x_offset += width;
296 }
315 }
297− // `x_offset + width > max_offset` could be integer overflow on 32-bit machines if we
316+ if ellipsis && x_offset - (x as usize) < string.as_ref().width() {
298− // change dimenstions to usize or u32 and someone resizes the terminal to 1x2^32.
317+ self.content[index].set_symbol("…");
299− if width > max_offset.saturating_sub(x_offset) {
300− break;
301 }
318 }
302−
319+ } else {
320+ let mut start_index = self.index_of(x, y);
321+ let mut index = self.index_of(max_offset as u16, y);
322+
323+ let total_width = string.as_ref().width();
324+ let truncated = total_width > width;
325+ if ellipsis && truncated {
326+ self.content[start_index].set_symbol("…");
327+ start_index += 1;
328+ }
329+ if !truncated {
330+ index -= width - total_width;
331+ }
332+ for s in graphemes.rev() {
333+ let width = s.width();
334+ if width == 0 {
335+ continue;
336+ }
337+ let start = index - width;
338+ if start < start_index {
339+ break;
340+ }
303− self.content[index].set_symbol(s);
341+ self.content[start].set_symbol(s);
304− self.content[index].set_style(style);
342+ self.content[start].set_style(style);
305− // Reset following cells if multi-width (they would be hidden by the grapheme),
306− for i in index + 1..index + width {
343+ for i in start + 1..index {
307− self.content[i].reset();
344+ self.content[i].reset();
345+ }
346+ index -= width;
308 }
347 }
309− index += width;
310− x_offset += width;
311− }
312− if ellipsis && x_offset - (x as usize) < string.as_ref().width() {
313− self.content[index].set_symbol("…");
314 }
348 }
315 (x_offset as u16, y)
349 (x_offset as u16, y)
316 }
350 }