nushell/crates/nu-cli/src/commands/char_.rs

142 lines
5.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use crate::commands::WholeStreamCommand;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
use nu_source::Tagged;
pub struct Char;
#[derive(Deserialize)]
struct CharArgs {
name: Tagged<String>,
}
#[async_trait]
impl WholeStreamCommand for Char {
fn name(&self) -> &str {
"char"
}
fn signature(&self) -> Signature {
Signature::build("ansi").required(
"character",
SyntaxShape::Any,
"the name of the character to output",
)
}
fn usage(&self) -> &str {
"Output special characters (eg. 'newline')"
}
fn examples(&self) -> Vec<Example> {
vec![
Example {
description: "Output newline",
example: r#"char newline"#,
result: Some(vec![Value::from("\n")]),
},
Example {
description: "Output prompt character, newline and a hamburger character",
example: r#"echo $(char prompt) $(char newline) $(char hamburger)"#,
result: Some(vec![
UntaggedValue::string("\u{25b6}").into(),
UntaggedValue::string("\n").into(),
UntaggedValue::string("\u{2261}").into(),
]),
},
]
}
async fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
let (CharArgs { name }, _) = args.process(&registry).await?;
let special_character = str_to_character(&name.item);
if let Some(output) = special_character {
Ok(OutputStream::one(ReturnSuccess::value(
UntaggedValue::string(output).into_value(name.tag()),
)))
} else {
Err(ShellError::labeled_error(
"Unknown character",
"unknown character",
name.tag(),
))
}
}
}
fn str_to_character(s: &str) -> Option<String> {
match s {
"newline" | "enter" | "nl" => Some("\n".into()),
"tab" => Some("\t".into()),
"sp" | "space" => Some(" ".into()),
// Unicode names came from https://www.compart.com/en/unicode
// Private Use Area (U+E000-U+F8FF)
"branch" => Some('\u{e0a0}'.to_string()), // 
"segment" => Some('\u{e0b0}'.to_string()), // 
"identical_to" | "hamburger" => Some('\u{2261}'.to_string()), // ≡
"not_identical_to" | "branch_untracked" => Some('\u{2262}'.to_string()), // ≢
"strictly_equivalent_to" | "branch_identical" => Some('\u{2263}'.to_string()), // ≣
"upwards_arrow" | "branch_ahead" => Some('\u{2191}'.to_string()), // ↑
"downwards_arrow" | "branch_behind" => Some('\u{2193}'.to_string()), // ↓
"up_down_arrow" | "branch_ahead_behind" => Some('\u{2195}'.to_string()), // ↕
"black_right_pointing_triangle" | "prompt" => Some('\u{25b6}'.to_string()), // ▶
"vector_or_cross_product" | "failed" => Some('\u{2a2f}'.to_string()), //
"high_voltage_sign" | "elevated" => Some('\u{26a1}'.to_string()), // ⚡
"tilde" | "twiddle" | "squiggly" | "home" => Some("~".into()), // ~
"hash" | "hashtag" | "pound_sign" | "sharp" | "root" => Some("#".into()), // #
// Weather symbols
"sun" => Some("\x1b[33;1m\u{2600}\x1b[0m".to_string()), // Yellow Bold ☀
"moon" => Some("\x1b[36m\u{263d}\x1b[0m".to_string()), // Cyan ☽
"clouds" => Some("\x1b[37;1m\u{2601}\x1b[0m".to_string()), // White Bold ☁
"rain" => Some("\x1b[37;1m\u{2614}\x1b[0m".to_string()), // White Bold ☔
"fog" => Some("\x1b[37;1m\u{2592}\x1b[0m".to_string()), // White Bold ▒
"mist" => Some("\x1b[34m\u{2591}\x1b[0m".to_string()), // Blue ░
"haze" => Some("\x1b[33m\u{2591}\x1b[0m".to_string()), // Yellow ░
"snow" => Some("\x1b[37;1m\u{2744}\x1b[0m".to_string()), // White Bold ❄
"thunderstorm" => Some("\x1b[33;1m\u{26a1}\x1b[0m".to_string()), // Yellow Bold ⚡
// Reference for ansi codes https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
// Another good reference http://ascii-table.com/ansi-escape-sequences.php
// For setting title like `echo [$(char title) $(pwd) $(char bel)] | str collect`
"title" => Some("\x1b]2;".to_string()), // ESC]2; xterm sets window title
"bel" => Some('\x07'.to_string()), // Terminal Bell
"backspace" => Some('\x08'.to_string()), // Backspace
// Ansi Erase Sequences
"clear_screen" => Some("\x1b[J".to_string()), // clears the screen
"clear_screen_from_cursor_to_end" => Some("\x1b[0J".to_string()), // clears from cursor until end of screen
"clear_screen_from_cursor_to_beginning" => Some("\x1b[1J".to_string()), // clears from cursor to beginning of screen
"cls" | "clear_entire_screen" => Some("\x1b[2J".to_string()), // clears the entire screen
"erase_line" => Some("\x1b[K".to_string()), // clears the current line
"erase_line_from_cursor_to_end" => Some("\x1b[0K".to_string()), // clears from cursor to end of line
"erase_line_from_cursor_to_beginning" => Some("\x1b[1K".to_string()), // clears from cursor to start of line
"erase_entire_line" => Some("\x1b[2K".to_string()), // clears entire line
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::Char;
use super::ShellError;
#[test]
fn examples_work_as_expected() -> Result<(), ShellError> {
use crate::examples::test as test_examples;
Ok(test_examples(Char {})?)
}
}