From ca05553fc66e319c4290ff7d5917a360ca9011ce Mon Sep 17 00:00:00 2001 From: nibon7 Date: Sun, 10 Dec 2023 05:24:19 +0800 Subject: [PATCH] Simplify `clear` implementation (#11273) # Description This PR uses the `crossterm` api to reimplement `clear` command, since `crossterm` is cross-platform. This seems to work on linux and windows. # User-Facing Changes N/A # Tests + Formatting - [x] `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - [x] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to check that you're using the standard code style - [x] `cargo test --workspace` to check that all tests pass (on Windows make sure to [enable developer mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging)) - [x] `cargo run -- -c "use std testing; testing run-tests --path crates/nu-std"` to run the tests for the standard library # After Submitting N/A --- crates/nu-command/src/platform/clear.rs | 47 ++++++++----------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/crates/nu-command/src/platform/clear.rs b/crates/nu-command/src/platform/clear.rs index abdd704cb..f264271f9 100644 --- a/crates/nu-command/src/platform/clear.rs +++ b/crates/nu-command/src/platform/clear.rs @@ -1,9 +1,12 @@ +use crossterm::{ + cursor::MoveTo, + terminal::{Clear as ClearCommand, ClearType}, + QueueableCommand, +}; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; -use nu_protocol::{ - Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Type, Value, -}; -use std::process::Command as CommandSys; +use nu_protocol::{Category, Example, PipelineData, ShellError, Signature, Type}; +use std::io::Write; #[derive(Clone)] pub struct Clear; @@ -25,37 +28,17 @@ impl Command for Clear { fn run( &self, - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, + _engine_state: &EngineState, + _stack: &mut Stack, + _call: &Call, _input: PipelineData, ) -> Result { - let span = call.head; + std::io::stdout() + .queue(ClearCommand(ClearType::All))? + .queue(MoveTo(0, 0))? + .flush()?; - if cfg!(windows) { - CommandSys::new("cmd") - .args(["/C", "cls"]) - .status() - .map_err(|e| ShellError::IOErrorSpanned { - msg: e.to_string(), - span, - })?; - } else if cfg!(unix) { - let mut cmd = CommandSys::new("/bin/sh"); - - if let Some(Value::String { val, .. }) = stack.get_env_var(engine_state, "TERM") { - cmd.env("TERM", val); - } - - cmd.args(["-c", "clear"]) - .status() - .map_err(|e| ShellError::IOErrorSpanned { - msg: e.to_string(), - span, - })?; - } - - Ok(Value::nothing(span).into_pipeline_data()) + Ok(PipelineData::Empty) } fn examples(&self) -> Vec {