mirror of
https://github.com/nushell/nushell
synced 2025-01-28 21:05:48 +00:00
Change import pattern delimiter to space
Subcommands and module imports will have the same syntax now.
This commit is contained in:
parent
595fc7a7f6
commit
bd6c550470
4 changed files with 53 additions and 81 deletions
|
@ -15,7 +15,7 @@ impl Command for Use {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> nu_protocol::Signature {
|
fn signature(&self) -> nu_protocol::Signature {
|
||||||
Signature::build("use").required("pattern", SyntaxShape::String, "import pattern")
|
Signature::build("use").rest("pattern", SyntaxShape::String, "import pattern parts")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
|
|
|
@ -495,7 +495,7 @@ pub fn parse_use(
|
||||||
let (module_name_expr, err) = parse_string(working_set, spans[1]);
|
let (module_name_expr, err) = parse_string(working_set, spans[1]);
|
||||||
error = error.or(err);
|
error = error.or(err);
|
||||||
|
|
||||||
let (import_pattern, err) = parse_import_pattern(working_set, spans[1]);
|
let (import_pattern, err) = parse_import_pattern(working_set, &spans[1..]);
|
||||||
error = error.or(err);
|
error = error.or(err);
|
||||||
|
|
||||||
let (import_pattern, exports) =
|
let (import_pattern, exports) =
|
||||||
|
@ -548,8 +548,7 @@ pub fn parse_use(
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, id)| {
|
.map(|(name, id)| {
|
||||||
let mut new_name = import_pattern.head.to_vec();
|
let mut new_name = import_pattern.head.to_vec();
|
||||||
new_name.push(b':');
|
new_name.push(b' ');
|
||||||
new_name.push(b':');
|
|
||||||
new_name.extend(&name);
|
new_name.extend(&name);
|
||||||
(new_name, id)
|
(new_name, id)
|
||||||
})
|
})
|
||||||
|
@ -634,7 +633,7 @@ pub fn parse_hide(
|
||||||
let (name_expr, err) = parse_string(working_set, spans[1]);
|
let (name_expr, err) = parse_string(working_set, spans[1]);
|
||||||
error = error.or(err);
|
error = error.or(err);
|
||||||
|
|
||||||
let (import_pattern, err) = parse_import_pattern(working_set, spans[1]);
|
let (import_pattern, err) = parse_import_pattern(working_set, &spans[1..]);
|
||||||
error = error.or(err);
|
error = error.or(err);
|
||||||
|
|
||||||
let exported_names: Vec<Vec<u8>> =
|
let exported_names: Vec<Vec<u8>> =
|
||||||
|
@ -664,8 +663,7 @@ pub fn parse_hide(
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|name| {
|
.map(|name| {
|
||||||
let mut new_name = import_pattern.head.to_vec();
|
let mut new_name = import_pattern.head.to_vec();
|
||||||
new_name.push(b':');
|
new_name.push(b' ');
|
||||||
new_name.push(b':');
|
|
||||||
new_name.extend(&name);
|
new_name.extend(&name);
|
||||||
new_name
|
new_name
|
||||||
})
|
})
|
||||||
|
@ -676,8 +674,7 @@ pub fn parse_hide(
|
||||||
.filter(|n| n == name)
|
.filter(|n| n == name)
|
||||||
.map(|n| {
|
.map(|n| {
|
||||||
let mut new_name = import_pattern.head.to_vec();
|
let mut new_name = import_pattern.head.to_vec();
|
||||||
new_name.push(b':');
|
new_name.push(b' ');
|
||||||
new_name.push(b':');
|
|
||||||
new_name.extend(&n);
|
new_name.extend(&n);
|
||||||
new_name
|
new_name
|
||||||
})
|
})
|
||||||
|
@ -698,8 +695,7 @@ pub fn parse_hide(
|
||||||
.filter_map(|n| if n == name { Some(n.clone()) } else { None })
|
.filter_map(|n| if n == name { Some(n.clone()) } else { None })
|
||||||
.map(|n| {
|
.map(|n| {
|
||||||
let mut new_name = import_pattern.head.to_vec();
|
let mut new_name = import_pattern.head.to_vec();
|
||||||
new_name.push(b':');
|
new_name.push(b' ');
|
||||||
new_name.push(b':');
|
|
||||||
new_name.extend(n);
|
new_name.extend(n);
|
||||||
new_name
|
new_name
|
||||||
})
|
})
|
||||||
|
|
|
@ -1693,70 +1693,54 @@ 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,
|
||||||
span: Span,
|
spans: &[Span],
|
||||||
) -> (ImportPattern, Option<ParseError>) {
|
) -> (ImportPattern, Option<ParseError>) {
|
||||||
let source = working_set.get_span_contents(span);
|
|
||||||
let mut error = None;
|
let mut error = None;
|
||||||
|
|
||||||
let (tokens, err) = lex(source, span.start, &[], &[b':']);
|
// return (
|
||||||
error = error.or(err);
|
// ImportPattern {
|
||||||
|
// head: vec![],
|
||||||
|
// members: vec![],
|
||||||
|
// },
|
||||||
|
// Some(ParseError::MissingImportPattern(span)),
|
||||||
|
// );
|
||||||
|
|
||||||
if tokens.is_empty() {
|
// return (
|
||||||
return (
|
// ImportPattern {
|
||||||
ImportPattern {
|
// head: vec![],
|
||||||
head: vec![],
|
// members: vec![],
|
||||||
members: vec![],
|
// },
|
||||||
},
|
// Some(ParseError::WrongImportPattern(span)),
|
||||||
Some(ParseError::MissingImportPattern(span)),
|
// );
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can have either "head" or "head::tail"
|
let head = if let Some(head_span) = spans.get(0) {
|
||||||
if (tokens.len() != 1) && (tokens.len() != 4) {
|
let (head_expr, err) = parse_string(working_set, *head_span);
|
||||||
return (
|
error = error.or(err);
|
||||||
ImportPattern {
|
working_set.get_span_contents(head_expr.span).to_vec()
|
||||||
head: vec![],
|
|
||||||
members: vec![],
|
|
||||||
},
|
|
||||||
Some(ParseError::WrongImportPattern(span)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the second : of the :: is really a :
|
|
||||||
let has_second_colon = if let Some(t) = tokens.get(2) {
|
|
||||||
let potential_colon = working_set.get_span_contents(t.span);
|
|
||||||
potential_colon == b":"
|
|
||||||
} else {
|
} else {
|
||||||
false
|
return (
|
||||||
|
ImportPattern {
|
||||||
|
head: vec![],
|
||||||
|
members: vec![],
|
||||||
|
},
|
||||||
|
Some(ParseError::WrongImportPattern(span(spans))),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (tokens.len() == 4) && !has_second_colon {
|
if let Some(tail_span) = spans.get(1) {
|
||||||
// Applies only to the "head::tail" structure; "head" only doesn't have :
|
|
||||||
return (
|
|
||||||
ImportPattern {
|
|
||||||
head: vec![],
|
|
||||||
members: vec![],
|
|
||||||
},
|
|
||||||
Some(ParseError::WrongImportPattern(span)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let head = working_set.get_span_contents(tokens[0].span).to_vec();
|
|
||||||
|
|
||||||
if let Some(tail) = tokens.get(3) {
|
|
||||||
// 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_span = tail.span;
|
let tail = working_set.get_span_contents(*tail_span);
|
||||||
let tail = working_set.get_span_contents(tail.span);
|
|
||||||
if tail == b"*" {
|
if tail == b"*" {
|
||||||
(
|
(
|
||||||
ImportPattern {
|
ImportPattern {
|
||||||
head,
|
head,
|
||||||
members: vec![ImportPatternMember::Glob { span: tail_span }],
|
members: vec![ImportPatternMember::Glob { span: *tail_span }],
|
||||||
},
|
},
|
||||||
error,
|
error,
|
||||||
)
|
)
|
||||||
} else if tail.starts_with(b"[") {
|
} else if tail.starts_with(b"[") {
|
||||||
let (result, err) = parse_list_expression(working_set, tail_span, &SyntaxShape::String);
|
let (result, err) =
|
||||||
|
parse_list_expression(working_set, *tail_span, &SyntaxShape::String);
|
||||||
error = error.or(err);
|
error = error.or(err);
|
||||||
|
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
|
@ -1793,7 +1777,7 @@ pub fn parse_import_pattern(
|
||||||
head,
|
head,
|
||||||
members: vec![ImportPatternMember::Name {
|
members: vec![ImportPatternMember::Name {
|
||||||
name: tail.to_vec(),
|
name: tail.to_vec(),
|
||||||
span: tail_span,
|
span: *tail_span,
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
error,
|
error,
|
||||||
|
|
36
src/tests.rs
36
src/tests.rs
|
@ -389,7 +389,7 @@ fn better_block_types() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn module_imports_1() -> TestResult {
|
fn module_imports_1() -> TestResult {
|
||||||
run_test(
|
run_test(
|
||||||
r#"module foo { export def a [] { 1 }; def b [] { 2 } }; use foo; foo::a"#,
|
r#"module foo { export def a [] { 1 }; def b [] { 2 } }; use foo; foo a"#,
|
||||||
"1",
|
"1",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -397,7 +397,7 @@ fn module_imports_1() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn module_imports_2() -> TestResult {
|
fn module_imports_2() -> TestResult {
|
||||||
run_test(
|
run_test(
|
||||||
r#"module foo { export def a [] { 1 }; def b [] { 2 } }; use foo::a; a"#,
|
r#"module foo { export def a [] { 1 }; def b [] { 2 } }; use foo a; a"#,
|
||||||
"1",
|
"1",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -405,7 +405,7 @@ fn module_imports_2() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn module_imports_3() -> TestResult {
|
fn module_imports_3() -> TestResult {
|
||||||
run_test(
|
run_test(
|
||||||
r#"module foo { export def a [] { 1 }; export def b [] { 2 } }; use foo::*; b"#,
|
r#"module foo { export def a [] { 1 }; export def b [] { 2 } }; use foo *; b"#,
|
||||||
"2",
|
"2",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -413,7 +413,7 @@ fn module_imports_3() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn module_imports_4() -> TestResult {
|
fn module_imports_4() -> TestResult {
|
||||||
fail_test(
|
fail_test(
|
||||||
r#"module foo { export def a [] { 1 }; export def b [] { 2 } }; use foo::c"#,
|
r#"module foo { export def a [] { 1 }; export def b [] { 2 } }; use foo c"#,
|
||||||
"not find import",
|
"not find import",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -421,7 +421,7 @@ fn module_imports_4() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn module_imports_5() -> TestResult {
|
fn module_imports_5() -> TestResult {
|
||||||
run_test(
|
run_test(
|
||||||
r#"module foo { export def a [] { 1 }; def b [] { 2 }; export def c [] { 3 } }; use foo::[a, c]; c"#,
|
r#"module foo { export def a [] { 1 }; def b [] { 2 }; export def c [] { 3 } }; use foo [a, c]; c"#,
|
||||||
"3",
|
"3",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -429,7 +429,7 @@ fn module_imports_5() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn module_import_uses_internal_command() -> TestResult {
|
fn module_import_uses_internal_command() -> TestResult {
|
||||||
run_test(
|
run_test(
|
||||||
r#"module foo { def b [] { 2 }; export def a [] { b } }; use foo; foo::a"#,
|
r#"module foo { def b [] { 2 }; export def a [] { b } }; use foo; foo a"#,
|
||||||
"2",
|
"2",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -442,14 +442,6 @@ fn module_import_does_not_parse_with_incorrect_delimiter() -> TestResult {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn module_import_does_not_parse_with_missing_tail() -> TestResult {
|
|
||||||
fail_test(
|
|
||||||
r#"module foo { export def a [] { 1 } }; use foo::"#,
|
|
||||||
not_found_msg(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Test the use/hide tests also as separate lines in REPL (i.e., with merging the delta in between)
|
// TODO: Test the use/hide tests also as separate lines in REPL (i.e., with merging the delta in between)
|
||||||
#[test]
|
#[test]
|
||||||
fn hides_def() -> TestResult {
|
fn hides_def() -> TestResult {
|
||||||
|
@ -507,7 +499,7 @@ fn hide_twice_not_allowed() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn hides_import_1() -> TestResult {
|
fn hides_import_1() -> TestResult {
|
||||||
fail_test(
|
fail_test(
|
||||||
r#"module spam { export def foo [] { "foo" } }; use spam; hide spam::foo; foo"#,
|
r#"module spam { export def foo [] { "foo" } }; use spam; hide spam foo; foo"#,
|
||||||
not_found_msg(),
|
not_found_msg(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -515,7 +507,7 @@ fn hides_import_1() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn hides_import_2() -> TestResult {
|
fn hides_import_2() -> TestResult {
|
||||||
fail_test(
|
fail_test(
|
||||||
r#"module spam { export def foo [] { "foo" } }; use spam; hide spam::*; foo"#,
|
r#"module spam { export def foo [] { "foo" } }; use spam; hide spam *; foo"#,
|
||||||
not_found_msg(),
|
not_found_msg(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -523,7 +515,7 @@ fn hides_import_2() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn hides_import_3() -> TestResult {
|
fn hides_import_3() -> TestResult {
|
||||||
fail_test(
|
fail_test(
|
||||||
r#"module spam { export def foo [] { "foo" } }; use spam; hide spam::[foo]; foo"#,
|
r#"module spam { export def foo [] { "foo" } }; use spam; hide spam [foo]; foo"#,
|
||||||
not_found_msg(),
|
not_found_msg(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -531,7 +523,7 @@ fn hides_import_3() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn hides_import_4() -> TestResult {
|
fn hides_import_4() -> TestResult {
|
||||||
fail_test(
|
fail_test(
|
||||||
r#"module spam { export def foo [] { "foo" } }; use spam::foo; hide foo; foo"#,
|
r#"module spam { export def foo [] { "foo" } }; use spam foo; hide foo; foo"#,
|
||||||
not_found_msg(),
|
not_found_msg(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -539,7 +531,7 @@ fn hides_import_4() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn hides_import_5() -> TestResult {
|
fn hides_import_5() -> TestResult {
|
||||||
fail_test(
|
fail_test(
|
||||||
r#"module spam { export def foo [] { "foo" } }; use spam::*; hide foo; foo"#,
|
r#"module spam { export def foo [] { "foo" } }; use spam *; hide foo; foo"#,
|
||||||
not_found_msg(),
|
not_found_msg(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -555,7 +547,7 @@ fn def_twice_should_fail() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn use_import_after_hide() -> TestResult {
|
fn use_import_after_hide() -> TestResult {
|
||||||
run_test(
|
run_test(
|
||||||
r#"module spam { export def foo [] { "foo" } }; use spam::foo; hide foo; use spam::foo; foo"#,
|
r#"module spam { export def foo [] { "foo" } }; use spam foo; hide foo; use spam foo; foo"#,
|
||||||
"foo",
|
"foo",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -563,7 +555,7 @@ fn use_import_after_hide() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn hide_shadowed_decl() -> TestResult {
|
fn hide_shadowed_decl() -> TestResult {
|
||||||
run_test(
|
run_test(
|
||||||
r#"module spam { export def foo [] { "bar" } }; def foo [] { "foo" }; do { use spam::foo; hide foo; foo }"#,
|
r#"module spam { export def foo [] { "bar" } }; def foo [] { "foo" }; do { use spam foo; hide foo; foo }"#,
|
||||||
"foo",
|
"foo",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -571,7 +563,7 @@ fn hide_shadowed_decl() -> TestResult {
|
||||||
#[test]
|
#[test]
|
||||||
fn hides_all_decls_within_scope() -> TestResult {
|
fn hides_all_decls_within_scope() -> TestResult {
|
||||||
fail_test(
|
fail_test(
|
||||||
r#"module spam { export def foo [] { "bar" } }; def foo [] { "foo" }; use spam::foo; hide foo; foo"#,
|
r#"module spam { export def foo [] { "bar" } }; def foo [] { "foo" }; use spam foo; hide foo; foo"#,
|
||||||
not_found_msg(),
|
not_found_msg(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue