Skip to content

Commit aacf481

Browse files
committed
shape color closure
1 parent 94b2726 commit aacf481

3 files changed

Lines changed: 114 additions & 39 deletions

File tree

crates/nu-cli/src/nu_highlight.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::sync::Arc;
2+
13
use nu_protocol::ast::Call;
24
use nu_protocol::engine::{Command, EngineState, Stack};
35
use nu_protocol::{Category, Example, PipelineData, ShellError, Signature, Type, Value};
@@ -28,18 +30,18 @@ impl Command for NuHighlight {
2830
fn run(
2931
&self,
3032
engine_state: &EngineState,
31-
_stack: &mut Stack,
33+
stack: &mut Stack,
3234
call: &Call,
3335
input: PipelineData,
3436
) -> Result<PipelineData, ShellError> {
3537
let head = call.head;
3638

3739
let ctrlc = engine_state.ctrlc.clone();
38-
let engine_state = std::sync::Arc::new(engine_state.clone());
3940
let config = engine_state.get_config().clone();
4041

4142
let highlighter = crate::NuHighlighter {
42-
engine_state,
43+
engine_state: Arc::new(engine_state.clone()),
44+
stack: Arc::new(stack.clone()),
4345
config,
4446
};
4547

crates/nu-cli/src/repl.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use std::{
2929
env::temp_dir,
3030
io::{self, IsTerminal, Write},
3131
path::Path,
32-
sync::atomic::Ordering,
32+
sync::{atomic::Ordering, Arc},
3333
time::Instant,
3434
};
3535
use sysinfo::SystemExt;
@@ -255,6 +255,7 @@ pub fn evaluate_repl(
255255
.use_bracketed_paste(cfg!(not(target_os = "windows")) && config.bracketed_paste)
256256
.with_highlighter(Box::new(NuHighlighter {
257257
engine_state: engine_reference.clone(),
258+
stack: Arc::new(stack.clone()),
258259
config: config.clone(),
259260
}))
260261
.with_validator(Box::new(NuValidator {

crates/nu-cli/src/syntax_highlight.rs

Lines changed: 107 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,79 @@
11
use log::trace;
22
use nu_ansi_term::Style;
3-
use nu_color_config::{get_matching_brackets_style, get_shape_color};
3+
use nu_color_config::{
4+
color_record_to_nustyle, default_shape_color, get_matching_brackets_style,
5+
lookup_ansi_color_style,
6+
};
7+
use nu_engine::eval_block;
48
use nu_parser::{flatten_block, parse, FlatShape};
59
use nu_protocol::ast::{Argument, Block, Expr, Expression, PipelineElement, RecordItem};
6-
use nu_protocol::engine::{EngineState, StateWorkingSet};
7-
use nu_protocol::{Config, Span};
10+
use nu_protocol::engine::{EngineState, Stack, StateWorkingSet};
11+
use nu_protocol::{CliError, Config, IntoPipelineData, Span, Value};
812
use reedline::{Highlighter, StyledText};
913
use std::sync::Arc;
1014

1115
pub struct NuHighlighter {
1216
pub engine_state: Arc<EngineState>,
17+
pub stack: Arc<Stack>,
1318
pub config: Config,
1419
}
1520

21+
impl NuHighlighter {
22+
fn get_shape_color(&self, shape: String, conf: &Config, val: &Value) -> Style {
23+
fn get_style_simple(shape: String, v: &Value) -> Style {
24+
match v {
25+
Value::Record { .. } => color_record_to_nustyle(v),
26+
Value::String { val, .. } => lookup_ansi_color_style(val),
27+
_ => default_shape_color(shape),
28+
}
29+
}
30+
match conf.color_config.get(shape.as_str()) {
31+
Some(color) => {
32+
// Shapes do not use color_config closures, currently.
33+
match color {
34+
Value::Closure { val: closure, .. } => {
35+
let block = self.engine_state.get_block(closure.block_id).clone();
36+
// Because captures_to_stack() clones, we don't need to use with_env() here
37+
// (contrast with_env() usage in `each` or `do`).
38+
let mut stack = self.stack.captures_to_stack(closure.captures.clone());
39+
40+
// Support 1-argument blocks as well as 0-argument blocks.
41+
if let Some(var) = block.signature.get_positional(0) {
42+
if let Some(var_id) = &var.var_id {
43+
stack.add_var(*var_id, val.clone());
44+
}
45+
}
46+
47+
// Run the block.
48+
match eval_block(
49+
&self.engine_state,
50+
&mut stack,
51+
&block,
52+
val.clone().into_pipeline_data(),
53+
false,
54+
false,
55+
) {
56+
Ok(v) => get_style_simple(shape, &v.into_value(color.span())),
57+
// This is basically a copy of nu_cli::report_error(), but that isn't usable due to
58+
// dependencies. While crudely spitting out a bunch of errors like this is not ideal,
59+
// currently hook closure errors behave roughly the same.
60+
Err(e) => {
61+
eprintln!(
62+
"Error: {:?}",
63+
CliError(&e, &StateWorkingSet::new(&self.engine_state))
64+
);
65+
Style::default()
66+
}
67+
}
68+
}
69+
_ => get_style_simple(shape, color),
70+
}
71+
}
72+
None => default_shape_color(shape),
73+
}
74+
}
75+
}
76+
1677
impl Highlighter for NuHighlighter {
1778
fn highlight(&self, line: &str, _cursor: usize) -> StyledText {
1879
trace!("highlighting: {}", line);
@@ -84,7 +145,11 @@ impl Highlighter for NuHighlighter {
84145
let start = part.start - $span.start;
85146
let end = part.end - $span.start;
86147
let text = (&next_token[start..end]).to_string();
87-
let mut style = get_shape_color($shape.to_string(), &self.config);
148+
let mut style = self.get_shape_color(
149+
$shape.to_string(),
150+
&self.config,
151+
&Value::string(next_token.clone(), $span),
152+
);
88153
if *highlight {
89154
style = get_matching_brackets_style(style, &self.config);
90155
}
@@ -93,29 +158,36 @@ impl Highlighter for NuHighlighter {
93158
}};
94159
}
95160

96-
let mut add_colored_token = |shape: &FlatShape, text: String| {
97-
output.push((get_shape_color(shape.to_string(), &self.config), text));
161+
let mut add_colored_token = |(span, shape): &(Span, FlatShape), text: String| {
162+
output.push((
163+
self.get_shape_color(
164+
shape.to_string(),
165+
&self.config,
166+
&Value::string(text.clone(), *span),
167+
),
168+
text,
169+
));
98170
};
99171

100172
match shape.1 {
101-
FlatShape::Garbage => add_colored_token(&shape.1, next_token),
102-
FlatShape::Nothing => add_colored_token(&shape.1, next_token),
103-
FlatShape::Binary => add_colored_token(&shape.1, next_token),
104-
FlatShape::Bool => add_colored_token(&shape.1, next_token),
105-
FlatShape::Int => add_colored_token(&shape.1, next_token),
106-
FlatShape::Float => add_colored_token(&shape.1, next_token),
107-
FlatShape::Range => add_colored_token(&shape.1, next_token),
108-
FlatShape::InternalCall(_) => add_colored_token(&shape.1, next_token),
109-
FlatShape::External => add_colored_token(&shape.1, next_token),
110-
FlatShape::ExternalArg => add_colored_token(&shape.1, next_token),
111-
FlatShape::ExternalResolved => add_colored_token(&shape.1, next_token),
112-
FlatShape::Keyword => add_colored_token(&shape.1, next_token),
113-
FlatShape::Literal => add_colored_token(&shape.1, next_token),
114-
FlatShape::Operator => add_colored_token(&shape.1, next_token),
115-
FlatShape::Signature => add_colored_token(&shape.1, next_token),
116-
FlatShape::String => add_colored_token(&shape.1, next_token),
117-
FlatShape::StringInterpolation => add_colored_token(&shape.1, next_token),
118-
FlatShape::DateTime => add_colored_token(&shape.1, next_token),
173+
FlatShape::Garbage => add_colored_token(shape, next_token),
174+
FlatShape::Nothing => add_colored_token(shape, next_token),
175+
FlatShape::Binary => add_colored_token(shape, next_token),
176+
FlatShape::Bool => add_colored_token(shape, next_token),
177+
FlatShape::Int => add_colored_token(shape, next_token),
178+
FlatShape::Float => add_colored_token(shape, next_token),
179+
FlatShape::Range => add_colored_token(shape, next_token),
180+
FlatShape::InternalCall(_) => add_colored_token(shape, next_token),
181+
FlatShape::External => add_colored_token(shape, next_token),
182+
FlatShape::ExternalArg => add_colored_token(shape, next_token),
183+
FlatShape::ExternalResolved => add_colored_token(&shape, next_token),
184+
FlatShape::Keyword => add_colored_token(shape, next_token),
185+
FlatShape::Literal => add_colored_token(shape, next_token),
186+
FlatShape::Operator => add_colored_token(shape, next_token),
187+
FlatShape::Signature => add_colored_token(shape, next_token),
188+
FlatShape::String => add_colored_token(shape, next_token),
189+
FlatShape::StringInterpolation => add_colored_token(shape, next_token),
190+
FlatShape::DateTime => add_colored_token(shape, next_token),
119191
FlatShape::List => {
120192
add_colored_token_with_bracket_highlight!(shape.1, shape.0, next_token)
121193
}
@@ -133,19 +205,19 @@ impl Highlighter for NuHighlighter {
133205
add_colored_token_with_bracket_highlight!(shape.1, shape.0, next_token)
134206
}
135207

136-
FlatShape::Filepath => add_colored_token(&shape.1, next_token),
137-
FlatShape::Directory => add_colored_token(&shape.1, next_token),
138-
FlatShape::GlobPattern => add_colored_token(&shape.1, next_token),
208+
FlatShape::Filepath => add_colored_token(shape, next_token),
209+
FlatShape::Directory => add_colored_token(shape, next_token),
210+
FlatShape::GlobPattern => add_colored_token(shape, next_token),
139211
FlatShape::Variable(_) | FlatShape::VarDecl(_) => {
140-
add_colored_token(&shape.1, next_token)
212+
add_colored_token(shape, next_token)
141213
}
142-
FlatShape::Flag => add_colored_token(&shape.1, next_token),
143-
FlatShape::Pipe => add_colored_token(&shape.1, next_token),
144-
FlatShape::And => add_colored_token(&shape.1, next_token),
145-
FlatShape::Or => add_colored_token(&shape.1, next_token),
146-
FlatShape::Redirection => add_colored_token(&shape.1, next_token),
147-
FlatShape::Custom(..) => add_colored_token(&shape.1, next_token),
148-
FlatShape::MatchPattern => add_colored_token(&shape.1, next_token),
214+
FlatShape::Flag => add_colored_token(shape, next_token),
215+
FlatShape::Pipe => add_colored_token(shape, next_token),
216+
FlatShape::And => add_colored_token(shape, next_token),
217+
FlatShape::Or => add_colored_token(shape, next_token),
218+
FlatShape::Redirection => add_colored_token(shape, next_token),
219+
FlatShape::Custom(..) => add_colored_token(shape, next_token),
220+
FlatShape::MatchPattern => add_colored_token(shape, next_token),
149221
}
150222
last_seen_span = shape.0.end;
151223
}

0 commit comments

Comments
 (0)