From b8efd2a347833b279378837346bae41eab3c0a9a Mon Sep 17 00:00:00 2001 From: Douglas <32344964+NotTheDr01ds@users.noreply.github.com> Date: Tue, 29 Oct 2024 08:01:32 -0400 Subject: [PATCH] ansi name for clear-scrollback code (#14184) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Related to #14181 # Description Our understanding of `ESC[3J` has apparently been wrong. And I say "our" because I posted a [Super User answer](https://superuser.com/a/1738611/1210833) a couple of years ago with the same misconception (now fixed). In addition, the [crossterm crate doc](https://docs.rs/crossterm/latest/crossterm/terminal/enum.ClearType.html) is wrong on the topic. `ESC[3J` doesn't clear the screen plus the scrollback; it *only* clears the scrollback. Reference the official [Xterm Control Sequences doc](https://www.xfree86.org/4.8.0/ctlseqs.html). > CSI P s J > > Erase in Display (ED) > > P s = 0 → Erase Below (default) > P s = 1 → Erase Above > P s = 2 → Erase All > P s = 3 → Erase Saved Lines (xterm) This also means that: ```nu $"(ansi clear_entire_screen_plus_buffer)" ``` ... doesn't. This PR updates it to `ansi clear_scrollback_buffer` (short-code remains the same). # User-Facing Changes Breaking-change: `ansi clear_entire_screen_plus_buffer` is renamed `ansi clear_scrollback_buffer` # Tests + Formatting - :green_circle: `toolkit fmt` - :green_circle: `toolkit clippy` - :green_circle: `toolkit test` - :green_circle: `toolkit test stdlib` # After Submitting Self-documenting command via `ansi -l` --- crates/nu-command/src/platform/ansi/ansi_.rs | 3 ++- .../nu-command/tests/commands/platform/ansi_.rs | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/nu-command/src/platform/ansi/ansi_.rs b/crates/nu-command/src/platform/ansi/ansi_.rs index 43fd7d83df..13c229a456 100644 --- a/crates/nu-command/src/platform/ansi/ansi_.rs +++ b/crates/nu-command/src/platform/ansi/ansi_.rs @@ -448,7 +448,8 @@ static CODE_LIST: Lazy> = Lazy::new(|| { vec![ AnsiCode{ short_name: None, long_name:"clear_screen_from_cursor_to_end", code: "\x1b[0J".to_string()}, // clears from cursor until end of screen AnsiCode{ short_name: None, long_name:"clear_screen_from_cursor_to_beginning", code: "\x1b[1J".to_string()}, // clears from cursor to beginning of screen AnsiCode{ short_name: Some("cls"), long_name:"clear_entire_screen", code: "\x1b[2J".to_string()}, // clears the entire screen - AnsiCode{ short_name: Some("clsb"), long_name:"clear_entire_screen_plus_buffer", code: "\x1b[3J".to_string()}, // clear entire screen and delete all lines saved in the scrollback buffer + AnsiCode{ short_name: Some("clsb"), long_name:"clear_entire_screen_plus_buffer", code: "\x1b[2J\x1b[3J".to_string()}, // clear entire screen and delete all lines saved in the scrollback buffer + AnsiCode{ short_name: Some("clb"), long_name:"clear_scrollback_buffer", code: "\x1b[3J".to_string()}, // clear entire screen and delete all lines saved in the scrollback buffer AnsiCode{ short_name: None, long_name:"erase_line", code: "\x1b[K".to_string()}, // clears the current line AnsiCode{ short_name: None, long_name:"erase_line_from_cursor_to_end", code: "\x1b[0K".to_string()}, // clears from cursor to end of line AnsiCode{ short_name: None, long_name:"erase_line_from_cursor_to_beginning", code: "\x1b[1K".to_string()}, // clears from cursor to start of line diff --git a/crates/nu-command/tests/commands/platform/ansi_.rs b/crates/nu-command/tests/commands/platform/ansi_.rs index e08ae7ebf0..c7bea5cafb 100644 --- a/crates/nu-command/tests/commands/platform/ansi_.rs +++ b/crates/nu-command/tests/commands/platform/ansi_.rs @@ -11,5 +11,19 @@ fn test_ansi_shows_error_on_escape() { fn test_ansi_list_outputs_table() { let actual = nu!("ansi --list | length"); - assert_eq!(actual.out, "424"); + assert_eq!(actual.out, "425"); +} + +#[test] +fn test_ansi_codes() { + let actual = nu!("$'(ansi clear_scrollback_buffer)'"); + assert_eq!(actual.out, "\x1b[3J"); + + // Currently, bg is placed before fg in the results + // It's okay if something internally changes this, but + // if so, the test case will need to be updated to: + // assert_eq!(actual.out, "\x1b[31;48;2;0;255;0mHello\x1b[0m"); + + let actual = nu!("$'(ansi { fg: red, bg: \"#00ff00\" })Hello(ansi reset)'"); + assert_eq!(actual.out, "\x1b[48;2;0;255;0;31mHello\x1b[0m"); }