mirror of
https://github.com/nushell/nushell.git
synced 2025-02-23 05:51:28 +01:00
Config refactoring baseline.
The initial configuration refactoring already gave significant benefits with my use case. On another note, Commands should know and ask for configuration variables. We could, as we refactor, add the ability for commands to tell what configuration variables knows about and their types. This way, completers can be used too when using `config` command if we also add a sub command that config could set variables to. Commands stating the config variables they know about will allow us to implement it in `help` and display them.
This commit is contained in:
parent
8d269f62dd
commit
05aca1c157
@ -1,5 +1,8 @@
|
||||
use crate::commands::UnevaluatedCallInfo;
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::data::config::table::AutoPivotMode;
|
||||
use crate::data::config::table::HasTableProperties;
|
||||
use crate::data::config::NuConfig as Configuration;
|
||||
use crate::data::value::format_leaf;
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
@ -82,28 +85,13 @@ impl RunnableContextWithoutInput {
|
||||
}
|
||||
|
||||
pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellError> {
|
||||
let configuration = Configuration::new();
|
||||
|
||||
let binary = context.get_command("binaryview");
|
||||
let text = context.get_command("textview");
|
||||
let table = context.get_command("table");
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum AutoPivotMode {
|
||||
Auto,
|
||||
Always,
|
||||
Never,
|
||||
}
|
||||
|
||||
let pivot_mode = crate::data::config::config(Tag::unknown());
|
||||
let pivot_mode = if let Some(v) = pivot_mode?.get("pivot_mode") {
|
||||
match v.as_string() {
|
||||
Ok(m) if m.to_lowercase() == "auto" => AutoPivotMode::Auto,
|
||||
Ok(m) if m.to_lowercase() == "always" => AutoPivotMode::Always,
|
||||
Ok(m) if m.to_lowercase() == "never" => AutoPivotMode::Never,
|
||||
_ => AutoPivotMode::Always,
|
||||
}
|
||||
} else {
|
||||
AutoPivotMode::Always
|
||||
};
|
||||
let pivot_mode = configuration.pivot_mode();
|
||||
|
||||
let (mut input_stream, context) = RunnableContextWithoutInput::convert(context);
|
||||
let term_width = context.host.lock().width();
|
||||
|
@ -1,9 +1,11 @@
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::data::config::table::HasTableProperties;
|
||||
use crate::data::config::NuConfig as TableConfiguration;
|
||||
use crate::data::value::{format_leaf, style_leaf};
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Primitive, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_table::{draw_table, Alignment, StyledString, TextStyle, Theme};
|
||||
use nu_table::{draw_table, Alignment, StyledString, TextStyle};
|
||||
use std::time::Instant;
|
||||
|
||||
const STREAM_PAGE_SIZE: usize = 1000;
|
||||
@ -35,102 +37,42 @@ impl WholeStreamCommand for Table {
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
table(args, registry).await
|
||||
table(TableConfiguration::new(), args, registry).await
|
||||
}
|
||||
}
|
||||
|
||||
fn str_to_color(s: String) -> Option<ansi_term::Color> {
|
||||
match s.as_str() {
|
||||
"g" | "green" => Some(ansi_term::Color::Green),
|
||||
"r" | "red" => Some(ansi_term::Color::Red),
|
||||
"u" | "blue" => Some(ansi_term::Color::Blue),
|
||||
"b" | "black" => Some(ansi_term::Color::Black),
|
||||
"y" | "yellow" => Some(ansi_term::Color::Yellow),
|
||||
"p" | "purple" => Some(ansi_term::Color::Purple),
|
||||
"c" | "cyan" => Some(ansi_term::Color::Cyan),
|
||||
"w" | "white" => Some(ansi_term::Color::White),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_list(values: &[Value], starting_idx: usize) -> nu_table::Table {
|
||||
let config = crate::data::config::config(Tag::unknown());
|
||||
|
||||
let header_style = if let Ok(config) = &config {
|
||||
let header_align = config.get("header_align").map_or(Alignment::Left, |a| {
|
||||
a.as_string()
|
||||
.map_or(Alignment::Center, |a| match a.to_lowercase().as_str() {
|
||||
"center" | "c" => Alignment::Center,
|
||||
"right" | "r" => Alignment::Right,
|
||||
_ => Alignment::Center,
|
||||
})
|
||||
});
|
||||
|
||||
let header_color = match config.get("header_color") {
|
||||
Some(c) => match c.as_string() {
|
||||
Ok(color) => str_to_color(color.to_lowercase()).unwrap_or(ansi_term::Color::Green),
|
||||
_ => ansi_term::Color::Green,
|
||||
},
|
||||
_ => ansi_term::Color::Green,
|
||||
};
|
||||
|
||||
let header_bold = config
|
||||
.get("header_bold")
|
||||
.map(|x| x.as_bool().unwrap_or(true))
|
||||
.unwrap_or(true);
|
||||
|
||||
TextStyle {
|
||||
alignment: header_align,
|
||||
color: Some(header_color),
|
||||
is_bold: header_bold,
|
||||
}
|
||||
} else {
|
||||
TextStyle::default_header()
|
||||
pub fn from_list(
|
||||
values: &[Value],
|
||||
configuration: &TableConfiguration,
|
||||
starting_idx: usize,
|
||||
) -> nu_table::Table {
|
||||
let header_style = TextStyle {
|
||||
is_bold: configuration.header_bold(),
|
||||
alignment: configuration.header_alignment(),
|
||||
color: configuration.header_color(),
|
||||
};
|
||||
|
||||
let mut headers: Vec<StyledString> = nu_protocol::merge_descriptors(values)
|
||||
.into_iter()
|
||||
.map(|x| StyledString::new(x, header_style.clone()))
|
||||
.collect();
|
||||
let entries = values_to_entries(values, &mut headers, starting_idx);
|
||||
let entries = values_to_entries(values, &mut headers, configuration, starting_idx);
|
||||
|
||||
if let Ok(config) = config {
|
||||
if let Some(style) = config.get("table_mode") {
|
||||
if let Ok(table_mode) = style.as_string() {
|
||||
if table_mode == "light" {
|
||||
return nu_table::Table {
|
||||
headers,
|
||||
data: entries,
|
||||
theme: Theme::light(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nu_table::Table {
|
||||
headers,
|
||||
data: entries,
|
||||
theme: Theme::compact(),
|
||||
}
|
||||
}
|
||||
|
||||
fn are_table_indexes_disabled() -> bool {
|
||||
let config = crate::data::config::config(Tag::unknown());
|
||||
match config {
|
||||
Ok(config) => {
|
||||
let disable_indexes = config.get("disable_table_indexes");
|
||||
disable_indexes.map_or(false, |x| x.as_bool().unwrap_or(false))
|
||||
}
|
||||
_ => false,
|
||||
theme: configuration.table_mode(),
|
||||
}
|
||||
}
|
||||
|
||||
fn values_to_entries(
|
||||
values: &[Value],
|
||||
headers: &mut Vec<StyledString>,
|
||||
configuration: &TableConfiguration,
|
||||
starting_idx: usize,
|
||||
) -> Vec<Vec<StyledString>> {
|
||||
let disable_indexes = are_table_indexes_disabled();
|
||||
let disable_indexes = configuration.disabled_indexes();
|
||||
|
||||
let mut entries = vec![];
|
||||
|
||||
if headers.is_empty() {
|
||||
@ -212,7 +154,11 @@ fn values_to_entries(
|
||||
entries
|
||||
}
|
||||
|
||||
async fn table(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
||||
async fn table(
|
||||
configuration: TableConfiguration,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let registry = registry.clone();
|
||||
let mut args = args.evaluate_once(®istry).await?;
|
||||
let mut finished = false;
|
||||
@ -289,7 +235,7 @@ async fn table(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputSt
|
||||
let input: Vec<Value> = new_input.into();
|
||||
|
||||
if !input.is_empty() {
|
||||
let t = from_list(&input, start_number);
|
||||
let t = from_list(&input, &configuration, start_number);
|
||||
|
||||
draw_table(&t, term_width);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
mod conf;
|
||||
mod nuconfig;
|
||||
pub mod table;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests;
|
||||
|
128
crates/nu-cli/src/data/config/table.rs
Normal file
128
crates/nu-cli/src/data/config/table.rs
Normal file
@ -0,0 +1,128 @@
|
||||
use crate::data::config::nuconfig::NuConfig;
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum AutoPivotMode {
|
||||
Auto,
|
||||
Always,
|
||||
Never,
|
||||
}
|
||||
|
||||
pub trait HasTableProperties: Debug + Send {
|
||||
fn pivot_mode(&self) -> AutoPivotMode;
|
||||
fn header_alignment(&self) -> nu_table::Alignment;
|
||||
fn header_color(&self) -> Option<ansi_term::Color>;
|
||||
fn header_bold(&self) -> bool;
|
||||
fn table_mode(&self) -> nu_table::Theme;
|
||||
fn disabled_indexes(&self) -> bool;
|
||||
}
|
||||
|
||||
pub fn pivot_mode(config: &NuConfig) -> AutoPivotMode {
|
||||
let vars = config.vars.lock();
|
||||
|
||||
if let Some(mode) = vars.get("pivot_mode") {
|
||||
let mode = match mode.as_string() {
|
||||
Ok(m) if m.to_lowercase() == "auto" => AutoPivotMode::Auto,
|
||||
Ok(m) if m.to_lowercase() == "always" => AutoPivotMode::Always,
|
||||
Ok(m) if m.to_lowercase() == "never" => AutoPivotMode::Never,
|
||||
_ => AutoPivotMode::Always,
|
||||
};
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
AutoPivotMode::Always
|
||||
}
|
||||
|
||||
pub fn header_alignment(config: &NuConfig) -> nu_table::Alignment {
|
||||
let vars = config.vars.lock();
|
||||
|
||||
let alignment = vars.get("header_align");
|
||||
|
||||
if alignment.is_none() {
|
||||
return nu_table::Alignment::Center;
|
||||
}
|
||||
|
||||
alignment.map_or(nu_table::Alignment::Left, |a| {
|
||||
a.as_string().map_or(nu_table::Alignment::Center, |a| {
|
||||
match a.to_lowercase().as_str() {
|
||||
"center" | "c" => nu_table::Alignment::Center,
|
||||
"right" | "r" => nu_table::Alignment::Right,
|
||||
_ => nu_table::Alignment::Center,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn header_color(config: &NuConfig) -> Option<ansi_term::Color> {
|
||||
let vars = config.vars.lock();
|
||||
|
||||
Some(match vars.get("header_color") {
|
||||
Some(c) => match c.as_string() {
|
||||
Ok(color) => match color.to_lowercase().as_str() {
|
||||
"g" | "green" => ansi_term::Color::Green,
|
||||
"r" | "red" => ansi_term::Color::Red,
|
||||
"u" | "blue" => ansi_term::Color::Blue,
|
||||
"b" | "black" => ansi_term::Color::Black,
|
||||
"y" | "yellow" => ansi_term::Color::Yellow,
|
||||
"p" | "purple" => ansi_term::Color::Purple,
|
||||
"c" | "cyan" => ansi_term::Color::Cyan,
|
||||
"w" | "white" => ansi_term::Color::White,
|
||||
_ => ansi_term::Color::Green,
|
||||
},
|
||||
_ => ansi_term::Color::Green,
|
||||
},
|
||||
_ => ansi_term::Color::Green,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn header_bold(config: &NuConfig) -> bool {
|
||||
let vars = config.vars.lock();
|
||||
|
||||
vars.get("header_bold")
|
||||
.map(|x| x.as_bool().unwrap_or(true))
|
||||
.unwrap_or(true)
|
||||
}
|
||||
|
||||
pub fn table_mode(config: &NuConfig) -> nu_table::Theme {
|
||||
let vars = config.vars.lock();
|
||||
|
||||
vars.get("table_mode")
|
||||
.map_or(nu_table::Theme::compact(), |mode| match mode.as_string() {
|
||||
Ok(m) if m == "light" => nu_table::Theme::light(),
|
||||
_ => nu_table::Theme::compact(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn disabled_indexes(config: &NuConfig) -> bool {
|
||||
let vars = config.vars.lock();
|
||||
|
||||
vars.get("disable_table_indexes")
|
||||
.map_or(false, |x| x.as_bool().unwrap_or(false))
|
||||
}
|
||||
|
||||
impl HasTableProperties for NuConfig {
|
||||
fn pivot_mode(&self) -> AutoPivotMode {
|
||||
pivot_mode(self)
|
||||
}
|
||||
|
||||
fn header_alignment(&self) -> nu_table::Alignment {
|
||||
header_alignment(self)
|
||||
}
|
||||
|
||||
fn header_color(&self) -> Option<ansi_term::Color> {
|
||||
header_color(self)
|
||||
}
|
||||
|
||||
fn header_bold(&self) -> bool {
|
||||
header_bold(self)
|
||||
}
|
||||
|
||||
fn table_mode(&self) -> nu_table::Theme {
|
||||
table_mode(self)
|
||||
}
|
||||
|
||||
fn disabled_indexes(&self) -> bool {
|
||||
disabled_indexes(self)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user