Add env.nu file for environment config (#5099)

* Add env.nu file for environment config

* Add missing flag

* Add $nu.env-path variable

Prints `env.nu` path

* Add example of adding entries to PATH
This commit is contained in:
Jakub Žádník 2022-04-06 20:11:51 +03:00 committed by GitHub
parent c3bed1352a
commit 12d3e4e424
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 126 additions and 76 deletions

View File

@ -1142,6 +1142,7 @@ pub fn eval_variable(
if let Some(mut config_path) = nu_path::config_dir() {
config_path.push("nushell");
let mut env_config_path = config_path.clone();
let mut history_path = config_path.clone();
@ -1160,6 +1161,14 @@ pub fn eval_variable(
val: config_path.to_string_lossy().to_string(),
span,
});
env_config_path.push("env.nu");
output_cols.push("env-path".into());
output_vals.push(Value::String {
val: env_config_path.to_string_lossy().to_string(),
span,
});
}
#[cfg(feature = "plugin")]

View File

@ -1,59 +1,5 @@
# Nushell Config File
def create_left_prompt [] {
let path_segment = ($env.PWD)
$path_segment
}
def create_right_prompt [] {
let time_segment = ([
(date now | date format '%m/%d/%Y %r')
] | str collect)
$time_segment
}
# Use nushell functions to define your right and left prompt
let-env PROMPT_COMMAND = { create_left_prompt }
let-env PROMPT_COMMAND_RIGHT = { create_right_prompt }
# The prompt indicators are environmental variables that represent
# the state of the prompt
let-env PROMPT_INDICATOR = { "〉" }
let-env PROMPT_INDICATOR_VI_INSERT = { ": " }
let-env PROMPT_INDICATOR_VI_NORMAL = { "〉" }
let-env PROMPT_MULTILINE_INDICATOR = { "::: " }
# 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
let-env ENV_CONVERSIONS = {
"PATH": {
from_string: { |s| $s | split row (char esep) }
to_string: { |v| $v | str collect (char esep) }
}
"Path": {
from_string: { |s| $s | split row (char esep) }
to_string: { |v| $v | str collect (char esep) }
}
}
# Directories to search for scripts when calling source or use
#
# By default, <nushell-config-dir>/scripts is added
let-env NU_LIB_DIRS = [
($nu.config-path | path dirname | path join 'scripts')
]
# Directories to search for plugin binaries when calling register
#
# By default, <nushell-config-dir>/plugins is added
let-env NU_PLUGIN_DIRS = [
($nu.config-path | path dirname | path join 'plugins')
]
module completions {
# Custom completions for external commands (those outside of Nushell)
# Each completions has two parts: the form of the external command, including its flags and parameters
@ -259,7 +205,7 @@ let $config = {
type: {
layout: columnar
columns: 4
col_width: 20
col_width: 20
col_padding: 2
}
style: {
@ -267,9 +213,9 @@ let $config = {
selected_text: green_reverse
description_text: yellow
}
source: { |buffer, position|
$nu.scope.commands
| where command =~ $buffer
source: { |buffer, position|
$nu.scope.commands
| where command =~ $buffer
| each { |it| {value: $it.command description: $it.usage} }
}
}
@ -286,10 +232,10 @@ let $config = {
selected_text: green_reverse
description_text: yellow
}
source: { |buffer, position|
$nu.scope.vars
| where name =~ $buffer
| sort-by name
source: { |buffer, position|
$nu.scope.vars
| where name =~ $buffer
| sort-by name
| each { |it| {value: $it.name description: $it.type} }
}
}
@ -300,7 +246,7 @@ let $config = {
type: {
layout: description
columns: 4
col_width: 20
col_width: 20
col_padding: 2
selection_rows: 4
description_rows: 10
@ -310,9 +256,9 @@ let $config = {
selected_text: green_reverse
description_text: yellow
}
source: { |buffer, position|
$nu.scope.commands
| where command =~ $buffer
source: { |buffer, position|
$nu.scope.commands
| where command =~ $buffer
| each { |it| {value: $it.command description: $it.usage} }
}
}
@ -366,21 +312,21 @@ let $config = {
name: commands_menu
modifier: control
keycode: char_t
mode: [emacs, vi_normal, vi_insert]
mode: [emacs, vi_normal, vi_insert]
event: { send: menu name: commands_menu }
}
{
name: commands_menu
modifier: control
keycode: char_y
mode: [emacs, vi_normal, vi_insert]
mode: [emacs, vi_normal, vi_insert]
event: { send: menu name: vars_menu }
}
{
name: commands_with_description
modifier: control
keycode: char_u
mode: [emacs, vi_normal, vi_insert]
mode: [emacs, vi_normal, vi_insert]
event: { send: menu name: commands_with_description }
}
]

View File

@ -0,0 +1,58 @@
# Nushell Environment Config File
def create_left_prompt [] {
let path_segment = ($env.PWD)
$path_segment
}
def create_right_prompt [] {
let time_segment = ([
(date now | date format '%m/%d/%Y %r')
] | str collect)
$time_segment
}
# Use nushell functions to define your right and left prompt
let-env PROMPT_COMMAND = { create_left_prompt }
let-env PROMPT_COMMAND_RIGHT = { create_right_prompt }
# The prompt indicators are environmental variables that represent
# the state of the prompt
let-env PROMPT_INDICATOR = { "〉" }
let-env PROMPT_INDICATOR_VI_INSERT = { ": " }
let-env PROMPT_INDICATOR_VI_NORMAL = { "〉" }
let-env PROMPT_MULTILINE_INDICATOR = { "::: " }
# 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
let-env ENV_CONVERSIONS = {
"PATH": {
from_string: { |s| $s | split row (char esep) }
to_string: { |v| $v | str collect (char esep) }
}
"Path": {
from_string: { |s| $s | split row (char esep) }
to_string: { |v| $v | str collect (char esep) }
}
}
# Directories to search for scripts when calling source or use
#
# By default, <nushell-config-dir>/scripts is added
let-env NU_LIB_DIRS = [
($nu.config-path | path dirname | path join 'scripts')
]
# Directories to search for plugin binaries when calling register
#
# By default, <nushell-config-dir>/plugins is added
let-env NU_PLUGIN_DIRS = [
($nu.config-path | path dirname | path join 'plugins')
]
# To add entries to PATH (on Windows you might use Path), you can use the following pattern:
# let-env PATH = ($env.PATH | prepend '/some/path')

View File

@ -10,6 +10,7 @@ use std::path::PathBuf;
pub(crate) const NUSHELL_FOLDER: &str = "nushell";
const CONFIG_FILE: &str = "config.nu";
const ENV_FILE: &str = "env.nu";
const HISTORY_FILE: &str = "history.txt";
pub(crate) fn read_config_file(
@ -17,6 +18,7 @@ pub(crate) fn read_config_file(
stack: &mut Stack,
config_file: Option<Spanned<String>>,
is_perf_true: bool,
is_env_config: bool,
) {
// Load config startup file
if let Some(file) = config_file {
@ -43,10 +45,19 @@ pub(crate) fn read_config_file(
}
}
config_path.push(CONFIG_FILE);
config_path.push(if is_env_config { ENV_FILE } else { CONFIG_FILE });
if !config_path.exists() {
println!("No config file found at {}", config_path.to_string_lossy());
let file_msg = if is_env_config {
"environment config"
} else {
"config"
};
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();
@ -54,7 +65,11 @@ pub(crate) fn read_config_file(
.read_line(&mut answer)
.expect("Failed to read user input");
let config_file = include_str!("../docs/sample_config/default_config.nu");
let config_file = if is_env_config {
include_str!("../docs/sample_config/default_env.nu")
} else {
include_str!("../docs/sample_config/default_config.nu")
};
match answer.to_lowercase().trim() {
"y" | "" => {
@ -64,12 +79,16 @@ pub(crate) fn read_config_file(
}
_ => {
println!("Continuing without config file");
// Just use the contents of "default_config.nu"
// Just use the contents of "default_config.nu" or "default_env.nu"
eval_source(
engine_state,
stack,
config_file.as_bytes(),
"default_config.nu",
if is_env_config {
"default_env.nu"
} else {
"default_config.nu"
},
PipelineData::new(Span::new(0, 0)),
);
return;

View File

@ -101,6 +101,7 @@ fn main() -> Result<()> {
|| arg == "--testbin"
|| arg == "--log-level"
|| arg == "--config"
|| arg == "--env-config"
|| arg == "--threads"
|| arg == "-t"
{
@ -249,7 +250,12 @@ fn main() -> Result<()> {
ret_val
} else {
setup_config(&mut engine_state, &mut stack, binary_args.config_file);
setup_config(
&mut engine_state,
&mut stack,
binary_args.config_file,
binary_args.env_file,
);
let history_path = config_files::create_history_path();
let ret_val =
@ -269,6 +275,7 @@ fn setup_config(
engine_state: &mut EngineState,
stack: &mut Stack,
config_file: Option<Spanned<String>>,
env_file: Option<Spanned<String>>,
) {
#[cfg(feature = "plugin")]
read_plugin_file(engine_state, stack, NUSHELL_FOLDER, is_perf_true());
@ -277,7 +284,8 @@ fn setup_config(
info!("read_config_file {}:{}:{}", file!(), line!(), column!());
}
config_files::read_config_file(engine_state, stack, config_file, is_perf_true());
config_files::read_config_file(engine_state, stack, env_file, is_perf_true(), true);
config_files::read_config_file(engine_state, stack, config_file, is_perf_true(), false);
}
fn parse_commandline_args(
@ -332,6 +340,7 @@ fn parse_commandline_args(
let testbin: Option<Expression> = call.get_flag_expr("testbin");
let perf = call.has_flag("perf");
let config_file: Option<Expression> = call.get_flag_expr("config");
let env_file: Option<Expression> = call.get_flag_expr("env-config");
let log_level: Option<Expression> = call.get_flag_expr("log-level");
let threads: Option<Value> = call.get_flag(engine_state, &mut stack, "threads")?;
@ -352,6 +361,7 @@ fn parse_commandline_args(
let commands = extract_contents(commands, engine_state);
let testbin = extract_contents(testbin, engine_state);
let config_file = extract_contents(config_file, engine_state);
let env_file = extract_contents(env_file, engine_state);
let log_level = extract_contents(log_level, engine_state);
let help = call.has_flag("help");
@ -387,6 +397,7 @@ fn parse_commandline_args(
commands,
testbin,
config_file,
env_file,
log_level,
perf,
threads,
@ -408,6 +419,7 @@ struct NushellCliArgs {
commands: Option<Spanned<String>>,
testbin: Option<Spanned<String>>,
config_file: Option<Spanned<String>>,
env_file: Option<Spanned<String>>,
log_level: Option<Spanned<String>>,
perf: bool,
threads: Option<Value>,
@ -451,6 +463,12 @@ impl Command for Nu {
"start with an alternate config file",
None,
)
.named(
"env-config",
SyntaxShape::String,
"start with an alternate environment config file",
None,
)
.named(
"log-level",
SyntaxShape::String,