use log::trace; use nu_ansi_term::Style; use nu_color_config::get_shape_color; use nu_parser::{flatten_block, parse, FlatShape}; use nu_protocol::engine::{EngineState, StateWorkingSet}; use nu_protocol::Config; use reedline::{Highlighter, StyledText}; pub struct NuHighlighter { pub engine_state: EngineState, pub config: Config, } impl Highlighter for NuHighlighter { fn highlight(&self, line: &str) -> StyledText { trace!("highlighting: {}", line); let (shapes, global_span_offset) = { let mut working_set = StateWorkingSet::new(&self.engine_state); let (block, _) = parse(&mut working_set, None, line.as_bytes(), false); let shapes = flatten_block(&working_set, &block); (shapes, self.engine_state.next_span_start()) }; let mut output = StyledText::default(); let mut last_seen_span = global_span_offset; for shape in &shapes { if shape.0.end <= last_seen_span || last_seen_span < global_span_offset || shape.0.start < global_span_offset { // 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)); } let next_token = line [(shape.0.start - global_span_offset)..(shape.0.end - global_span_offset)] .to_string(); match shape.1 { FlatShape::Garbage => output.push(( // nushell Garbage get_shape_color(shape.1.to_string(), &self.config), next_token, )), FlatShape::Nothing => output.push(( // nushell Nothing get_shape_color(shape.1.to_string(), &self.config), next_token, )), FlatShape::Bool => { // nushell ? output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::Int => { // nushell Int output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::Float => { // nushell Decimal output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::Range => output.push(( // nushell DotDot ? get_shape_color(shape.1.to_string(), &self.config), next_token, )), FlatShape::InternalCall => output.push(( // nushell InternalCommand get_shape_color(shape.1.to_string(), &self.config), next_token, )), FlatShape::External => { // nushell ExternalCommand output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::ExternalArg => { // nushell ExternalWord output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::Literal => { // nushell ? output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::Operator => output.push(( // nushell Operator get_shape_color(shape.1.to_string(), &self.config), next_token, )), FlatShape::Signature => output.push(( // nushell ? get_shape_color(shape.1.to_string(), &self.config), next_token, )), FlatShape::String => { // nushell String output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::StringInterpolation => { // nushell ??? output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::DateTime => { // nushell ??? output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::List => { // nushell ??? output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::Table => { // nushell ??? output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::Record => { // nushell ??? output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::Block => { // nushell ??? output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::Filepath => output.push(( // nushell Path get_shape_color(shape.1.to_string(), &self.config), next_token, )), FlatShape::GlobPattern => output.push(( // nushell GlobPattern get_shape_color(shape.1.to_string(), &self.config), next_token, )), FlatShape::Variable => output.push(( // nushell Variable get_shape_color(shape.1.to_string(), &self.config), next_token, )), FlatShape::Flag => { // nushell Flag output.push(( get_shape_color(shape.1.to_string(), &self.config), next_token, )) } FlatShape::Custom(..) => output.push(( get_shape_color(shape.1.to_string(), &self.config), 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)); } output } }