add a new welcome banner to nushell (#6163)

* add a new welcome banner to nushell

* remove top line

* tweaked colors and wording

* changed to dimmed white

* removed a comment

* make config nu stand out a little

* fix type-o
This commit is contained in:
Darren Schroeder 2022-07-29 12:50:12 -05:00 committed by GitHub
parent 767201c40d
commit 7a820b1304
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 149 additions and 2 deletions

1
Cargo.lock generated
View File

@ -2537,6 +2537,7 @@ dependencies = [
"reedline",
"regex",
"rstest",
"strip-ansi-escapes",
"sysinfo",
"thiserror",
]

View File

@ -30,6 +30,7 @@ is_executable = "1.0.1"
lazy_static = "1.4.0"
log = "0.4"
regex = "1.5.4"
strip-ansi-escapes = "0.1.1"
sysinfo = "0.24.1"
[features]

View File

@ -14,12 +14,14 @@ use nu_parser::{lex, parse};
use nu_protocol::{
ast::PathMember,
engine::{EngineState, Stack, StateWorkingSet},
BlockId, HistoryFileFormat, PipelineData, PositionalArg, ShellError, Span, Type, Value, VarId,
format_duration, BlockId, HistoryFileFormat, PipelineData, PositionalArg, ShellError, Span,
Type, Value, VarId,
};
use reedline::{DefaultHinter, Emacs, SqliteBackedHistory, Vi};
use regex::Regex;
use std::io::{self, Write};
use std::{sync::atomic::Ordering, time::Instant};
use strip_ansi_escapes::strip;
use sysinfo::SystemExt;
// According to Daniel Imms @Tyriar, we need to do these this way:
@ -119,6 +121,25 @@ pub fn evaluate_repl(
let sys = sysinfo::System::new();
let show_banner = config.show_banner;
let use_ansi = config.use_ansi_coloring;
if show_banner {
let banner = get_banner(engine_state, stack);
if use_ansi {
println!("{}", banner);
} else {
let stripped_string = {
if let Ok(bytes) = strip(&banner) {
String::from_utf8_lossy(&bytes).to_string()
} else {
banner
}
};
println!("{}", stripped_string);
}
}
loop {
if is_perf_true {
info!(
@ -460,6 +481,121 @@ pub fn evaluate_repl(
Ok(())
}
fn get_banner(engine_state: &mut EngineState, stack: &mut Stack) -> String {
let age = match eval_string_with_input(
engine_state,
stack,
None,
"(date now) - ('05/10/2019' | into datetime)",
) {
Ok(Value::Duration { val, .. }) => format_duration(val),
_ => "".to_string(),
};
let banner = format!(
r#"{} __ ,
{} .--()°'.' {}Welcome to {}Nushell{},
{}'|, . ,' {}based on the {}nu{} language,
{} !_-(_\ {}where all data is structured!
Please join our {}Discord{} community at {}https://discord.gg/NtAbbGn{}
Our {}GitHub{} repository is at {}https://github.com/nushell/nushell{}
Our {}Documentation{} is located at {}http://nushell.sh{}
{}Tweet{} us at {}@nu_shell{}
{}Nushell{} has been around for:
{}
{}You can disable this banner using the {}config nu{}{} command
to modify the config.nu file and setting show_banner to false.
let-env config {{
show_banner: false
...
}}{}
"#,
"\x1b[32m", //start line 1 green
"\x1b[32m", //start line 2
"\x1b[0m", //before welcome
"\x1b[32m", //before nushell
"\x1b[0m", //after nushell
"\x1b[32m", //start line 3
"\x1b[0m", //before based
"\x1b[32m", //before nu
"\x1b[0m", //after nu
"\x1b[32m", //start line 4
"\x1b[0m", //before where
"\x1b[35m", //before Discord purple
"\x1b[0m", //after Discord
"\x1b[35m", //before Discord URL
"\x1b[0m", //after Discord URL
"\x1b[1;32m", //before GitHub green_bold
"\x1b[0m", //after GitHub
"\x1b[1;32m", //before GitHub URL
"\x1b[0m", //after GitHub URL
"\x1b[32m", //before Documentation
"\x1b[0m", //after Documentation
"\x1b[32m", //before Documentation URL
"\x1b[0m", //after Documentation URL
"\x1b[36m", //before Tweet blue
"\x1b[0m", //after Tweet
"\x1b[1;36m", //before @nu_shell cyan_bold
"\x1b[0m", //after @nu_shell
"\x1b[32m", //before Nushell
"\x1b[0m", //after Nushell
age,
"\x1b[2;37m", //before banner disable dim white
"\x1b[2;36m", //before config nu dim cyan
"\x1b[0m", //after config nu
"\x1b[2;37m", //after config nu dim white
"\x1b[0m", //after banner disable
);
banner
}
// Taken from Nana's simple_eval
/// Evaluate a block of Nu code, optionally with input.
/// For example, source="$in * 2" will multiply the value in input by 2.
pub fn eval_string_with_input(
engine_state: &mut EngineState,
stack: &mut Stack,
input: Option<Value>,
source: &str,
) -> Result<Value, ShellError> {
let (block, delta) = {
let mut working_set = StateWorkingSet::new(engine_state);
let (output, _) = parse(
&mut working_set,
Some("nana"),
source.as_bytes(),
false,
&[],
);
(output, working_set.render())
};
if let Err(err) = engine_state.merge_delta(delta) {
return Err(err);
}
let input_as_pipeline_data = match input {
Some(input) => PipelineData::Value(input, None),
None => PipelineData::new(Span::test_data()),
};
eval_block(
engine_state,
stack,
&block,
input_as_pipeline_data,
false,
true,
)
.map(|x| x.into_value(Span::test_data()))
}
pub fn get_command_finished_marker(stack: &Stack, engine_state: &EngineState) -> String {
let exit_code = stack
.get_env_var(engine_state, "LAST_EXIT_CODE")

View File

@ -81,6 +81,7 @@ pub struct Config {
pub case_sensitive_completions: bool,
pub enable_external_completion: bool,
pub trim_strategy: TrimStrategy,
pub show_banner: bool,
}
impl Default for Config {
@ -115,6 +116,7 @@ impl Default for Config {
case_sensitive_completions: false,
enable_external_completion: true,
trim_strategy: TRIM_STRATEGY_DEFAULT,
show_banner: true,
}
}
}
@ -388,6 +390,13 @@ impl Value {
}
}
"table_trim" => config.trim_strategy = try_parse_trim_strategy(value, &config)?,
"show_banner" => {
if let Ok(b) = value.as_bool() {
config.show_banner = b;
} else {
eprintln!("$config.show_banner is not a bool")
}
}
x => {
eprintln!("$config.{} is an unknown config setting", x)
}

View File

@ -257,7 +257,6 @@ let-env config = {
case_sensitive_completions: false # set to true to enable case-sensitive completions
enable_external_completion: true # set to false to prevent nushell looking into $env.PATH to find more suggestions, `false` recommended for WSL users as this look up my be very slow
max_external_completion_results: 100 # setting it lower can improve completion performance at the cost of omitting some options
# A strategy of managing table view in case of limited space.
table_trim: {
methodology: wrapping, # truncating
@ -266,6 +265,7 @@ let-env config = {
# A suffix which will be used with 'truncating' methodology
# truncating_suffix: "..."
}
show_banner: true # true or false to enable or disable the banner
hooks: {
pre_prompt: [{