mirror of
https://github.com/nushell/nushell.git
synced 2025-04-29 07:34:28 +02:00
Cleanup parsing of use and hide commands (#705)
This commit is contained in:
parent
3a17b60862
commit
733b2836f1
@ -12,7 +12,7 @@ impl Command for Hide {
|
|||||||
|
|
||||||
fn signature(&self) -> nu_protocol::Signature {
|
fn signature(&self) -> nu_protocol::Signature {
|
||||||
Signature::build("hide")
|
Signature::build("hide")
|
||||||
.required("pattern", SyntaxShape::String, "import pattern")
|
.required("pattern", SyntaxShape::ImportPattern, "import pattern")
|
||||||
.category(Category::Core)
|
.category(Category::Core)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,10 @@ impl Command for Hide {
|
|||||||
{
|
{
|
||||||
output.push((name, id));
|
output.push((name, id));
|
||||||
} else if !overlay.has_decl(name) {
|
} else if !overlay.has_decl(name) {
|
||||||
return Err(ShellError::EnvVarNotFoundAtRuntime(*span));
|
return Err(ShellError::EnvVarNotFoundAtRuntime(
|
||||||
|
String::from_utf8_lossy(name).into(),
|
||||||
|
*span,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
output
|
output
|
||||||
@ -82,7 +85,10 @@ impl Command for Hide {
|
|||||||
{
|
{
|
||||||
output.push((name, id));
|
output.push((name, id));
|
||||||
} else if !overlay.has_decl(name) {
|
} else if !overlay.has_decl(name) {
|
||||||
return Err(ShellError::EnvVarNotFoundAtRuntime(*span));
|
return Err(ShellError::EnvVarNotFoundAtRuntime(
|
||||||
|
String::from_utf8_lossy(name).into(),
|
||||||
|
*span,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ impl Command for Use {
|
|||||||
|
|
||||||
fn signature(&self) -> nu_protocol::Signature {
|
fn signature(&self) -> nu_protocol::Signature {
|
||||||
Signature::build("use")
|
Signature::build("use")
|
||||||
.rest("pattern", SyntaxShape::String, "import pattern parts")
|
.required("pattern", SyntaxShape::ImportPattern, "import pattern")
|
||||||
.category(Category::Core)
|
.category(Category::Core)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,10 @@ impl Command for Use {
|
|||||||
if let Some(id) = overlay.get_env_var_id(name) {
|
if let Some(id) = overlay.get_env_var_id(name) {
|
||||||
output.push((name.clone(), id));
|
output.push((name.clone(), id));
|
||||||
} else if !overlay.has_decl(name) {
|
} else if !overlay.has_decl(name) {
|
||||||
return Err(ShellError::EnvVarNotFoundAtRuntime(*span));
|
return Err(ShellError::EnvVarNotFoundAtRuntime(
|
||||||
|
String::from_utf8_lossy(name).into(),
|
||||||
|
*span,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
output
|
output
|
||||||
@ -68,7 +71,10 @@ impl Command for Use {
|
|||||||
if let Some(id) = overlay.get_env_var_id(name) {
|
if let Some(id) = overlay.get_env_var_id(name) {
|
||||||
output.push((name.clone(), id));
|
output.push((name.clone(), id));
|
||||||
} else if !overlay.has_decl(name) {
|
} else if !overlay.has_decl(name) {
|
||||||
return Err(ShellError::EnvVarNotFoundAtRuntime(*span));
|
return Err(ShellError::EnvVarNotFoundAtRuntime(
|
||||||
|
String::from_utf8_lossy(name).into(),
|
||||||
|
*span,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +100,17 @@ impl Command for Use {
|
|||||||
stack.add_env_var(name, val);
|
stack.add_env_var(name, val);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(ShellError::EnvVarNotFoundAtRuntime(call.positional[0].span));
|
// TODO: This is a workaround since call.positional[0].span points at 0 for some reason
|
||||||
|
// when this error is triggered
|
||||||
|
let bytes = engine_state.get_span_contents(&call.positional[0].span);
|
||||||
|
return Err(ShellError::SpannedLabeledError(
|
||||||
|
format!(
|
||||||
|
"Could not use '{}' import pattern",
|
||||||
|
String::from_utf8_lossy(bytes)
|
||||||
|
),
|
||||||
|
"called here".to_string(),
|
||||||
|
call.head,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(PipelineData::new(call.head))
|
Ok(PipelineData::new(call.head))
|
||||||
|
@ -13,8 +13,8 @@ use crate::{
|
|||||||
lex, lite_parse,
|
lex, lite_parse,
|
||||||
parser::{
|
parser::{
|
||||||
check_call, check_name, garbage, garbage_statement, parse, parse_block_expression,
|
check_call, check_name, garbage, garbage_statement, parse, parse_block_expression,
|
||||||
parse_import_pattern, parse_internal_call, parse_multispan_value, parse_signature,
|
parse_internal_call, parse_multispan_value, parse_signature, parse_string,
|
||||||
parse_string, parse_var_with_opt_type, trim_quotes,
|
parse_var_with_opt_type, trim_quotes,
|
||||||
},
|
},
|
||||||
ParseError,
|
ParseError,
|
||||||
};
|
};
|
||||||
@ -636,21 +636,77 @@ pub fn parse_use(
|
|||||||
working_set: &mut StateWorkingSet,
|
working_set: &mut StateWorkingSet,
|
||||||
spans: &[Span],
|
spans: &[Span],
|
||||||
) -> (Statement, Option<ParseError>) {
|
) -> (Statement, Option<ParseError>) {
|
||||||
let mut error = None;
|
if working_set.get_span_contents(spans[0]) != b"use" {
|
||||||
let bytes = working_set.get_span_contents(spans[0]);
|
return (
|
||||||
|
garbage_statement(spans),
|
||||||
if bytes == b"use" && spans.len() >= 2 {
|
Some(ParseError::UnknownState(
|
||||||
let cwd = working_set.get_cwd();
|
"internal error: Wrong call name for 'use' command".into(),
|
||||||
for span in spans[1..].iter() {
|
span(spans),
|
||||||
let (_, err) = parse_string(working_set, *span);
|
)),
|
||||||
error = error.or(err);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (call, call_span, use_decl_id) = match working_set.find_decl(b"use") {
|
||||||
|
Some(decl_id) => {
|
||||||
|
let (call, mut err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||||
|
let decl = working_set.get_decl(decl_id);
|
||||||
|
|
||||||
|
let call_span = span(spans);
|
||||||
|
|
||||||
|
err = check_call(call_span, &decl.signature(), &call).or(err);
|
||||||
|
if err.is_some() || call.has_flag("help") {
|
||||||
|
return (
|
||||||
|
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||||
|
expr: Expr::Call(call),
|
||||||
|
span: call_span,
|
||||||
|
ty: Type::Unknown,
|
||||||
|
custom_completion: None,
|
||||||
|
}])),
|
||||||
|
err,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
(call, call_span, decl_id)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return (
|
||||||
|
garbage_statement(spans),
|
||||||
|
Some(ParseError::UnknownState(
|
||||||
|
"internal error: 'use' declaration not found".into(),
|
||||||
|
span(spans),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let import_pattern = if let Some(expr) = call.nth(0) {
|
||||||
|
if let Some(pattern) = expr.as_import_pattern() {
|
||||||
|
pattern
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
garbage_statement(spans),
|
||||||
|
Some(ParseError::UnknownState(
|
||||||
|
"internal error: Import pattern positional is not import pattern".into(),
|
||||||
|
call_span,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
garbage_statement(spans),
|
||||||
|
Some(ParseError::UnknownState(
|
||||||
|
"internal error: Missing required positional after call parsing".into(),
|
||||||
|
call_span,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
let cwd = working_set.get_cwd();
|
||||||
|
|
||||||
|
let mut error = None;
|
||||||
|
|
||||||
// TODO: Add checking for importing too long import patterns, e.g.:
|
// TODO: Add checking for importing too long import patterns, e.g.:
|
||||||
// > use spam foo non existent names here do not throw error
|
// > use spam foo non existent names here do not throw error
|
||||||
let (import_pattern, err) = parse_import_pattern(working_set, &spans[1..]);
|
|
||||||
error = error.or(err);
|
|
||||||
|
|
||||||
let (import_pattern, overlay) =
|
let (import_pattern, overlay) =
|
||||||
if let Some(overlay_id) = working_set.find_overlay(&import_pattern.head.name) {
|
if let Some(overlay_id) = working_set.find_overlay(&import_pattern.head.name) {
|
||||||
(import_pattern, working_set.get_overlay(overlay_id).clone())
|
(import_pattern, working_set.get_overlay(overlay_id).clone())
|
||||||
@ -663,7 +719,12 @@ pub fn parse_use(
|
|||||||
stem.to_string_lossy().to_string()
|
stem.to_string_lossy().to_string()
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
garbage_statement(spans),
|
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||||
|
expr: Expr::Call(call),
|
||||||
|
span: call_span,
|
||||||
|
ty: Type::Unknown,
|
||||||
|
custom_completion: None,
|
||||||
|
}])),
|
||||||
Some(ParseError::ModuleNotFound(spans[1])),
|
Some(ParseError::ModuleNotFound(spans[1])),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -693,7 +754,12 @@ pub fn parse_use(
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
garbage_statement(spans),
|
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||||
|
expr: Expr::Call(call),
|
||||||
|
span: call_span,
|
||||||
|
ty: Type::Unknown,
|
||||||
|
custom_completion: None,
|
||||||
|
}])),
|
||||||
Some(ParseError::ModuleNotFound(spans[1])),
|
Some(ParseError::ModuleNotFound(spans[1])),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -748,11 +814,7 @@ pub fn parse_use(
|
|||||||
// Extend the current scope with the module's overlay
|
// Extend the current scope with the module's overlay
|
||||||
working_set.use_decls(decls_to_use);
|
working_set.use_decls(decls_to_use);
|
||||||
|
|
||||||
// Create the Use command call
|
// Create a new Use command call to pass the new import pattern
|
||||||
let use_decl_id = working_set
|
|
||||||
.find_decl(b"use")
|
|
||||||
.expect("internal error: missing use command");
|
|
||||||
|
|
||||||
let import_pattern_expr = Expression {
|
let import_pattern_expr = Expression {
|
||||||
expr: Expr::ImportPattern(import_pattern),
|
expr: Expr::ImportPattern(import_pattern),
|
||||||
span: span(&spans[1..]),
|
span: span(&spans[1..]),
|
||||||
@ -776,21 +838,77 @@ pub fn parse_use(
|
|||||||
}])),
|
}])),
|
||||||
error,
|
error,
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
(
|
|
||||||
garbage_statement(spans),
|
|
||||||
Some(ParseError::UnknownState(
|
|
||||||
"Expected structure: use <name>".into(),
|
|
||||||
span(spans),
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_hide(
|
pub fn parse_hide(
|
||||||
working_set: &mut StateWorkingSet,
|
working_set: &mut StateWorkingSet,
|
||||||
spans: &[Span],
|
spans: &[Span],
|
||||||
) -> (Statement, Option<ParseError>) {
|
) -> (Statement, Option<ParseError>) {
|
||||||
|
if working_set.get_span_contents(spans[0]) != b"hide" {
|
||||||
|
return (
|
||||||
|
garbage_statement(spans),
|
||||||
|
Some(ParseError::UnknownState(
|
||||||
|
"internal error: Wrong call name for 'hide' command".into(),
|
||||||
|
span(spans),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (call, call_span, hide_decl_id) = match working_set.find_decl(b"hide") {
|
||||||
|
Some(decl_id) => {
|
||||||
|
let (call, mut err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||||
|
let decl = working_set.get_decl(decl_id);
|
||||||
|
|
||||||
|
let call_span = span(spans);
|
||||||
|
|
||||||
|
err = check_call(call_span, &decl.signature(), &call).or(err);
|
||||||
|
if err.is_some() || call.has_flag("help") {
|
||||||
|
return (
|
||||||
|
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||||
|
expr: Expr::Call(call),
|
||||||
|
span: call_span,
|
||||||
|
ty: Type::Unknown,
|
||||||
|
custom_completion: None,
|
||||||
|
}])),
|
||||||
|
err,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
(call, call_span, decl_id)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return (
|
||||||
|
garbage_statement(spans),
|
||||||
|
Some(ParseError::UnknownState(
|
||||||
|
"internal error: 'hide' declaration not found".into(),
|
||||||
|
span(spans),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let import_pattern = if let Some(expr) = call.nth(0) {
|
||||||
|
if let Some(pattern) = expr.as_import_pattern() {
|
||||||
|
pattern
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
garbage_statement(spans),
|
||||||
|
Some(ParseError::UnknownState(
|
||||||
|
"internal error: Import pattern positional is not import pattern".into(),
|
||||||
|
call_span,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
garbage_statement(spans),
|
||||||
|
Some(ParseError::UnknownState(
|
||||||
|
"internal error: Missing required positional after call parsing".into(),
|
||||||
|
call_span,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
let mut error = None;
|
let mut error = None;
|
||||||
let bytes = working_set.get_span_contents(spans[0]);
|
let bytes = working_set.get_span_contents(spans[0]);
|
||||||
|
|
||||||
@ -800,9 +918,6 @@ pub fn parse_hide(
|
|||||||
error = error.or(err);
|
error = error.or(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (import_pattern, err) = parse_import_pattern(working_set, &spans[1..]);
|
|
||||||
error = error.or(err);
|
|
||||||
|
|
||||||
let (is_module, overlay) =
|
let (is_module, overlay) =
|
||||||
if let Some(overlay_id) = working_set.find_overlay(&import_pattern.head.name) {
|
if let Some(overlay_id) = working_set.find_overlay(&import_pattern.head.name) {
|
||||||
(true, working_set.get_overlay(overlay_id).clone())
|
(true, working_set.get_overlay(overlay_id).clone())
|
||||||
@ -881,11 +996,7 @@ pub fn parse_hide(
|
|||||||
let import_pattern = import_pattern
|
let import_pattern = import_pattern
|
||||||
.with_hidden(decls_to_hide.iter().map(|(name, _)| name.clone()).collect());
|
.with_hidden(decls_to_hide.iter().map(|(name, _)| name.clone()).collect());
|
||||||
|
|
||||||
// Create the Hide command call
|
// Create a new Use command call to pass the new import pattern
|
||||||
let hide_decl_id = working_set
|
|
||||||
.find_decl(b"hide")
|
|
||||||
.expect("internal error: missing hide command");
|
|
||||||
|
|
||||||
let import_pattern_expr = Expression {
|
let import_pattern_expr = Expression {
|
||||||
expr: Expr::ImportPattern(import_pattern),
|
expr: Expr::ImportPattern(import_pattern),
|
||||||
span: span(&spans[1..]),
|
span: span(&spans[1..]),
|
||||||
|
@ -481,6 +481,15 @@ pub fn parse_multispan_value(
|
|||||||
|
|
||||||
(arg, error)
|
(arg, error)
|
||||||
}
|
}
|
||||||
|
SyntaxShape::ImportPattern => {
|
||||||
|
trace!("parsing: import pattern");
|
||||||
|
|
||||||
|
let (arg, err) = parse_import_pattern(working_set, &spans[*spans_idx..]);
|
||||||
|
error = error.or(err);
|
||||||
|
*spans_idx = spans.len() - 1;
|
||||||
|
|
||||||
|
(arg, error)
|
||||||
|
}
|
||||||
SyntaxShape::Keyword(keyword, arg) => {
|
SyntaxShape::Keyword(keyword, arg) => {
|
||||||
trace!(
|
trace!(
|
||||||
"parsing: keyword({}) {:?}",
|
"parsing: keyword({}) {:?}",
|
||||||
@ -1951,7 +1960,7 @@ pub fn parse_type(_working_set: &StateWorkingSet, bytes: &[u8]) -> Type {
|
|||||||
pub fn parse_import_pattern(
|
pub fn parse_import_pattern(
|
||||||
working_set: &mut StateWorkingSet,
|
working_set: &mut StateWorkingSet,
|
||||||
spans: &[Span],
|
spans: &[Span],
|
||||||
) -> (ImportPattern, Option<ParseError>) {
|
) -> (Expression, Option<ParseError>) {
|
||||||
let mut error = None;
|
let mut error = None;
|
||||||
|
|
||||||
let (head, head_span) = if let Some(head_span) = spans.get(0) {
|
let (head, head_span) = if let Some(head_span) = spans.get(0) {
|
||||||
@ -1961,19 +1970,12 @@ pub fn parse_import_pattern(
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
ImportPattern {
|
garbage(span(spans)),
|
||||||
head: ImportPatternHead {
|
|
||||||
name: vec![],
|
|
||||||
span: span(spans),
|
|
||||||
},
|
|
||||||
members: vec![],
|
|
||||||
hidden: HashSet::new(),
|
|
||||||
},
|
|
||||||
Some(ParseError::WrongImportPattern(span(spans))),
|
Some(ParseError::WrongImportPattern(span(spans))),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(tail_span) = spans.get(1) {
|
let (import_pattern, err) = if let Some(tail_span) = spans.get(1) {
|
||||||
// FIXME: expand this to handle deeper imports once we support module imports
|
// FIXME: expand this to handle deeper imports once we support module imports
|
||||||
let tail = working_set.get_span_contents(*tail_span);
|
let tail = working_set.get_span_contents(*tail_span);
|
||||||
if tail == b"*" {
|
if tail == b"*" {
|
||||||
@ -1986,7 +1988,7 @@ pub fn parse_import_pattern(
|
|||||||
members: vec![ImportPatternMember::Glob { span: *tail_span }],
|
members: vec![ImportPatternMember::Glob { span: *tail_span }],
|
||||||
hidden: HashSet::new(),
|
hidden: HashSet::new(),
|
||||||
},
|
},
|
||||||
error,
|
None,
|
||||||
)
|
)
|
||||||
} else if tail.starts_with(b"[") {
|
} else if tail.starts_with(b"[") {
|
||||||
let (result, err) =
|
let (result, err) =
|
||||||
@ -2014,7 +2016,7 @@ pub fn parse_import_pattern(
|
|||||||
members: vec![ImportPatternMember::List { names: output }],
|
members: vec![ImportPatternMember::List { names: output }],
|
||||||
hidden: HashSet::new(),
|
hidden: HashSet::new(),
|
||||||
},
|
},
|
||||||
error,
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => (
|
_ => (
|
||||||
@ -2043,7 +2045,7 @@ pub fn parse_import_pattern(
|
|||||||
}],
|
}],
|
||||||
hidden: HashSet::new(),
|
hidden: HashSet::new(),
|
||||||
},
|
},
|
||||||
error,
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2058,7 +2060,17 @@ pub fn parse_import_pattern(
|
|||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
}
|
};
|
||||||
|
|
||||||
|
(
|
||||||
|
Expression {
|
||||||
|
expr: Expr::ImportPattern(import_pattern),
|
||||||
|
span: span(&spans[1..]),
|
||||||
|
ty: Type::List(Box::new(Type::String)),
|
||||||
|
custom_completion: None,
|
||||||
|
},
|
||||||
|
error.or(err),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_var_with_opt_type(
|
pub fn parse_var_with_opt_type(
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::{Expr, Operator, Statement};
|
use super::{Expr, Operator, Statement};
|
||||||
|
use crate::ast::ImportPattern;
|
||||||
use crate::{engine::StateWorkingSet, BlockId, Signature, Span, Type, VarId, IN_VARIABLE_ID};
|
use crate::{engine::StateWorkingSet, BlockId, Signature, Span, Type, VarId, IN_VARIABLE_ID};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -96,6 +97,13 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_import_pattern(&self) -> Option<ImportPattern> {
|
||||||
|
match &self.expr {
|
||||||
|
Expr::ImportPattern(pattern) => Some(pattern.clone()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn has_in_variable(&self, working_set: &StateWorkingSet) -> bool {
|
pub fn has_in_variable(&self, working_set: &StateWorkingSet) -> bool {
|
||||||
match &self.expr {
|
match &self.expr {
|
||||||
Expr::BinaryOp(left, _, right) => {
|
Expr::BinaryOp(left, _, right) => {
|
||||||
|
@ -95,9 +95,9 @@ pub enum ShellError {
|
|||||||
#[diagnostic(code(nu::shell::variable_not_found), url(docsrs))]
|
#[diagnostic(code(nu::shell::variable_not_found), url(docsrs))]
|
||||||
VariableNotFoundAtRuntime(#[label = "variable not found"] Span),
|
VariableNotFoundAtRuntime(#[label = "variable not found"] Span),
|
||||||
|
|
||||||
#[error("Environment variable not found")]
|
#[error("Environment variable '{0}' not found")]
|
||||||
#[diagnostic(code(nu::shell::env_variable_not_found), url(docsrs))]
|
#[diagnostic(code(nu::shell::env_variable_not_found), url(docsrs))]
|
||||||
EnvVarNotFoundAtRuntime(#[label = "environment variable not found"] Span),
|
EnvVarNotFoundAtRuntime(String, #[label = "environment variable not found"] Span),
|
||||||
|
|
||||||
#[error("Not found.")]
|
#[error("Not found.")]
|
||||||
#[diagnostic(code(nu::parser::not_found), url(docsrs))]
|
#[diagnostic(code(nu::parser::not_found), url(docsrs))]
|
||||||
|
Loading…
Reference in New Issue
Block a user