use nu_cmd_base::input_handler::{operate, CellPathOnlyArgs}; use nu_engine::CallExt; use nu_protocol::{ ast::Call, ast::CellPath, engine::Command, engine::EngineState, engine::Stack, Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; #[derive(Clone)] pub struct SubCommand; impl Command for SubCommand { fn name(&self) -> &str { "ansi strip" } fn signature(&self) -> Signature { Signature::build("ansi strip") .input_output_types(vec![(Type::String, Type::String)]) .rest( "cell path", SyntaxShape::CellPath, "for a data structure input, remove ANSI sequences from strings at the given cell paths", ) .category(Category::Platform) } fn usage(&self) -> &str { "Strip ANSI escape sequences from a string." } fn run( &self, engine_state: &EngineState, stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let cell_paths: Vec = call.rest(engine_state, stack, 0)?; let arg = CellPathOnlyArgs::from(cell_paths); operate(action, arg, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { vec![Example { description: "Strip ANSI escape sequences from a string", example: r#"$'(ansi green)(ansi cursor_on)hello' | ansi strip"#, result: Some(Value::test_string("hello")), }] } } fn action(input: &Value, _args: &CellPathOnlyArgs, command_span: Span) -> Value { match input { Value::String { val, span } => { Value::string(nu_utils::strip_ansi_likely(val).to_string(), *span) } other => { let got = format!("value is {}, not string", other.get_type()); Value::Error { error: Box::new(ShellError::TypeMismatch { err_message: got, span: other.span().unwrap_or(command_span), }), } } } } #[cfg(test)] mod tests { use super::{action, SubCommand}; use nu_protocol::{Span, Value}; #[test] fn examples_work_as_expected() { use crate::test_examples; test_examples(SubCommand {}) } #[test] fn test_stripping() { let input_string = Value::test_string("\u{1b}[3;93;41mHello\u{1b}[0m \u{1b}[1;32mNu \u{1b}[1;35mWorld"); let expected = Value::test_string("Hello Nu World"); let actual = action(&input_string, &vec![].into(), Span::test_data()); assert_eq!(actual, expected); } }