From 057bfff0cb2a9bdad9f4e64aeec448a3e094622f Mon Sep 17 00:00:00 2001 From: Darren Schroeder <343840+fdncred@users.noreply.github.com> Date: Thu, 20 Jan 2022 21:31:33 -0600 Subject: [PATCH] add `term size` command (#792) * add `term-size` command * Update term_size.rs Co-authored-by: JT <547158+jntrnr@users.noreply.github.com> --- crates/nu-command/src/default_context.rs | 1 + crates/nu-command/src/platform/mod.rs | 2 + crates/nu-command/src/platform/term_size.rs | 113 ++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 crates/nu-command/src/platform/term_size.rs diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index 6a925eee54..353cf39941 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -172,6 +172,7 @@ pub fn create_default_context(cwd: impl AsRef) -> EngineState { Input, Kill, Sleep, + TermSize, }; // Date diff --git a/crates/nu-command/src/platform/mod.rs b/crates/nu-command/src/platform/mod.rs index 45d2d87c66..d18209ba3b 100644 --- a/crates/nu-command/src/platform/mod.rs +++ b/crates/nu-command/src/platform/mod.rs @@ -3,9 +3,11 @@ mod clear; mod input; mod kill; mod sleep; +mod term_size; pub use ansi::{Ansi, AnsiGradient, AnsiStrip}; pub use clear::Clear; pub use input::Input; pub use kill::Kill; pub use sleep::Sleep; +pub use term_size::TermSize; diff --git a/crates/nu-command/src/platform/term_size.rs b/crates/nu-command/src/platform/term_size.rs new file mode 100644 index 0000000000..2b6506aedd --- /dev/null +++ b/crates/nu-command/src/platform/term_size.rs @@ -0,0 +1,113 @@ +use nu_protocol::ast::Call; +use nu_protocol::engine::{Command, EngineState, Stack}; +use nu_protocol::{Category, Example, IntoPipelineData, PipelineData, Signature, Span, Value}; +use terminal_size::{terminal_size, Height, Width}; + +#[derive(Clone)] +pub struct TermSize; + +impl Command for TermSize { + fn name(&self) -> &str { + "term size" + } + + fn usage(&self) -> &str { + "Returns the terminal size" + } + + fn signature(&self) -> Signature { + Signature::build("term size") + .switch( + "columns", + "Report only the width of the terminal", + Some('c'), + ) + .switch("rows", "Report only the height of the terminal", Some('r')) + .category(Category::Platform) + } + + fn examples(&self) -> Vec { + vec![ + Example { + description: "Return the width height of the terminal", + example: "term size", + result: None, + }, + Example { + description: "Return the width (columns) of the terminal", + example: "term size -c", + result: None, + }, + Example { + description: "Return the height (rows) of the terminal", + example: "term size -r", + result: None, + }, + ] + } + + fn run( + &self, + _engine_state: &EngineState, + _stack: &mut Stack, + call: &Call, + _input: PipelineData, + ) -> Result { + let head = call.head; + let wide = call.has_flag("columns"); + let tall = call.has_flag("rows"); + + let (cols, rows) = match terminal_size() { + Some((w, h)) => (Width(w.0), Height(h.0)), + None => (Width(0), Height(0)), + }; + + Ok((match (wide, tall) { + (true, false) => Value::Record { + cols: vec!["columns".into()], + vals: vec![Value::Int { + val: cols.0 as i64, + span: Span::test_data(), + }], + span: head, + }, + (true, true) => Value::Record { + cols: vec!["columns".into(), "rows".into()], + vals: vec![ + Value::Int { + val: cols.0 as i64, + span: Span::test_data(), + }, + Value::Int { + val: rows.0 as i64, + span: Span::test_data(), + }, + ], + span: head, + }, + (false, true) => Value::Record { + cols: vec!["rows".into()], + vals: vec![Value::Int { + val: rows.0 as i64, + span: Span::test_data(), + }], + span: head, + }, + (false, false) => Value::Record { + cols: vec!["columns".into(), "rows".into()], + vals: vec![ + Value::Int { + val: cols.0 as i64, + span: Span::test_data(), + }, + Value::Int { + val: rows.0 as i64, + span: Span::test_data(), + }, + ], + span: head, + }, + }) + .into_pipeline_data()) + } +}