Use CommandType in more places (#12832)

# Description
Kind of a vague title, but this PR does two main things:
1. Rather than overriding functions like `Command::is_parser_keyword`,
this PR instead changes commands to override `Command::command_type`.
The `CommandType` returned by `Command::command_type` is then used to
automatically determine whether `Command::is_parser_keyword` and the
other `is_{type}` functions should return true. These changes allow us
to remove the `CommandType::Other` case and should also guarantee than
only one of the `is_{type}` functions on `Command` will return true.
2. Uses the new, reworked `Command::command_type` function in the `scope
commands` and `which` commands.


# User-Facing Changes
- Breaking change for `scope commands`: multiple columns (`is_builtin`,
`is_keyword`, `is_plugin`, etc.) have been merged into the `type`
column.
- Breaking change: the `which` command can now report `plugin` or
`keyword` instead of `built-in` in the `type` column. It may also now
report `external` instead of `custom` in the `type` column for known
`extern`s.
This commit is contained in:
Ian Manske
2024-05-18 23:37:31 +00:00
committed by GitHub
parent 580c60bb82
commit cc9f41e553
68 changed files with 224 additions and 217 deletions

View File

@ -35,7 +35,7 @@ impl Command for Bytes {
&Bytes.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -35,7 +35,7 @@ impl Command for Into {
&[],
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -35,7 +35,7 @@ impl Command for View {
&View.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -55,7 +55,7 @@ impl Command for ViewSource {
}
}
// gets vector of positionals.
else if let Some(block_id) = decl.get_block_id() {
else if let Some(block_id) = decl.block_id() {
let block = engine_state.get_block(block_id);
if let Some(block_span) = block.span {
let contents = engine_state.get_span_contents(block_span);

View File

@ -35,7 +35,7 @@ impl Command for ConfigMeta {
&ConfigMeta.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -172,7 +172,7 @@ impl Command for Open {
match converter {
Some((converter_id, ext)) => {
let decl = engine_state.get_decl(converter_id);
let command_output = if let Some(block_id) = decl.get_block_id() {
let command_output = if let Some(block_id) = decl.block_id() {
let block = engine_state.get_block(block_id);
eval_block(engine_state, stack, block, stream)
} else {

View File

@ -393,7 +393,7 @@ fn convert_to_extension(
) -> Result<PipelineData, ShellError> {
if let Some(decl_id) = engine_state.find_decl(format!("to {extension}").as_bytes(), &[]) {
let decl = engine_state.get_decl(decl_id);
if let Some(block_id) = decl.get_block_id() {
if let Some(block_id) = decl.block_id() {
let block = engine_state.get_block(block_id);
let eval_block = get_eval_block(engine_state);
eval_block(engine_state, stack, block, input)

View File

@ -35,7 +35,7 @@ impl Command for From {
&From.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -35,7 +35,7 @@ impl Command for To {
&To.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -35,7 +35,7 @@ impl Command for Hash {
&Self.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -1,6 +1,7 @@
use crate::help::highlight_search_in_table;
use nu_color_config::StyleComputer;
use nu_engine::{command_prelude::*, get_full_help};
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct HelpCommands;
@ -90,9 +91,15 @@ pub fn help_commands(
let output = engine_state
.get_signatures_with_examples(false)
.iter()
.filter(|(signature, _, _, _, _)| signature.name == name)
.map(|(signature, examples, _, _, is_parser_keyword)| {
get_full_help(signature, examples, engine_state, stack, *is_parser_keyword)
.filter(|(signature, _, _)| signature.name == name)
.map(|(signature, examples, cmd_type)| {
get_full_help(
signature,
examples,
engine_state,
stack,
cmd_type == &CommandType::Keyword,
)
})
.collect::<Vec<String>>();

View File

@ -1,6 +1,7 @@
use crate::help::highlight_search_in_table;
use nu_color_config::StyleComputer;
use nu_engine::{command_prelude::*, get_full_help, scope::ScopeData};
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct HelpExterns;
@ -110,9 +111,15 @@ pub fn help_externs(
let output = engine_state
.get_signatures_with_examples(false)
.iter()
.filter(|(signature, _, _, _, _)| signature.name == name)
.map(|(signature, examples, _, _, is_parser_keyword)| {
get_full_help(signature, examples, engine_state, stack, *is_parser_keyword)
.filter(|(signature, _, _)| signature.name == name)
.map(|(signature, examples, cmd_type)| {
get_full_help(
signature,
examples,
engine_state,
stack,
cmd_type == &CommandType::Keyword,
)
})
.collect::<Vec<String>>();

View File

@ -35,7 +35,7 @@ impl Command for MathCommand {
&MathCommand.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -1,4 +1,5 @@
use nu_engine::{command_prelude::*, get_eval_block_with_early_return};
use nu_protocol::engine::CommandType;
/// Source a file for environment variables.
#[derive(Clone)]
@ -29,8 +30,8 @@ impl Command for Source {
https://www.nushell.sh/book/thinking_in_nu.html"#
}
fn is_parser_keyword(&self) -> bool {
true
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(

View File

@ -41,7 +41,7 @@ impl Command for Http {
&Http.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -39,7 +39,7 @@ impl Command for Url {
&Url.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -48,7 +48,7 @@ the path literal."#
&PathCommand.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -39,7 +39,7 @@ impl Command for RandomCommand {
&RandomCommand.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -35,7 +35,7 @@ impl Command for Stor {
&Stor.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -35,7 +35,7 @@ impl Command for Format {
&Format.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -35,7 +35,7 @@ impl Command for SplitCommand {
&SplitCommand.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -35,7 +35,7 @@ impl Command for Str {
&Str.examples(),
engine_state,
stack,
self.is_parser_keyword(),
self.is_keyword(),
),
call.head,
)

View File

@ -1,5 +1,5 @@
use log::trace;
use nu_engine::{command_prelude::*, env};
use nu_protocol::engine::CommandType;
use std::{ffi::OsStr, path::Path};
#[derive(Clone)]
@ -51,14 +51,14 @@ impl Command for Which {
fn entry(
arg: impl Into<String>,
path: impl Into<String>,
cmd_type: impl Into<String>,
cmd_type: CommandType,
span: Span,
) -> Value {
Value::record(
record! {
"command" => Value::string(arg.into(), span),
"path" => Value::string(path.into(), span),
"type" => Value::string(cmd_type.into(), span),
"command" => Value::string(arg, span),
"path" => Value::string(path, span),
"type" => Value::string(cmd_type.to_string(), span),
},
span,
)
@ -66,17 +66,8 @@ fn entry(
fn get_entry_in_commands(engine_state: &EngineState, name: &str, span: Span) -> Option<Value> {
if let Some(decl_id) = engine_state.find_decl(name.as_bytes(), &[]) {
let cmd_type = if engine_state.get_decl(decl_id).is_custom_command() {
"custom"
} else if engine_state.get_decl(decl_id).is_alias() {
"alias"
} else {
"built-in"
};
trace!("Found command: {}", name);
Some(entry(name, "", cmd_type, span))
let decl = engine_state.get_decl(decl_id);
Some(entry(name, "", decl.command_type(), span))
} else {
None
}
@ -109,7 +100,7 @@ fn get_first_entry_in_path(
paths: impl AsRef<OsStr>,
) -> Option<Value> {
which::which_in(item, Some(paths), cwd)
.map(|path| entry(item, path.to_string_lossy().to_string(), "external", span))
.map(|path| entry(item, path.to_string_lossy(), CommandType::External, span))
.ok()
}
@ -132,7 +123,7 @@ fn get_all_entries_in_path(
) -> Vec<Value> {
which::which_in_all(&item, Some(paths), cwd)
.map(|iter| {
iter.map(|path| entry(item, path.to_string_lossy().to_string(), "external", span))
iter.map(|path| entry(item, path.to_string_lossy(), CommandType::External, span))
.collect()
})
.unwrap_or_default()