From 4ed25b63a6fc3444bb870dd6fa2c5a9abb936b00 Mon Sep 17 00:00:00 2001
From: Douglas <32344964+NotTheDr01ds@users.noreply.github.com>
Date: Wed, 20 Nov 2024 17:15:15 -0500
Subject: [PATCH] Always load default env/config values (#14249)
# Release-Notes Short Description
* Nushell now always loads its internal `default_env.nu` before the user
`env.nu` is loaded, then loads the internal `default_config.nu` before
the user's `config.nu` is loaded. This allows for a simpler
user-configuration experience. The Configuration Chapter of the Book
will be updated soon with the new behavior.
# Description
Implements the main ideas in #13671 and a few more:
* Users can now specify only the environment and config options they
want to override in *their* `env.nu` and `config.nu`and yet still have
access to all of the defaults:
* `default_env.nu` (internally defined) will be loaded whenever (and
before) the user's `env.nu` is loaded.
* `default_config.nu` (internally defined) will be loaded whenever (and
before) the user's `config.nu` is loaded.
* No more 900+ line config out-of-the-box.
* Faster startup (again): ~40-45% improvement in launch time with a
default configuration.
* New keys that are added to the defaults in the future will
automatically be available to all users after updating Nushell. No need
to regenerate config to get the new defaults.
* It is now possible to have different internal defaults (which will be
used with `-c` and scripts) vs. REPL defaults. This would have solved
many of the user complaints about the [`display_errors`
implementation](https://www.nushell.sh/blog/2024-09-17-nushell_0_98_0.html#non-zero-exit-codes-are-now-errors-toc).
* A basic "scaffold" `config.nu` and `env.nu` are created on first
launch (if the config directory isn't present).
* Improved "out-of-the-box" experience (OOBE) - No longer asks to create
the files; the minimal scaffolding will be automatically created. If
deleted, they will not be regenerated. This provides a better
"out-of-the-box" experience for the user as they no longer have to make
this decision (without much info on the pros or cons) when first
launching.
* (New: 2024-11-07) Runs the env_conversions process after the
`default_env.nu` is loaded so that users can treat `Path`/`PATH` as
lists in their own config.
* (New: 2024-11-08) Given the changes in #13802, `default_config.nu`
will be a minimal file to minimize load-times. This shaves another (on
my system) ~3ms off the base launch time.
* Related: Keybindings, menus, and hooks that are already internal
defaults are no longer duplicated in `$env.config`. The documentation
will be updated to cover these scenarios.
* (New: 2024-11-08) Move existing "full" `default_config.nu` to
`sample_config.nu` for short-term "documentation" purposes.
* (New: 2024-11-18) Move the `dark-theme` and `light-theme` to Standard
Library and demonstrate their use - Also improves startup times, but
we're reaching the limit of optimization.
* (New: 2024-11-18) Extensively documented/commented `sample_env.nu` and
`sample_config.nu`. These can be displayed in-shell using (for example)
`config nu --sample | nu-highlight | less -R`. Note: Much of this will
eventually be moved to or (some) duplicated in the Doc. But for now,
this some nice in-shell doc that replaces the older
"commented/documented default".
* (New: 2024-11-20) Runs the `ENV_CONVERSIONS` process (1) after the
`default_env.nu` (allows `PATH` to be used as a list in user's `env.nu`)
and (2) before `default_config.nu` is loaded (allows user's
`ENV_CONVERSIONS` from their `env.nu` to be used in their `config.nu`).
* (New: 2024-11-20) The default `ENV_CONVERSIONS` is now an empty
record. The internal Rust code handles `PATH` (and variants) conversions
regardless of the `ENV_CONVERSIONS` variable. This shaves a *very* small
amount of time off the startup. Reset - Looks like there might be a
bug in `nu-enginer::env::ensure_path()` on Windows that would need to be
fixed in order for this to work.
# User-Facing Changes
By default, you shouldn't see much, if any, change when running this
with your existing configuration.
To see the greatest benefit from these changes, you'll probably want to
start with a "fresh" config. This can be easily tested using something
like:
```nushell
let temp_home = (mktemp -d)
$env.XDG_CONFIG_HOME = $temp_home
$env.XDG_DATA_HOME = $temp_home
./target/release/nu
```
You should see a message where the (mostly empty) `env.nu` and
`config.nu` are created on first start. Defaults should be the same (or
similar to) those before the PR. Please let me know if you notice any
differences.
---
Users should now specify configuration in terms of overrides of each
setting. For instance, rather than modifying `history` settings in the
monolithic `config.nu`, the following is recommended in an updated
`config.nu`:
```nu
$env.config.history = {
file_format: sqlite,
sync_on_enter: true
isolation: true
max_size: 1_000_000
}
```
or even just:
```nu
$env.config.history.file_format = sqlite
$env.config.history.isolation: true
$env.config.history.max_size = 1_000_000
```
Note: It seems many users are already appending a `source my_config.nu`
(or similar pattern) to the end of the existing `config.nu` to make
updates easier. In this case, they will likely want to remove all of the
previous defaults and just move their `my_config.nu` to `config.nu`.
Note: It should be unlikely that there are any breaking changes here,
but there's a slim chance that some code, somewhere, *expects* an
absence of certain config values. Otherwise, all config values are
available before and after this change.
# Tests + Formatting
- :green_circle: `toolkit fmt`
- :green_circle: `toolkit clippy`
- :green_circle: `toolkit test`
- :green_circle: `toolkit test stdlib`
# After Submitting
Configuration Chapter (and related) of the doc is currently WIP and will
be finished in time for 0.101 release.
---
.../nu-command/src/env/config/config_env.rs | 37 +-
crates/nu-command/src/env/config/config_nu.rs | 37 +-
crates/nu-protocol/tests/into_config.rs | 14 +-
crates/nu-std/src/lib.rs | 1 +
crates/nu-std/std/config/mod.nu | 139 +++
crates/nu-std/std/mod.nu | 1 +
crates/nu-utils/src/default_files/README.md | 82 ++
.../src/default_files/default_config.nu | 63 ++
.../nu-utils/src/default_files/default_env.nu | 57 ++
.../src/default_files/sample_config.nu | 792 +++++++++++++++
.../nu-utils/src/default_files/sample_env.nu | 135 +++
.../sample_login.nu | 0
.../src/default_files/scaffold_config.nu | 19 +
.../src/default_files/scaffold_env.nu | 18 +
crates/nu-utils/src/lib.rs | 5 +-
.../src/sample_config/default_config.nu | 899 ------------------
.../nu-utils/src/sample_config/default_env.nu | 101 --
crates/nu-utils/src/utils.rs | 21 +-
src/config_files.rs | 98 +-
src/run.rs | 14 +-
tests/repl/test_config_path.rs | 4 +-
21 files changed, 1454 insertions(+), 1083 deletions(-)
create mode 100644 crates/nu-std/std/config/mod.nu
create mode 100644 crates/nu-utils/src/default_files/README.md
create mode 100644 crates/nu-utils/src/default_files/default_config.nu
create mode 100644 crates/nu-utils/src/default_files/default_env.nu
create mode 100644 crates/nu-utils/src/default_files/sample_config.nu
create mode 100644 crates/nu-utils/src/default_files/sample_env.nu
rename crates/nu-utils/src/{sample_config => default_files}/sample_login.nu (100%)
create mode 100644 crates/nu-utils/src/default_files/scaffold_config.nu
create mode 100644 crates/nu-utils/src/default_files/scaffold_env.nu
delete mode 100644 crates/nu-utils/src/sample_config/default_config.nu
delete mode 100644 crates/nu-utils/src/sample_config/default_env.nu
diff --git a/crates/nu-command/src/env/config/config_env.rs b/crates/nu-command/src/env/config/config_env.rs
index cb4a217d9b222..5331d2d3bedee 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 9969968ed201e..176643a76f22f 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 63d7eb8b22578..3ff8d44672c86 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 ebc6ee00536d5..b03b710cfc5fd 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 0000000000000..b73964e8d3ad2
--- /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 4d1e74e72d55a..89454ee1f30ec 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 0000000000000..2269771bbddcf
--- /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 0000000000000..d95f4b3f97a74
--- /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 0000000000000..498c9670b314b
--- /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 0000000000000..5a8181506cf25
--- /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 0000000000000..84926abb2f09d
--- /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 0000000000000..7bf7ecc632275
--- /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 0000000000000..a3ce3cab07b89
--- /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 4b91d923db9f1..413b5f8893663 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 c8b398b684e00..0000000000000
--- 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 fb527dc1125c9..0000000000000
--- 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 472afc92f75bb..798e542be5775 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 7631a951bc284..5c43764580d85 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 1cbfbc03a2206..89bad3866faff 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 c812f3404cfe6..63488ecb6a101 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");