Skip to content

Commit 5b5d1b9

Browse files
Omnikararchseer
andauthored
Truncate the starts of file paths instead of the ends in picker (#951)
* Truncate the starts of file paths in picker * Simplify the truncate implementation * Break loop at appropriate point * Fix alignment and ellipsis presence * Remove extraneous usage of `x_offset` Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
1 parent e39cfa4 commit 5b5d1b9

File tree

2 files changed

+57
-22
lines changed

2 files changed

+57
-22
lines changed

helix-term/src/ui/picker.rs

+1
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,7 @@ impl<T: 'static> Component for Picker<T> {
483483
text_style
484484
},
485485
true,
486+
true,
486487
);
487488
}
488489
}

helix-tui/src/buffer.rs

+56-22
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,14 @@ impl Buffer {
266266
where
267267
S: AsRef<str>,
268268
{
269-
self.set_string_truncated(x, y, string, width, style, false)
269+
self.set_string_truncated(x, y, string, width, style, false, false)
270270
}
271271

272272
/// 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
274-
/// truncated lines.
273+
/// until the end of the line. If `ellipsis` is true appends a `…` at the end of
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)]
275277
pub fn set_string_truncated<S>(
276278
&mut self,
277279
x: u16,
@@ -280,6 +282,7 @@ impl Buffer {
280282
width: usize,
281283
style: Style,
282284
ellipsis: bool,
285+
truncate_start: bool,
283286
) -> (u16, u16)
284287
where
285288
S: AsRef<str>,
@@ -289,28 +292,59 @@ impl Buffer {
289292
let width = if ellipsis { width - 1 } else { width };
290293
let graphemes = UnicodeSegmentation::graphemes(string.as_ref(), true);
291294
let max_offset = min(self.area.right() as usize, width.saturating_add(x as usize));
292-
for s in graphemes {
293-
let width = s.width();
294-
if width == 0 {
295-
continue;
295+
if !truncate_start {
296+
for s in graphemes {
297+
let width = s.width();
298+
if width == 0 {
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;
296315
}
297-
// `x_offset + width > max_offset` could be integer overflow on 32-bit machines if we
298-
// change dimenstions to usize or u32 and someone resizes the terminal to 1x2^32.
299-
if width > max_offset.saturating_sub(x_offset) {
300-
break;
316+
if ellipsis && x_offset - (x as usize) < string.as_ref().width() {
317+
self.content[index].set_symbol("…");
301318
}
302-
303-
self.content[index].set_symbol(s);
304-
self.content[index].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 {
307-
self.content[i].reset();
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+
}
341+
self.content[start].set_symbol(s);
342+
self.content[start].set_style(style);
343+
for i in start + 1..index {
344+
self.content[i].reset();
345+
}
346+
index -= width;
308347
}
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("…");
314348
}
315349
(x_offset as u16, y)
316350
}

0 commit comments

Comments
 (0)