Fix minimal input backend to handle multi-line continuation#944
Fix minimal input backend to handle multi-line continuation#944Osso wants to merge 5 commits intoreubeno:mainfrom
Conversation
When reading from a non-terminal stdin, the minimal input backend now properly handles incomplete commands that span multiple lines (e.g., commands ending with && or ||). Previously, the backend read a single line and passed it directly to the parser, which failed with "syntax error at end of input" for incomplete commands like "echo a &&\necho b". Now the backend: 1. Reads lines in a loop 2. Checks if the accumulated input parses completely 3. If incomplete (ParsingAtEndOfInput), reads more lines 4. Shows continuation prompt when in terminal mode This matches the behavior of the reedline backend which uses a validator to detect incomplete input. Fixes: Commands like `echo a &&` followed by `echo b` on the next line now work correctly when piped to brush.
Performance Benchmark Report
Code Coverage Report: Only Changed Files listed
Minimum allowed coverage is Test Summary: bash-completion test suite
|
|
Thanks for your contribution, @Osso! Our minimal input backend is intended to be very, well, minimal 🙂. I'm curious to know if you actually ran into this while using it or if it was more something you identified while reading or analyzing the code? Regardless of which, we're open to some minor changes to it as long as it stays relatively simple. For the new tests you've added, did you confirm they ran against the minimal backend? I don't see any command-line arguments specifying that. One great way to confirm could be to check they fail without the fix. I'd also encourage you to look over the tests and see if there are some ways you could reduce the repeated logic across them. The separate cases are mostly doing the same thing but with different inputs + result expectations. Perhaps you could extract out the common logic or convert them into a data/table driven test of some kind? |
|
Yes I have been using a modified version of brush (alias handling, history handling, ...) as my default shell for about about a week and the minimal backend is being used while piping. There no need command line arguments as it is the default behavior: maybe that's the real problem? should it be using a different backend while piping? If you are not aiming for that usage we can close this merge request. Yes I can cleanup the tests. |
|
Ah, interesting. So you're still using the shell interactively but via a pipe? I think understand a bit better. I'm okay proceeding with the change after you clean up the tests. Very cool to hear you've been able to build something that extends |
|
Right I didn't show an example. What I am doing is this: ```console
$ printf 'echo hello &&\necho world\n' | /tmp/claude/brush -s
error: main: syntax error at end of input
$ printf 'echo hello &&\necho world\n' | /tmp/claude/brush-fixed -s
hello
world
$ printf 'echo hello &&\necho world\n' | bash -s
hello
world |
- Consolidate three separate tests into one with TestCase struct - Explicitly specify --input-backend=minimal to clarify test target
Extract read_line_from<R: BufRead>() method that accepts any reader, allowing tests to call it directly with a Cursor instead of spawning a subprocess. Tests now verify the backend's line accumulation logic without process overhead.
|
Ok I updated the tests first by factoring them then I changed them to call minimal backend directly in the latest commit. Let me know which one your prefer. |
|
Thanks! I should be able to properly review this weekend. In the meantime I see 2 checks failing on the PR from non-Unix builds. Would you be able to look at them? |
On WASM targets, tokio::task::block_in_place is not available (no multi-thread runtime), so we fall back to treating every line as complete (no multi-line continuation support on WASM).
When reading from a non-terminal stdin, the minimal input backend now properly handles incomplete commands that span multiple lines (e.g., commands ending with
&&or||).Previously, the backend read a single line and passed it directly to the parser, which failed with "syntax error at end of input" for incomplete commands like
echo a &&followed byecho bon the next line.Now the backend:
Added tests for
&&continuation,||continuation, and complex multi-line patterns with pipes via stdin.