Fix tab rendering to use dynamic tab width

Each tab is just wide enough to round to the nearest tab stop.

Refs #1243
pull/1747/head
Blaž Hrastnik 3 years ago
parent 5f386fa355
commit fd02d1bf89
No known key found for this signature in database
GPG Key ID: 1238B9C4AD889640

@ -83,7 +83,7 @@ pub fn visual_coords_at_pos(text: RopeSlice, pos: usize, tab_width: usize) -> Po
for grapheme in RopeGraphemes::new(text.slice(line_start..pos)) { for grapheme in RopeGraphemes::new(text.slice(line_start..pos)) {
if grapheme == "\t" { if grapheme == "\t" {
col += tab_width; col += tab_width - (col % tab_width);
} else { } else {
let grapheme = Cow::from(grapheme); let grapheme = Cow::from(grapheme);
col += grapheme_width(&grapheme); col += grapheme_width(&grapheme);

@ -378,7 +378,8 @@ impl EditorView {
let (grapheme, width) = if grapheme == "\t" { let (grapheme, width) = if grapheme == "\t" {
// make sure we display tab as appropriate amount of spaces // make sure we display tab as appropriate amount of spaces
(tab.as_str(), tab_width) let visual_tab_width = tab_width - (visual_x as usize % tab_width);
(&tab[..visual_tab_width], visual_tab_width)
} else { } else {
// Cow will prevent allocations if span contained in a single slice // Cow will prevent allocations if span contained in a single slice
// which should really be the majority case // which should really be the majority case

@ -243,18 +243,29 @@ impl View {
let current_line = text.line(line_number); let current_line = text.line(line_number);
let target = (column - inner.x) as usize + self.offset.col; let target = (column - inner.x) as usize + self.offset.col;
let mut selected = 0; let mut col = 0;
// TODO: extract this part as pos_at_visual_coords
for grapheme in RopeGraphemes::new(current_line) { for grapheme in RopeGraphemes::new(current_line) {
if selected >= target { if col >= target {
break; break;
} }
if grapheme == "\t" {
selected += tab_width; let width = if grapheme == "\t" {
tab_width - (col % tab_width)
} else { } else {
let width = grapheme_width(&Cow::from(grapheme)); let grapheme = Cow::from(grapheme);
selected += width; grapheme_width(&grapheme)
};
// If pos is in the middle of a wider grapheme (tab for example)
// return the starting offset.
if col + width >= target {
break;
} }
col += width;
// TODO: use byte pos that converts back to char pos?
pos += grapheme.chars().count(); pos += grapheme.chars().count();
} }

Loading…
Cancel
Save