diff --git a/src/config_files.rs b/src/config_files.rs index 3dd6a2a762..f362213abc 100644 --- a/src/config_files.rs +++ b/src/config_files.rs @@ -5,6 +5,8 @@ use nu_parser::ParseError; use nu_path::canonicalize_with; use nu_protocol::engine::{EngineState, Stack, StateDelta, StateWorkingSet}; use nu_protocol::{PipelineData, Span, Spanned}; +use std::fs::File; +use std::io::Write; use std::path::PathBuf; const NUSHELL_FOLDER: &str = "nushell"; @@ -71,6 +73,30 @@ pub(crate) fn read_config_file( } config_path.push(CONFIG_FILE); + + if !config_path.exists() { + println!("No config file found at {:?}", config_path); + println!("Would you like to create one (Y/n): "); + + let mut answer = String::new(); + std::io::stdin() + .read_line(&mut answer) + .expect("Failed to read user input"); + + match answer.to_lowercase().trim() { + "y" => { + let mut output = File::create(&config_path).expect("Unable to create file"); + let config_file = include_str!("default_config.nu"); + write!(output, "{}", config_file).expect("Unable to write to config file"); + println!("Config file created {:?}", config_path); + } + _ => { + println!("Continuing without config file"); + return; + } + } + } + eval_config_contents(config_path, engine_state, stack); } diff --git a/src/default_config.nu b/src/default_config.nu new file mode 100644 index 0000000000..157703c4e1 --- /dev/null +++ b/src/default_config.nu @@ -0,0 +1,93 @@ +# Nushell Config File + +def create_left_prompt [] { + let path_segment = ([ + ($nu.cwd) + (char space) + ] | str collect) + + $path_segment +} + +def create_right_prompt [] { + let time_segment = ([ + (date now | date format '%m/%d/%Y %I:%M:%S%.3f') + ] | 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 = "::: " + +let $config = { + filesize_metric: $true + table_mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other + use_ls_colors: $true + rm_always_trash: $false + color_config: { + separator: yd + leading_trailing_space_bg: white + header: cb + date: pu + filesize: ub + row_index: yb + hints: dark_gray + bool: red + int: green + duration: red + range: red + float: red + string: red + nothing: red + binary: red + cellpath: red + } + use_grid_icons: $true + footer_mode: always #always, never, number_of_rows, auto + quick_completions: $false + animate_prompt: $false + float_precision: 2 + use_ansi_coloring: $true + filesize_format: "b" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib, auto + env_conversions: { + "PATH": { + from_string: { |s| $s | split row (char esep) } + to_string: { |v| $v | str collect (char esep) } + } + } + edit_mode: emacs # emacs, vi + max_history_size: 10000 + menu_config: { + columns: 4 + col_width: 20 # Optional value. If missing all the screen width is used to calculate column width + col_padding: 2 + text_style: red + selected_text_style: green_reverse + marker: "| " + } + history_config: { + page_size: 10 + selector: ":" + text_style: green + selected_text_style: green_reverse + marker: "? " + } + keybindings: [ + { + name: completion + modifier: control + keycode: char_t + mode: vi_insert # emacs vi_normal vi_insert + event: { send: menu name: context_menu } + } + ] +} diff --git a/src/main.rs b/src/main.rs index 88b3810ee2..259589594c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -105,6 +105,7 @@ fn main() -> Result<()> { || arg == "--perf" || arg == "--threads" || arg == "--version" + || arg == "--log-level" { collect_arg_nushell = true; } @@ -139,8 +140,13 @@ fn main() -> Result<()> { if binary_args.perf { // if we started in perf mode show only the info logs // TODO: what happens when the config log_level is read? + let level = binary_args + .log_level + .map(|level| level.item) + .unwrap_or_else(|| "info".to_string()); + logger(|builder| { - configure("info", builder)?; + configure(level.as_str(), builder)?; Ok(()) })?; info!("start logging {}:{}:{}", file!(), line!(), column!()); @@ -256,6 +262,7 @@ fn parse_commandline_args( let testbin: Option = call.get_flag_expr("testbin"); let perf = call.has_flag("perf"); let config_file: Option = call.get_flag_expr("config"); + let log_level: Option = call.get_flag_expr("log-level"); let threads: Option = call.get_flag(engine_state, &mut stack, "threads")?; fn extract_contents( @@ -275,6 +282,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 log_level = extract_contents(log_level, engine_state); let help = call.has_flag("help"); @@ -309,6 +317,7 @@ fn parse_commandline_args( commands, testbin, config_file, + log_level, perf, threads, }); @@ -329,6 +338,7 @@ struct NushellCliArgs { commands: Option>, testbin: Option>, config_file: Option>, + log_level: Option>, perf: bool, threads: Option, } @@ -376,6 +386,12 @@ impl Command for Nu { "start with an alternate config file", None, ) + .named( + "log-level", + SyntaxShape::String, + "log level for performance logs", + None, + ) .named( "threads", SyntaxShape::Int,