From 50fb97f6b736f2a01ee356845744810cb7ff1810 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Sun, 8 Mar 2020 18:33:30 +1300 Subject: [PATCH] Merge env into $nu and simplify table/get (#1463) --- crates/nu-cli/src/cli.rs | 1 - crates/nu-cli/src/commands.rs | 2 - crates/nu-cli/src/commands/env.rs | 91 ---------------- crates/nu-cli/src/commands/get.rs | 20 +--- crates/nu-cli/src/commands/pivot.rs | 16 +-- crates/nu-cli/src/data/base/shape.rs | 136 +++--------------------- crates/nu-cli/src/evaluate/variables.rs | 20 ++++ crates/nu-cli/src/format/table.rs | 23 +--- crates/nu-protocol/src/lib.rs | 2 +- crates/nu-protocol/src/value.rs | 21 ++++ docs/commands/env.md | 27 ----- 11 files changed, 63 insertions(+), 296 deletions(-) delete mode 100644 crates/nu-cli/src/commands/env.rs delete mode 100644 docs/commands/env.md diff --git a/crates/nu-cli/src/cli.rs b/crates/nu-cli/src/cli.rs index 9d05732333..76aaa54f6f 100644 --- a/crates/nu-cli/src/cli.rs +++ b/crates/nu-cli/src/cli.rs @@ -240,7 +240,6 @@ pub fn create_default_context( per_item_command(Ls), per_item_command(Du), whole_stream_command(Cd), - whole_stream_command(Env), per_item_command(Remove), per_item_command(Open), whole_stream_command(Config), diff --git a/crates/nu-cli/src/commands.rs b/crates/nu-cli/src/commands.rs index 3dfb3d17c8..06cba20bf0 100644 --- a/crates/nu-cli/src/commands.rs +++ b/crates/nu-cli/src/commands.rs @@ -23,7 +23,6 @@ pub(crate) mod du; pub(crate) mod echo; pub(crate) mod edit; pub(crate) mod enter; -pub(crate) mod env; #[allow(unused)] pub(crate) mod evaluate_by; pub(crate) mod exit; @@ -126,7 +125,6 @@ pub(crate) mod clear; pub(crate) use clear::Clear; pub(crate) mod touch; pub(crate) use enter::Enter; -pub(crate) use env::Env; #[allow(unused_imports)] pub(crate) use evaluate_by::EvaluateBy; pub(crate) use exit::Exit; diff --git a/crates/nu-cli/src/commands/env.rs b/crates/nu-cli/src/commands/env.rs deleted file mode 100644 index 5fa72651a6..0000000000 --- a/crates/nu-cli/src/commands/env.rs +++ /dev/null @@ -1,91 +0,0 @@ -use crate::cli::History; -use crate::data::config; -use crate::prelude::*; -use nu_errors::ShellError; -use nu_protocol::{Dictionary, Signature, TaggedDictBuilder, UntaggedValue, Value}; - -use crate::commands::WholeStreamCommand; -use indexmap::IndexMap; - -pub struct Env; - -impl WholeStreamCommand for Env { - fn name(&self) -> &str { - "env" - } - - fn signature(&self) -> Signature { - Signature::build("env") - } - - fn usage(&self) -> &str { - "Get the current environment." - } - - fn run( - &self, - args: CommandArgs, - registry: &CommandRegistry, - ) -> Result { - env(args, registry) - } -} - -pub fn get_environment(tag: Tag) -> Result> { - let mut indexmap = IndexMap::new(); - - let path = std::env::current_dir()?; - indexmap.insert( - "cwd".to_string(), - UntaggedValue::path(path).into_value(&tag), - ); - - if let Some(home) = dirs::home_dir() { - indexmap.insert( - "home".to_string(), - UntaggedValue::path(home).into_value(&tag), - ); - } - - let config = config::default_path()?; - indexmap.insert( - "config".to_string(), - UntaggedValue::path(config).into_value(&tag), - ); - - let history = History::path(); - indexmap.insert( - "history".to_string(), - UntaggedValue::path(history).into_value(&tag), - ); - - let temp = std::env::temp_dir(); - indexmap.insert( - "temp".to_string(), - UntaggedValue::path(temp).into_value(&tag), - ); - - let mut dict = TaggedDictBuilder::new(&tag); - for v in std::env::vars() { - dict.insert_untagged(v.0, UntaggedValue::string(v.1)); - } - if !dict.is_empty() { - indexmap.insert("vars".to_string(), dict.into_value()); - } - - Ok(UntaggedValue::Row(Dictionary::from(indexmap)).into_value(&tag)) -} - -pub fn env(args: CommandArgs, registry: &CommandRegistry) -> Result { - let args = args.evaluate_once(registry)?; - - let mut env_out = VecDeque::new(); - let tag = args.call_info.name_tag.clone(); - - let value = get_environment(tag)?; - env_out.push_back(value); - - let env_out = futures::stream::iter(env_out); - - Ok(env_out.to_output_stream()) -} diff --git a/crates/nu-cli/src/commands/get.rs b/crates/nu-cli/src/commands/get.rs index e5434ef78f..841142178d 100644 --- a/crates/nu-cli/src/commands/get.rs +++ b/crates/nu-cli/src/commands/get.rs @@ -1,7 +1,5 @@ use crate::commands::WholeStreamCommand; -use crate::data::base::shape::Shapes; use crate::prelude::*; -use futures_util::pin_mut; use indexmap::set::IndexSet; use log::trace; use nu_errors::ShellError; @@ -180,23 +178,15 @@ pub fn get_column_path(path: &ColumnPath, obj: &Value) -> Result Result { if fields.is_empty() { let stream = async_stream! { - let values = input.values; - pin_mut!(values); + let mut vec = input.drain_vec().await; - let mut shapes = Shapes::new(); - let mut index = 0; - - while let Some(row) = values.next().await { - shapes.add(&row, index); - index += 1; - } - - for row in shapes.to_values() { - yield ReturnSuccess::value(row); + let descs = nu_protocol::merge_descriptors(&vec); + for desc in descs { + yield ReturnSuccess::value(desc); } }; diff --git a/crates/nu-cli/src/commands/pivot.rs b/crates/nu-cli/src/commands/pivot.rs index 8ba557de3f..8b5efbe9d3 100644 --- a/crates/nu-cli/src/commands/pivot.rs +++ b/crates/nu-cli/src/commands/pivot.rs @@ -1,7 +1,9 @@ use crate::commands::WholeStreamCommand; use crate::prelude::*; use nu_errors::ShellError; -use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value}; +use nu_protocol::{ + merge_descriptors, ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, +}; use nu_source::{SpannedItem, Tagged}; use nu_value_ext::get_data_by_key; @@ -52,18 +54,6 @@ impl WholeStreamCommand for Pivot { } } -fn merge_descriptors(values: &[Value]) -> Vec { - let mut ret = vec![]; - for value in values { - for desc in value.data_descriptors() { - if !ret.contains(&desc) { - ret.push(desc); - } - } - } - ret -} - pub fn pivot(args: PivotArgs, context: RunnableContext) -> Result { let stream = async_stream! { let input = context.input.into_vec().await; diff --git a/crates/nu-cli/src/data/base/shape.rs b/crates/nu-cli/src/data/base/shape.rs index f33596b32f..b29d00125c 100644 --- a/crates/nu-cli/src/data/base/shape.rs +++ b/crates/nu-cli/src/data/base/shape.rs @@ -1,17 +1,11 @@ use crate::prelude::*; use chrono::{DateTime, Utc}; -use indexmap::IndexMap; -use nu_errors::ShellError; use nu_protocol::RangeInclusion; -use nu_protocol::{ - format_primitive, ColumnPath, Dictionary, Evaluate, Primitive, ShellTypeName, - TaggedDictBuilder, UntaggedValue, Value, -}; +use nu_protocol::{format_primitive, ColumnPath, Dictionary, Primitive, UntaggedValue, Value}; use nu_source::{b, PrettyDebug}; use std::collections::BTreeMap; use std::fmt::Debug; use std::hash::Hash; -use std::io::Write; use std::path::PathBuf; #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] @@ -193,13 +187,17 @@ impl PrettyDebug for FormatInlineShape { "[", b::kind("row") + b::space() - + b::intersperse( - row.keys().map(|key| match key { - Column::String(string) => b::description(string), - Column::Value => b::blank(), - }), - b::space(), - ), + + if row.keys().len() <= 6 { + b::intersperse( + row.keys().map(|key| match key { + Column::String(string) => b::description(string), + Column::Value => b::blank(), + }), + b::space(), + ) + } else { + b::description(format!("{} columns", row.keys().len())) + }, "]", ) .group(), @@ -269,113 +267,3 @@ impl Into for &str { Column::String(self.to_string()) } } - -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] -pub enum Shape { - Primitive(&'static str), - Row(Vec), - Table { from: usize, to: usize }, - Error(ShellError), - Block(Evaluate), -} - -impl Shape { - pub fn for_value(value: &Value) -> Shape { - match &value.value { - UntaggedValue::Primitive(p) => Shape::Primitive(p.type_name()), - UntaggedValue::Row(row) => Shape::for_dict(row), - UntaggedValue::Table(table) => Shape::Table { - from: 0, - to: table.len(), - }, - UntaggedValue::Error(error) => Shape::Error(error.clone()), - UntaggedValue::Block(block) => Shape::Block(block.clone()), - } - } - - fn for_dict(dict: &Dictionary) -> Shape { - Shape::Row(dict.keys().map(|key| Column::String(key.clone())).collect()) - } - - pub fn describe(&self, w: &mut impl Write) -> Result<(), std::io::Error> { - match self { - Shape::Primitive(desc) => write!(w, "[{}]", desc), - Shape::Row(d) => write!( - w, - "[row: {}]", - d.iter() - .map(|c| match c { - Column::String(s) => s.clone(), - Column::Value => "".to_owned(), - }) - .join(", ") - ), - Shape::Table { to, .. } => { - if *to == 1 { - write!(w, "[table: {} row]", to) - } else { - write!(w, "[table: {} rows]", to) - } - } - Shape::Error(_) => write!(w, "[error]"), - Shape::Block(_) => write!(w, "[block]"), - } - } - - fn to_value(&self) -> Value { - let mut out = vec![]; - self.describe(&mut out) - .expect("Writing into a Vec can't fail"); - let string = String::from_utf8_lossy(&out); - - UntaggedValue::string(string).into_untagged_value() - } -} - -pub struct Shapes { - shapes: IndexMap>, -} - -impl Shapes { - pub fn new() -> Shapes { - Shapes { - shapes: IndexMap::default(), - } - } - - pub fn add(&mut self, value: &Value, row: usize) { - let shape = Shape::for_value(value); - - self.shapes - .entry(shape) - .and_modify(|indexes| indexes.push(row)) - .or_insert_with(|| vec![row]); - } - - pub fn to_values(&self) -> Vec { - if self.shapes.len() == 1 { - if let Some(shape) = self.shapes.keys().nth(0) { - let mut tagged_dict = TaggedDictBuilder::new(Tag::unknown()); - tagged_dict.insert_untagged("type", shape.to_value()); - tagged_dict.insert_untagged("rows", UntaggedValue::string("all")); - vec![tagged_dict.into_value()] - } else { - unreachable!("Internal error: impossible state in to_values") - } - } else { - self.shapes - .iter() - .map(|(shape, rows)| { - let rows = rows.iter().map(|i| i.to_string()).join(", "); - - let mut tagged_dict = TaggedDictBuilder::new(Tag::unknown()); - tagged_dict.insert_untagged("type", shape.to_value()); - tagged_dict - .insert_untagged("rows", UntaggedValue::string(format!("[ {} ]", rows))); - - tagged_dict.into_value() - }) - .collect() - } - } -} diff --git a/crates/nu-cli/src/evaluate/variables.rs b/crates/nu-cli/src/evaluate/variables.rs index d3d4ddc05c..f46255c264 100644 --- a/crates/nu-cli/src/evaluate/variables.rs +++ b/crates/nu-cli/src/evaluate/variables.rs @@ -1,3 +1,4 @@ +use crate::cli::History; use nu_errors::ShellError; use nu_protocol::{TaggedDictBuilder, UntaggedValue, Value}; use nu_source::Tag; @@ -27,5 +28,24 @@ pub fn nu(tag: impl Into) -> Result { } nu_dict.insert_value("path", UntaggedValue::table(&table).into_value(&tag)); + let path = std::env::current_dir()?; + nu_dict.insert_value("cwd", UntaggedValue::path(path).into_value(&tag)); + + if let Some(home) = dirs::home_dir() { + nu_dict.insert_value("home-dir", UntaggedValue::path(home).into_value(&tag)); + } + + let temp = std::env::temp_dir(); + nu_dict.insert_value("temp-dir", UntaggedValue::path(temp).into_value(&tag)); + + let config = crate::data::config::default_path()?; + nu_dict.insert_value("config-path", UntaggedValue::path(config).into_value(&tag)); + + let history = History::path(); + nu_dict.insert_value( + "history-path", + UntaggedValue::path(history).into_value(&tag), + ); + Ok(nu_dict.into_value()) } diff --git a/crates/nu-cli/src/format/table.rs b/crates/nu-cli/src/format/table.rs index 6549898883..e1831c7327 100644 --- a/crates/nu-cli/src/format/table.rs +++ b/crates/nu-cli/src/format/table.rs @@ -26,27 +26,6 @@ enum TableMode { } impl TableView { - fn merge_descriptors(values: &[Value]) -> Vec { - let mut ret: Vec = vec![]; - let value_column = "".to_string(); - for value in values { - let descs = value.data_descriptors(); - - if descs.is_empty() { - if !ret.contains(&value_column) { - ret.push("".to_string()); - } - } else { - for desc in value.data_descriptors() { - if !ret.contains(&desc) { - ret.push(desc); - } - } - } - } - ret - } - pub fn from_list(values: &[Value], starting_idx: usize) -> Option { if values.is_empty() { return None; @@ -55,7 +34,7 @@ impl TableView { // Different platforms want different amounts of buffer, not sure why let termwidth = std::cmp::max(textwrap::termwidth(), 20); - let mut headers = TableView::merge_descriptors(values); + let mut headers = nu_protocol::merge_descriptors(values); let mut entries = values_to_entries(values, &mut headers, starting_idx); let max_per_column = max_per_column(&headers, &entries, values.len()); diff --git a/crates/nu-protocol/src/lib.rs b/crates/nu-protocol/src/lib.rs index ba4dbb0941..08d96f58cd 100644 --- a/crates/nu-protocol/src/lib.rs +++ b/crates/nu-protocol/src/lib.rs @@ -23,4 +23,4 @@ pub use crate::value::evaluate::{Evaluate, EvaluateTrait, Scope}; pub use crate::value::primitive::Primitive; pub use crate::value::primitive::{format_date, format_duration, format_primitive}; pub use crate::value::range::{Range, RangeInclusion}; -pub use crate::value::{UntaggedValue, Value}; +pub use crate::value::{merge_descriptors, UntaggedValue, Value}; diff --git a/crates/nu-protocol/src/value.rs b/crates/nu-protocol/src/value.rs index beaf2a557f..de3f0f62f3 100644 --- a/crates/nu-protocol/src/value.rs +++ b/crates/nu-protocol/src/value.rs @@ -378,3 +378,24 @@ impl From for UntaggedValue { UntaggedValue::Error(e) } } + +pub fn merge_descriptors(values: &[Value]) -> Vec { + let mut ret: Vec = vec![]; + let value_column = "".to_string(); + for value in values { + let descs = value.data_descriptors(); + + if descs.is_empty() { + if !ret.contains(&value_column) { + ret.push("".to_string()); + } + } else { + for desc in value.data_descriptors() { + if !ret.contains(&desc) { + ret.push(desc); + } + } + } + } + ret +} diff --git a/docs/commands/env.md b/docs/commands/env.md deleted file mode 100644 index 5dd08fac51..0000000000 --- a/docs/commands/env.md +++ /dev/null @@ -1,27 +0,0 @@ -# env - -The `env` command prints to terminal the environment of nushell - -This includes -- cwd : the path to the current working the directory (`cwd`), -- home : the path to the home directory -- config : the path to the config file for nushell -- history : the path to the nushell command history -- temp : the path to the temp file -- vars : descriptor variable for the table - -`env` does not take any arguments, and ignores any arguments given. - - -## Examples - - - -```shell -/home/username/mynushell/docs/commands(master)> env -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━━━━━━━ - cwd │ home │ config │ history │ temp │ vars -────────────────────────────────────────┼────────────────┼───────────────────────────────────────┼────────────────────────────────────────────┼──────┼──────────────── - /home/username/mynushell/docs/commands │ /home/username │ /home/username/.config/nu/config.toml │ /home/username/.local/share/nu/history.txt │ /tmp │ [table: 1 row] -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━━━━━━━ -``` -