2023-01-20 22:20:38 +01:00
|
|
|
use nu_engine::{get_full_help, CallExt};
|
|
|
|
use nu_parser::parse;
|
2023-01-27 00:56:55 +01:00
|
|
|
use nu_parser::{escape_for_script_arg, escape_quote_string};
|
2023-04-08 13:53:43 +02:00
|
|
|
use nu_protocol::report_error;
|
2023-01-20 22:20:38 +01:00
|
|
|
use nu_protocol::{
|
|
|
|
ast::{Call, Expr, Expression, PipelineElement},
|
|
|
|
engine::{Command, EngineState, Stack, StateWorkingSet},
|
|
|
|
Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Spanned, SyntaxShape,
|
|
|
|
Value,
|
|
|
|
};
|
|
|
|
use nu_utils::stdout_write_all_and_flush;
|
|
|
|
|
2023-01-27 00:56:55 +01:00
|
|
|
pub(crate) fn gather_commandline_args() -> (Vec<String>, String, Vec<String>) {
|
|
|
|
// Would be nice if we had a way to parse this. The first flags we see will be going to nushell
|
|
|
|
// then it'll be the script name
|
|
|
|
// then the args to the script
|
|
|
|
let mut args_to_nushell = Vec::from(["nu".into()]);
|
|
|
|
let mut script_name = String::new();
|
|
|
|
let mut args = std::env::args();
|
|
|
|
|
|
|
|
// Mimic the behaviour of bash/zsh
|
|
|
|
if let Some(argv0) = args.next() {
|
|
|
|
if argv0.starts_with('-') {
|
|
|
|
args_to_nushell.push("--login".into());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while let Some(arg) = args.next() {
|
|
|
|
if !arg.starts_with('-') {
|
|
|
|
script_name = arg;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
let flag_value = match arg.as_ref() {
|
|
|
|
"--commands" | "-c" | "--table-mode" | "-m" | "-e" | "--execute" | "--config"
|
add `--ide-ast` for a simplistic ast for editors (#8995)
# Description
This is WIP. This generates a simplistic AST so that we can call it from
the vscode side for semantic token highlighting. The output is a
minified version of this screenshot.
![image](https://user-images.githubusercontent.com/343840/234354668-872d6267-9946-4b92-8a13-4fed45b4513a.png)
The script
```
def test [arg] {
print $arg
for i in (seq 1 10) {
echo $i
}
}
```
The simplistic AST
```json
[{"content":"def","index":0,"shape":"shape_internalcall","span":{"end":15,"start":12}},{"content":"test","index":1,"shape":"shape_string","span":{"end":20,"start":16}},{"content":"[arg]","index":2,"shape":"shape_signature","span":{"end":26,"start":21}},{"content":"{\r\n ","index":3,"shape":"shape_closure","span":{"end":32,"start":27}},{"content":"print","index":4,"shape":"shape_internalcall","span":{"end":37,"start":32}},{"content":"$arg","index":5,"shape":"shape_variable","span":{"end":42,"start":38}},{"content":"for","index":6,"shape":"shape_internalcall","span":{"end":49,"start":46}},{"content":"i","index":7,"shape":"shape_vardecl","span":{"end":51,"start":50}},{"content":"in","index":8,"shape":"shape_keyword","span":{"end":54,"start":52}},{"content":"(","index":9,"shape":"shape_block","span":{"end":56,"start":55}},{"content":"seq","index":10,"shape":"shape_internalcall","span":{"end":59,"start":56}},{"content":"1","index":11,"shape":"shape_int","span":{"end":61,"start":60}},{"content":"10","index":12,"shape":"shape_int","span":{"end":64,"start":62}},{"content":")","index":13,"shape":"shape_block","span":{"end":65,"start":64}},{"content":"{\r\n ","index":14,"shape":"shape_block","span":{"end":73,"start":66}},{"content":"echo","index":15,"shape":"shape_internalcall","span":{"end":77,"start":73}},{"content":"$i","index":16,"shape":"shape_variable","span":{"end":80,"start":78}},{"content":"\r\n }","index":17,"shape":"shape_block","span":{"end":85,"start":80}},{"content":"\r\n}","index":18,"shape":"shape_closure","span":{"end":88,"start":85}}]
```
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->
# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass
- `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the
standard library
> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->
# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-04-28 15:51:51 +02:00
|
|
|
| "--env-config" | "-I" | "ide-ast" => args.next().map(|a| escape_quote_string(&a)),
|
2023-01-27 00:56:55 +01:00
|
|
|
#[cfg(feature = "plugin")]
|
|
|
|
"--plugin-config" => args.next().map(|a| escape_quote_string(&a)),
|
2023-04-05 21:34:47 +02:00
|
|
|
"--log-level" | "--log-target" | "--testbin" | "--threads" | "-t"
|
2023-04-18 02:07:54 +02:00
|
|
|
| "--include-path" | "--ide-goto-def" | "--ide-hover" | "--ide-complete"
|
2023-04-13 19:53:18 +02:00
|
|
|
| "--ide-check" => args.next(),
|
2023-01-27 00:56:55 +01:00
|
|
|
_ => None,
|
|
|
|
};
|
|
|
|
|
|
|
|
args_to_nushell.push(arg);
|
|
|
|
|
|
|
|
if let Some(flag_value) = flag_value {
|
|
|
|
args_to_nushell.push(flag_value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let args_to_script = if !script_name.is_empty() {
|
|
|
|
args.map(|arg| escape_for_script_arg(&arg)).collect()
|
|
|
|
} else {
|
|
|
|
Vec::default()
|
|
|
|
};
|
|
|
|
(args_to_nushell, script_name, args_to_script)
|
|
|
|
}
|
|
|
|
|
2023-01-20 22:20:38 +01:00
|
|
|
pub(crate) fn parse_commandline_args(
|
|
|
|
commandline_args: &str,
|
|
|
|
engine_state: &mut EngineState,
|
|
|
|
) -> Result<NushellCliArgs, ShellError> {
|
|
|
|
let (block, delta) = {
|
|
|
|
let mut working_set = StateWorkingSet::new(engine_state);
|
|
|
|
working_set.add_decl(Box::new(Nu));
|
|
|
|
|
2023-04-07 20:09:38 +02:00
|
|
|
let output = parse(&mut working_set, None, commandline_args.as_bytes(), false);
|
2023-04-07 02:35:45 +02:00
|
|
|
if let Some(err) = working_set.parse_errors.first() {
|
|
|
|
report_error(&working_set, err);
|
2023-01-20 22:20:38 +01:00
|
|
|
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
working_set.hide_decl(b"nu");
|
|
|
|
(output, working_set.render())
|
|
|
|
};
|
|
|
|
|
|
|
|
engine_state.merge_delta(delta)?;
|
|
|
|
|
|
|
|
let mut stack = Stack::new();
|
|
|
|
|
|
|
|
// We should have a successful parse now
|
|
|
|
if let Some(pipeline) = block.pipelines.get(0) {
|
|
|
|
if let Some(PipelineElement::Expression(
|
|
|
|
_,
|
|
|
|
Expression {
|
|
|
|
expr: Expr::Call(call),
|
|
|
|
..
|
|
|
|
},
|
|
|
|
)) = pipeline.elements.get(0)
|
|
|
|
{
|
|
|
|
let redirect_stdin = call.get_named_arg("stdin");
|
|
|
|
let login_shell = call.get_named_arg("login");
|
|
|
|
let interactive_shell = call.get_named_arg("interactive");
|
|
|
|
let commands: Option<Expression> = call.get_flag_expr("commands");
|
|
|
|
let testbin: Option<Expression> = call.get_flag_expr("testbin");
|
|
|
|
#[cfg(feature = "plugin")]
|
|
|
|
let plugin_file: Option<Expression> = call.get_flag_expr("plugin-config");
|
2023-03-06 16:36:15 +01:00
|
|
|
let no_config_file = call.get_named_arg("no-config-file");
|
2023-04-10 00:55:29 +02:00
|
|
|
let no_std_lib = call.get_named_arg("no-std-lib");
|
2023-01-20 22:20:38 +01:00
|
|
|
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 log_target: Option<Expression> = call.get_flag_expr("log-target");
|
|
|
|
let execute: Option<Expression> = call.get_flag_expr("execute");
|
|
|
|
let table_mode: Option<Value> =
|
|
|
|
call.get_flag(engine_state, &mut stack, "table-mode")?;
|
|
|
|
|
add `--ide-ast` for a simplistic ast for editors (#8995)
# Description
This is WIP. This generates a simplistic AST so that we can call it from
the vscode side for semantic token highlighting. The output is a
minified version of this screenshot.
![image](https://user-images.githubusercontent.com/343840/234354668-872d6267-9946-4b92-8a13-4fed45b4513a.png)
The script
```
def test [arg] {
print $arg
for i in (seq 1 10) {
echo $i
}
}
```
The simplistic AST
```json
[{"content":"def","index":0,"shape":"shape_internalcall","span":{"end":15,"start":12}},{"content":"test","index":1,"shape":"shape_string","span":{"end":20,"start":16}},{"content":"[arg]","index":2,"shape":"shape_signature","span":{"end":26,"start":21}},{"content":"{\r\n ","index":3,"shape":"shape_closure","span":{"end":32,"start":27}},{"content":"print","index":4,"shape":"shape_internalcall","span":{"end":37,"start":32}},{"content":"$arg","index":5,"shape":"shape_variable","span":{"end":42,"start":38}},{"content":"for","index":6,"shape":"shape_internalcall","span":{"end":49,"start":46}},{"content":"i","index":7,"shape":"shape_vardecl","span":{"end":51,"start":50}},{"content":"in","index":8,"shape":"shape_keyword","span":{"end":54,"start":52}},{"content":"(","index":9,"shape":"shape_block","span":{"end":56,"start":55}},{"content":"seq","index":10,"shape":"shape_internalcall","span":{"end":59,"start":56}},{"content":"1","index":11,"shape":"shape_int","span":{"end":61,"start":60}},{"content":"10","index":12,"shape":"shape_int","span":{"end":64,"start":62}},{"content":")","index":13,"shape":"shape_block","span":{"end":65,"start":64}},{"content":"{\r\n ","index":14,"shape":"shape_block","span":{"end":73,"start":66}},{"content":"echo","index":15,"shape":"shape_internalcall","span":{"end":77,"start":73}},{"content":"$i","index":16,"shape":"shape_variable","span":{"end":80,"start":78}},{"content":"\r\n }","index":17,"shape":"shape_block","span":{"end":85,"start":80}},{"content":"\r\n}","index":18,"shape":"shape_closure","span":{"end":88,"start":85}}]
```
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->
# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass
- `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the
standard library
> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->
# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-04-28 15:51:51 +02:00
|
|
|
// ide flags
|
|
|
|
let include_path: Option<Expression> = call.get_flag_expr("include-path");
|
2023-04-13 19:53:18 +02:00
|
|
|
let ide_goto_def: Option<Value> =
|
|
|
|
call.get_flag(engine_state, &mut stack, "ide-goto-def")?;
|
|
|
|
let ide_hover: Option<Value> = call.get_flag(engine_state, &mut stack, "ide-hover")?;
|
|
|
|
let ide_complete: Option<Value> =
|
|
|
|
call.get_flag(engine_state, &mut stack, "ide-complete")?;
|
|
|
|
let ide_check: Option<Value> = call.get_flag(engine_state, &mut stack, "ide-check")?;
|
add `--ide-ast` for a simplistic ast for editors (#8995)
# Description
This is WIP. This generates a simplistic AST so that we can call it from
the vscode side for semantic token highlighting. The output is a
minified version of this screenshot.
![image](https://user-images.githubusercontent.com/343840/234354668-872d6267-9946-4b92-8a13-4fed45b4513a.png)
The script
```
def test [arg] {
print $arg
for i in (seq 1 10) {
echo $i
}
}
```
The simplistic AST
```json
[{"content":"def","index":0,"shape":"shape_internalcall","span":{"end":15,"start":12}},{"content":"test","index":1,"shape":"shape_string","span":{"end":20,"start":16}},{"content":"[arg]","index":2,"shape":"shape_signature","span":{"end":26,"start":21}},{"content":"{\r\n ","index":3,"shape":"shape_closure","span":{"end":32,"start":27}},{"content":"print","index":4,"shape":"shape_internalcall","span":{"end":37,"start":32}},{"content":"$arg","index":5,"shape":"shape_variable","span":{"end":42,"start":38}},{"content":"for","index":6,"shape":"shape_internalcall","span":{"end":49,"start":46}},{"content":"i","index":7,"shape":"shape_vardecl","span":{"end":51,"start":50}},{"content":"in","index":8,"shape":"shape_keyword","span":{"end":54,"start":52}},{"content":"(","index":9,"shape":"shape_block","span":{"end":56,"start":55}},{"content":"seq","index":10,"shape":"shape_internalcall","span":{"end":59,"start":56}},{"content":"1","index":11,"shape":"shape_int","span":{"end":61,"start":60}},{"content":"10","index":12,"shape":"shape_int","span":{"end":64,"start":62}},{"content":")","index":13,"shape":"shape_block","span":{"end":65,"start":64}},{"content":"{\r\n ","index":14,"shape":"shape_block","span":{"end":73,"start":66}},{"content":"echo","index":15,"shape":"shape_internalcall","span":{"end":77,"start":73}},{"content":"$i","index":16,"shape":"shape_variable","span":{"end":80,"start":78}},{"content":"\r\n }","index":17,"shape":"shape_block","span":{"end":85,"start":80}},{"content":"\r\n}","index":18,"shape":"shape_closure","span":{"end":88,"start":85}}]
```
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->
# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass
- `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the
standard library
> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->
# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-04-28 15:51:51 +02:00
|
|
|
let ide_ast: Option<Spanned<String>> = call.get_named_arg("ide-ast");
|
2023-04-13 19:53:18 +02:00
|
|
|
|
2023-01-20 22:20:38 +01:00
|
|
|
fn extract_contents(
|
|
|
|
expression: Option<Expression>,
|
|
|
|
) -> Result<Option<Spanned<String>>, ShellError> {
|
|
|
|
if let Some(expr) = expression {
|
|
|
|
let str = expr.as_string();
|
|
|
|
if let Some(str) = str {
|
|
|
|
Ok(Some(Spanned {
|
|
|
|
item: str,
|
|
|
|
span: expr.span,
|
|
|
|
}))
|
|
|
|
} else {
|
2023-03-06 11:31:07 +01:00
|
|
|
Err(ShellError::TypeMismatch {
|
|
|
|
err_message: "string".into(),
|
|
|
|
span: expr.span,
|
|
|
|
})
|
2023-01-20 22:20:38 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Ok(None)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let commands = extract_contents(commands)?;
|
|
|
|
let testbin = extract_contents(testbin)?;
|
|
|
|
#[cfg(feature = "plugin")]
|
|
|
|
let plugin_file = extract_contents(plugin_file)?;
|
|
|
|
let config_file = extract_contents(config_file)?;
|
|
|
|
let env_file = extract_contents(env_file)?;
|
|
|
|
let log_level = extract_contents(log_level)?;
|
|
|
|
let log_target = extract_contents(log_target)?;
|
|
|
|
let execute = extract_contents(execute)?;
|
2023-04-12 19:36:29 +02:00
|
|
|
let include_path = extract_contents(include_path)?;
|
2023-01-20 22:20:38 +01:00
|
|
|
|
|
|
|
let help = call.has_flag("help");
|
|
|
|
|
|
|
|
if help {
|
|
|
|
let full_help = get_full_help(
|
|
|
|
&Nu.signature(),
|
|
|
|
&Nu.examples(),
|
|
|
|
engine_state,
|
|
|
|
&mut stack,
|
|
|
|
true,
|
|
|
|
);
|
|
|
|
|
|
|
|
let _ = std::panic::catch_unwind(move || stdout_write_all_and_flush(full_help));
|
|
|
|
|
2023-03-16 13:03:29 +01:00
|
|
|
std::process::exit(0);
|
2023-01-20 22:20:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if call.has_flag("version") {
|
|
|
|
let version = env!("CARGO_PKG_VERSION").to_string();
|
|
|
|
let _ = std::panic::catch_unwind(move || {
|
2023-01-30 02:37:54 +01:00
|
|
|
stdout_write_all_and_flush(format!("{version}\n"))
|
2023-01-20 22:20:38 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
std::process::exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ok(NushellCliArgs {
|
|
|
|
redirect_stdin,
|
|
|
|
login_shell,
|
|
|
|
interactive_shell,
|
|
|
|
commands,
|
|
|
|
testbin,
|
|
|
|
#[cfg(feature = "plugin")]
|
|
|
|
plugin_file,
|
2023-03-06 16:36:15 +01:00
|
|
|
no_config_file,
|
2023-04-10 00:55:29 +02:00
|
|
|
no_std_lib,
|
2023-01-20 22:20:38 +01:00
|
|
|
config_file,
|
|
|
|
env_file,
|
|
|
|
log_level,
|
|
|
|
log_target,
|
|
|
|
execute,
|
2023-04-12 19:36:29 +02:00
|
|
|
include_path,
|
2023-04-05 21:34:47 +02:00
|
|
|
ide_goto_def,
|
|
|
|
ide_hover,
|
|
|
|
ide_complete,
|
|
|
|
ide_check,
|
add `--ide-ast` for a simplistic ast for editors (#8995)
# Description
This is WIP. This generates a simplistic AST so that we can call it from
the vscode side for semantic token highlighting. The output is a
minified version of this screenshot.
![image](https://user-images.githubusercontent.com/343840/234354668-872d6267-9946-4b92-8a13-4fed45b4513a.png)
The script
```
def test [arg] {
print $arg
for i in (seq 1 10) {
echo $i
}
}
```
The simplistic AST
```json
[{"content":"def","index":0,"shape":"shape_internalcall","span":{"end":15,"start":12}},{"content":"test","index":1,"shape":"shape_string","span":{"end":20,"start":16}},{"content":"[arg]","index":2,"shape":"shape_signature","span":{"end":26,"start":21}},{"content":"{\r\n ","index":3,"shape":"shape_closure","span":{"end":32,"start":27}},{"content":"print","index":4,"shape":"shape_internalcall","span":{"end":37,"start":32}},{"content":"$arg","index":5,"shape":"shape_variable","span":{"end":42,"start":38}},{"content":"for","index":6,"shape":"shape_internalcall","span":{"end":49,"start":46}},{"content":"i","index":7,"shape":"shape_vardecl","span":{"end":51,"start":50}},{"content":"in","index":8,"shape":"shape_keyword","span":{"end":54,"start":52}},{"content":"(","index":9,"shape":"shape_block","span":{"end":56,"start":55}},{"content":"seq","index":10,"shape":"shape_internalcall","span":{"end":59,"start":56}},{"content":"1","index":11,"shape":"shape_int","span":{"end":61,"start":60}},{"content":"10","index":12,"shape":"shape_int","span":{"end":64,"start":62}},{"content":")","index":13,"shape":"shape_block","span":{"end":65,"start":64}},{"content":"{\r\n ","index":14,"shape":"shape_block","span":{"end":73,"start":66}},{"content":"echo","index":15,"shape":"shape_internalcall","span":{"end":77,"start":73}},{"content":"$i","index":16,"shape":"shape_variable","span":{"end":80,"start":78}},{"content":"\r\n }","index":17,"shape":"shape_block","span":{"end":85,"start":80}},{"content":"\r\n}","index":18,"shape":"shape_closure","span":{"end":88,"start":85}}]
```
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->
# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass
- `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the
standard library
> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->
# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-04-28 15:51:51 +02:00
|
|
|
ide_ast,
|
2023-01-20 22:20:38 +01:00
|
|
|
table_mode,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Just give the help and exit if the above fails
|
|
|
|
let full_help = get_full_help(
|
|
|
|
&Nu.signature(),
|
|
|
|
&Nu.examples(),
|
|
|
|
engine_state,
|
|
|
|
&mut stack,
|
|
|
|
true,
|
|
|
|
);
|
2023-01-30 02:37:54 +01:00
|
|
|
print!("{full_help}");
|
2023-01-20 22:20:38 +01:00
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) struct NushellCliArgs {
|
|
|
|
pub(crate) redirect_stdin: Option<Spanned<String>>,
|
|
|
|
pub(crate) login_shell: Option<Spanned<String>>,
|
|
|
|
pub(crate) interactive_shell: Option<Spanned<String>>,
|
|
|
|
pub(crate) commands: Option<Spanned<String>>,
|
|
|
|
pub(crate) testbin: Option<Spanned<String>>,
|
|
|
|
#[cfg(feature = "plugin")]
|
|
|
|
pub(crate) plugin_file: Option<Spanned<String>>,
|
2023-03-06 16:36:15 +01:00
|
|
|
pub(crate) no_config_file: Option<Spanned<String>>,
|
2023-04-10 00:55:29 +02:00
|
|
|
pub(crate) no_std_lib: Option<Spanned<String>>,
|
2023-01-20 22:20:38 +01:00
|
|
|
pub(crate) config_file: Option<Spanned<String>>,
|
|
|
|
pub(crate) env_file: Option<Spanned<String>>,
|
|
|
|
pub(crate) log_level: Option<Spanned<String>>,
|
|
|
|
pub(crate) log_target: Option<Spanned<String>>,
|
|
|
|
pub(crate) execute: Option<Spanned<String>>,
|
|
|
|
pub(crate) table_mode: Option<Value>,
|
2023-04-12 19:36:29 +02:00
|
|
|
pub(crate) include_path: Option<Spanned<String>>,
|
2023-04-05 21:34:47 +02:00
|
|
|
pub(crate) ide_goto_def: Option<Value>,
|
|
|
|
pub(crate) ide_hover: Option<Value>,
|
|
|
|
pub(crate) ide_complete: Option<Value>,
|
2023-04-13 19:53:18 +02:00
|
|
|
pub(crate) ide_check: Option<Value>,
|
add `--ide-ast` for a simplistic ast for editors (#8995)
# Description
This is WIP. This generates a simplistic AST so that we can call it from
the vscode side for semantic token highlighting. The output is a
minified version of this screenshot.
![image](https://user-images.githubusercontent.com/343840/234354668-872d6267-9946-4b92-8a13-4fed45b4513a.png)
The script
```
def test [arg] {
print $arg
for i in (seq 1 10) {
echo $i
}
}
```
The simplistic AST
```json
[{"content":"def","index":0,"shape":"shape_internalcall","span":{"end":15,"start":12}},{"content":"test","index":1,"shape":"shape_string","span":{"end":20,"start":16}},{"content":"[arg]","index":2,"shape":"shape_signature","span":{"end":26,"start":21}},{"content":"{\r\n ","index":3,"shape":"shape_closure","span":{"end":32,"start":27}},{"content":"print","index":4,"shape":"shape_internalcall","span":{"end":37,"start":32}},{"content":"$arg","index":5,"shape":"shape_variable","span":{"end":42,"start":38}},{"content":"for","index":6,"shape":"shape_internalcall","span":{"end":49,"start":46}},{"content":"i","index":7,"shape":"shape_vardecl","span":{"end":51,"start":50}},{"content":"in","index":8,"shape":"shape_keyword","span":{"end":54,"start":52}},{"content":"(","index":9,"shape":"shape_block","span":{"end":56,"start":55}},{"content":"seq","index":10,"shape":"shape_internalcall","span":{"end":59,"start":56}},{"content":"1","index":11,"shape":"shape_int","span":{"end":61,"start":60}},{"content":"10","index":12,"shape":"shape_int","span":{"end":64,"start":62}},{"content":")","index":13,"shape":"shape_block","span":{"end":65,"start":64}},{"content":"{\r\n ","index":14,"shape":"shape_block","span":{"end":73,"start":66}},{"content":"echo","index":15,"shape":"shape_internalcall","span":{"end":77,"start":73}},{"content":"$i","index":16,"shape":"shape_variable","span":{"end":80,"start":78}},{"content":"\r\n }","index":17,"shape":"shape_block","span":{"end":85,"start":80}},{"content":"\r\n}","index":18,"shape":"shape_closure","span":{"end":88,"start":85}}]
```
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->
# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass
- `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the
standard library
> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->
# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-04-28 15:51:51 +02:00
|
|
|
pub(crate) ide_ast: Option<Spanned<String>>,
|
2023-01-20 22:20:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
struct Nu;
|
|
|
|
|
|
|
|
impl Command for Nu {
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
"nu"
|
|
|
|
}
|
|
|
|
|
|
|
|
fn signature(&self) -> Signature {
|
|
|
|
let mut signature = Signature::build("nu")
|
|
|
|
.usage("The nushell language and shell.")
|
|
|
|
.named(
|
|
|
|
"commands",
|
|
|
|
SyntaxShape::String,
|
|
|
|
"run the given commands and then exit",
|
|
|
|
Some('c'),
|
|
|
|
)
|
|
|
|
.named(
|
|
|
|
"execute",
|
|
|
|
SyntaxShape::String,
|
|
|
|
"run the given commands and then enter an interactive shell",
|
|
|
|
Some('e'),
|
|
|
|
)
|
2023-04-12 19:36:29 +02:00
|
|
|
.named(
|
|
|
|
"include-path",
|
|
|
|
SyntaxShape::String,
|
2023-04-12 20:21:02 +02:00
|
|
|
"set the NU_LIB_DIRS for the given script (semicolon-delimited)",
|
2023-04-12 19:36:29 +02:00
|
|
|
Some('I'),
|
|
|
|
)
|
2023-01-20 22:20:38 +01:00
|
|
|
.switch("interactive", "start as an interactive shell", Some('i'))
|
|
|
|
.switch("login", "start as a login shell", Some('l'))
|
|
|
|
.named(
|
|
|
|
"table-mode",
|
|
|
|
SyntaxShape::String,
|
|
|
|
"the table mode to use. rounded is default.",
|
|
|
|
Some('m'),
|
|
|
|
)
|
2023-03-06 16:36:15 +01:00
|
|
|
.switch(
|
|
|
|
"no-config-file",
|
|
|
|
"start with no config file and no env file",
|
|
|
|
Some('n'),
|
|
|
|
)
|
2023-04-10 00:55:29 +02:00
|
|
|
.switch("no-std-lib", "start with no standard library", None)
|
2023-01-20 22:20:38 +01:00
|
|
|
.named(
|
|
|
|
"threads",
|
|
|
|
SyntaxShape::Int,
|
|
|
|
"threads to use for parallel commands",
|
|
|
|
Some('t'),
|
|
|
|
)
|
|
|
|
.switch("version", "print the version", Some('v'))
|
|
|
|
.named(
|
|
|
|
"config",
|
|
|
|
SyntaxShape::String,
|
|
|
|
"start with an alternate config file",
|
|
|
|
None,
|
|
|
|
)
|
|
|
|
.named(
|
|
|
|
"env-config",
|
|
|
|
SyntaxShape::String,
|
|
|
|
"start with an alternate environment config file",
|
|
|
|
None,
|
2023-04-05 21:34:47 +02:00
|
|
|
)
|
|
|
|
.named(
|
|
|
|
"ide-goto-def",
|
|
|
|
SyntaxShape::Int,
|
|
|
|
"go to the definition of the item at the given position",
|
|
|
|
None,
|
|
|
|
)
|
|
|
|
.named(
|
|
|
|
"ide-hover",
|
|
|
|
SyntaxShape::Int,
|
|
|
|
"give information about the item at the given position",
|
|
|
|
None,
|
|
|
|
)
|
|
|
|
.named(
|
|
|
|
"ide-complete",
|
|
|
|
SyntaxShape::Int,
|
|
|
|
"list completions for the item at the given position",
|
|
|
|
None,
|
|
|
|
)
|
2023-04-13 19:53:18 +02:00
|
|
|
.named(
|
2023-04-05 21:34:47 +02:00
|
|
|
"ide-check",
|
2023-04-13 19:53:18 +02:00
|
|
|
SyntaxShape::Int,
|
2023-04-05 21:34:47 +02:00
|
|
|
"run a diagnostic check on the given source",
|
|
|
|
None,
|
add `--ide-ast` for a simplistic ast for editors (#8995)
# Description
This is WIP. This generates a simplistic AST so that we can call it from
the vscode side for semantic token highlighting. The output is a
minified version of this screenshot.
![image](https://user-images.githubusercontent.com/343840/234354668-872d6267-9946-4b92-8a13-4fed45b4513a.png)
The script
```
def test [arg] {
print $arg
for i in (seq 1 10) {
echo $i
}
}
```
The simplistic AST
```json
[{"content":"def","index":0,"shape":"shape_internalcall","span":{"end":15,"start":12}},{"content":"test","index":1,"shape":"shape_string","span":{"end":20,"start":16}},{"content":"[arg]","index":2,"shape":"shape_signature","span":{"end":26,"start":21}},{"content":"{\r\n ","index":3,"shape":"shape_closure","span":{"end":32,"start":27}},{"content":"print","index":4,"shape":"shape_internalcall","span":{"end":37,"start":32}},{"content":"$arg","index":5,"shape":"shape_variable","span":{"end":42,"start":38}},{"content":"for","index":6,"shape":"shape_internalcall","span":{"end":49,"start":46}},{"content":"i","index":7,"shape":"shape_vardecl","span":{"end":51,"start":50}},{"content":"in","index":8,"shape":"shape_keyword","span":{"end":54,"start":52}},{"content":"(","index":9,"shape":"shape_block","span":{"end":56,"start":55}},{"content":"seq","index":10,"shape":"shape_internalcall","span":{"end":59,"start":56}},{"content":"1","index":11,"shape":"shape_int","span":{"end":61,"start":60}},{"content":"10","index":12,"shape":"shape_int","span":{"end":64,"start":62}},{"content":")","index":13,"shape":"shape_block","span":{"end":65,"start":64}},{"content":"{\r\n ","index":14,"shape":"shape_block","span":{"end":73,"start":66}},{"content":"echo","index":15,"shape":"shape_internalcall","span":{"end":77,"start":73}},{"content":"$i","index":16,"shape":"shape_variable","span":{"end":80,"start":78}},{"content":"\r\n }","index":17,"shape":"shape_block","span":{"end":85,"start":80}},{"content":"\r\n}","index":18,"shape":"shape_closure","span":{"end":88,"start":85}}]
```
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->
# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass
- `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the
standard library
> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->
# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-04-28 15:51:51 +02:00
|
|
|
)
|
|
|
|
.switch("ide-ast", "generate the ast on the given source", None);
|
2023-01-20 22:20:38 +01:00
|
|
|
|
|
|
|
#[cfg(feature = "plugin")]
|
|
|
|
{
|
|
|
|
signature = signature.named(
|
|
|
|
"plugin-config",
|
|
|
|
SyntaxShape::String,
|
|
|
|
"start with an alternate plugin signature file",
|
|
|
|
None,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
signature = signature
|
|
|
|
.named(
|
|
|
|
"log-level",
|
|
|
|
SyntaxShape::String,
|
|
|
|
"log level for diagnostic logs (error, warn, info, debug, trace). Off by default",
|
|
|
|
None,
|
|
|
|
)
|
|
|
|
.named(
|
|
|
|
"log-target",
|
|
|
|
SyntaxShape::String,
|
|
|
|
"set the target for the log to output. stdout, stderr(default), mixed or file",
|
|
|
|
None,
|
|
|
|
)
|
|
|
|
.switch(
|
|
|
|
"stdin",
|
|
|
|
"redirect standard input to a command (with `-c`) or a script file",
|
|
|
|
None,
|
|
|
|
)
|
|
|
|
.named(
|
|
|
|
"testbin",
|
|
|
|
SyntaxShape::String,
|
|
|
|
"run internal test binary",
|
|
|
|
None,
|
|
|
|
)
|
|
|
|
.optional(
|
|
|
|
"script file",
|
|
|
|
SyntaxShape::Filepath,
|
|
|
|
"name of the optional script file to run",
|
|
|
|
)
|
|
|
|
.rest(
|
|
|
|
"script args",
|
|
|
|
SyntaxShape::String,
|
|
|
|
"parameters to the script file",
|
|
|
|
)
|
|
|
|
.category(Category::System);
|
|
|
|
|
|
|
|
signature
|
|
|
|
}
|
|
|
|
|
|
|
|
fn usage(&self) -> &str {
|
|
|
|
"The nushell language and shell."
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run(
|
|
|
|
&self,
|
|
|
|
engine_state: &EngineState,
|
|
|
|
stack: &mut Stack,
|
|
|
|
call: &Call,
|
|
|
|
_input: PipelineData,
|
2023-02-05 22:17:46 +01:00
|
|
|
) -> Result<PipelineData, ShellError> {
|
2023-01-20 22:20:38 +01:00
|
|
|
Ok(Value::String {
|
|
|
|
val: get_full_help(&Nu.signature(), &Nu.examples(), engine_state, stack, true),
|
|
|
|
span: call.head,
|
|
|
|
}
|
|
|
|
.into_pipeline_data())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn examples(&self) -> Vec<nu_protocol::Example> {
|
|
|
|
vec![
|
|
|
|
Example {
|
|
|
|
description: "Run a script",
|
|
|
|
example: "nu myfile.nu",
|
|
|
|
result: None,
|
|
|
|
},
|
|
|
|
Example {
|
|
|
|
description: "Run nushell interactively (as a shell or REPL)",
|
|
|
|
example: "nu",
|
|
|
|
result: None,
|
|
|
|
},
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|