diff --git a/crates/nu-command/src/env/config/config_env.rs b/crates/nu-command/src/env/config/config_env.rs index cb4a217d9b..5331d2d3be 100644 --- a/crates/nu-command/src/env/config/config_env.rs +++ b/crates/nu-command/src/env/config/config_env.rs @@ -15,7 +15,16 @@ impl Command for ConfigEnv { Signature::build(self.name()) .category(Category::Env) .input_output_types(vec![(Type::Nothing, Type::Any)]) - .switch("default", "Print default `env.nu` file instead.", Some('d')) + .switch( + "default", + "Print the internal default `env.nu` file instead.", + Some('d'), + ) + .switch( + "sample", + "Print a commented, sample `env.nu` file instead.", + Some('s'), + ) // TODO: Signature narrower than what run actually supports theoretically } @@ -26,18 +35,18 @@ impl Command for ConfigEnv { fn examples(&self) -> Vec { vec![ Example { - description: "allow user to open and update nu env", + description: "open user's env.nu in the default editor", example: "config env", result: None, }, Example { - description: "allow user to print default `env.nu` file", - example: "config env --default,", + description: "pretty-print a commented, sample `env.nu` that explains common settings", + example: "config env --sample | nu-highlight,", result: None, }, Example { - description: "allow saving the default `env.nu` locally", - example: "config env --default | save -f ~/.config/nushell/default_env.nu", + description: "pretty-print the internal `env.nu` file which is loaded before the user's environment", + example: "config env --default | nu-highlight,", result: None, }, ] @@ -50,12 +59,28 @@ impl Command for ConfigEnv { call: &Call, _input: PipelineData, ) -> Result { + let default_flag = call.has_flag(engine_state, stack, "default")?; + let sample_flag = call.has_flag(engine_state, stack, "sample")?; + if default_flag && sample_flag { + return Err(ShellError::IncompatibleParameters { + left_message: "can't use `--default` at the same time".into(), + left_span: call.get_flag_span(stack, "default").expect("has flag"), + right_message: "because of `--sample`".into(), + right_span: call.get_flag_span(stack, "sample").expect("has flag"), + }); + } // `--default` flag handling if call.has_flag(engine_state, stack, "default")? { let head = call.head; return Ok(Value::string(nu_utils::get_default_env(), head).into_pipeline_data()); } + // `--sample` flag handling + if sample_flag { + let head = call.head; + return Ok(Value::string(nu_utils::get_sample_env(), head).into_pipeline_data()); + } + // Find the editor executable. let (editor_name, editor_args) = get_editor(engine_state, stack, call.head)?; let paths = nu_engine::env::path_str(engine_state, stack, call.head)?; diff --git a/crates/nu-command/src/env/config/config_nu.rs b/crates/nu-command/src/env/config/config_nu.rs index 9969968ed2..176643a76f 100644 --- a/crates/nu-command/src/env/config/config_nu.rs +++ b/crates/nu-command/src/env/config/config_nu.rs @@ -17,9 +17,14 @@ impl Command for ConfigNu { .input_output_types(vec![(Type::Nothing, Type::Any)]) .switch( "default", - "Print default `config.nu` file instead.", + "Print the internal default `config.nu` file instead.", Some('d'), ) + .switch( + "sample", + "Print a commented, sample `config.nu` file instead.", + Some('s'), + ) // TODO: Signature narrower than what run actually supports theoretically } @@ -30,18 +35,19 @@ impl Command for ConfigNu { fn examples(&self) -> Vec { vec![ Example { - description: "allow user to open and update nu config", + description: "open user's config.nu in the default editor", example: "config nu", result: None, }, Example { - description: "allow user to print default `config.nu` file", - example: "config nu --default,", + description: "pretty-print a commented, sample `config.nu` that explains common settings", + example: "config nu --sample | nu-highlight", result: None, }, Example { - description: "allow saving the default `config.nu` locally", - example: "config nu --default | save -f ~/.config/nushell/default_config.nu", + description: + "pretty-print the internal `config.nu` file which is loaded before user's config", + example: "config nu --default | nu-highlight", result: None, }, ] @@ -54,12 +60,29 @@ impl Command for ConfigNu { call: &Call, _input: PipelineData, ) -> Result { + let default_flag = call.has_flag(engine_state, stack, "default")?; + let sample_flag = call.has_flag(engine_state, stack, "sample")?; + if default_flag && sample_flag { + return Err(ShellError::IncompatibleParameters { + left_message: "can't use `--default` at the same time".into(), + left_span: call.get_flag_span(stack, "default").expect("has flag"), + right_message: "because of `--sample`".into(), + right_span: call.get_flag_span(stack, "sample").expect("has flag"), + }); + } + // `--default` flag handling - if call.has_flag(engine_state, stack, "default")? { + if default_flag { let head = call.head; return Ok(Value::string(nu_utils::get_default_config(), head).into_pipeline_data()); } + // `--sample` flag handling + if sample_flag { + let head = call.head; + return Ok(Value::string(nu_utils::get_sample_config(), head).into_pipeline_data()); + } + // Find the editor executable. let (editor_name, editor_args) = get_editor(engine_state, stack, call.head)?; let paths = nu_engine::env::path_str(engine_state, stack, call.head)?; diff --git a/crates/nu-protocol/tests/into_config.rs b/crates/nu-protocol/tests/into_config.rs index 63d7eb8b22..3ff8d44672 100644 --- a/crates/nu-protocol/tests/into_config.rs +++ b/crates/nu-protocol/tests/into_config.rs @@ -35,7 +35,7 @@ fn config_affected_when_mutated() { #[test] fn config_affected_when_deep_mutated() { - let actual = nu!(cwd: "crates/nu-utils/src/sample_config", nu_repl_code(&[ + let actual = nu!(cwd: "crates/nu-utils/src/default_files", nu_repl_code(&[ r#"source default_config.nu"#, r#"$env.config.filesize.metric = true"#, r#"20mib | into string"#])); @@ -45,7 +45,7 @@ fn config_affected_when_deep_mutated() { #[test] fn config_add_unsupported_key() { - let actual = nu!(cwd: "crates/nu-utils/src/sample_config", nu_repl_code(&[ + let actual = nu!(cwd: "crates/nu-utils/src/default_files", nu_repl_code(&[ r#"source default_config.nu"#, r#"$env.config.foo = 2"#, r#";"#])); @@ -57,7 +57,7 @@ fn config_add_unsupported_key() { #[test] fn config_add_unsupported_type() { - let actual = nu!(cwd: "crates/nu-utils/src/sample_config", nu_repl_code(&[r#"source default_config.nu"#, + let actual = nu!(cwd: "crates/nu-utils/src/default_files", nu_repl_code(&[r#"source default_config.nu"#, r#"$env.config.ls = '' "#, r#";"#])); @@ -66,7 +66,7 @@ fn config_add_unsupported_type() { #[test] fn config_add_unsupported_value() { - let actual = nu!(cwd: "crates/nu-utils/src/sample_config", nu_repl_code(&[r#"source default_config.nu"#, + let actual = nu!(cwd: "crates/nu-utils/src/default_files", nu_repl_code(&[r#"source default_config.nu"#, r#"$env.config.history.file_format = ''"#, r#";"#])); @@ -77,7 +77,7 @@ fn config_add_unsupported_value() { #[test] #[ignore = "Figure out how to make test_bins::nu_repl() continue execution after shell errors"] fn config_unsupported_key_reverted() { - let actual = nu!(cwd: "crates/nu-utils/src/sample_config", nu_repl_code(&[r#"source default_config.nu"#, + let actual = nu!(cwd: "crates/nu-utils/src/default_files", nu_repl_code(&[r#"source default_config.nu"#, r#"$env.config.foo = 1"#, r#"'foo' in $env.config"#])); @@ -87,7 +87,7 @@ fn config_unsupported_key_reverted() { #[test] #[ignore = "Figure out how to make test_bins::nu_repl() continue execution after shell errors"] fn config_unsupported_type_reverted() { - let actual = nu!(cwd: "crates/nu-utils/src/sample_config", nu_repl_code(&[r#" source default_config.nu"#, + let actual = nu!(cwd: "crates/nu-utils/src/default_files", nu_repl_code(&[r#" source default_config.nu"#, r#"$env.config.ls = ''"#, r#"$env.config.ls | describe"#])); @@ -97,7 +97,7 @@ fn config_unsupported_type_reverted() { #[test] #[ignore = "Figure out how to make test_bins::nu_repl() continue execution after errors"] fn config_unsupported_value_reverted() { - let actual = nu!(cwd: "crates/nu-utils/src/sample_config", nu_repl_code(&[r#" source default_config.nu"#, + let actual = nu!(cwd: "crates/nu-utils/src/default_files", nu_repl_code(&[r#" source default_config.nu"#, r#"$env.config.history.file_format = 'plaintext'"#, r#"$env.config.history.file_format = ''"#, r#"$env.config.history.file_format | to json"#])); diff --git a/crates/nu-std/src/lib.rs b/crates/nu-std/src/lib.rs index ebc6ee0053..b03b710cfc 100644 --- a/crates/nu-std/src/lib.rs +++ b/crates/nu-std/src/lib.rs @@ -54,6 +54,7 @@ pub fn load_standard_library( ("mod.nu", "std/math", include_str!("../std/math/mod.nu")), ("mod.nu", "std/util", include_str!("../std/util/mod.nu")), ("mod.nu", "std/xml", include_str!("../std/xml/mod.nu")), + ("mod.nu", "std/config", include_str!("../std/config/mod.nu")), ]; for (filename, std_subdir_name, content) in std_submodules.drain(..) { diff --git a/crates/nu-std/std/config/mod.nu b/crates/nu-std/std/config/mod.nu new file mode 100644 index 0000000000..b73964e8d3 --- /dev/null +++ b/crates/nu-std/std/config/mod.nu @@ -0,0 +1,139 @@ +# Returns a dark-mode theme that can be assigned to $env.config.color_config +export def dark-theme [] { + { + # color for nushell primitives + separator: white + leading_trailing_space_bg: { attr: n } # no fg, no bg, attr none effectively turns this off + header: green_bold + empty: blue + # Closures can be used to choose colors for specific values. + # The value (in this case, a bool) is piped into the closure. + # eg) {|| if $in { 'light_cyan' } else { 'light_gray' } } + bool: light_cyan + int: white + filesize: cyan + duration: white + date: purple + range: white + float: white + string: white + nothing: white + binary: white + cell-path: white + row_index: green_bold + record: white + list: white + block: white + hints: dark_gray + search_result: { bg: red fg: white } + shape_and: purple_bold + shape_binary: purple_bold + shape_block: blue_bold + shape_bool: light_cyan + shape_closure: green_bold + shape_custom: green + shape_datetime: cyan_bold + shape_directory: cyan + shape_external: cyan + shape_externalarg: green_bold + shape_external_resolved: light_yellow_bold + shape_filepath: cyan + shape_flag: blue_bold + shape_float: purple_bold + # shapes are used to change the cli syntax highlighting + shape_garbage: { fg: white bg: red attr: b } + shape_glob_interpolation: cyan_bold + shape_globpattern: cyan_bold + shape_int: purple_bold + shape_internalcall: cyan_bold + shape_keyword: cyan_bold + shape_list: cyan_bold + shape_literal: blue + shape_match_pattern: green + shape_matching_brackets: { attr: u } + shape_nothing: light_cyan + shape_operator: yellow + shape_or: purple_bold + shape_pipe: purple_bold + shape_range: yellow_bold + shape_record: cyan_bold + shape_redirection: purple_bold + shape_signature: green_bold + shape_string: green + shape_string_interpolation: cyan_bold + shape_table: blue_bold + shape_variable: purple + shape_vardecl: purple + shape_raw_string: light_purple + } +} + +# Returns a light-mode theme that can be assigned to $env.config.color_config +export def light-theme [] { + { + # color for nushell primitives + separator: dark_gray + leading_trailing_space_bg: { attr: n } # no fg, no bg, attr none effectively turns this off + header: green_bold + empty: blue + # Closures can be used to choose colors for specific values. + # The value (in this case, a bool) is piped into the closure. + # eg) {|| if $in { 'dark_cyan' } else { 'dark_gray' } } + bool: dark_cyan + int: dark_gray + filesize: cyan_bold + duration: dark_gray + date: purple + range: dark_gray + float: dark_gray + string: dark_gray + nothing: dark_gray + binary: dark_gray + cell-path: dark_gray + row_index: green_bold + record: dark_gray + list: dark_gray + block: dark_gray + hints: dark_gray + search_result: { fg: white bg: red } + shape_and: purple_bold + shape_binary: purple_bold + shape_block: blue_bold + shape_bool: light_cyan + shape_closure: green_bold + shape_custom: green + shape_datetime: cyan_bold + shape_directory: cyan + shape_external: cyan + shape_externalarg: green_bold + shape_external_resolved: light_purple_bold + shape_filepath: cyan + shape_flag: blue_bold + shape_float: purple_bold + # shapes are used to change the cli syntax highlighting + shape_garbage: { fg: white bg: red attr: b } + shape_glob_interpolation: cyan_bold + shape_globpattern: cyan_bold + shape_int: purple_bold + shape_internalcall: cyan_bold + shape_keyword: cyan_bold + shape_list: cyan_bold + shape_literal: blue + shape_match_pattern: green + shape_matching_brackets: { attr: u } + shape_nothing: light_cyan + shape_operator: yellow + shape_or: purple_bold + shape_pipe: purple_bold + shape_range: yellow_bold + shape_record: cyan_bold + shape_redirection: purple_bold + shape_signature: green_bold + shape_string: green + shape_string_interpolation: cyan_bold + shape_table: blue_bold + shape_variable: purple + shape_vardecl: purple + shape_raw_string: light_purple + } +} \ No newline at end of file diff --git a/crates/nu-std/std/mod.nu b/crates/nu-std/std/mod.nu index 4d1e74e72d..89454ee1f3 100644 --- a/crates/nu-std/std/mod.nu +++ b/crates/nu-std/std/mod.nu @@ -14,6 +14,7 @@ export module std/iter export module std/log export module std/math export module std/xml +export module std/config # Load main dirs command and all subcommands export use std/dirs main diff --git a/crates/nu-utils/src/default_files/README.md b/crates/nu-utils/src/default_files/README.md new file mode 100644 index 0000000000..2269771bbd --- /dev/null +++ b/crates/nu-utils/src/default_files/README.md @@ -0,0 +1,82 @@ +# Nushell configuration files + +## `default_env.nu`: + +* The internal default environment variables (other than `$env.config`) that will be set during Nushell startup. +* Is loaded *before* the user's `env.nu`. +* Will be loaded during any startup where the user's `env.nu` is also loaded. For example: + * During normal startup with `nu` + * During a startup where the user specifies an alternative `env.nu` via `nu --env-config ` +* Likewise, is never loaded during a startup where the user's `env.nu` would not be loaded. For example: + * `nu -n/--no-config` + * `nu -c "ls"` + * `nu ` +* Is not commented - Comments are in `sample_env.nu`. +* Should be optimized for fastest load times. +* Can be introspected via `config env --default | nu-highlight` + +## `default_config.nu`: + +Counterpart to `default_env.nu`. + +* Contains any `$env.config` values that are not set via Rust defaults. +* Is loaded *after* the user's `env.nu`. +* Is loaded *before* the user's `config.nu`. +* Will be loaded during any startup where the user's `config.nu` is also loaded. For example: + * During normal startup with `nu` + * During a startup where the user specifies an alternative `config.nu` via `nu --config ` +* Likewise, is never loaded during a startup where the user's `config.nu` would not be loaded. For example: + * `nu -n/--no-config` + * `nu -c "ls"` + * `nu ` +* Is not commented - Comments are in `sample_config.nu`. +* Should be optimized for fastest load times. Whenever possible, values should be set via nu-protocol::config + * Exception: `color_config` values are currently set in this file so that user's can introspect the values + * TODO: Implement defaults for `color_config` in nu-protocol::config and remove from `default_config.nu` +* Can be introspected via `config nu --default | nu-highlight` +* An ideal `default_config.nu` (when all values are set via `nu-protocol::config`) will simply be: + ``` + $env.config = {} + ``` + +## `sample_env.nu` + +* A commented file documenting the most common environment variables that a user might configure in `env.nu` +* For convenient in-shell access +* Can be pretty-printed via `config env --sample | nu-highlight` +* Since this file is for documentation only, include actual Nushell code without comments so that it can be pretty-printed +* No optimization necessary - Not intended for use other than documentation. +* Consider replacing `config env --sample` with `help env.nu` at some point. +* Uses a mix of default values (explained) as well as other examples that users might want in their own `env.nu` + +## `sample_config.nu` + +Counterpart to `sample_env.nu`. + +TODO: **Not in final form** + +* A commented file documenting the most common environment variables that a user might configure in `config.nu` +* For convenient in-shell access +* Can be pretty-printed via `config nu --sample | nu-highlight` +* Since this file is for documentation only, include actual Nushell code without comments so that it can be pretty-printed +* No optimization necessary - Not intended for use other than documentation. +* Consider replacing `config nu --sample` with `help config.nu` at some point. +* Uses a mix of default values (explained) as well as other examples that users might want in their own `config.nu` + +## `scaffold_env.nu` + +* This file is used *one-time* (typically) at **first** startup +* If the `$nu.default-config-path` directory does not exist, the directory is created and then both `scaffold_env.nu` and `scaffold_config.nu` are written to it +* Contains only commented lines explaining the purpose of the file to the user, along with information on the `config env` command. + +## `scaffold_config.nu` + +Counterpart to `scaffold_env.nu`. + +* This file is used *one-time* (typically) at **first** startup +* If the `$nu.default-config-path` directory does not exist, the directory is created and then both `scaffold_env.nu` and `scaffold_config.nu` are written to it +* Contains only commented lines explaining the purpose of the file to the user, along with information on the `config nu` command. + +## `sample_login.nu` + +This file is not used by any Nushell code. Of course, if the user has a `login.nu`, then it will be evaluated during startup of a login shell. \ No newline at end of file diff --git a/crates/nu-utils/src/default_files/default_config.nu b/crates/nu-utils/src/default_files/default_config.nu new file mode 100644 index 0000000000..d95f4b3f97 --- /dev/null +++ b/crates/nu-utils/src/default_files/default_config.nu @@ -0,0 +1,63 @@ +# Nushell Config File +# +# version = "0.100.1" +$env.config.color_config = { + separator: white + leading_trailing_space_bg: { attr: n } + header: green_bold + empty: blue + bool: light_cyan + int: white + filesize: cyan + duration: white + date: purple + range: white + float: white + string: white + nothing: white + binary: white + cell-path: white + row_index: green_bold + record: white + list: white + block: white + hints: dark_gray + search_result: { bg: red fg: white } + shape_and: purple_bold + shape_binary: purple_bold + shape_block: blue_bold + shape_bool: light_cyan + shape_closure: green_bold + shape_custom: green + shape_datetime: cyan_bold + shape_directory: cyan + shape_external: cyan + shape_externalarg: green_bold + shape_external_resolved: light_yellow_bold + shape_filepath: cyan + shape_flag: blue_bold + shape_float: purple_bold + shape_glob_interpolation: cyan_bold + shape_globpattern: cyan_bold + shape_int: purple_bold + shape_internalcall: cyan_bold + shape_keyword: cyan_bold + shape_list: cyan_bold + shape_literal: blue + shape_match_pattern: green + shape_matching_brackets: { attr: u } + shape_nothing: light_cyan + shape_operator: yellow + shape_or: purple_bold + shape_pipe: purple_bold + shape_range: yellow_bold + shape_record: cyan_bold + shape_redirection: purple_bold + shape_signature: green_bold + shape_string: green + shape_string_interpolation: cyan_bold + shape_table: blue_bold + shape_variable: purple + shape_vardecl: purple + shape_raw_string: light_purple +} \ No newline at end of file diff --git a/crates/nu-utils/src/default_files/default_env.nu b/crates/nu-utils/src/default_files/default_env.nu new file mode 100644 index 0000000000..498c9670b3 --- /dev/null +++ b/crates/nu-utils/src/default_files/default_env.nu @@ -0,0 +1,57 @@ +# Default Nushell Environment Config File +# These "sensible defaults" are set before the user's `env.nu` is loaded +# +# version = "0.100.1" + +$env.PROMPT_COMMAND = {|| + let dir = match (do --ignore-shell-errors { $env.PWD | path relative-to $nu.home-path }) { + null => $env.PWD + '' => '~' + $relative_pwd => ([~ $relative_pwd] | path join) + } + + let path_color = (if (is-admin) { ansi red_bold } else { ansi green_bold }) + let separator_color = (if (is-admin) { ansi light_red_bold } else { ansi light_green_bold }) + let path_segment = $"($path_color)($dir)(ansi reset)" + + $path_segment | str replace --all (char path_sep) $"($separator_color)(char path_sep)($path_color)" +} + +$env.PROMPT_INDICATOR = "> " +$env.PROMPT_INDICATOR_VI_NORMAL = "> " +$env.PROMPT_INDICATOR_VI_INSERT = ": " +$env.PROMPT_MULTILINE_INDICATOR = "::: " + +$env.PROMPT_COMMAND_RIGHT = {|| + # create a right prompt in magenta with green separators and am/pm underlined + let time_segment = ([ + (ansi reset) + (ansi magenta) + (date now | format date '%x %X') # try to respect user's locale + ] | str join | str replace --regex --all "([/:])" $"(ansi green)${1}(ansi magenta)" | + str replace --regex --all "([AP]M)" $"(ansi magenta_underline)${1}") + + let last_exit_code = if ($env.LAST_EXIT_CODE != 0) {([ + (ansi rb) + ($env.LAST_EXIT_CODE) + ] | str join) + } else { "" } + + ([$last_exit_code, (char space), $time_segment] | str join) +} + +$env.ENV_CONVERSIONS = { + "PATH": { + from_string: { |s| $s | split row (char esep) | path expand --no-symlink } + to_string: { |v| $v | path expand --no-symlink | str join (char esep) } + } +} + +$env.NU_LIB_DIRS = [ + ($nu.default-config-dir | path join 'scripts') # add /scripts + ($nu.data-dir | path join 'completions') # default home for nushell completions +] + +$env.NU_PLUGIN_DIRS = [ + ($nu.default-config-dir | path join 'plugins') # add /plugins +] \ No newline at end of file diff --git a/crates/nu-utils/src/default_files/sample_config.nu b/crates/nu-utils/src/default_files/sample_config.nu new file mode 100644 index 0000000000..5a8181506c --- /dev/null +++ b/crates/nu-utils/src/default_files/sample_config.nu @@ -0,0 +1,792 @@ +# Nushell Config File +# +# version = "0.99.2" +# +# A `config.nu` file is used to override default Nushell settings, +# define (or import) custom commands, or run any other startup tasks. +# See https://www.nushell.sh/book/configuration.html +# +# Nushell sets "sensible defaults" for most configuration settings, so +# the user's `config.nu` only needs to override these defaults if +# desired. +# +# This file serves as simple "in-shell" documentation for these +# settings, or you can view a more complete discussion online at: +# https://nushell.sh/book/configuration +# +# You can pretty-print and page this file using: +# config nu --sample | nu-highlight | less -R + +# $env.config +# ----------- +# The $env.config environment variable is a record containing most Nushell +# configuration settings. Keep in mind that, as a record, setting it to a +# new record will remove any keys which aren't in the new record. Nushell +# will then automatically merge in the internal defaults for missing keys. +# +# The same holds true for keys in the $env.config which are also records +# or lists. +# +# For this reason, settings are typically changed by updating the value of +# a particular key. Merging a new config record is also possible. See the +# Configuration chapter of the book for more information. + +# ------------------------ +# History-related settings +# ------------------------ +# $env.config.history.* + +# file_format (string): Either "sqlite" or "plaintext". While text-backed history +# is currently the default for historical reasons, "sqlite" is stable and +# provides more advanced history features. +$env.config.history.file_format = "sqlite" + +# max_size (int): The maximum number of entries allowed in the history. +# After exceeding this value, the oldest history items will be removed +# as new commands are added. +$env.config.history.max_size = 5_000_000 + +# sync_on_enter (bool): Whether the plaintext history file is updated +# each time a command is entered. If set to `false`, the plaintext history +# is only updated/written when the shell exits. This setting has no effect +# for SQLite-backed history. +$env.config.history.sync_on_enter = true + +# isolation (bool): +# `true`: New history from other currently-open Nushell sessions is not +# seen when scrolling through the history using PrevHistory (typically +# the Up key) or NextHistory (Down key) +# `false`: All commands entered in other Nushell sessions will be mixed with +# those from the current shell. +# Note: Older history items (from before the current shell was started) are +# always shown. +# This setting only applies to SQLite-backed history +$env.config.history.isolation = true + +# ---------------------- +# Miscellaneous Settings +# ---------------------- + +# show_banner (bool): Enable or disable the welcome banner at startup +$env.config.show_banner = true + +# rm.always_trash (bool): +# true: rm behaves as if the --trash/-t option is specified +# false: rm behaves as if the --permanent/-p option is specified (default) +# Explicitly calling `rm` with `--trash` or `--permanent` always override this setting +# Note that this feature is dependent on the host OS trashcan support. +$env.config.rm.always_trash = false + +# recursion_limit (int): how many times a command can call itself recursively +# before an error will be generated. +$env.config.recursion_limit = 50 + +# --------------------------- +# Commandline Editor Settings +# --------------------------- + +# edit_mode (string) "vi" or "emacs" sets the editing behavior of Reedline +edit_mode: "emacs" + +# Command that will be used to edit the current line buffer with Ctrl+O. +# If unset, uses $env.VISUAL and then $env.EDITOR +# +# Tip: Set to "editor" to use the default editor on Unix platforms using +# the Alternatives system or equivalent +buffer_editor: "editor" + +# cursor_shape_* (string) +# ----------------------- +# The following variables accept a string from the following selections: +# "block", "underscore", "line", "blink_block", "blink_underscore", "blink_line", or "inherit" +# "inherit" skips setting cursor shape and uses the current terminal setting. +$env.config.cursor_shape.emacs = "inherit" # Cursor shape in emacs mode +$env.config.cursor_shape.vi_insert = "block" # Cursor shape in vi-insert mode +$env.config.cursor_shape.vi_normal = "underscore" # Cursor shape in normal vi mode + +# -------------------- +# Completions Behavior +# -------------------- +# $env.config.completions.* +# Apply to the Nushell completion system + +# algorithm (string): Either "prefix" or "fuzzy" +$env.config.completions.algorithm = "prefix" + +# sort (string): One of "smart" or "alphabetical" +# In "smart" mode sort order is based on the "algorithm" setting. +# When using the "prefix" algorithm, results are alphabetically sorted. +# When using the "fuzzy" algorithm, results are sorted based on their fuzzy score. +$env.config.completions.sort = "smart" + +# case_sensitive (bool): true/false to enable/disable case-sensitive completions +$env.config.completions.case_sensitive = false + +# quick (bool): +# true: auto-select the completion when only one remains +# false: prevents auto-select of the final result +$env.config.completions.quick = true + +# partial (bool): +# true: Partially complete up to the best possible match +# false: Do not partially complete +# Partial Example: If a directory contains only files named "forage", "food", and "forest", +# then typing "ls " and pressing will partially complete the first two +# letters, "f" and "o". If the directory also includes a file named "faster", +# then only "f" would be partially completed. +$env.config.completions.partial = true + +# use_ls_colors (bool): When true, apply LS_COLORS to file/path/directory matches +$env.config.completions.use_ls_colors = true + +# -------------------- +# External Completions +# -------------------- +# completions.external.*: Settings related to completing external commands +# and additional completers + +# external.exnable (bool) +# true: search for external commands on the Path +# false: disabling might be desired for performance if your path includes +# directories on a slower filesystem +$env.config.completions.external.enable = true + +# max_results (int): Limit the number of external commands retrieved from +# path to this value. Has no effect if `...external.enable` (above) is set to `false` +$env.config.completions.external.max_results = 50 + +# completer (closure with a |spans| parameter): A command to call for *argument* completions +# to commands (internal or external). +# +# The |spans| parameter is a list of strings representing the tokens (spans) +# on the current commandline. It is always a list of at least two strings - The +# command being completed plus the first argument of that command ("" if no argument has +# been partially typed yet), and additional strings for additional arguments beyond +# the first. +# +# This setting is usually set to a closure which will call a third-party completion system, such +# as Carapace. +# +# Note: The following is an over-simplified completer command that will call Carapace if it +# is installed. Please use the official Carapace completer, which can be generated automatically +# by Carapace itself. See the Carapace documentation for the proper syntax. +$env.config.completions.external.completer = {|spans| + carapace $spans.0 nushell ...$spans | from json +} + +# -------------------- +# Terminal Integration +# -------------------- +# Nushell can output a number of escape codes to enable advanced features in Terminal Emulators +# that support them. Settings in this section enable or disable these features in Nushell. +# Features aren't supported by your Terminal can be disabled. Features can also be disabled, +# of course, if there is a conflict between the Nushell and Terminal's implementation. + +# use_kitty_protocol (bool): +# A keyboard enhancement protocol supported by the Kitty Terminal. Additional keybindings are +# available when using this protocol in a supported terminal. For example, without this protocol, +# Ctrl+I is interpreted as the Tab Key. With this protocol, Ctrl+I and Tab can be mapped separately. +$env.config.use_kitty_protocol = false + +# osc2 (bool): +# When true, the current directory and running command are shown in the terminal tab/window title. +# Also abbreviates the directory name by prepending ~ to the home directory and its subdirectories. +$env.config.shell_integration.osc2 = true + +# osc7 (bool): +# Nushell will report the current directory to the terminal using OSC 7. This is useful when +# spawning new tabs in the same directory. +$env.config.shell_integration.osc7 = true + +# osc9_9 (bool): +# Enables/Disables OSC 9;9 support, originally a ConEmu terminal feature. This is an +# alternative to OSC 7 which also communicates the current path to the terminal. +$env.config.shell_integration.osc9_9 = false + +# osc8 (bool): +# When true, the `ls` command will generate clickable links that can be launched in another +# application by the terminal. +# Note: This setting replaces the now deprecated `ls.show_clickable_links` +$env.config.shell.integration.osc8: true + +# Deprecated +# $env.config.ls.clickable_links = true + +# osc133 (bool): +# true/false to enable/disable OSC 133 support, a set of several escape sequences which +# report the (1) starting location of the prompt, (2) ending location of the prompt, +# (3) starting location of the command output, and (4) the exit code of the command. + +# originating with Final Term. These sequences report information regarding the prompt +# location as well as command status to the terminal. This enables advanced features in +# some terminals, including the ability to provide separate background colors for the +# command vs. the output, collapsible output, or keybindings to scroll between prompts. +$env.config.shell_integration.osc133 = true + +# osc633 (bool): +# true/false to enable/disable OSC 633, an extension to OSC 133 for Visual Studio Code +$env.config.shell_integration.osc633 = true + +# reset_application_mode (bool): +# true/false to enable/disable sending ESC[?1l to the terminal +# This sequence is commonly used to keep cursor key modes in sync between the local +# terminal and a remove SSH host. +$env.config.shell_integration.reset_application_mode = true + +# bracketed_paste (bool): +# true/false to enable/disable the bracketed-paste feature, which allows multiple-lines +# to be pasted into Nushell at once without immediate execution. When disabled, +# each pasted line is executed as it is received. +# Note that bracketed paste is not currently supported on the Windows version of +# Nushell. +$env.config.bracketed_paste = true + +# use_ansi_coloring (bool): +# true/false to enable/disable the use of ANSI colors in Nushell internal commands. +# When disabled, output from Nushell built-in commands will display only in the default +# foreground color. +# Note: Does not apply to the `ansi` command. +$env.config.use_ansi_coloring = true + +# ---------------------- +# Error Display Settings +# ---------------------- + +# error_style (string): One of "fancy" or "plain" +# Plain: Display plain-text errors for screen-readers +# Fancy: Display errors using line-drawing characters to point to the span in which the +# problem occurred. +$env.config.error_style = "fancy" + +# display_errors.exit_code (bool): +# true: Display a Nushell error when an external command returns a non-zero exit code +# false: Display only the error information printed by the external command itself +# Note: Core dump errors are always printed; SIGPIPE never triggers an error +$env.config.display_errors.exit_code = false + +# display_errors.termination_signal (bool): +# true/false to enable/disable displaying a Nushell error when a child process is +# terminated via any signal +$env.config.display_errors.termination_signal = true + +# ------------- +# Table Display +# ------------- +# footer_mode (string or int): +# Specifies when to display table footers with column names. Allowed values: +# "always" +# "never" +# "auto": When the length of the table would scroll the header past the first line of the terminal +# (int): When the number of table rows meets or exceeds this value +# Note: Does not take into account rows with multiple lines themselves +$env.config.footer_mode = 25 + +# table.* +# table_mode (string): +# One of: "default", "basic", "compact", "compact_double", "heavy", "light", "none", "reinforced", +# "rounded", "thin", "with_love", "psql", "markdown", "dots", "restructured", "ascii_rounded", +# or "basic_compact" +# Can be overridden by passing a table to `| table --theme/-t` +$env.config.table.mode = "default" + +# index_mode (string) - One of: +# "never": never show the index column in a table or list +# "always": always show the index column in tables and lists +# "auto": show the column only when there is an explicit "index" column in the table +# Can be overridden by passing a table to `| table --index/-i` +$env.config.table.index_mode = "always" + +# show_empty (bool): +# true: show "empty list" or "empty table" when no values exist +# false: display no output when no values exist +$env.config.table.show_empty = true + +# padding.left/right (int): The number of spaces to pad around values in each column +$env.config.table.padding.left = 1 +$env.config.table.padding.right = 1 + +# trim.*: The rules that will be used to display content in a table row when it would cause the +# table to exceed the terminal width. +# methodology (string): One of "wrapping" or "truncating" +# truncating_suffix (string): The text to show at the end of the row to indicate that it has +# been truncated. Only valid when `methodology = "truncating"`. +# wrapping_try_keep_words (bool): true to keep words together based on whitespace +# false to allow wrapping in the middle of a word. +# Only valid when `methodology = wrapping`. +$env.config.table.trim = { + methodology: "wrapping" + wrapping_try_keep_words: true +} +# or +$env.config.table.trim = { + methodology: "truncating" + truncating_suffix: "..." +} + +# header_on_separator (bool): +# true: Displays the column headers as part of the top (or bottom) border of the table +# false: Displays the column header in its own row with a separator below. +$env.config.table.header_on_separator = false + +# abbreviated_row_count (int or nothing): +# If set to an int, all tables will be abbreviated to only show the first and last rows +# If set to `null`, all table rows will be displayed +# Can be overridden by passing a table to `| table --abbreviated/-a` +$env.config.table.abbreviated_row_count + +# footer_inheritance (bool): Footer behavior in nested tables +# true: If a nested table is long enough on its own to display a footer (per `footer_mode` above), +# then also display the footer for the parent table +# false: Always apply `footer_mode` rules to the parent table +$env.config.table.footer_inheritance = false + +# ---------------- +# Datetime Display +# ---------------- +# datetime_format.* (string or nothing): +# Format strings that will be used for datetime values. +# When set to `null`, the default behavior is to "humanize" the value (e.g., "now" or "a day ago") + +# datetime_format.table (string or nothing): +# The format string (or `null`) that will be used to display a datetime value when it appears in a +# structured value such as a table, list, or record. +$env.config.datetime_format.table = null + +# datetime_format.normal (string or nothing): +# The format string (or `null`) that will be used to display a datetime value when it appears as +# a raw value. +$env.config.datetime_format.normal = "%m/%d/%y %I:%M:%S%p" + +# ---------------- +# Filesize Display +# ---------------- +# filesize.metric (bool): When displaying filesize values ... +# true: Use the ISO-standard KB, MB, GB +# false: Use the Windows-standard KiB, MiB, GiB +$env.config.filesize.metric = false + +# filesize.format (string): One of either: +# - The filesize units such as "KB", "KiB", etc. In this case, filesize values always display using +# this unit. +# - Or "auto": Filesizes are displayed using the closest unit. For example, 1_000_000_000b will display +# as 953.7 MiB (when `metric = false`) or 1.0GB (when `metric = true`) +$env.config.filesize.format = "auto" + +# --------------------- +# Miscellaneous Display +# --------------------- + +# render_right_prompt_on_last_line(bool): +# true: When using a multi-line left-prompt, the right-prompt will be displayed on the last line +# false: The right-prompt is displayed on the first line of the left-prompt +$env.config.render_right_prompt_on_last_line = false + +# float_precision (int): +# Float values will be rounded to this precision when displaying in structured values such as lists, +# tables, or records. +$env.config.float_precision = 2 + +# ls.use_ls_colors (bool): +# true: The `ls` command will apply the $env.LS_COLORS standard to filenames +# false: Filenames in the `ls` table will use the color_config for strings +$env.config.ls = true + +# Hooks +# ----- +# $env.config.hooks is a record containing the five different types of Nushell hooks. +# See the Hooks documentation at https://www.nushell.sh/book/hooks for details +# +# Most hooks can accept a string, a closure, or a list containing strings and/or closures. +# The display_output record can only accept a string or a closure, but never a list +# +# WARNING: A malformed display_output hook can suppress all Nushell output to the terminal. +# It can be reset by assigning an empty string as below: + +$env.config.hooks.pre_prompt = [] # Before each prompt is displayed +$env.config.hooks.pre_execution = [] # After is pressed; before the commandline + # is executed +$env.config.hooks.env_change = [] # When a specified environment variable changes +$env.config.hooks.display_output = "" # Before Nushell output is displayed in the terminal +$env.config.hooks.command_not_found = [] # When a command is not found + +# ----------- +# Keybindings +# ----------- +# keybindings (list): A list of user-defined keybindings +# Nushell/Reedline keybindings can be added or overridden using this setting. +# See https://www.nushell.sh/book/line_editor.html#keybindings for details. +# +# Example - Add a new Alt+. keybinding to insert the last token used on the previous commandline +$env.config.keybindings ++= [ + { + name: insert_last_token + modifier: alt + keycode: char_. + mode: [emacs vi_normal vi_insert] + event: [ + { edit: InsertString, value: "!$" } + { send: Enter } + ] + } +] + +# Example: Override the F1 keybinding with a user-defined help menu (see "Menus" below): +$env.config.keybindings ++= [ + { + name: help_menu + modifier: none + keycode: f1 + mode: [emacs, vi_insert, vi_normal] + event: { send: menu name: help_menu } + } +] + +# ----- +# Menus +# ----- +# menus (list): +# +# Nushell/Reedline menus can be created and modified using this setting. +# See https://www.nushell.sh/book/line_editor.html#menus for details. +# +# Note that menus are usually activated via keybindings, which are defined in +# $env.config.keybindings (above). +# +# Simple example - Add a new Help menu to the list (note that a similar menu is already +# defined internally): +$env.config.menus ++= [ + { + name: help_menu + only_buffer_difference: true + marker: "? " + type: { + layout: description + columns: 4 + col_width: 20 # Optional value. If missing all the screen width is used to calculate column width + col_padding: 2 + selection_rows: 4 + description_rows: 10 + } + style: { + text: green + selected_text: green_reverse + description_text: yellow + } + } +] + + +# --------------- +# Plugin behavior +# --------------- +# Per-plugin configuration. See https://www.nushell.sh/contributor-book/plugins.html#configuration. +plugins: {} +$env.config.plugins +$env.config.plugin_gc +$env.config.plugin_gc.default +$env.config.plugin_gc.default.enabled +$env.config.plugin_gc.default.stop_after +$env.config.plugin_gc.plugins + plugin_gc: { + # Configuration for plugin garbage collection + default: { + enabled: true # true to enable stopping of inactive plugins + stop_after: 10sec # how long to wait after a plugin is inactive to stop it + } + plugins: { + # alternate configuration for specific plugins, by name, for example: + # + # gstat: { + # enabled: false + # } + } + } + + +# ------------------------------------- +# Themes/Colors and Syntax Highlighting +# ------------------------------------- +# For more information on defining custom themes, see +# https://www.nushell.sh/book/coloring_and_theming.html + +# Use and/or contribute to the theme collection at +# https://github.com/nushell/nu_scripts/tree/main/themes + +# Values: + +# highlight_resolved_externals (bool): +# true: Applies the `color_config.shape_external_resolved` color (below) to external commands +# which are found (resolved) on the path +# false: Applies the `color_config.shape_external` color to *all* externals simply based on whether +# or not they would be *parsed* as an external command based on their position. +# Defaults to false for systems with a slower search path +$env.config.highlight_resolved_externals = true + +# color_config (record): A record of shapes, types, UI elements, etc. that can be styled (e.g., +# colorized) in Nushell, either on the commandline itself (shapes) or in output. +# +# Note that this is usually set through a theme provided by a record in a custom command. For +# instance, the standard library contains two "starter" theme commands: "dark-theme" and +# "light-theme". For example: +use std/config dark-theme +$env.config.color_config = (dark-theme) + +# Or, individual color settings can be configured or overridden. +# +# Values can be one of: +# - A color name such as "red" (see `ansi -l` for a list) +# - A color RGB value in the form of "#C4C9C6" +# - A record including: +# * `fg` (color) +# * `bg` (color) +# * `attr`: a string with one or more of: +# - 'n': normal +# - 'b': bold +# - 'u': underline +# - 'r': reverse +# - 'i': italics +# - 'd': dimmed + +# foreground, background, and cursor colors are not handled by Nushell, but can be used by +# custom-commands such as `theme` from the nu_scripts repository. That `theme` command can be +# used to set the terminal foreground, background, and cursor colors. +$env.config.color_config.foreground +$env.config.color_config.background +$env.config.color_config.cursor + +# ------------------------------------------------------------------------------------------------- +# shape_: Applies syntax highlighting based on the "shape" (inferred or declared type) of an +# element on the commandline. Nushell's parser can identify shapes based on many criteria, often +# as the commandline is being typed. + +# shape_string: Can appear as a single-or-quoted value, a bareword string, the key of a record, +# an argument which has been declared as a string, and other parsed strings. +$env.config.color_config.shape_string + +# shape_string_interpolation: A single-or-double-quoted string interpolation. This style +# applies to the dollar sign and quotes of the string. The elements inside the string are +# styled according to their own shape. +$env.config.color_config.shape_string_interpolation + +# shape_raw_string: a raw string literal. E.g., r#'This is a raw string'#. This style applies +# to the entire raw string. +$env.config.color_config.shape_raw_string + +# shape_record: A record-literal. This style applies to the brackets around the record. The keys +# and values will be styled according to their individual shapes. +$env.config.color_config.shape_record + +# shape_list: A list-literal. This style applies to the brackets and list separator only. The +# items in a list are styled according to their individual shapes. +$env.config.color_config.shape_list + +# shape_table: A table-literl. Color applies to the brackets, semicolon, and list separators. The +# items in the table are style according to their individual shapes. +$env.config.color_config.shape_table + +# shape_bool: A boolean-literal `true` or `false` value +$env.config.color_config.shape_bool + +# shape_int: Integer literals +$env.config.color_config.shape_int + +# shape_float: Float literals. E.g., 5.4 +# Also integer literals in a float-argument position +$env.config.color_config.shape_float + +# shape_range: Range literals +$env.config.color_config.shape_range + +# shape_binary: Binary literals +$env.config.color_config.shape_binary + +# shape_datetime: Datetime literals +$env.config.color_config.shape_datetime + +# shape_custom: A custom value, usually from a plugin +$env.config.color_config.shape_custom + +# shape_nothing: A literal `null` +$env.config.color_config.shape_nothing + +# shape_literal: Not currently used +$env.config.color_config.shape_literal + +# shape_operator: An operator such as +, -, ++, in, not-in, etc. +$env.config.color_config.shape_operator + +# shape_filepath: An argument that appears in the position of a `path` shape for a command +$env.config.color_config.shape_filepath + +# shape_directory: A more specific 'path' shape that only accepts a directory. +$env.config.color_config.shape_directory + +# shape_globpattern: An argument in the position of a glob parameter. E.g., the asterisk (or any other string) in `ls *`. +$env.config.color_config.shape_globpattern + +# shape_glob_interpolation: Deprecated +$env.config.color_config.shape_glob_interpolation + +# shape_garbage: When an argument is of the wrong type or cannot otherwise be parsed. +# E.g., `ls {a: 5}` - A record argument to `ls` is 'garbage'. Also applied in real-time when +# an expression is not (yet) properly closed. +$env.config.color_config.shape_garbage + +# shape_or and shape_and: The and and or operators. +# Note: Not currently implemented. +$env.config.color_config.shape_or +$env.config.color_config.shape_and + +# shape_variable: The *use* of a variable. E.g., `$env` or `$a`. +$env.config.color_config.shape_variable + +# shape_vardecl: The *declaration* of a variable. E.g. the "a" in `let a = 5`. +$env.config.color_config.shape_vardecl + +# shape_matching_brackets: When the cursor is positioned on an opening or closing bracket (e.g, +# braces, curly braces, or parenthesis), and there is a matching opening/closing bracket, both will +# temporarily have this style applied. +$env.config.color_config.shape_matching_brackets + +# shape_pipe: The pipe `|` when used to separate expressions in a pipeline +$env.config.color_config.shape_pipe + +# shape_internalcall: A known Nushell built-in or custom command in the "command position" (usually +# the first bare word of an expression). +$env.config.color_config.shape_internalcall + +# shape_external: A token in the "command position" (see above) that is not a known Nushell +# built-in or custom command. This is assumed to be an external command. +$env.config.color_config.shape_external + +# shape_external_resolved: Requires "highlight_resolved_externals" (above) to be enabled. +# When a token matches the "external" requirement (above) and is also a *confirmed* external +# command, this style will be applied. +$env.config.color_config.shape_external_resolved + +# shape_externalarg: Arguments to an external command (whether resolved or not) +$env.config.color_config.shape_externalarg + +# shape_match_pattern: The matching pattern for each arm in a match expression. Does not +# include the guard expression (if present). +$env.config.color_config.shape_match_pattern + +# shape_block: The curly-braces around a block. Expressions within the block will have their +# their own shapes' styles applied. +$env.config.color_config.shape_block + +# shape_signature: The parameter definitions and input/output types for a command signature. +$env.config.color_config.shape_signature + +# shape_keyword: Not current used +$env.config.color_config.shape_keyword + +# shape_closure: Styles the brackets and arguments of a closure. +$env.config.color_config.shape_closure + +# shape_direction: The redirection symbols such as `o>`, `error>`, `e>|`, etc. +$env.config.color_config.shape_redirection + +# shape_flag: Flags and switches to internal and custom-commands. Only the `--flag` (`-f`) portion +# is styled. The argument to a flag will be styled using its own shape. +$env.config.color_config.shape_flag + +# ------------------------------------------------------------------------------------------------- +# color.config. +# *Values* of a particular *type* can be styled differently than the *shape*. +# Note that the style is applied only when this type is displayed in *structured* data (list, +# record, or table). It is not currently applied to basic raw values. +# +# Note that some types are rarely or never seen in a context in which styling would be applied. +# For example, a cell-path *value* is unlikely to (but can) appear in a list, record, or table. +# +# Tip: In addition to the styles above (fg, bg, attr), types typically accept a closure which can +# dynamically change the style based on the *value*. For instance, the themes in the nu_scripts +# repository will style filesizes difference in an `ls` (or other table) differently depending on +# their magnitude. + +# Simple examples: + +# bool: A boolean value +$env.config.color_config.bool = {|| + if $in { + { + bg: 'light_green' + fg: 'white' + attr: 'b' + } + } else { + { + bg: 'yellow' + fg: 'black' + attr: 'b' + } + } +} + +# int: An integer value +$env.config.color_config.int = {|| + if $in == 42 { 'green' } else { 'red' } +} + +# Additional type values (without examples): +$env.config.color_config.string # String +$env.config.color_config.float # Float value +$env.config.color_config.glob # Glob value (must be declared) +$env.config.color_config.binary # Binary value +$env.config.color_config.custom # Custom value (often from a plugin) +$env.config.color_config.nothing # Not used, since a null is not displayed +$env.config.color_config.date # datetime value +$env.config.color_config.filesize # filesize value +$env.config.color_config.list # Not currently used. Lists are displayed using their + # members' styles +$env.config.color_config.record # Not currently used. Records are displayed using their + # member's styles +$env.config.color_config.duration # Duration type +$env.config.color_config.range # Range value +$env.config.color_config.cell-path # Cell-path value +$env.config.color_config.closure # Not currently used +$env.config.color_config.block # Not currently used + +# Additional UI elements +# hints: The (usually dimmed) style in which completion hints are displayed +$env.config.color_config.hints + +# search_result: The style applied to `find` search results +$env.config.color_config.search_result + +# header: The column names in a table header +$env.config.color_config.header + +# separator: Used for table/list/record borders +$env.config.color_config.separator + +# row_index: The `#` or `index` column of a table or list +$env.config.color_config.row_index + +# empty: This style is applied to empty/missing values in a table. However, since the ❎ +# emoji is used for this purpose, there is limited styling that can be applied. +$env.config.color_config.empty + +# leading_trailing_space_bg: When a string value inside structured data has leading or trailing +# whitespace, that whitespace will be displayed using this style. +# Use { attr: n } to disable. +$env.config.color_config.leading_trailing_space_bg = { bg: 'red' } + +# ------------------------ +# `explore` command colors +# ------------------------ +# Configure the UI colors of the `explore` command +# Allowed values are the same as for the `color_config` options above. +# Example: +$env.config.explore = { + status_bar_background: { fg: "#1D1F21", bg: "#C4C9C6" }, + command_bar_text: { fg: "#C4C9C6" }, + highlight: { fg: "black", bg: "yellow" }, + status: { + error: { fg: "white", bg: "red" }, + warn: {} + info: {} + }, + selected_cell: { bg: light_blue }, +} diff --git a/crates/nu-utils/src/default_files/sample_env.nu b/crates/nu-utils/src/default_files/sample_env.nu new file mode 100644 index 0000000000..84926abb2f --- /dev/null +++ b/crates/nu-utils/src/default_files/sample_env.nu @@ -0,0 +1,135 @@ +# Sample Nushell Environment Config File +# +# Environment variables are usually configured in `env.nu`. Nushell +# sets sensible defaults for many environment variables, so the user's +# `env.nu` only needs to override these defaults if desired. +# +# This file serves as simple "in-shell" documentation for these +# settings, or you can view a more complete discussion online at: +# https://nushell.sh/book/configuration +# +# You can pretty-print and page this file using: +# config env --sample | nu-highlight | less -R + +# PROMPT_* +# -------- +# Prompt configuration +# PROMPT_ variables accept either a string or a closure that returns a string + +# PROMPT_COMMAND +# -------------- +# Defines the primary prompt. Note that the PROMPT_INDICATOR (below) is appended to this value. +# Simple example - Static string: +$env.PROMPT_COMMAND = "Nushell" +# Simple example - Dynamic closure displaying the path: +$env.PROMPT_COMMAND = {|| pwd} + +# PROMPT_INDICATOR* +# ----------------- +# The prompt indicators are environmental variables that represent +# the state of the prompt. The specified character(s) will appear +# immediately following the PROMPT_COMMAND + +# When in Emacs mode (default): +$env.PROMPT_INDICATOR = "> " + +# When in normal vi mode: +$env.PROMPT_INDICATOR_VI_NORMAL = "> " +# When in vi insert-mode: +$env.PROMPT_INDICATOR_VI_INSERT = ": " + +# When a commandline extends across multiple lines: +$env.PROMPT_MULTILINE_INDICATOR = "::: " + +# TRANSIENT_PROMPT_* +# ------------------ +# Allows a different prompt to be shown after a command has been executed. This +# can be useful if you have a 2-line prompt. Instead of each previously-entered +# command taking up at least 2 lines, the transient prompt can condense it to a +# shorter version. The following example shows a rocket emoji before each +# previously-entered command: +$env.TRANSIENT_PROMPT_COMMAND = "🚀 " +$env.TRANSIENT_PROMPT_INDICATOR = "" +$env.TRANSIENT_PROMPT_INDICATOR_VI_INSERT = "" +$env.TRANSIENT_PROMPT_INDICATOR_VI_NORMAL = "" +# Tip: Removing the transient multiline indicator and right-prompt can simplify +# copying from the terminal +$env.TRANSIENT_PROMPT_MULTILINE_INDICATOR = "" +$env.TRANSIENT_PROMPT_COMMAND_RIGHT = "" + +# ENV_CONVERSIONS +# --------------- +# Certain variables, such as those containing multiple paths, are often stored as a +# colon-separated string in other shells. Nushell can convert these automatically to a +# more convenient Nushell list. The ENV_CONVERSIONS variable specifies how environment +# variables are: +# - converted from a string to a value on Nushell startup (from_string) +# - converted from a value back to a string when running external commands (to_string) +# +# Note: The OS Path variable is automatically converted before env.nu loads, so it can +# be treated a list in this file. +# +# Note: Environment variables are not case-sensitive, so the following will work +# for both Windows and Unix-like platforms. +# +# By default, the internal conversion looks something like the following, so there +# is no need to add this in your actual env.nu: +$env.ENV_CONVERSIONS = { + "Path": { + from_string: { |s| $s | split row (char esep) | path expand --no-symlink } + to_string: { |v| $v | path expand --no-symlink | str join (char esep) } + } +} + +# Here's an example converts the XDG_DATA_DIRS variable to and from a list: +$env.ENV_CONVERSIONS = $env.ENV_CONVERSIONS | merge { + "XDG_DATA_DIRS": { + from_string: { |s| $s | split row (char esep) | path expand --no-symlink } + to_string: { |v| $v | path expand --no-symlink | str join (char esep) } + } +} +# +# Other common directory-lists for conversion: TERMINFO_DIRS. +# Note that other variable conversions take place after `config.nu` is loaded. + +# NU_LIB_DIRS +# ----------- +# Directories in this environment variable are searched by the +# `use` and `source` commands. +# +# By default, the `scripts` subdirectory of the default configuration +# directory is included: +$env.NU_LIB_DIRS = [ + ($nu.default-config-dir | path join 'scripts') # add /scripts + ($nu.data-dir | path join 'completions') # default home for nushell completions +] +# You can replace (override) or append to this list: +$env.NU_LIB_DIRS ++= ($nu.default-config-dir | path join 'modules') + +# NU_PLUGIN_DIRS +# -------------- +# Directories to search for plugin binaries when calling register. + +# By default, the `plugins` subdirectory of the default configuration +# directory is included: +$env.NU_PLUGIN_DIRS = [ + ($nu.default-config-dir | path join 'plugins') # add /plugins +] + +# Appending to the OS path is a common configuration task. +# Because of the previous ENV_CONVERSIONS (performed internally +# before your env.nu loads), the path variable is a list that can +# be appended to using, for example: +$env.path ++= "~/.local/bin" + +# Or prepend using +$env.path = "~/.local/bin" ++ $env.path + +# The `path add` function from the Standard Library also provides +# a convenience method for prepending to the path: +use std/util "path add" +path add "~/.local/bin" +path add ($env.CARGO_HOME | path join "bin") + +# You can remove duplicate directories from the path using: +$env.PATH = ($env.PATH | uniq) diff --git a/crates/nu-utils/src/sample_config/sample_login.nu b/crates/nu-utils/src/default_files/sample_login.nu similarity index 100% rename from crates/nu-utils/src/sample_config/sample_login.nu rename to crates/nu-utils/src/default_files/sample_login.nu diff --git a/crates/nu-utils/src/default_files/scaffold_config.nu b/crates/nu-utils/src/default_files/scaffold_config.nu new file mode 100644 index 0000000000..7bf7ecc632 --- /dev/null +++ b/crates/nu-utils/src/default_files/scaffold_config.nu @@ -0,0 +1,19 @@ +# config.nu +# +# This file is used to override default Nushell settings, define +# (or import) custom commands, or run any other startup tasks. +# See https://www.nushell.sh/book/configuration.html +# +# This file is loaded after env.nu and before login.nu +# +# You can open this file in your default editor using: +# config nu +# +# To pretty-print a sample config.nu with documentation, run: +# config nu --sample | nu-highlight | less -R +# +# To pretty-print the default configuration values, run: +# config nu --default | nu-highlight | less -R +# +# You can remove these comments if you want or leave +# them for future reference. diff --git a/crates/nu-utils/src/default_files/scaffold_env.nu b/crates/nu-utils/src/default_files/scaffold_env.nu new file mode 100644 index 0000000000..a3ce3cab07 --- /dev/null +++ b/crates/nu-utils/src/default_files/scaffold_env.nu @@ -0,0 +1,18 @@ +# env.nu +# +# This file is typically used to add or override environment variables. +# See https://www.nushell.sh/book/configuration.html +# +# This file is loaded before config.nu and login.nu +# +# You can open this file in your default editor using: +# config env +# +# To pretty-print a sample env.nu with documentation, run: +# config env --sample | nu-highlight | less -R +# +# To pretty-print the default environment values, run: +# config env --default | nu-highlight | less -R +# +# You can remove these comments if you want or leave +# them for future reference. diff --git a/crates/nu-utils/src/lib.rs b/crates/nu-utils/src/lib.rs index 4b91d923db..413b5f8893 100644 --- a/crates/nu-utils/src/lib.rs +++ b/crates/nu-utils/src/lib.rs @@ -10,8 +10,9 @@ pub mod utils; pub use locale::get_system_locale; pub use utils::{ - enable_vt_processing, get_default_config, get_default_env, get_ls_colors, - stderr_write_all_and_flush, stdout_write_all_and_flush, + enable_vt_processing, get_default_config, get_default_env, get_ls_colors, get_sample_config, + get_sample_env, get_scaffold_config, get_scaffold_env, stderr_write_all_and_flush, + stdout_write_all_and_flush, }; pub use casing::IgnoreCaseExt; diff --git a/crates/nu-utils/src/sample_config/default_config.nu b/crates/nu-utils/src/sample_config/default_config.nu deleted file mode 100644 index c8b398b684..0000000000 --- a/crates/nu-utils/src/sample_config/default_config.nu +++ /dev/null @@ -1,899 +0,0 @@ -# Nushell Config File -# -# version = "0.100.1" - -# For more information on defining custom themes, see -# https://www.nushell.sh/book/coloring_and_theming.html -# And here is the theme collection -# https://github.com/nushell/nu_scripts/tree/main/themes -let dark_theme = { - # color for nushell primitives - separator: white - leading_trailing_space_bg: { attr: n } # no fg, no bg, attr none effectively turns this off - header: green_bold - empty: blue - # Closures can be used to choose colors for specific values. - # The value (in this case, a bool) is piped into the closure. - # eg) {|| if $in { 'light_cyan' } else { 'light_gray' } } - bool: light_cyan - int: white - filesize: cyan - duration: white - date: purple - range: white - float: white - string: white - nothing: white - binary: white - cell-path: white - row_index: green_bold - record: white - list: white - block: white - hints: dark_gray - search_result: { bg: red fg: white } - shape_and: purple_bold - shape_binary: purple_bold - shape_block: blue_bold - shape_bool: light_cyan - shape_closure: green_bold - shape_custom: green - shape_datetime: cyan_bold - shape_directory: cyan - shape_external: cyan - shape_externalarg: green_bold - shape_external_resolved: light_yellow_bold - shape_filepath: cyan - shape_flag: blue_bold - shape_float: purple_bold - # shapes are used to change the cli syntax highlighting - shape_garbage: { fg: white bg: red attr: b } - shape_glob_interpolation: cyan_bold - shape_globpattern: cyan_bold - shape_int: purple_bold - shape_internalcall: cyan_bold - shape_keyword: cyan_bold - shape_list: cyan_bold - shape_literal: blue - shape_match_pattern: green - shape_matching_brackets: { attr: u } - shape_nothing: light_cyan - shape_operator: yellow - shape_or: purple_bold - shape_pipe: purple_bold - shape_range: yellow_bold - shape_record: cyan_bold - shape_redirection: purple_bold - shape_signature: green_bold - shape_string: green - shape_string_interpolation: cyan_bold - shape_table: blue_bold - shape_variable: purple - shape_vardecl: purple - shape_raw_string: light_purple -} - -let light_theme = { - # color for nushell primitives - separator: dark_gray - leading_trailing_space_bg: { attr: n } # no fg, no bg, attr none effectively turns this off - header: green_bold - empty: blue - # Closures can be used to choose colors for specific values. - # The value (in this case, a bool) is piped into the closure. - # eg) {|| if $in { 'dark_cyan' } else { 'dark_gray' } } - bool: dark_cyan - int: dark_gray - filesize: cyan_bold - duration: dark_gray - date: purple - range: dark_gray - float: dark_gray - string: dark_gray - nothing: dark_gray - binary: dark_gray - cell-path: dark_gray - row_index: green_bold - record: dark_gray - list: dark_gray - block: dark_gray - hints: dark_gray - search_result: { fg: white bg: red } - shape_and: purple_bold - shape_binary: purple_bold - shape_block: blue_bold - shape_bool: light_cyan - shape_closure: green_bold - shape_custom: green - shape_datetime: cyan_bold - shape_directory: cyan - shape_external: cyan - shape_externalarg: green_bold - shape_external_resolved: light_purple_bold - shape_filepath: cyan - shape_flag: blue_bold - shape_float: purple_bold - # shapes are used to change the cli syntax highlighting - shape_garbage: { fg: white bg: red attr: b } - shape_glob_interpolation: cyan_bold - shape_globpattern: cyan_bold - shape_int: purple_bold - shape_internalcall: cyan_bold - shape_keyword: cyan_bold - shape_list: cyan_bold - shape_literal: blue - shape_match_pattern: green - shape_matching_brackets: { attr: u } - shape_nothing: light_cyan - shape_operator: yellow - shape_or: purple_bold - shape_pipe: purple_bold - shape_range: yellow_bold - shape_record: cyan_bold - shape_redirection: purple_bold - shape_signature: green_bold - shape_string: green - shape_string_interpolation: cyan_bold - shape_table: blue_bold - shape_variable: purple - shape_vardecl: purple - shape_raw_string: light_purple -} - -# External completer example -# let carapace_completer = {|spans| -# carapace $spans.0 nushell ...$spans | from json -# } - -# The default config record. This is where much of your global configuration is setup. -$env.config = { - show_banner: true # true or false to enable or disable the welcome banner at startup - - ls: { - use_ls_colors: true # use the LS_COLORS environment variable to colorize output - clickable_links: true # enable or disable clickable links. Your terminal has to support links. - } - - rm: { - always_trash: false # always act as if -t was given. Can be overridden with -p - } - - table: { - mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other - index_mode: always # "always" show indexes, "never" show indexes, "auto" = show indexes when a table has "index" column - show_empty: true # show 'empty list' and 'empty record' placeholders for command output - padding: { left: 1, right: 1 } # a left right padding of each column in a table - trim: { - methodology: wrapping # wrapping or truncating - wrapping_try_keep_words: true # A strategy used by the 'wrapping' methodology - truncating_suffix: "..." # A suffix used by the 'truncating' methodology - } - header_on_separator: false # show header text on separator/border line - footer_inheritance: false # render footer in parent table if child is big enough (extended table option) - # abbreviated_row_count: 10 # limit data rows from top and bottom after reaching a set point - } - - error_style: "fancy" # "fancy" or "plain" for screen reader-friendly error messages - - # Whether an error message should be printed if an error of a certain kind is triggered. - display_errors: { - exit_code: false # assume the external command prints an error message - # Core dump errors are always printed, and SIGPIPE never triggers an error. - # The setting below controls message printing for termination by all other signals. - termination_signal: true - } - - # datetime_format determines what a datetime rendered in the shell would look like. - # Behavior without this configuration point will be to "humanize" the datetime display, - # showing something like "a day ago." - datetime_format: { - # normal: '%a, %d %b %Y %H:%M:%S %z' # shows up in displays of variables or other datetime's outside of tables - # table: '%m/%d/%y %I:%M:%S%p' # generally shows up in tabular outputs such as ls. commenting this out will change it to the default human readable datetime format - } - - explore: { - status_bar_background: { fg: "#1D1F21", bg: "#C4C9C6" }, - command_bar_text: { fg: "#C4C9C6" }, - highlight: { fg: "black", bg: "yellow" }, - status: { - error: { fg: "white", bg: "red" }, - warn: {} - info: {} - }, - selected_cell: { bg: light_blue }, - } - - history: { - 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" - isolation: false # only available with sqlite file_format. true enables history isolation, false disables it. true will allow the history to be isolated to the current session using up/down arrows. false will allow the history to be shared across all sessions. - } - - completions: { - case_sensitive: false # set to true to enable case-sensitive completions - quick: true # set this to false to prevent auto-selecting completions when only one remains - partial: true # set this to false to prevent partial filling of the prompt - algorithm: "prefix" # prefix or fuzzy - sort: "smart" # "smart" (alphabetical for prefix matching, fuzzy score for fuzzy matching) or "alphabetical" - external: { - enable: true # set to false to prevent nushell looking into $env.PATH to find more suggestions, `false` recommended for WSL users as this look up may be very slow - max_results: 100 # setting it lower can improve completion performance at the cost of omitting some options - completer: null # check 'carapace_completer' above as an example - } - use_ls_colors: true # set this to true to enable file/path/directory completions using LS_COLORS - } - - filesize: { - metric: false # true => KB, MB, GB (ISO standard), false => KiB, MiB, GiB (Windows standard) - format: "auto" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, auto - } - - cursor_shape: { - emacs: line # block, underscore, line, blink_block, blink_underscore, blink_line, inherit to skip setting cursor shape (line is the default) - vi_insert: block # block, underscore, line, blink_block, blink_underscore, blink_line, inherit to skip setting cursor shape (block is the default) - vi_normal: underscore # block, underscore, line, blink_block, blink_underscore, blink_line, inherit to skip setting cursor shape (underscore is the default) - } - - color_config: $dark_theme # if you want a more interesting theme, you can replace the empty record with `$dark_theme`, `$light_theme` or another custom record - footer_mode: 25 # always, never, number_of_rows, auto - float_precision: 2 # the precision for displaying floats in tables - buffer_editor: null # command that will be used to edit the current line buffer with ctrl+o, if unset fallback to $env.VISUAL and $env.EDITOR - use_ansi_coloring: true - bracketed_paste: true # enable bracketed paste, currently useless on windows - edit_mode: emacs # emacs, vi - shell_integration: { - # osc2 abbreviates the path if in the home_dir, sets the tab/window title, shows the running command in the tab/window title - osc2: true - # osc7 is a way to communicate the path to the terminal, this is helpful for spawning new tabs in the same directory - osc7: true - # osc8 is also implemented as the deprecated setting ls.show_clickable_links, it shows clickable links in ls output if your terminal supports it. show_clickable_links is deprecated in favor of osc8 - osc8: true - # osc9_9 is from ConEmu and is starting to get wider support. It's similar to osc7 in that it communicates the path to the terminal - osc9_9: false - # osc133 is several escapes invented by Final Term which include the supported ones below. - # 133;A - Mark prompt start - # 133;B - Mark prompt end - # 133;C - Mark pre-execution - # 133;D;exit - Mark execution finished with exit code - # This is used to enable terminals to know where the prompt is, the command is, where the command finishes, and where the output of the command is - osc133: true - # osc633 is closely related to osc133 but only exists in visual studio code (vscode) and supports their shell integration features - # 633;A - Mark prompt start - # 633;B - Mark prompt end - # 633;C - Mark pre-execution - # 633;D;exit - Mark execution finished with exit code - # 633;E - Explicitly set the command line with an optional nonce - # 633;P;Cwd= - Mark the current working directory and communicate it to the terminal - # and also helps with the run recent menu in vscode - osc633: true - # reset_application_mode is escape \x1b[?1l and was added to help ssh work better - reset_application_mode: true - } - render_right_prompt_on_last_line: false # true or false to enable or disable right prompt to be rendered on last line of the prompt. - use_kitty_protocol: false # enables keyboard enhancement protocol implemented by kitty console, only if your terminal support this. - highlight_resolved_externals: false # true enables highlighting of external commands in the repl resolved by which. - recursion_limit: 50 # the maximum number of times nushell allows recursion before stopping it - - plugins: {} # Per-plugin configuration. See https://www.nushell.sh/contributor-book/plugins.html#configuration. - - plugin_gc: { - # Configuration for plugin garbage collection - default: { - enabled: true # true to enable stopping of inactive plugins - stop_after: 10sec # how long to wait after a plugin is inactive to stop it - } - plugins: { - # alternate configuration for specific plugins, by name, for example: - # - # gstat: { - # enabled: false - # } - } - } - - hooks: { - pre_prompt: [{ null }] # run before the prompt is shown - pre_execution: [{ null }] # run before the repl input is run - env_change: { - PWD: [{|before, after| null }] # run if the PWD environment is different since the last repl input - } - display_output: "if (term size).columns >= 100 { table -e } else { table }" # run to display the output of a pipeline - command_not_found: { null } # return an error message when a command is not found - } - - menus: [ - # Configuration for default nushell menus - # Note the lack of source parameter - { - name: completion_menu - only_buffer_difference: false - marker: "| " - type: { - layout: columnar - columns: 4 - col_width: 20 # Optional value. If missing all the screen width is used to calculate column width - col_padding: 2 - } - style: { - text: green - selected_text: { attr: r } - description_text: yellow - match_text: { attr: u } - selected_match_text: { attr: ur } - } - } - { - name: ide_completion_menu - only_buffer_difference: false - marker: "| " - type: { - layout: ide - min_completion_width: 0, - max_completion_width: 50, - max_completion_height: 10, # will be limited by the available lines in the terminal - padding: 0, - border: true, - cursor_offset: 0, - description_mode: "prefer_right" - min_description_width: 0 - max_description_width: 50 - max_description_height: 10 - description_offset: 1 - # If true, the cursor pos will be corrected, so the suggestions match up with the typed text - # - # C:\> str - # str join - # str trim - # str split - correct_cursor_pos: false - } - style: { - text: green - selected_text: { attr: r } - description_text: yellow - match_text: { attr: u } - selected_match_text: { attr: ur } - } - } - { - name: history_menu - only_buffer_difference: true - marker: "? " - type: { - layout: list - page_size: 10 - } - style: { - text: green - selected_text: green_reverse - description_text: yellow - } - } - { - name: help_menu - only_buffer_difference: true - marker: "? " - type: { - layout: description - columns: 4 - col_width: 20 # Optional value. If missing all the screen width is used to calculate column width - col_padding: 2 - selection_rows: 4 - description_rows: 10 - } - style: { - text: green - selected_text: green_reverse - description_text: yellow - } - } - ] - - keybindings: [ - { - name: completion_menu - modifier: none - keycode: tab - mode: [emacs vi_normal vi_insert] - event: { - until: [ - { send: menu name: completion_menu } - { send: menunext } - { edit: complete } - ] - } - } - { - name: completion_previous_menu - modifier: shift - keycode: backtab - mode: [emacs, vi_normal, vi_insert] - event: { send: menuprevious } - } - { - name: ide_completion_menu - modifier: control - keycode: space - mode: [emacs vi_normal vi_insert] - event: { - until: [ - { send: menu name: ide_completion_menu } - { send: menunext } - { edit: complete } - ] - } - } - { - name: history_menu - modifier: control - keycode: char_r - mode: [emacs, vi_insert, vi_normal] - event: { send: menu name: history_menu } - } - { - name: help_menu - modifier: none - keycode: f1 - mode: [emacs, vi_insert, vi_normal] - event: { send: menu name: help_menu } - } - { - name: next_page_menu - modifier: control - keycode: char_x - mode: emacs - event: { send: menupagenext } - } - { - name: undo_or_previous_page_menu - modifier: control - keycode: char_z - mode: emacs - event: { - until: [ - { send: menupageprevious } - { edit: undo } - ] - } - } - { - name: escape - modifier: none - keycode: escape - mode: [emacs, vi_normal, vi_insert] - event: { send: esc } # NOTE: does not appear to work - } - { - name: cancel_command - modifier: control - keycode: char_c - mode: [emacs, vi_normal, vi_insert] - event: { send: ctrlc } - } - { - name: quit_shell - modifier: control - keycode: char_d - mode: [emacs, vi_normal, vi_insert] - event: { send: ctrld } - } - { - name: clear_screen - modifier: control - keycode: char_l - mode: [emacs, vi_normal, vi_insert] - event: { send: clearscreen } - } - { - name: search_history - modifier: control - keycode: char_q - mode: [emacs, vi_normal, vi_insert] - event: { send: searchhistory } - } - { - name: open_command_editor - modifier: control - keycode: char_o - mode: [emacs, vi_normal, vi_insert] - event: { send: openeditor } - } - { - name: move_up - modifier: none - keycode: up - mode: [emacs, vi_normal, vi_insert] - event: { - until: [ - { send: menuup } - { send: up } - ] - } - } - { - name: move_down - modifier: none - keycode: down - mode: [emacs, vi_normal, vi_insert] - event: { - until: [ - { send: menudown } - { send: down } - ] - } - } - { - name: move_left - modifier: none - keycode: left - mode: [emacs, vi_normal, vi_insert] - event: { - until: [ - { send: menuleft } - { send: left } - ] - } - } - { - name: move_right_or_take_history_hint - modifier: none - keycode: right - mode: [emacs, vi_normal, vi_insert] - event: { - until: [ - { send: historyhintcomplete } - { send: menuright } - { send: right } - ] - } - } - { - name: move_one_word_left - modifier: control - keycode: left - mode: [emacs, vi_normal, vi_insert] - event: { edit: movewordleft } - } - { - name: move_one_word_right_or_take_history_hint - modifier: control - keycode: right - mode: [emacs, vi_normal, vi_insert] - event: { - until: [ - { send: historyhintwordcomplete } - { edit: movewordright } - ] - } - } - { - name: move_to_line_start - modifier: none - keycode: home - mode: [emacs, vi_normal, vi_insert] - event: { edit: movetolinestart } - } - { - name: move_to_line_start - modifier: control - keycode: char_a - mode: [emacs, vi_normal, vi_insert] - event: { edit: movetolinestart } - } - { - name: move_to_line_end_or_take_history_hint - modifier: none - keycode: end - mode: [emacs, vi_normal, vi_insert] - event: { - until: [ - { send: historyhintcomplete } - { edit: movetolineend } - ] - } - } - { - name: move_to_line_end_or_take_history_hint - modifier: control - keycode: char_e - mode: [emacs, vi_normal, vi_insert] - event: { - until: [ - { send: historyhintcomplete } - { edit: movetolineend } - ] - } - } - { - name: move_to_line_start - modifier: control - keycode: home - mode: [emacs, vi_normal, vi_insert] - event: { edit: movetolinestart } - } - { - name: move_to_line_end - modifier: control - keycode: end - mode: [emacs, vi_normal, vi_insert] - event: { edit: movetolineend } - } - { - name: move_down - modifier: control - keycode: char_n - mode: [emacs, vi_normal, vi_insert] - event: { - until: [ - { send: menudown } - { send: down } - ] - } - } - { - name: move_up - modifier: control - keycode: char_p - mode: [emacs, vi_normal, vi_insert] - event: { - until: [ - { send: menuup } - { send: up } - ] - } - } - { - name: delete_one_character_backward - modifier: none - keycode: backspace - mode: [emacs, vi_insert] - event: { edit: backspace } - } - { - name: delete_one_word_backward - modifier: control - keycode: backspace - mode: [emacs, vi_insert] - event: { edit: backspaceword } - } - { - name: delete_one_character_forward - modifier: none - keycode: delete - mode: [emacs, vi_insert] - event: { edit: delete } - } - { - name: delete_one_character_forward - modifier: control - keycode: delete - mode: [emacs, vi_insert] - event: { edit: delete } - } - { - name: delete_one_character_backward - modifier: control - keycode: char_h - mode: [emacs, vi_insert] - event: { edit: backspace } - } - { - name: delete_one_word_backward - modifier: control - keycode: char_w - mode: [emacs, vi_insert] - event: { edit: backspaceword } - } - { - name: move_left - modifier: none - keycode: backspace - mode: vi_normal - event: { edit: moveleft } - } - { - name: newline_or_run_command - modifier: none - keycode: enter - mode: emacs - event: { send: enter } - } - { - name: move_left - modifier: control - keycode: char_b - mode: emacs - event: { - until: [ - { send: menuleft } - { send: left } - ] - } - } - { - name: move_right_or_take_history_hint - modifier: control - keycode: char_f - mode: emacs - event: { - until: [ - { send: historyhintcomplete } - { send: menuright } - { send: right } - ] - } - } - { - name: redo_change - modifier: control - keycode: char_g - mode: emacs - event: { edit: redo } - } - { - name: undo_change - modifier: control - keycode: char_z - mode: emacs - event: { edit: undo } - } - { - name: paste_before - modifier: control - keycode: char_y - mode: emacs - event: { edit: pastecutbufferbefore } - } - { - name: cut_word_left - modifier: control - keycode: char_w - mode: emacs - event: { edit: cutwordleft } - } - { - name: cut_line_to_end - modifier: control - keycode: char_k - mode: emacs - event: { edit: cuttolineend } - } - { - name: cut_line_from_start - modifier: control - keycode: char_u - mode: emacs - event: { edit: cutfromstart } - } - { - name: swap_graphemes - modifier: control - keycode: char_t - mode: emacs - event: { edit: swapgraphemes } - } - { - name: move_one_word_left - modifier: alt - keycode: left - mode: emacs - event: { edit: movewordleft } - } - { - name: move_one_word_right_or_take_history_hint - modifier: alt - keycode: right - mode: emacs - event: { - until: [ - { send: historyhintwordcomplete } - { edit: movewordright } - ] - } - } - { - name: move_one_word_left - modifier: alt - keycode: char_b - mode: emacs - event: { edit: movewordleft } - } - { - name: move_one_word_right_or_take_history_hint - modifier: alt - keycode: char_f - mode: emacs - event: { - until: [ - { send: historyhintwordcomplete } - { edit: movewordright } - ] - } - } - { - name: delete_one_word_forward - modifier: alt - keycode: delete - mode: emacs - event: { edit: deleteword } - } - { - name: delete_one_word_backward - modifier: alt - keycode: backspace - mode: emacs - event: { edit: backspaceword } - } - { - name: delete_one_word_backward - modifier: alt - keycode: char_m - mode: emacs - event: { edit: backspaceword } - } - { - name: cut_word_to_right - modifier: alt - keycode: char_d - mode: emacs - event: { edit: cutwordright } - } - { - name: upper_case_word - modifier: alt - keycode: char_u - mode: emacs - event: { edit: uppercaseword } - } - { - name: lower_case_word - modifier: alt - keycode: char_l - mode: emacs - event: { edit: lowercaseword } - } - { - name: capitalize_char - modifier: alt - keycode: char_c - mode: emacs - event: { edit: capitalizechar } - } - # The following bindings with `*system` events require that Nushell has - # been compiled with the `system-clipboard` feature. - # If you want to use the system clipboard for visual selection or to - # paste directly, uncomment the respective lines and replace the version - # using the internal clipboard. - { - name: copy_selection - modifier: control_shift - keycode: char_c - mode: emacs - event: { edit: copyselection } - # event: { edit: copyselectionsystem } - } - { - name: cut_selection - modifier: control_shift - keycode: char_x - mode: emacs - event: { edit: cutselection } - # event: { edit: cutselectionsystem } - } - # { - # name: paste_system - # modifier: control_shift - # keycode: char_v - # mode: emacs - # event: { edit: pastesystem } - # } - { - name: select_all - modifier: control_shift - keycode: char_a - mode: emacs - event: { edit: selectall } - } - ] -} diff --git a/crates/nu-utils/src/sample_config/default_env.nu b/crates/nu-utils/src/sample_config/default_env.nu deleted file mode 100644 index fb527dc112..0000000000 --- a/crates/nu-utils/src/sample_config/default_env.nu +++ /dev/null @@ -1,101 +0,0 @@ -# Nushell Environment Config File -# -# version = "0.100.1" - -def create_left_prompt [] { - let dir = match (do --ignore-shell-errors { $env.PWD | path relative-to $nu.home-path }) { - null => $env.PWD - '' => '~' - $relative_pwd => ([~ $relative_pwd] | path join) - } - - let path_color = (if (is-admin) { ansi red_bold } else { ansi green_bold }) - let separator_color = (if (is-admin) { ansi light_red_bold } else { ansi light_green_bold }) - let path_segment = $"($path_color)($dir)(ansi reset)" - - $path_segment | str replace --all (char path_sep) $"($separator_color)(char path_sep)($path_color)" -} - -def create_right_prompt [] { - # create a right prompt in magenta with green separators and am/pm underlined - let time_segment = ([ - (ansi reset) - (ansi magenta) - (date now | format date '%x %X') # try to respect user's locale - ] | str join | str replace --regex --all "([/:])" $"(ansi green)${1}(ansi magenta)" | - str replace --regex --all "([AP]M)" $"(ansi magenta_underline)${1}") - - let last_exit_code = if ($env.LAST_EXIT_CODE != 0) {([ - (ansi rb) - ($env.LAST_EXIT_CODE) - ] | str join) - } else { "" } - - ([$last_exit_code, (char space), $time_segment] | str join) -} - -# Use nushell functions to define your right and left prompt -$env.PROMPT_COMMAND = {|| create_left_prompt } -# FIXME: This default is not implemented in rust code as of 2023-09-08. -$env.PROMPT_COMMAND_RIGHT = {|| create_right_prompt } - -# The prompt indicators are environmental variables that represent -# the state of the prompt -$env.PROMPT_INDICATOR = {|| "> " } -$env.PROMPT_INDICATOR_VI_INSERT = {|| ": " } -$env.PROMPT_INDICATOR_VI_NORMAL = {|| "> " } -$env.PROMPT_MULTILINE_INDICATOR = {|| "::: " } - -# If you want previously entered commands to have a different prompt from the usual one, -# you can uncomment one or more of the following lines. -# This can be useful if you have a 2-line prompt and it's taking up a lot of space -# because every command entered takes up 2 lines instead of 1. You can then uncomment -# the line below so that previously entered commands show with a single `🚀`. -# $env.TRANSIENT_PROMPT_COMMAND = {|| "🚀 " } -# $env.TRANSIENT_PROMPT_INDICATOR = {|| "" } -# $env.TRANSIENT_PROMPT_INDICATOR_VI_INSERT = {|| "" } -# $env.TRANSIENT_PROMPT_INDICATOR_VI_NORMAL = {|| "" } -# $env.TRANSIENT_PROMPT_MULTILINE_INDICATOR = {|| "" } -# $env.TRANSIENT_PROMPT_COMMAND_RIGHT = {|| "" } - -# Specifies how environment variables are: -# - converted from a string to a value on Nushell startup (from_string) -# - converted from a value back to a string when running external commands (to_string) -# Note: The conversions happen *after* config.nu is loaded -$env.ENV_CONVERSIONS = { - "PATH": { - from_string: { |s| $s | split row (char esep) | path expand --no-symlink } - to_string: { |v| $v | path expand --no-symlink | str join (char esep) } - } - "Path": { - from_string: { |s| $s | split row (char esep) | path expand --no-symlink } - to_string: { |v| $v | path expand --no-symlink | str join (char esep) } - } -} - -# Directories to search for scripts when calling source or use -# The default for this is $nu.default-config-dir/scripts -$env.NU_LIB_DIRS = [ - ($nu.default-config-dir | path join 'scripts') # add /scripts - ($nu.data-dir | path join 'completions') # default home for nushell completions -] - -# Directories to search for plugin binaries when calling register -# The default for this is $nu.default-config-dir/plugins -$env.NU_PLUGIN_DIRS = [ - ($nu.default-config-dir | path join 'plugins') # add /plugins -] - -# To add entries to PATH (on Windows you might use Path), you can use the following pattern: -# $env.PATH = ($env.PATH | split row (char esep) | prepend '/some/path') -# An alternate way to add entries to $env.PATH is to use the custom command `path add` -# which is built into the nushell stdlib: -# use std "path add" -# $env.PATH = ($env.PATH | split row (char esep)) -# path add /some/path -# path add ($env.CARGO_HOME | path join "bin") -# path add ($env.HOME | path join ".local" "bin") -# $env.PATH = ($env.PATH | uniq) - -# To load from a custom file you can use: -# source ($nu.default-config-dir | path join 'custom.nu') diff --git a/crates/nu-utils/src/utils.rs b/crates/nu-utils/src/utils.rs index 472afc92f7..798e542be5 100644 --- a/crates/nu-utils/src/utils.rs +++ b/crates/nu-utils/src/utils.rs @@ -85,12 +85,29 @@ where ret } +// See default_files/README.md for a description of these files pub fn get_default_env() -> &'static str { - include_str!("sample_config/default_env.nu") + include_str!("default_files/default_env.nu") +} + +pub fn get_scaffold_env() -> &'static str { + include_str!("default_files/scaffold_env.nu") +} + +pub fn get_sample_env() -> &'static str { + include_str!("default_files/sample_env.nu") } pub fn get_default_config() -> &'static str { - include_str!("sample_config/default_config.nu") + include_str!("default_files/default_config.nu") +} + +pub fn get_scaffold_config() -> &'static str { + include_str!("default_files/scaffold_config.nu") +} + +pub fn get_sample_config() -> &'static str { + include_str!("default_files/sample_config.nu") } pub fn get_ls_colors(lscolors_env_string: Option) -> LsColors { diff --git a/src/config_files.rs b/src/config_files.rs index 7631a951bc..5c43764580 100644 --- a/src/config_files.rs +++ b/src/config_files.rs @@ -2,12 +2,13 @@ use log::warn; #[cfg(feature = "plugin")] use nu_cli::read_plugin_file; use nu_cli::{eval_config_contents, eval_source}; +use nu_engine::convert_env_values; use nu_path::canonicalize_with; use nu_protocol::{ engine::{EngineState, Stack, StateWorkingSet}, report_parse_error, report_shell_error, Config, ParseError, PipelineData, Spanned, }; -use nu_utils::{get_default_config, get_default_env}; +use nu_utils::{get_default_config, get_default_env, get_scaffold_config, get_scaffold_env, perf}; use std::{ fs, fs::File, @@ -26,12 +27,47 @@ pub(crate) fn read_config_file( stack: &mut Stack, config_file: Option>, is_env_config: bool, - ask_to_create: bool, + create_scaffold: bool, ) { warn!( "read_config_file() config_file_specified: {:?}, is_env_config: {is_env_config}", &config_file ); + + if is_env_config { + eval_default_config(engine_state, stack, get_default_env(), is_env_config); + + let start_time = std::time::Instant::now(); + let config = engine_state.get_config(); + let use_color = config.use_ansi_coloring; + // Translate environment variables from Strings to Values + if let Err(e) = convert_env_values(engine_state, stack) { + report_shell_error(engine_state, &e); + } + + perf!( + "translate env vars after default_env.nu", + start_time, + use_color + ); + } else { + let start_time = std::time::Instant::now(); + let config = engine_state.get_config(); + let use_color = config.use_ansi_coloring; + if let Err(e) = convert_env_values(engine_state, stack) { + report_shell_error(engine_state, &e); + } + perf!( + "translate env vars before default_config.nu", + start_time, + use_color + ); + + eval_default_config(engine_state, stack, get_default_config(), is_env_config); + }; + + warn!("read_config_file() loading_defaults is_env_config: {is_env_config}"); + // Load config startup file if let Some(file) = config_file { match engine_state.cwd_as_string(Some(stack)) { @@ -59,41 +95,16 @@ pub(crate) fn read_config_file( config_path.push(if is_env_config { ENV_FILE } else { CONFIG_FILE }); if !config_path.exists() { - let file_msg = if is_env_config { - "environment config" + let scaffold_config_file = if is_env_config { + get_scaffold_env() } else { - "config" + get_scaffold_config() }; - let will_create_file = match ask_to_create { - true => { - println!( - "No {} file found at {}", - file_msg, - config_path.to_string_lossy() - ); - println!("Would you like to create one with defaults (Y/n): "); - - let mut answer = String::new(); - std::io::stdin() - .read_line(&mut answer) - .expect("Failed to read user input"); - - matches!(answer.trim(), "y" | "Y" | "") - } - _ => false, - }; - - let config_file = if is_env_config { - get_default_env() - } else { - get_default_config() - }; - - match will_create_file { + match create_scaffold { true => { if let Ok(mut output) = File::create(&config_path) { - if write!(output, "{config_file}").is_ok() { + if write!(output, "{scaffold_config_file}").is_ok() { let config_type = if is_env_config { "Environment config" } else { @@ -109,17 +120,14 @@ pub(crate) fn read_config_file( "Unable to write to {}, sourcing default file instead", config_path.to_string_lossy(), ); - eval_default_config(engine_state, stack, config_file, is_env_config); return; } } else { - eprintln!("Unable to create {config_file}, sourcing default file instead"); - eval_default_config(engine_state, stack, config_file, is_env_config); + eprintln!("Unable to create {scaffold_config_file}"); return; } } _ => { - eval_default_config(engine_state, stack, config_file, is_env_config); return; } } @@ -227,11 +235,7 @@ fn eval_default_config( config_file: &str, is_env_config: bool, ) { - warn!( - "eval_default_config() config_file_specified: {:?}, is_env_config: {}", - &config_file, is_env_config - ); - // Just use the contents of "default_config.nu" or "default_env.nu" + warn!("eval_default_config() is_env_config: {}", is_env_config); eval_source( engine_state, stack, @@ -264,20 +268,14 @@ pub(crate) fn setup_config( &config_file, &env_file, is_login_shell ); - let ask_to_create_config = nu_path::nu_config_dir().map_or(false, |p| !p.exists()); + let create_scaffold = nu_path::nu_config_dir().map_or(false, |p| !p.exists()); let result = catch_unwind(AssertUnwindSafe(|| { #[cfg(feature = "plugin")] read_plugin_file(engine_state, plugin_file); - read_config_file(engine_state, stack, env_file, true, ask_to_create_config); - read_config_file( - engine_state, - stack, - config_file, - false, - ask_to_create_config, - ); + read_config_file(engine_state, stack, env_file, true, create_scaffold); + read_config_file(engine_state, stack, config_file, false, create_scaffold); if is_login_shell { read_loginshell_file(engine_state, stack); diff --git a/src/run.rs b/src/run.rs index 1cbfbc03a2..89bad3866f 100644 --- a/src/run.rs +++ b/src/run.rs @@ -23,7 +23,7 @@ pub(crate) fn run_commands( trace!("run_commands"); let start_time = std::time::Instant::now(); - let ask_to_create_config = nu_path::nu_config_dir().map_or(false, |p| !p.exists()); + let create_scaffold = nu_path::nu_config_dir().map_or(false, |p| !p.exists()); let mut stack = Stack::new(); @@ -46,7 +46,7 @@ pub(crate) fn run_commands( &mut stack, parsed_nu_cli_args.env_file, true, - ask_to_create_config, + create_scaffold, ); } else { config_files::read_default_env_file(engine_state, &mut stack) @@ -55,7 +55,7 @@ pub(crate) fn run_commands( perf!("read env.nu", start_time, use_color); let start_time = std::time::Instant::now(); - let ask_to_create_config = nu_path::nu_config_dir().map_or(false, |p| !p.exists()); + let create_scaffold = nu_path::nu_config_dir().map_or(false, |p| !p.exists()); // If we have a config file parameter *OR* we have a login shell parameter, read the config file if parsed_nu_cli_args.config_file.is_some() || parsed_nu_cli_args.login_shell.is_some() { @@ -64,7 +64,7 @@ pub(crate) fn run_commands( &mut stack, parsed_nu_cli_args.config_file, false, - ask_to_create_config, + create_scaffold, ); } @@ -123,7 +123,7 @@ pub(crate) fn run_file( // if the --no-config-file(-n) flag is passed, do not load plugin, env, or config files if parsed_nu_cli_args.no_config_file.is_none() { let start_time = std::time::Instant::now(); - let ask_to_create_config = nu_path::nu_config_dir().map_or(false, |p| !p.exists()); + let create_scaffold = nu_path::nu_config_dir().map_or(false, |p| !p.exists()); #[cfg(feature = "plugin")] read_plugin_file(engine_state, parsed_nu_cli_args.plugin_file); perf!("read plugins", start_time, use_color); @@ -136,7 +136,7 @@ pub(crate) fn run_file( &mut stack, parsed_nu_cli_args.env_file, true, - ask_to_create_config, + create_scaffold, ); } else { config_files::read_default_env_file(engine_state, &mut stack) @@ -150,7 +150,7 @@ pub(crate) fn run_file( &mut stack, parsed_nu_cli_args.config_file, false, - ask_to_create_config, + create_scaffold, ); } perf!("read config.nu", start_time, use_color); diff --git a/tests/repl/test_config_path.rs b/tests/repl/test_config_path.rs index c812f3404c..63488ecb6a 100644 --- a/tests/repl/test_config_path.rs +++ b/tests/repl/test_config_path.rs @@ -221,8 +221,8 @@ fn test_default_config_path_symlinked_config_files() { #[test] fn test_alternate_config_path() { - let config_file = "crates/nu-utils/src/sample_config/default_config.nu"; - let env_file = "crates/nu-utils/src/sample_config/default_env.nu"; + let config_file = "crates/nu-utils/src/default_files/scaffold_config.nu"; + let env_file = "crates/nu-utils/src/default_files/scaffold_env.nu"; let cwd = std::env::current_dir().expect("Could not get current working directory");