Skip to content

Commit

Permalink
fix: correct handling of multi-byte chars in highlighter (#277)
Browse files Browse the repository at this point in the history
Use chars() instead of byte-slicing into the str while segmenting the input string into differently styled substrings.
  • Loading branch information
reubeno authored Nov 29, 2024
1 parent 0e53820 commit 316e9c9
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions brush-interactive/src/reedline/highlighter.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::str::Chars;

use super::refs;
use nu_ansi_term::{Color, Style};

Expand Down Expand Up @@ -98,21 +100,21 @@ enum CommandType {

struct StyledInputLine<'a> {
shell: &'a brush_core::Shell,
input_line: &'a str,
cursor: usize,
styled: reedline::StyledText,
current_index: usize,
remaining_chars: Chars<'a>,
current_char_index: usize,
next_missing_style: Option<Style>,
}

impl<'a> StyledInputLine<'a> {
fn new(shell: &'a brush_core::Shell, input_line: &'a str, cursor: usize) -> Self {
Self {
shell,
input_line,
cursor,
styled: reedline::StyledText::new(),
current_index: 0,
remaining_chars: input_line.chars(),
current_char_index: 0,
next_missing_style: None,
}
}
Expand Down Expand Up @@ -229,18 +231,21 @@ impl<'a> StyledInputLine<'a> {

fn append_style(&mut self, style: Style, start: usize, end: usize) {
// See if we need to cover a gap between this substring and the one that preceded it.
if start > self.current_index {
if start > self.current_char_index {
let missing_style = self.next_missing_style.map_or_else(styles::comment, |s| s);
let missing_text = &self.input_line[self.current_index..start];
self.styled.push((missing_style, missing_text.to_owned()));
let missing_text: String = (&mut self.remaining_chars)
.take(start - self.current_char_index)
.collect();
self.styled.push((missing_style, missing_text));
self.current_char_index = start;
}

if end > start {
self.styled
.push((style, self.input_line[start..end].to_string()));
let text: String = (&mut self.remaining_chars).take(end - start).collect();
self.styled.push((style, text));
}

self.current_index = end;
self.current_char_index = end;
}

fn skip_ahead(&mut self, dest: usize) {
Expand Down

0 comments on commit 316e9c9

Please sign in to comment.