Skip to content

Commit

Permalink
Terminal escape sequence constants (#2461)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey authored Nov 11, 2024
1 parent 1ae6a6d commit bbc0872
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 11 deletions.
46 changes: 45 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,30 @@ A number of constants are predefined:
| `HEX`<sup>1.27.0</sup> | `"0123456789abcdef"` |
| `HEXLOWER`<sup>1.27.0</sup> | `"0123456789abcdef"` |
| `HEXUPPER`<sup>1.27.0</sup> | `"0123456789ABCDEF"` |
| `CLEAR`<sup>master</sup> | `"\ec"` |
| `NORMAL`<sup>master</sup> | `"\e[0m"` |
| `BOLD`<sup>master</sup> | `"\e[1m"` |
| `ITALIC`<sup>master</sup> | `"\e[3m"` |
| `UNDERLINE`<sup>master</sup> | `"\e[4m"` |
| `INVERT`<sup>master</sup> | `"\e[7m"` |
| `HIDE`<sup>master</sup> | `"\e[8m"` |
| `STRIKETHROUGH`<sup>master</sup> | `"\e[9m"` |
| `BLACK`<sup>master</sup> | `"\e[30m"` |
| `RED`<sup>master</sup> | `"\e[31m"` |
| `GREEN`<sup>master</sup> | `"\e[32m"` |
| `YELLOW`<sup>master</sup> | `"\e[33m"` |
| `BLUE`<sup>master</sup> | `"\e[34m"` |
| `MAGENTA`<sup>master</sup> | `"\e[35m"` |
| `CYAN`<sup>master</sup> | `"\e[36m"` |
| `WHITE`<sup>master</sup> | `"\e[37m"` |
| `BG_BLACK`<sup>master</sup> | `"\e[40m"` |
| `BG_RED`<sup>master</sup> | `"\e[41m"` |
| `BG_GREEN`<sup>master</sup> | `"\e[42m"` |
| `BG_YELLOW`<sup>master</sup> | `"\e[43m"` |
| `BG_BLUE`<sup>master</sup> | `"\e[44m"` |
| `BG_MAGENTA`<sup>master</sup> | `"\e[45m"` |
| `BG_CYAN`<sup>master</sup> | `"\e[46m"` |
| `BG_WHITE`<sup>master</sup> | `"\e[47m"` |

```just
@foo:
Expand All @@ -1888,9 +1912,29 @@ $ just foo
0123456789abcdef
```

Constants starting with `\e` are
[ANSI escape sequences](https://en.wikipedia.org/wiki/ANSI_escape_code).

`CLEAR` clears the screen, similar to the `clear` command. The rest are of the
form `\e[Nm`, where `N` is an integer, and set terminal display attributes.

Terminal display attribute escape sequences can be combined, for example text
weight `BOLD`, text style `STRIKETHROUGH`, foreground color `CYAN`, and
background color `BG_BLUE`. They should be followed by `NORMAL`, to reset the
terminal back to normal.

Escape sequences should be quoted, since `[` is treated as a special character
by some shells.

```just
@foo:
echo '{{BOLD + STRIKETHROUGH + CYAN + BG_BLUE}}Hi!{{NORMAL}}'
```

### Attributes

Recipes, `mod` statements, and aliases may be annotated with attributes that change their behavior.
Recipes, `mod` statements, and aliases may be annotated with attributes that
change their behavior.

| Name | Type | Description |
|------|------|-------------|
Expand Down
4 changes: 4 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ build-book:
mdbook build book/en
mdbook build book/zh

[group: 'dev']
print-readme-constants-table:
cargo test constants::tests::readme_table -- --nocapture

# run all polyglot recipes
[group: 'demo']
polyglot: _python _js _perl _sh _ruby
Expand Down
63 changes: 53 additions & 10 deletions src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,58 @@
use super::*;

const CONSTANTS: [(&str, &str, &str); 27] = [
("HEX", "0123456789abcdef", "1.27.0"),
("HEXLOWER", "0123456789abcdef", "1.27.0"),
("HEXUPPER", "0123456789ABCDEF", "1.27.0"),
("CLEAR", "\x1bc", "master"),
("NORMAL", "\x1b[0m", "master"),
("BOLD", "\x1b[1m", "master"),
("ITALIC", "\x1b[3m", "master"),
("UNDERLINE", "\x1b[4m", "master"),
("INVERT", "\x1b[7m", "master"),
("HIDE", "\x1b[8m", "master"),
("STRIKETHROUGH", "\x1b[9m", "master"),
("BLACK", "\x1b[30m", "master"),
("RED", "\x1b[31m", "master"),
("GREEN", "\x1b[32m", "master"),
("YELLOW", "\x1b[33m", "master"),
("BLUE", "\x1b[34m", "master"),
("MAGENTA", "\x1b[35m", "master"),
("CYAN", "\x1b[36m", "master"),
("WHITE", "\x1b[37m", "master"),
("BG_BLACK", "\x1b[40m", "master"),
("BG_RED", "\x1b[41m", "master"),
("BG_GREEN", "\x1b[42m", "master"),
("BG_YELLOW", "\x1b[43m", "master"),
("BG_BLUE", "\x1b[44m", "master"),
("BG_MAGENTA", "\x1b[45m", "master"),
("BG_CYAN", "\x1b[46m", "master"),
("BG_WHITE", "\x1b[47m", "master"),
];

pub(crate) fn constants() -> &'static HashMap<&'static str, &'static str> {
static CONSTANTS: OnceLock<HashMap<&str, &str>> = OnceLock::new();

CONSTANTS.get_or_init(|| {
vec![
("HEX", "0123456789abcdef"),
("HEXLOWER", "0123456789abcdef"),
("HEXUPPER", "0123456789ABCDEF"),
]
.into_iter()
.collect()
static MAP: OnceLock<HashMap<&str, &str>> = OnceLock::new();
MAP.get_or_init(|| {
CONSTANTS
.into_iter()
.map(|(name, value, _version)| (name, value))
.collect()
})
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn readme_table() {
println!("| Name | Value |");
println!("|------|-------------|");
for (name, value, version) in CONSTANTS {
println!(
"| `{name}`<sup>{version}</sup> | `\"{}\"` |",
value.replace('\x1b', "\\e")
);
}
}
}

0 comments on commit bbc0872

Please sign in to comment.