From eedf833b6f43cb205742f17f254f355d8a152dd3 Mon Sep 17 00:00:00 2001 From: Douglas <32344964+NotTheDr01ds@users.noreply.github.com> Date: Mon, 28 Oct 2024 07:42:18 -0400 Subject: [PATCH] Send both 2J and 3J on clear (#14181) Fixes #14176 # Description Since the Linux `/usr/bin/clear` binary doesn't exhibit the issue in #14176, I checked to see what ANSI escapes it is emitting: ```nu nu -c '^clear; "111\n222\n333"' | less # or bash -c 'clear -x; echo -e "111\n222\n333"' | less ``` Both show the same thing: ``` ESC[HESC[2JESC[3J111 222 333 (END) ``` This is the equivalent of: ```nu $"(ansi home)(ansi clear_entire_screen)(ansi clear_entire_screen_plus_buffer)111\n222\n333" ``` However, our internal `clear` is sending only the Home and 3J. While this *should*, in theory, work, it's (a) clear that it doesn't, and (b) `/usr/bin/clear` seemingly knows this and already has the solution (or at least workaround). From looking at the `ncurses` source, it appears it is getting this information from the terminal capabilities. That said, support for `2J` and `3J` is fairly universal, and it's what we send in `clear` and `clear --keep-scrollback` anyway, so there's no harm AFAICT in sending both like `/usr/bin/clear` does. Also tested and fixes the issue on Windows. Note that PowerShell `Clear-Host` also did not have the issue. Side-note: It's interesting that on Tmux, which doesn't support 2J and 3J, that `/usr/bin/clear` knows this and doesn't send those codes, sending just an escape-[J instead. However, Nushell's `clear`, of course, isn't checking terminal capabilities, and is continuing to send the unsupported codes. Fortunately this doesn't appear to cause any issues on Tmux. # User-Facing Changes None, AFAICT - Bugfix only. # Tests + Formatting - :green_circle: `toolkit fmt` - :green_circle: `toolkit clippy` - :green_circle: `toolkit test` - :green_circle: `toolkit test stdlib` # After Submitting N/A --- crates/nu-command/src/platform/clear.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/crates/nu-command/src/platform/clear.rs b/crates/nu-command/src/platform/clear.rs index b47db161c6..21e3a3054c 100644 --- a/crates/nu-command/src/platform/clear.rs +++ b/crates/nu-command/src/platform/clear.rs @@ -41,14 +41,21 @@ impl Command for Clear { call: &Call, _input: PipelineData, ) -> Result { - let clear_type: ClearType = match call.has_flag(engine_state, stack, "keep-scrollback")? { - true => ClearType::All, - _ => ClearType::Purge, + match call.has_flag(engine_state, stack, "keep-scrollback")? { + true => { + std::io::stdout() + .queue(MoveTo(0, 0))? + .queue(ClearCommand(ClearType::All))? + .flush()?; + } + _ => { + std::io::stdout() + .queue(MoveTo(0, 0))? + .queue(ClearCommand(ClearType::All))? + .queue(ClearCommand(ClearType::Purge))? + .flush()?; + } }; - std::io::stdout() - .queue(ClearCommand(clear_type))? - .queue(MoveTo(0, 0))? - .flush()?; Ok(PipelineData::Empty) }