mirror of
https://github.com/nushell/nushell.git
synced 2024-12-01 04:43:48 +01:00
Raise error when using o>|
pipe (#13323)
# Description From the feedbacks from @amtoine , it's good to make nushell shows error for `o>|` syntax. # User-Facing Changes ## Before ```nushell 'foo' o>| print 07/09/2024 06:44:23 AM Error: nu::parser::parse_mismatch × Parse mismatch during operation. ╭─[entry #6:1:9] 1 │ 'foo' o>| print · ┬ · ╰── expected redirection target ``` ## After ```nushell 'foo' o>| print 07/09/2024 06:47:26 AM Error: nu::parser::parse_mismatch × Parse mismatch during operation. ╭─[entry #1:1:7] 1 │ 'foo' o>| print · ─┬─ · ╰── expected `|`. Redirection stdout to pipe is the same as piping directly. ╰──── ``` # Tests + Formatting Added one test --------- Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
This commit is contained in:
parent
e98b2ceb8c
commit
1964dacaef
@ -580,7 +580,10 @@ fn lex_internal(
|
|||||||
// If the next character is non-newline whitespace, skip it.
|
// If the next character is non-newline whitespace, skip it.
|
||||||
curr_offset += 1;
|
curr_offset += 1;
|
||||||
} else {
|
} else {
|
||||||
let token = try_lex_special_piped_item(input, &mut curr_offset, span_offset);
|
let (token, err) = try_lex_special_piped_item(input, &mut curr_offset, span_offset);
|
||||||
|
if error.is_none() {
|
||||||
|
error = err;
|
||||||
|
}
|
||||||
if let Some(token) = token {
|
if let Some(token) = token {
|
||||||
output.push(token);
|
output.push(token);
|
||||||
is_complete = false;
|
is_complete = false;
|
||||||
@ -614,40 +617,60 @@ fn try_lex_special_piped_item(
|
|||||||
input: &[u8],
|
input: &[u8],
|
||||||
curr_offset: &mut usize,
|
curr_offset: &mut usize,
|
||||||
span_offset: usize,
|
span_offset: usize,
|
||||||
) -> Option<Token> {
|
) -> (Option<Token>, Option<ParseError>) {
|
||||||
let c = input[*curr_offset];
|
let c = input[*curr_offset];
|
||||||
let e_pipe_len = 3;
|
let e_pipe_len = 3;
|
||||||
let eo_pipe_len = 5;
|
let eo_pipe_len = 5;
|
||||||
|
let o_pipe_len = 3;
|
||||||
let offset = *curr_offset;
|
let offset = *curr_offset;
|
||||||
if c == b'e' {
|
if c == b'e' {
|
||||||
// expect `e>|`
|
// expect `e>|`
|
||||||
if (offset + e_pipe_len <= input.len()) && (&input[offset..offset + e_pipe_len] == b"e>|") {
|
if (offset + e_pipe_len <= input.len()) && (&input[offset..offset + e_pipe_len] == b"e>|") {
|
||||||
*curr_offset += e_pipe_len;
|
*curr_offset += e_pipe_len;
|
||||||
return Some(Token::new(
|
return (
|
||||||
|
Some(Token::new(
|
||||||
TokenContents::ErrGreaterPipe,
|
TokenContents::ErrGreaterPipe,
|
||||||
Span::new(span_offset + offset, span_offset + offset + e_pipe_len),
|
Span::new(span_offset + offset, span_offset + offset + e_pipe_len),
|
||||||
));
|
)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (offset + eo_pipe_len <= input.len())
|
if (offset + eo_pipe_len <= input.len())
|
||||||
&& (&input[offset..offset + eo_pipe_len] == b"e+o>|")
|
&& (&input[offset..offset + eo_pipe_len] == b"e+o>|")
|
||||||
{
|
{
|
||||||
*curr_offset += eo_pipe_len;
|
*curr_offset += eo_pipe_len;
|
||||||
return Some(Token::new(
|
return (
|
||||||
|
Some(Token::new(
|
||||||
TokenContents::OutErrGreaterPipe,
|
TokenContents::OutErrGreaterPipe,
|
||||||
Span::new(span_offset + offset, span_offset + offset + eo_pipe_len),
|
Span::new(span_offset + offset, span_offset + offset + eo_pipe_len),
|
||||||
));
|
)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if c == b'o' {
|
} else if c == b'o' {
|
||||||
|
// indicates an error if user happened to type `o>|`
|
||||||
|
if offset + o_pipe_len <= input.len() && (&input[offset..offset + o_pipe_len] == b"o>|") {
|
||||||
|
return (
|
||||||
|
None,
|
||||||
|
Some(ParseError::Expected(
|
||||||
|
"`|`. Redirecting stdout to a pipe is the same as normal piping.",
|
||||||
|
Span::new(span_offset + offset, span_offset + offset + o_pipe_len),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
// it can be the following case: `o+e>|`
|
// it can be the following case: `o+e>|`
|
||||||
if (offset + eo_pipe_len <= input.len())
|
if (offset + eo_pipe_len <= input.len())
|
||||||
&& (&input[offset..offset + eo_pipe_len] == b"o+e>|")
|
&& (&input[offset..offset + eo_pipe_len] == b"o+e>|")
|
||||||
{
|
{
|
||||||
*curr_offset += eo_pipe_len;
|
*curr_offset += eo_pipe_len;
|
||||||
return Some(Token::new(
|
return (
|
||||||
|
Some(Token::new(
|
||||||
TokenContents::OutErrGreaterPipe,
|
TokenContents::OutErrGreaterPipe,
|
||||||
Span::new(span_offset + offset, span_offset + offset + eo_pipe_len),
|
Span::new(span_offset + offset, span_offset + offset + eo_pipe_len),
|
||||||
));
|
)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
(None, None)
|
||||||
}
|
}
|
||||||
|
@ -1161,3 +1161,11 @@ fn command_not_found_error_shows_not_found_2() {
|
|||||||
&& actual.err.contains("Did you mean `for`?")
|
&& actual.err.contains("Did you mean `for`?")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn error_on_out_greater_pipe() {
|
||||||
|
let actual = nu!(r#""foo" o>| print"#);
|
||||||
|
assert!(actual
|
||||||
|
.err
|
||||||
|
.contains("Redirecting stdout to a pipe is the same as normal piping"))
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user