nushell/src/syntax_highlight.rs

91 lines
3.4 KiB
Rust
Raw Normal View History

2021-07-22 21:50:59 +02:00
use crate::flatten::FlatShape;
use crate::{ParserState, ParserWorkingSet};
use nu_ansi_term::Style;
use reedline::{Highlighter, StyledText};
2021-07-22 09:48:45 +02:00
use std::{cell::RefCell, rc::Rc};
2021-07-17 08:31:34 +02:00
2021-07-22 21:50:59 +02:00
pub struct NuHighlighter {
pub parser_state: Rc<RefCell<ParserState>>,
2021-07-22 09:48:45 +02:00
}
2021-07-17 08:31:34 +02:00
2021-07-22 21:50:59 +02:00
impl Highlighter for NuHighlighter {
fn highlight(&self, line: &str) -> StyledText {
let (shapes, global_span_offset) = {
2021-07-22 09:48:45 +02:00
let parser_state = self.parser_state.borrow();
let mut working_set = ParserWorkingSet::new(&*parser_state);
2021-07-22 21:50:59 +02:00
let (block, _) = working_set.parse_source(line.as_bytes(), false);
2021-07-17 08:31:34 +02:00
2021-07-22 21:50:59 +02:00
let shapes = working_set.flatten_block(&block);
(shapes, parser_state.next_span_start())
2021-07-22 09:48:45 +02:00
};
2021-07-17 08:31:34 +02:00
2021-07-22 21:50:59 +02:00
let mut output = StyledText::default();
let mut last_seen_span = global_span_offset;
2021-07-22 09:48:45 +02:00
2021-07-22 21:50:59 +02:00
for shape in &shapes {
if shape.0.end <= last_seen_span {
// We've already output something for this span
// so just skip this one
continue;
}
if shape.0.start > last_seen_span {
let gap = line
[(last_seen_span - global_span_offset)..(shape.0.start - global_span_offset)]
.to_string();
output.push((Style::new(), gap));
}
2021-07-22 09:48:45 +02:00
2021-07-22 21:50:59 +02:00
let next_token = line
[(shape.0.start - global_span_offset)..(shape.0.end - global_span_offset)]
.to_string();
match shape.1 {
FlatShape::External => output.push((Style::new().bold(), next_token)),
FlatShape::Garbage => output.push((
Style::new()
.fg(nu_ansi_term::Color::White)
.on(nu_ansi_term::Color::Red)
.bold(),
next_token,
)),
FlatShape::InternalCall => output.push((
Style::new().fg(nu_ansi_term::Color::LightBlue).bold(),
next_token,
)),
FlatShape::Int => {
output.push((Style::new().fg(nu_ansi_term::Color::Green), next_token))
}
2021-07-24 07:57:17 +02:00
FlatShape::Bool => {
output.push((Style::new().fg(nu_ansi_term::Color::LightCyan), next_token))
}
2021-07-22 21:50:59 +02:00
FlatShape::Literal => {
output.push((Style::new().fg(nu_ansi_term::Color::Blue), next_token))
}
FlatShape::Operator => output.push((
Style::new().fg(nu_ansi_term::Color::LightPurple).bold(),
next_token,
)),
FlatShape::Signature => output.push((
Style::new().fg(nu_ansi_term::Color::Green).bold(),
next_token,
)),
FlatShape::String => output.push((
Style::new().fg(nu_ansi_term::Color::Yellow).bold(),
next_token,
)),
FlatShape::Variable => output.push((
Style::new().fg(nu_ansi_term::Color::Blue).bold(),
next_token,
)),
}
last_seen_span = shape.0.end;
}
let remainder = line[(last_seen_span - global_span_offset)..].to_string();
if !remainder.is_empty() {
output.push((Style::new(), remainder));
}
2021-07-17 08:31:34 +02:00
2021-07-22 21:50:59 +02:00
output
2021-07-22 09:48:45 +02:00
}
2021-07-17 08:31:34 +02:00
}