feedback: apply as much feedback as possible (round 1)

pull/7215/head
Alexandre Vinyals Valdepeñas 1 year ago
parent 60c06076b2
commit 99aa751c75

@ -397,9 +397,9 @@ impl<'a> TextRenderer<'a> {
&self.tab &self.tab
}; };
let mut whitespace_kind = WhitespaceKind::None; let mut whitespace_kind = WhitespaceKind::None;
let grapheme_value = match grapheme { let grapheme = match grapheme {
Grapheme::Tab { width } => { Grapheme::Tab { width } => {
whitespace_kind = WhitespaceKind::Tab(width); whitespace_kind = WhitespaceKind::Tab;
let grapheme_tab_width = char_to_byte_idx(tab, width); let grapheme_tab_width = char_to_byte_idx(tab, width);
&tab[..grapheme_tab_width] &tab[..grapheme_tab_width]
} }
@ -419,41 +419,31 @@ impl<'a> TextRenderer<'a> {
} }
}; };
self.trailing_whitespace_tracker
.track(position.col, whitespace_kind);
let viewport_right_edge = self.viewport.width as usize + self.col_offset - 1; let viewport_right_edge = self.viewport.width as usize + self.col_offset - 1;
let in_bounds = self.col_offset <= position.col && position.col <= viewport_right_edge; let in_bounds = self.col_offset <= position.col && position.col <= viewport_right_edge;
if in_bounds { if in_bounds {
if self.trailing_whitespace_tracker.is_enabled() let in_bounds_col = position.col - self.col_offset;
&& (grapheme == Grapheme::Newline || position.col == viewport_right_edge) self.surface.set_string(
self.viewport.x + in_bounds_col as u16,
self.viewport.y + position.row as u16,
grapheme,
style,
);
if self
.trailing_whitespace_tracker
.track(in_bounds_col, whitespace_kind)
|| position.col == viewport_right_edge
{ {
if let Some((from, trailing_whitespace)) = self.trailing_whitespace_tracker.get() { if let Some((from, trailing_whitespace)) = self.trailing_whitespace_tracker.get() {
let offset = if from < self.col_offset {
0
} else {
from - self.col_offset
};
let begin_at = if from < self.col_offset {
self.col_offset - from
} else {
0
};
self.surface.set_string( self.surface.set_string(
self.viewport.x + offset as u16, self.viewport.x + from as u16,
self.viewport.y + position.row as u16, self.viewport.y + position.row as u16,
&trailing_whitespace[char_to_byte_idx(&trailing_whitespace, begin_at)..], &trailing_whitespace,
style, style,
); );
} }
} else {
self.surface.set_string(
self.viewport.x + (position.col - self.col_offset) as u16,
self.viewport.y + position.row as u16,
grapheme_value,
style,
);
} }
} else if cut_off_start != 0 && cut_off_start < width { } else if cut_off_start != 0 && cut_off_start < width {
// partially on screen // partially on screen

@ -7,17 +7,31 @@ pub enum WhitespaceKind {
None, None,
Space, Space,
NonBreakingSpace, NonBreakingSpace,
Tab(usize), Tab,
Newline, Newline,
} }
impl WhitespaceKind {
pub fn to_str<'a>(&'a self, palette: &'a WhitespacePalette) -> &'a str {
match self {
WhitespaceKind::Space => &palette.space,
WhitespaceKind::NonBreakingSpace => &palette.nbsp,
WhitespaceKind::Tab => {
let grapheme_tab_width = char_to_byte_idx(&palette.tab, 1);
&palette.tab[..grapheme_tab_width]
}
WhitespaceKind::Newline => &palette.newline,
WhitespaceKind::None => "",
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct TrailingWhitespaceTracker { pub struct TrailingWhitespaceTracker {
enabled: bool, enabled: bool,
palette: WhitespacePalette, palette: WhitespacePalette,
tracking: bool,
tracking_from: usize, tracking_from: usize,
tracking_content: Vec<WhitespaceKind>, tracking_content: Vec<(WhitespaceKind, usize)>,
} }
impl TrailingWhitespaceTracker { impl TrailingWhitespaceTracker {
@ -25,54 +39,51 @@ impl TrailingWhitespaceTracker {
Self { Self {
palette, palette,
enabled: render.any(WhitespaceRenderValue::Trailing), enabled: render.any(WhitespaceRenderValue::Trailing),
tracking: false,
tracking_from: 0, tracking_from: 0,
tracking_content: vec![], tracking_content: vec![],
} }
} }
pub fn track(&mut self, from: usize, kind: WhitespaceKind) { // Tracks the whitespace and returns wether [`get`] should be called right after
if kind == WhitespaceKind::None { // to display the trailing whitespace.
self.tracking = false; pub fn track(&mut self, from: usize, kind: WhitespaceKind) -> bool {
return; if !self.enabled || kind == WhitespaceKind::None {
self.tracking_content.clear();
return false;
} }
if !self.tracking { if self.tracking_content.is_empty() {
self.tracking = true;
self.tracking_from = from; self.tracking_from = from;
self.tracking_content.clear();
} }
self.tracking_content.push(kind); let is_newline = kind == WhitespaceKind::Newline;
} self.compress(kind);
is_newline
pub fn is_enabled(&self) -> bool {
self.enabled
} }
#[must_use] #[must_use]
pub fn get(&mut self) -> Option<(usize, String)> { pub fn get(&mut self) -> Option<(usize, String)> {
if !self.enabled || !self.tracking { if self.tracking_content.is_empty() {
return None; return None;
} }
self.tracking = false;
let trailing_whitespace = self let trailing_whitespace = self
.tracking_content .tracking_content
.iter() .iter()
.map(|kind| match kind { .map(|(kind, n)| kind.to_str(&self.palette).repeat(*n))
WhitespaceKind::Space => &self.palette.space, .collect::<String>();
WhitespaceKind::NonBreakingSpace => &self.palette.nbsp,
WhitespaceKind::Tab(width) => {
let grapheme_tab_width = char_to_byte_idx(&self.palette.tab, *width);
&self.palette.tab[..grapheme_tab_width]
}
WhitespaceKind::Newline => &self.palette.newline,
WhitespaceKind::None => "",
})
.collect::<Vec<&str>>()
.join("");
self.tracking_content.clear();
Some((self.tracking_from, trailing_whitespace)) Some((self.tracking_from, trailing_whitespace))
} }
fn compress(&mut self, kind: WhitespaceKind) {
if let Some((last_kind, n)) = self.tracking_content.last_mut() {
if *last_kind == kind {
*n += 1;
return;
}
}
self.tracking_content.push((kind, 1));
}
} }
#[cfg(test)] #[cfg(test)]
@ -100,7 +111,7 @@ mod tests {
sut.track(5, WhitespaceKind::Space); sut.track(5, WhitespaceKind::Space);
sut.track(6, WhitespaceKind::NonBreakingSpace); sut.track(6, WhitespaceKind::NonBreakingSpace);
sut.track(7, WhitespaceKind::Tab(1)); sut.track(7, WhitespaceKind::Tab);
sut.track(8, WhitespaceKind::Newline); sut.track(8, WhitespaceKind::Newline);
let trailing = sut.get(); let trailing = sut.get();
@ -115,7 +126,7 @@ mod tests {
assert!(trailing.is_none()); assert!(trailing.is_none());
// Now we track again // Now we track again
sut.track(10, WhitespaceKind::Tab(1)); sut.track(10, WhitespaceKind::Tab);
sut.track(11, WhitespaceKind::NonBreakingSpace); sut.track(11, WhitespaceKind::NonBreakingSpace);
sut.track(12, WhitespaceKind::Space); sut.track(12, WhitespaceKind::Space);
sut.track(13, WhitespaceKind::Newline); sut.track(13, WhitespaceKind::Newline);
@ -125,5 +136,21 @@ mod tests {
let (from, display) = trailing.unwrap(); let (from, display) = trailing.unwrap();
assert_eq!(10, from); assert_eq!(10, from);
assert_eq!("TNSL", display); assert_eq!("TNSL", display);
// Verify compression works
sut.track(20, WhitespaceKind::Space);
sut.track(21, WhitespaceKind::Space);
sut.track(22, WhitespaceKind::NonBreakingSpace);
sut.track(23, WhitespaceKind::NonBreakingSpace);
sut.track(24, WhitespaceKind::Tab);
sut.track(25, WhitespaceKind::Tab);
sut.track(26, WhitespaceKind::Tab);
sut.track(27, WhitespaceKind::Newline);
let trailing = sut.get();
assert!(trailing.is_some());
let (from, display) = trailing.unwrap();
assert_eq!(20, from);
assert_eq!("SSNNTTTL", display);
} }
} }

Loading…
Cancel
Save