Define keywords (#13213)

# Description
Some commands in `nu-cmd-lang` are not classified as keywords even
though they should be.

# User-Facing Changes
In the output of `which`, `scope commands`, and `help commands`, some
commands will now have a `type` of `keyword` instead of `built-in`.
This commit is contained in:
Ian Manske 2024-06-26 01:32:54 +00:00 committed by GitHub
parent f241110005
commit 55ee476306
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 126 additions and 32 deletions

View File

@ -1,4 +1,5 @@
use nu_engine::command_prelude::*;
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct Break;
@ -18,6 +19,15 @@ impl Command for Break {
.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 command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
_engine_state: &EngineState,

View File

@ -1,4 +1,5 @@
use nu_engine::command_prelude::*;
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct Continue;
@ -18,6 +19,14 @@ impl Command for Continue {
.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 command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
_engine_state: &EngineState,

View File

@ -2,7 +2,7 @@ use nu_engine::{
command_prelude::*, get_eval_block, get_eval_expression, get_eval_expression_with_input,
};
use nu_protocol::{
engine::StateWorkingSet,
engine::{CommandType, StateWorkingSet},
eval_const::{eval_const_subexpression, eval_constant, eval_constant_with_input},
};
@ -41,6 +41,15 @@ impl Command for If {
.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 command_type(&self) -> CommandType {
CommandType::Keyword
}
fn is_const(&self) -> bool {
true
}

View File

@ -1,4 +1,5 @@
use nu_engine::{command_prelude::*, get_eval_block};
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct Loop;
@ -20,6 +21,15 @@ impl Command for Loop {
.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 command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -1,7 +1,7 @@
use nu_engine::{
command_prelude::*, get_eval_block, get_eval_expression, get_eval_expression_with_input,
};
use nu_protocol::engine::Matcher;
use nu_protocol::engine::{CommandType, Matcher};
#[derive(Clone)]
pub struct Match;
@ -27,6 +27,15 @@ impl Command for Match {
.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 command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -1,5 +1,4 @@
use nu_engine::{command_prelude::*, get_full_help};
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct Scope;
@ -20,10 +19,6 @@ impl Command for Scope {
"Commands for getting info about what is in scope."
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -1,5 +1,5 @@
use nu_engine::{command_prelude::*, get_eval_block, EvalBlockFn};
use nu_protocol::engine::Closure;
use nu_protocol::engine::{Closure, CommandType};
#[derive(Clone)]
pub struct Try;
@ -31,6 +31,15 @@ impl Command for Try {
.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 command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -1,4 +1,5 @@
use nu_engine::{command_prelude::*, get_eval_block, get_eval_expression};
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct While;
@ -29,6 +30,15 @@ impl Command for While {
vec!["loop"]
}
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 command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -1,4 +1,5 @@
use nu_engine::{command_prelude::*, get_eval_block, redirect_env};
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct ExportEnv;
@ -23,6 +24,15 @@ impl Command for ExportEnv {
"Run a block and preserve its environment in a current scope."
}
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 command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -2,6 +2,7 @@ use nu_engine::{
command_prelude::*, find_in_dirs_env, get_dirs_var_from_call, get_eval_block_with_early_return,
redirect_env,
};
use nu_protocol::engine::CommandType;
use std::path::PathBuf;
/// Source a file for environment variables.
@ -28,6 +29,15 @@ impl Command for SourceEnv {
"Source the environment from a source file into the current environment."
}
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 command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -1,5 +1,5 @@
use nu_engine::{command_prelude::*, ClosureEval};
use nu_protocol::engine::Closure;
use nu_protocol::engine::{Closure, CommandType};
#[derive(Clone)]
pub struct Where;
@ -19,6 +19,10 @@ tables, known as "row conditions". On the other hand, reading the condition from
not supported."#
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn signature(&self) -> nu_protocol::Signature {
Signature::build("where")
.input_output_types(vec![

View File

@ -42,32 +42,44 @@ use crate::{
};
/// These parser keywords can be aliased
pub const ALIASABLE_PARSER_KEYWORDS: &[&[u8]] = &[b"overlay hide", b"overlay new", b"overlay use"];
pub const ALIASABLE_PARSER_KEYWORDS: &[&[u8]] = &[
b"if",
b"match",
b"try",
b"overlay",
b"overlay hide",
b"overlay new",
b"overlay use",
];
pub const RESERVED_VARIABLE_NAMES: [&str; 3] = ["in", "nu", "env"];
/// These parser keywords cannot be aliased (either not possible, or support not yet added)
pub const UNALIASABLE_PARSER_KEYWORDS: &[&[u8]] = &[
b"export",
b"def",
b"export def",
b"for",
b"extern",
b"export extern",
b"alias",
b"export alias",
b"export-env",
b"const",
b"def",
b"extern",
b"module",
b"use",
b"export",
b"export alias",
b"export const",
b"export def",
b"export extern",
b"export module",
b"export use",
b"hide",
// b"overlay",
// b"overlay hide",
// b"overlay new",
// b"overlay use",
b"for",
b"loop",
b"while",
b"return",
b"break",
b"continue",
b"let",
b"const",
b"mut",
b"hide",
b"export-env",
b"source-env",
b"source",
b"where",
b"register",

View File

@ -934,15 +934,12 @@ pub fn parse_internal_call(
let output = signature.get_output_type();
// storing the var ID for later due to borrowing issues
let lib_dirs_var_id = if decl.is_builtin() {
match decl.name() {
"use" | "overlay use" | "source-env" | "nu-check" => {
find_dirs_var(working_set, LIB_DIRS_VAR)
}
_ => None,
let lib_dirs_var_id = match decl.name() {
"use" | "overlay use" | "source-env" if decl.is_keyword() => {
find_dirs_var(working_set, LIB_DIRS_VAR)
}
} else {
None
"nu-check" if decl.is_builtin() => find_dirs_var(working_set, LIB_DIRS_VAR),
_ => None,
};
// The index into the positional parameter in the definition