1use std::sync::Arc;
2
3use nu_engine::command_prelude::*;
4use reedline::{Highlighter, StyledText};
5
6use crate::syntax_highlight::highlight_syntax;
7
8#[derive(Clone)]
9pub struct NuHighlight;
10
11impl Command for NuHighlight {
12 fn name(&self) -> &str {
13 "nu-highlight"
14 }
15
16 fn signature(&self) -> Signature {
17 Signature::build("nu-highlight")
18 .category(Category::Strings)
19 .switch(
20 "reject-garbage",
21 "Return an error if invalid syntax (garbage) was encountered",
22 Some('r'),
23 )
24 .input_output_types(vec![(Type::String, Type::String)])
25 }
26
27 fn description(&self) -> &str {
28 "Syntax highlight the input string."
29 }
30
31 fn search_terms(&self) -> Vec<&str> {
32 vec!["syntax", "color", "convert"]
33 }
34
35 fn run(
36 &self,
37 engine_state: &EngineState,
38 stack: &mut Stack,
39 call: &Call,
40 input: PipelineData,
41 ) -> Result<PipelineData, ShellError> {
42 let reject_garbage = call.has_flag(engine_state, stack, "reject-garbage")?;
43 let head = call.head;
44
45 let signals = engine_state.signals();
46
47 let engine_state = Arc::new(engine_state.clone());
48 let stack = Arc::new(stack.clone());
49
50 input.map(
51 move |x| match x.coerce_into_string() {
52 Ok(line) => {
53 let result = highlight_syntax(&engine_state, &stack, &line, line.len());
54
55 let highlights = match (reject_garbage, result.found_garbage) {
56 (false, _) => result.text,
57 (true, None) => result.text,
58 (true, Some(span)) => {
59 let error = ShellError::OutsideSpannedLabeledError {
60 src: line,
61 error: "encountered invalid syntax while highlighting".into(),
62 msg: "invalid syntax".into(),
63 span,
64 };
65 return Value::error(error, head);
66 }
67 };
68
69 Value::string(highlights.render_simple(), head)
70 }
71 Err(err) => Value::error(err, head),
72 },
73 signals,
74 )
75 }
76
77 fn examples(&self) -> Vec<Example<'_>> {
78 vec![Example {
79 description: "Describe the type of a string",
80 example: "'let x = 3' | nu-highlight",
81 result: None,
82 }]
83 }
84}
85
86#[derive(Default)]
91pub struct NoOpHighlighter {}
92
93impl Highlighter for NoOpHighlighter {
94 fn highlight(&self, _line: &str, _cursor: usize) -> reedline::StyledText {
95 StyledText::new()
96 }
97}