kkawakam / rustyline

Readline Implementation in Rust
https://crates.io/crates/rustyline/
MIT License
1.52k stars 175 forks source link

Composing highlighters #715

Closed segeljakt closed 1 year ago

segeljakt commented 1 year ago

I created my own highlighter which colors keywords, numbers, etc and tried compose it highlighter with the MatchingBracketHighlighter:

#[derive(Helper)]
pub(crate) struct Repl {
    highlighter1: SyntaxHighlighter,
    highlighter2: MatchingBracketHighlighter,
}

impl Highlighter for Repl {
    fn highlight<'l>(&self, line: &'l str, pos: usize) -> Cow<'l, str> {
        let line = self.highlighter1.highlight(line, pos);
        match line {
            Cow::Borrowed(line) => self.highlighter2.highlight(line, pos),
            Cow::Owned(line) => match self.highlighter2.highlight(line.as_str(), pos) {
                Cow::Borrowed(line) => Cow::Owned(line.to_string()),
                Cow::Owned(line) => Cow::Owned(line),
            },
        }
    }
}

For an input like:

let x = [];

Where let is a keyword, it does not highlight the matching bracket [. The problem seems to be that highlighters insert control characters like format!("\x1b[1;34m{}\x1b[0m", matching_text) into the text. This can make highlighter1 confuse highlighter2. The same thing seems to happen if I swap the order of the highlighters. Do you have any ideas if this problem could be solved?

gwenn commented 1 year ago

If you pass to the MatchingBracketHighlighter a styled text as argument, then the position in https://github.com/kkawakam/rustyline/blob/a855443e93bc1b31cdcee84f8ed0aa55bdc55aa1/src/highlight.rs#L98C31-L98C36 will not be valid anymore. But that doesn't explain why it doesn't work if MatchingBracketHighlighter is the first highlighter...

segeljakt commented 1 year ago

I meant, SyntaxHighlighter breaks if I make MatchingHighlighter the first 😅. Whichever one comes first works and whichever comes second breaks. I think I can solve it in my case by creating a highlighter which handles both.

gwenn commented 1 year ago

I've just given a rational explanation when MatchingBracketHighlighter is the 2nd highlighter. I cannot give any rational explanation when MatchingBracketHighlighter is the 1st highlighter because SyntaxHighlighter impl. is unknown to me ! And I would prefer not to guess...

segeljakt commented 1 year ago

Yeah... thanks :)