Skip to content

Commit

Permalink
Merge branch 'nushell:main' into 9004-rm-filename-missing
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeljohnalbers committed May 11, 2023
2 parents 6fae9c3 + 39e51f1 commit 79b6fd4
Show file tree
Hide file tree
Showing 56 changed files with 2,687 additions and 906 deletions.
223 changes: 105 additions & 118 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion crates/nu-cli/src/commands/commandline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl Command for Commandline {
.expect("repl cursor pos mutex");
let char_pos = buffer
.grapheme_indices(true)
.chain(std::iter::once((*cursor_pos, "")))
.chain(std::iter::once((buffer.len(), "")))
.position(|(i, _c)| i == *cursor_pos)
.expect("Cursor position isn't on a grapheme boundary");
Ok(Value::String {
Expand Down
6 changes: 4 additions & 2 deletions crates/nu-cli/src/prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,13 @@ impl Prompt for NushellPrompt {
prompt_string.replace('\n', "\r\n").into()
} else {
let default = DefaultPrompt::default();
default
let prompt = default
.render_prompt_left()
.to_string()
.replace('\n', "\r\n")
.into()
+ " ";

prompt.into()
}
}

Expand Down
143 changes: 19 additions & 124 deletions crates/nu-cli/src/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ use miette::{IntoDiagnostic, Result};
use nu_color_config::StyleComputer;
use nu_command::hook::eval_hook;
use nu_command::util::get_guaranteed_cwd;
use nu_engine::{convert_env_values, eval_block};
use nu_parser::{lex, parse, trim_quotes_str};
use nu_engine::convert_env_values;
use nu_parser::{lex, trim_quotes_str};
use nu_protocol::{
config::NuCursorShape,
engine::{EngineState, Stack, StateWorkingSet},
format_duration, report_error, report_error_new, HistoryFileFormat, PipelineData, ShellError,
Span, Spanned, Value,
report_error, report_error_new, HistoryFileFormat, PipelineData, ShellError, Span, Spanned,
Value,
};
use nu_utils::utils::perf;
use reedline::{CursorConfig, DefaultHinter, EditCommand, Emacs, SqliteBackedHistory, Vi};
Expand All @@ -43,6 +43,7 @@ pub fn evaluate_repl(
stack: &mut Stack,
nushell_path: &str,
prerun_command: Option<Spanned<String>>,
load_std_lib: Option<Spanned<String>>,
entire_start_time: Instant,
) -> Result<()> {
use nu_command::hook;
Expand Down Expand Up @@ -153,19 +154,8 @@ pub fn evaluate_repl(

start_time = std::time::Instant::now();
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 {
println!("{}", nu_utils::strip_ansi_string_likely(banner));
}
}
perf(
"get sysinfo/show banner",
"get sysinfo",
start_time,
file!(),
line!(),
Expand All @@ -185,6 +175,19 @@ pub fn evaluate_repl(
engine_state.merge_env(stack, get_guaranteed_cwd(engine_state, stack))?;
}

engine_state.set_startup_time(entire_start_time.elapsed().as_nanos() as i64);

if load_std_lib.is_none() && engine_state.get_config().show_banner {
eval_source(
engine_state,
stack,
r#"use std banner; banner"#.as_bytes(),
"show_banner",
PipelineData::empty(),
false,
);
}

loop {
let loop_start_time = std::time::Instant::now();

Expand Down Expand Up @@ -445,16 +448,6 @@ pub fn evaluate_repl(

entry_num += 1;

if entry_num == 1 {
engine_state.set_startup_time(entire_start_time.elapsed().as_nanos() as i64);
if show_banner {
println!(
"Startup Time: {}",
format_duration(engine_state.get_startup_time())
);
}
}

start_time = std::time::Instant::now();
let input = line_editor.read_line(prompt);
let shell_integration = config.shell_integration;
Expand Down Expand Up @@ -740,104 +733,6 @@ fn map_nucursorshape_to_cursorshape(shape: NuCursorShape) -> SetCursorStyle {
}
}

fn get_banner(engine_state: &mut EngineState, stack: &mut Stack) -> String {
let age = match eval_string_with_input(
engine_state,
stack,
None,
"(date now) - ('2019-05-10 09:59:12-0700' | 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 {}https://nushell.sh{}
{}Tweet{} us at {}@nu_shell{}
Learn how to remove this at: {}https://nushell.sh/book/configuration.html#remove-welcome-message{}
It's been this long since {}Nushell{}'s first commit:
{}{}
"#,
"\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 Welcome Message
"\x1b[0m", //after Welcome Message
"\x1b[32m", //before Nushell
"\x1b[0m", //after Nushell
age,
"\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, None, source.as_bytes(), false);

(output, working_set.render())
};

engine_state.merge_delta(delta)?;

let input_as_pipeline_data = match input {
Some(input) => PipelineData::Value(input, None),
None => PipelineData::empty(),
};

eval_block(
engine_state,
stack,
&block,
input_as_pipeline_data,
false,
true,
)
.map(|x| x.into_value(Span::unknown()))
}

pub fn get_command_finished_marker(stack: &Stack, engine_state: &EngineState) -> String {
let exit_code = stack
.get_env_var(engine_state, "LAST_EXIT_CODE")
Expand Down
75 changes: 75 additions & 0 deletions crates/nu-cmd-lang/src/core_commands/export_module.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Type, Value,
};

#[derive(Clone)]
pub struct ExportModule;

impl Command for ExportModule {
fn name(&self) -> &str {
"export module"
}

fn usage(&self) -> &str {
"Export a custom module from a module."
}

fn signature(&self) -> nu_protocol::Signature {
Signature::build("export module")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.allow_variants_without_examples(true)
.required("module", SyntaxShape::String, "module name or module path")
.optional(
"block",
SyntaxShape::Block,
"body of the module if 'module' parameter is not a path",
)
.category(Category::Core)
}

fn extra_usage(&self) -> &str {
r#"This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html"#
}

fn is_parser_keyword(&self) -> bool {
true
}

fn run(
&self,
_engine_state: &EngineState,
_stack: &mut Stack,
_call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
Ok(PipelineData::empty())
}

fn examples(&self) -> Vec<Example> {
vec![Example {
description: "Define a custom command in a submodule of a module and call it",
example: r#"module spam {
export module eggs {
export def foo [] { "foo" }
}
}
use spam eggs
eggs foo"#,
result: Some(Value::test_string("foo")),
}]
}
}

#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_examples() {
use crate::test_examples;

test_examples(ExportModule {})
}
}
2 changes: 2 additions & 0 deletions crates/nu-cmd-lang/src/core_commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod export_alias;
mod export_def;
mod export_def_env;
mod export_extern;
mod export_module;
mod export_use;
mod extern_;
mod for_;
Expand Down Expand Up @@ -55,6 +56,7 @@ pub use export_alias::ExportAlias;
pub use export_def::ExportDef;
pub use export_def_env::ExportDefEnv;
pub use export_extern::ExportExtern;
pub use export_module::ExportModule;
pub use export_use::ExportUse;
pub use extern_::Extern;
pub use for_::For;
Expand Down
9 changes: 7 additions & 2 deletions crates/nu-cmd-lang/src/core_commands/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@ impl Command for Module {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("module")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("module_name", SyntaxShape::String, "module name")
.required("block", SyntaxShape::Block, "body of the module")
.allow_variants_without_examples(true)
.required("module", SyntaxShape::String, "module name or module path")
.optional(
"block",
SyntaxShape::Block,
"body of the module if 'module' parameter is not a module path",
)
.category(Category::Core)
}

Expand Down
2 changes: 1 addition & 1 deletion crates/nu-cmd-lang/src/core_commands/use_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl Command for Use {
Signature::build("use")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("module", SyntaxShape::String, "Module or module file")
.optional(
.rest(
"members",
SyntaxShape::Any,
"Which members of the module to import",
Expand Down
1 change: 1 addition & 0 deletions crates/nu-cmd-lang/src/default_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub fn create_default_context() -> EngineState {
ExportDefEnv,
ExportExtern,
ExportUse,
ExportModule,
Extern,
For,
Help,
Expand Down
19 changes: 15 additions & 4 deletions crates/nu-cmd-lang/src/example_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ mod test_examples {
check_example_evaluates_to_expected_output,
check_example_input_and_output_types_match_command_signature,
};
use crate::{Break, Collect, Describe, Mut};
use crate::{Echo, If, Let};
use crate::{
Break, Collect, Def, Describe, Echo, ExportCommand, ExportDef, If, Let, Module, Mut, Use,
};
use nu_protocol::{
engine::{Command, EngineState, StateWorkingSet},
Type,
Type, Value,
};
use std::collections::HashSet;

Expand Down Expand Up @@ -55,18 +56,28 @@ mod test_examples {

fn make_engine_state(cmd: Box<dyn Command>) -> Box<EngineState> {
let mut engine_state = Box::new(EngineState::new());
let cwd = std::env::current_dir()
.expect("Could not get current working directory.")
.to_string_lossy()
.to_string();
engine_state.add_env_var("PWD".to_string(), Value::test_string(cwd));

let delta = {
// Base functions that are needed for testing
// Try to keep this working set small to keep tests running as fast as possible
let mut working_set = StateWorkingSet::new(&engine_state);
working_set.add_decl(Box::new(Break));
working_set.add_decl(Box::new(Collect));
working_set.add_decl(Box::new(Def));
working_set.add_decl(Box::new(Describe));
working_set.add_decl(Box::new(Echo));
working_set.add_decl(Box::new(ExportCommand));
working_set.add_decl(Box::new(ExportDef));
working_set.add_decl(Box::new(If));
working_set.add_decl(Box::new(Let));
working_set.add_decl(Box::new(Module));
working_set.add_decl(Box::new(Mut));
working_set.add_decl(Box::new(Collect));
working_set.add_decl(Box::new(Use));

// Adding the command that is being tested to the working set
working_set.add_decl(cmd);
Expand Down
2 changes: 1 addition & 1 deletion crates/nu-command/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ features = [
"to_dummies",
]
optional = true
version = "0.27.2"
version = "0.28.0"

[target.'cfg(windows)'.dependencies.windows]
features = ["Win32_Foundation", "Win32_Storage_FileSystem", "Win32_System_SystemServices"]
Expand Down
Loading

0 comments on commit 79b6fd4

Please sign in to comment.