From a4a8f5df54cf44e248036fff805b546e98562edd Mon Sep 17 00:00:00 2001 From: JT <547158+jntrnr@users.noreply.github.com> Date: Sat, 5 Mar 2022 08:20:13 -0500 Subject: [PATCH] Add more multiline pipeline forms (#4740) --- crates/nu-parser/src/lex.rs | 36 ++++++++++++--- tests/main.rs | 1 + tests/parsing/mod.rs | 46 +++++++++++++++++++ tests/parsing/samples/multiline_end_pipe.nu | 2 + .../parsing/samples/multiline_end_pipe_win.nu | 2 + tests/parsing/samples/multiline_start_pipe.nu | 2 + .../samples/multiline_start_pipe_win.nu | 2 + tests/parsing/samples/single_line.nu | 1 + 8 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 tests/parsing/mod.rs create mode 100644 tests/parsing/samples/multiline_end_pipe.nu create mode 100644 tests/parsing/samples/multiline_end_pipe_win.nu create mode 100644 tests/parsing/samples/multiline_start_pipe.nu create mode 100644 tests/parsing/samples/multiline_start_pipe_win.nu create mode 100644 tests/parsing/samples/single_line.nu diff --git a/crates/nu-parser/src/lex.rs b/crates/nu-parser/src/lex.rs index 5d0916326b..c8a5aa8f93 100644 --- a/crates/nu-parser/src/lex.rs +++ b/crates/nu-parser/src/lex.rs @@ -243,7 +243,6 @@ pub fn lex( let c = *c; if c == b'|' { // If the next character is `|`, it's either `|` or `||`. - let idx = curr_offset; let prev_idx = idx; curr_offset += 1; @@ -262,10 +261,31 @@ pub fn lex( } // Otherwise, it's just a regular `|` token. - output.push(Token::new( - TokenContents::Pipe, - Span::new(span_offset + idx, span_offset + idx + 1), - )); + + // Before we push, check to see if the previous character was a newline. + // If so, then this is a continuation of the previous line + if let Some(prev) = output.last_mut() { + match prev.contents { + TokenContents::Eol => { + *prev = Token::new( + TokenContents::Pipe, + Span::new(span_offset + idx, span_offset + idx + 1), + ) + } + _ => { + output.push(Token::new( + TokenContents::Pipe, + Span::new(span_offset + idx, span_offset + idx + 1), + )); + } + } + } else { + output.push(Token::new( + TokenContents::Pipe, + Span::new(span_offset + idx, span_offset + idx + 1), + )); + } + is_complete = false; } else if c == b';' { // If the next character is a `;`, we're looking at a semicolon token. @@ -282,9 +302,11 @@ pub fn lex( TokenContents::Semicolon, Span::new(span_offset + idx, span_offset + idx + 1), )); - } else if c == b'\n' || c == b'\r' { + } else if c == b'\r' { + // Ignore a stand-alone carriage return + curr_offset += 1; + } else if c == b'\n' { // If the next character is a newline, we're looking at an EOL (end of line) token. - let idx = curr_offset; curr_offset += 1; if !additional_whitespace.contains(&c) { diff --git a/tests/main.rs b/tests/main.rs index 30f5e27fe2..600cb50742 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -1,5 +1,6 @@ extern crate nu_test_support; +mod parsing; mod path; mod plugins; mod shell; diff --git a/tests/parsing/mod.rs b/tests/parsing/mod.rs new file mode 100644 index 0000000000..9915b76242 --- /dev/null +++ b/tests/parsing/mod.rs @@ -0,0 +1,46 @@ +use nu_test_support::nu; + +#[test] +fn run_nu_script_single_line() { + let actual = nu!(cwd: "tests/parsing/samples", r#" + nu single_line.nu + "#); + + assert_eq!(actual.out, "5"); +} + +#[test] +fn run_nu_script_multiline_start_pipe() { + let actual = nu!(cwd: "tests/parsing/samples", r#" + nu multiline_start_pipe.nu + "#); + + assert_eq!(actual.out, "4"); +} + +#[test] +fn run_nu_script_multiline_start_pipe_win() { + let actual = nu!(cwd: "tests/parsing/samples", r#" + nu multiline_start_pipe_win.nu + "#); + + assert_eq!(actual.out, "3"); +} + +#[test] +fn run_nu_script_multiline_end_pipe() { + let actual = nu!(cwd: "tests/parsing/samples", r#" + nu multiline_end_pipe.nu + "#); + + assert_eq!(actual.out, "2"); +} + +#[test] +fn run_nu_script_multiline_end_pipe_win() { + let actual = nu!(cwd: "tests/parsing/samples", r#" + nu multiline_end_pipe_win.nu + "#); + + assert_eq!(actual.out, "3"); +} diff --git a/tests/parsing/samples/multiline_end_pipe.nu b/tests/parsing/samples/multiline_end_pipe.nu new file mode 100644 index 0000000000..4f2502ef75 --- /dev/null +++ b/tests/parsing/samples/multiline_end_pipe.nu @@ -0,0 +1,2 @@ +echo "hi" | +str length \ No newline at end of file diff --git a/tests/parsing/samples/multiline_end_pipe_win.nu b/tests/parsing/samples/multiline_end_pipe_win.nu new file mode 100644 index 0000000000..c2c15f9762 --- /dev/null +++ b/tests/parsing/samples/multiline_end_pipe_win.nu @@ -0,0 +1,2 @@ +echo "how" | +str length \ No newline at end of file diff --git a/tests/parsing/samples/multiline_start_pipe.nu b/tests/parsing/samples/multiline_start_pipe.nu new file mode 100644 index 0000000000..c2e50f4b54 --- /dev/null +++ b/tests/parsing/samples/multiline_start_pipe.nu @@ -0,0 +1,2 @@ +echo "four" +| str length \ No newline at end of file diff --git a/tests/parsing/samples/multiline_start_pipe_win.nu b/tests/parsing/samples/multiline_start_pipe_win.nu new file mode 100644 index 0000000000..010c1ca1e1 --- /dev/null +++ b/tests/parsing/samples/multiline_start_pipe_win.nu @@ -0,0 +1,2 @@ +echo "one" +| str length \ No newline at end of file diff --git a/tests/parsing/samples/single_line.nu b/tests/parsing/samples/single_line.nu new file mode 100644 index 0000000000..0c0dd9718f --- /dev/null +++ b/tests/parsing/samples/single_line.nu @@ -0,0 +1 @@ +echo "hello" | str length \ No newline at end of file