diff --git a/crates/nu-command/tests/commands/table.rs b/crates/nu-command/tests/commands/table.rs index 8e5746e839..5a0fdcb684 100644 --- a/crates/nu-command/tests/commands/table.rs +++ b/crates/nu-command/tests/commands/table.rs @@ -38,7 +38,7 @@ fn table_collapse_0() { #[test] fn table_collapse_basic() { let actual = nu!(nu_repl_code(&[ - "let-env config = { table_mode: basic };", + "let-env config = { table: { mode: basic }};", "[[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table --collapse" ])); assert_eq!( @@ -60,7 +60,7 @@ fn table_collapse_basic() { #[test] fn table_collapse_heavy() { let actual = nu!(nu_repl_code(&[ - "let-env config = { table_mode: heavy };", + "let-env config = { table: { mode: heavy }};", "[[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table --collapse" ])); assert_eq!( @@ -82,7 +82,7 @@ fn table_collapse_heavy() { #[test] fn table_collapse_compact() { let actual = nu!(nu_repl_code(&[ - "let-env config = { table_mode: compact };", + "let-env config = { table: { mode: compact }};", "[[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table --collapse" ])); assert_eq!( @@ -104,7 +104,7 @@ fn table_collapse_compact() { #[test] fn table_collapse_compact_double() { let actual = nu!(nu_repl_code(&[ - "let-env config = { table_mode: compact_double };", + "let-env config = { table: { mode: compact_double }};", "[[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table --collapse" ])); assert_eq!( @@ -126,7 +126,7 @@ fn table_collapse_compact_double() { #[test] fn table_collapse_compact_light() { let actual = nu!(nu_repl_code(&[ - "let-env config = { table_mode: light };", + "let-env config = { table: { mode: light }};", "[[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table --collapse" ])); assert_eq!( @@ -148,7 +148,7 @@ fn table_collapse_compact_light() { #[test] fn table_collapse_none() { let actual = nu!(nu_repl_code(&[ - "let-env config = { table_mode: none };", + "let-env config = { table: { mode: none }};", "[[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table --collapse" ])); assert_eq!( @@ -166,7 +166,7 @@ fn table_collapse_none() { #[test] fn table_collapse_compact_reinforced() { let actual = nu!(nu_repl_code(&[ - "let-env config = { table_mode: reinforced };", + "let-env config = { table: { mode: reinforced }};", "[[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table --collapse" ])); assert_eq!( @@ -188,7 +188,7 @@ fn table_collapse_compact_reinforced() { #[test] fn table_collapse_compact_thin() { let actual = nu!(nu_repl_code(&[ - "let-env config = { table_mode: thin };", + "let-env config = { table: { mode: thin }};", "[[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table --collapse" ])); assert_eq!( @@ -210,7 +210,7 @@ fn table_collapse_compact_thin() { #[test] fn table_collapse_hearts() { let actual = nu!(nu_repl_code(&[ - "let-env config = { table_mode: with_love };", + "let-env config = { table: { mode: with_love }};", "[[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table --collapse" ])); assert_eq!( @@ -1832,16 +1832,16 @@ fn test_collapse_big_0() { repository = "https://github.com/nushell/nushell" rust-version = "1.60" version = "0.74.1" - + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - + [package.metadata.binstall] pkg-url = "{ repo }/releases/download/{ version }/{ name }-{ version }-{ target }.{ archive-format }" pkg-fmt = "tgz" - + [package.metadata.binstall.overrides.x86_64-pc-windows-msvc] pkg-fmt = "zip" - + [workspace] members = [ "crates/nu-cli", @@ -1858,7 +1858,7 @@ fn test_collapse_big_0() { "crates/nu_plugin_custom_values", "crates/nu-utils", ] - + [dependencies] chrono = { version = "0.4.23", features = ["serde"] } crossterm = "0.24.0" @@ -1869,25 +1869,25 @@ fn test_collapse_big_0() { nu-cli = { path = "./crates/nu-cli", version = "0.74.1" } nu-engine = { path = "./crates/nu-engine", version = "0.74.1" } reedline = { version = "0.14.0", features = ["bashisms", "sqlite"] } - + rayon = "1.6.1" is_executable = "1.0.1" simplelog = "0.12.0" time = "0.3.12" - + [target.'cfg(not(target_os = "windows"))'.dependencies] # Our dependencies don't use OpenSSL on Windows openssl = { version = "0.10.38", features = ["vendored"], optional = true } signal-hook = { version = "0.3.14", default-features = false } - - + + [target.'cfg(windows)'.build-dependencies] winres = "0.1" - + [target.'cfg(target_family = "unix")'.dependencies] nix = { version = "0.25", default-features = false, features = ["signal", "process", "fs", "term"] } atty = "0.2" - + [dev-dependencies] nu-test-support = { path = "./crates/nu-test-support", version = "0.74.1" } tempfile = "3.2.0" @@ -1898,7 +1898,7 @@ fn test_collapse_big_0() { hamcrest2 = "0.3.0" rstest = { version = "0.15.0", default-features = false } itertools = "0.10.3" - + [features] plugin = [ "nu-plugin", @@ -1913,10 +1913,10 @@ fn test_collapse_big_0() { default = ["plugin", "which-support", "trash-support", "sqlite"] stable = ["default"] wasi = [] - + # Enable to statically link OpenSSL; otherwise the system version will be used. Not enabled by default because it takes a while to build static-link-openssl = ["dep:openssl"] - + # Stable (Default) which-support = ["nu-command/which-support"] trash-support = ["nu-command/trash-support"] @@ -1925,12 +1925,12 @@ fn test_collapse_big_0() { [[bin]] name = "nu" path = "src/main.rs" - + # To use a development version of a dependency please use a global override here # changing versions in each sub-crate of the workspace is tedious [patch.crates-io] reedline = { git = "https://github.com/nushell/reedline.git", branch = "main" } - + # Criterion benchmarking setup # Run all benchmarks with `cargo bench` # Run individual benchmarks like `cargo bench -- ` e.g. `cargo bench -- parse` diff --git a/crates/nu-protocol/src/config.rs b/crates/nu-protocol/src/config.rs index 088252b52f..1dbdbb5df8 100644 --- a/crates/nu-protocol/src/config.rs +++ b/crates/nu-protocol/src/config.rs @@ -87,7 +87,6 @@ pub struct Config { pub sync_history_on_enter: bool, pub history_file_format: HistoryFileFormat, pub history_isolation: bool, - pub log_level: String, pub keybindings: Vec, pub menus: Vec, pub hooks: Hooks, @@ -132,7 +131,6 @@ impl Default for Config { sync_history_on_enter: true, history_file_format: HistoryFileFormat::PlainText, history_isolation: false, - log_level: String::new(), keybindings: Vec::new(), menus: Vec::new(), hooks: Hooks::new(), @@ -225,9 +223,7 @@ impl TrimStrategy { impl Value { pub fn into_config(&mut self, config: &Config) -> (Config, Option) { // Clone the passed-in config rather than mutating it. - let mut config = config.clone(); - let mut legacy_options_used = false; // Vec for storing errors. // Current Nushell behaviour (Dec 2022) is that having some typo like "always_trash": tru in your config.nu's @@ -423,7 +419,7 @@ impl Value { let value = &vals[index]; let key2 = cols[index].as_str(); match key2 { - "history_isolation" => { + "isolation" => { try_bool!(cols, vals, index, span, history_isolation) } "sync_on_enter" => { @@ -478,11 +474,13 @@ impl Value { "sync_on_enter".into(), "max_size".into(), "file_format".into(), + "isolation".into(), ], vec![ Value::boolean(config.sync_history_on_enter, *span), Value::int(config.max_history_size, *span), reconstruct_history_file_format!(span), + Value::boolean(config.history_isolation, *span), ], *span, ); @@ -956,11 +954,17 @@ impl Value { invalid!(vals[index].span().ok(), "should be a record"); // Reconstruct vals[index] = Value::record( - vec!["mode".into(), "index_mode".into(), "trim".into()], + vec![ + "mode".into(), + "index_mode".into(), + "trim".into(), + "show_empty".into(), + ], vec![ Value::string(config.table_mode.clone(), *span), reconstruct_index_mode!(span), reconstruct_trim_strategy!(span), + Value::boolean(config.table_show_empty, *span), ], *span, ) @@ -1074,15 +1078,26 @@ impl Value { vals[index] = Value::string(config.edit_mode.clone(), *span); } } - "log_level" => { + "shell_integration" => { + try_bool!(cols, vals, index, span, shell_integration); + } + "buffer_editor" => { if let Ok(v) = value.as_string() { - config.log_level = v.to_lowercase(); + config.buffer_editor = v.to_lowercase(); } else { invalid!(Some(*span), "should be a string"); - // Reconstruct - vals[index] = Value::string(config.log_level.clone(), *span); } } + "show_banner" => { + try_bool!(cols, vals, index, span, show_banner); + } + "render_right_prompt_on_last_line" => { + try_bool!(cols, vals, index, span, render_right_prompt_on_last_line); + } + "bracketed_paste" => { + try_bool!(cols, vals, index, span, bracketed_paste); + } + // Menus "menus" => match create_menus(value) { Ok(map) => config.menus = map, Err(e) => { @@ -1128,6 +1143,7 @@ impl Value { } } }, + // Keybindings "keybindings" => match create_keybindings(value) { Ok(keybindings) => config.keybindings = keybindings, Err(e) => { @@ -1167,6 +1183,7 @@ impl Value { } } }, + // Hooks "hooks" => match create_hooks(value) { Ok(hooks) => config.hooks = hooks, Err(e) => { @@ -1198,229 +1215,7 @@ impl Value { }); } }, - "shell_integration" => { - try_bool!(cols, vals, index, span, shell_integration); - } - "buffer_editor" => { - if let Ok(v) = value.as_string() { - config.buffer_editor = v.to_lowercase(); - } else { - invalid!(Some(*span), "should be a string"); - } - } - "show_banner" => { - try_bool!(cols, vals, index, span, show_banner); - } - "render_right_prompt_on_last_line" => { - try_bool!(cols, vals, index, span, render_right_prompt_on_last_line); - } - "bracketed_paste" => { - try_bool!(cols, vals, index, span, bracketed_paste); - } - // Legacy config options (deprecated as of 2022-11-02) - // Legacy options do NOT reconstruct their values on error - "use_ls_colors" => { - legacy_options_used = true; - try_bool!(cols, vals, index, span, use_ls_colors); - } - "rm_always_trash" => { - legacy_options_used = true; - try_bool!(cols, vals, index, span, rm_always_trash); - } - "history_file_format" => { - legacy_options_used = true; - if let Ok(b) = value.as_string() { - let val_str = b.to_lowercase(); - config.history_file_format = match val_str.as_ref() { - "sqlite" => HistoryFileFormat::Sqlite, - "plaintext" => HistoryFileFormat::PlainText, - _ => { - invalid!( - Some(*span), - "unrecognized $env.config.{key} '{val_str}'" - ); - HistoryFileFormat::PlainText - } - }; - } else { - invalid!(Some(*span), "should be a string"); - } - } - "sync_history_on_enter" => { - legacy_options_used = true; - try_bool!(cols, vals, index, span, sync_history_on_enter); - } - "max_history_size" => { - legacy_options_used = true; - try_int!(cols, vals, index, span, max_history_size); - } - "quick_completions" => { - legacy_options_used = true; - try_bool!(cols, vals, index, span, quick_completions); - } - "partial_completions" => { - legacy_options_used = true; - try_bool!(cols, vals, index, span, partial_completions); - } - "max_external_completion_results" => { - legacy_options_used = true; - try_int!(cols, vals, index, span, max_external_completion_results); - } - "completion_algorithm" => { - legacy_options_used = true; - if let Ok(v) = value.as_string() { - let val_str = v.to_lowercase(); - config.completion_algorithm = match val_str.as_ref() { - // This should match the MatchAlgorithm enum in completions::completion_options - "prefix" => val_str, - "fuzzy" => val_str, - _ => { - invalid!( Some(*span), - "unrecognized $env.config.{key} '{val_str}'; expected either 'prefix' or 'fuzzy'" - ); - val_str - } - }; - } else { - invalid!(Some(*span), "should be a string"); - } - } - "case_sensitive_completions" => { - legacy_options_used = true; - try_bool!(cols, vals, index, span, case_sensitive_completions); - } - "enable_external_completion" => { - legacy_options_used = true; - try_bool!(cols, vals, index, span, enable_external_completion); - } - "external_completer" => { - legacy_options_used = true; - if let Ok(v) = value.as_block() { - config.external_completer = Some(v) - } - // No error here because external completers are optional. - // Idea: maybe error if this is a non-block, non-null? - } - "table_mode" => { - legacy_options_used = true; - if let Ok(v) = value.as_string() { - config.table_mode = v; - } else { - invalid!(Some(*span), "should be a string"); - } - } - "table_index_mode" => { - legacy_options_used = true; - if let Ok(b) = value.as_string() { - let val_str = b.to_lowercase(); - match val_str.as_ref() { - "always" => config.table_index_mode = TableIndexMode::Always, - "never" => config.table_index_mode = TableIndexMode::Never, - "auto" => config.table_index_mode = TableIndexMode::Auto, - _ => { - invalid!( Some(*span), - "unrecognized $env.config.table_index_mode '{val_str}'; expected either 'never', 'always' or 'auto'" - ); - } - } - } else { - invalid!(Some(*span), "should be a string"); - } - } - "table_trim" => { - legacy_options_used = true; - match try_parse_trim_strategy(value, &mut errors) { - Ok(v) => config.trim_strategy = v, - Err(e) => { - // try_parse_trim_strategy() already calls eprintln!() on error - cols.remove(index); - vals.remove(index); - errors.push(e); - } - } - } - "show_clickable_links_in_ls" => { - legacy_options_used = true; - try_bool!(cols, vals, index, span, show_clickable_links_in_ls); - } - "cd_with_abbreviations" => { - legacy_options_used = true; - try_bool!(cols, vals, index, span, cd_with_abbreviations); - } - "filesize_metric" => { - legacy_options_used = true; - try_bool!(cols, vals, index, span, filesize_metric); - } - "filesize_format" => { - legacy_options_used = true; - if let Ok(v) = value.as_string() { - config.filesize_format = v.to_lowercase(); - } else { - invalid!(Some(*span), "should be a string"); - } - } - "cursor_shape_vi_insert" => { - legacy_options_used = true; - if let Ok(b) = value.as_string() { - let val_str = b.to_lowercase(); - config.cursor_shape_vi_insert = match val_str.as_ref() { - "block" => NuCursorShape::Block, - "underline" => NuCursorShape::UnderScore, - "line" => NuCursorShape::Line, - _ => { - invalid!( - Some(*span), - "unrecognized $env.config.{key} '{val_str}'" - ); - NuCursorShape::Line - } - }; - } else { - invalid!(Some(*span), "should be a string"); - } - } - "cursor_shape_vi_normal" => { - legacy_options_used = true; - if let Ok(b) = value.as_string() { - let val_str = b.to_lowercase(); - config.cursor_shape_vi_normal = match val_str.as_ref() { - "block" => NuCursorShape::Block, - "underline" => NuCursorShape::UnderScore, - "line" => NuCursorShape::Line, - _ => { - invalid!( - Some(*span), - "unrecognized $env.config.{key} '{val_str}'" - ); - NuCursorShape::Line - } - }; - } else { - invalid!(Some(*span), "should be a string"); - } - } - "cursor_shape_emacs" => { - legacy_options_used = true; - if let Ok(b) = value.as_string() { - let val_str = b.to_lowercase(); - config.cursor_shape_emacs = match val_str.as_ref() { - "block" => NuCursorShape::Block, - "underline" => NuCursorShape::UnderScore, - "line" => NuCursorShape::Line, - _ => { - invalid!( - Some(*span), - "unrecognized $env.config.{key} '{val_str}'" - ); - NuCursorShape::Line - } - }; - } else { - invalid!(Some(*span), "should be a string"); - } - } - - // End legacy options + // Catch all x => { invalid_key!( cols, @@ -1445,14 +1240,6 @@ impl Value { ); } - if legacy_options_used { - // This is a notification message, not an error. - eprintln!( - r#"The format of $env.config has recently changed, and several options have been grouped into sub-records. You may need to update your config.nu file. -Please consult https://www.nushell.sh/blog/2022-11-29-nushell-0.72.html for details. Support for the old format will be removed in an upcoming Nu release."# - ); - } - // Return the config and the vec of errors. ( config, diff --git a/crates/nu-utils/src/sample_config/default_config.nu b/crates/nu-utils/src/sample_config/default_config.nu index c006022b5b..10ad7e5b50 100644 --- a/crates/nu-utils/src/sample_config/default_config.nu +++ b/crates/nu-utils/src/sample_config/default_config.nu @@ -268,7 +268,7 @@ let-env config = { max_size: 100_000 # Session has to be reloaded for this to take effect sync_on_enter: true # Enable to share history between multiple sessions, else you have to close the session to write history to file file_format: "plaintext" # "sqlite" or "plaintext" - history_isolation: true # true enables history isolation, false disables it. true will allow the history to be isolated to the current session. false will allow the history to be shared across all sessions. + isolation: true # true enables history isolation, false disables it. true will allow the history to be isolated to the current session. false will allow the history to be shared across all sessions. } completions: { case_sensitive: false # set to true to enable case-sensitive completions