Some shell apps care about what order the arguments appear in. When
`parseArgs()` is called with `tokens: true`, it produces this `tokens`
array which represents all the command line options and arguments, in
order, which is useful for these more advanced cases.
This is ported over from an old forgotten branch I'd deleted, then
thankfully managed to dig up again. 😅
Instead of making GroupCommand contain child commands, use a flat array
for commands and implement groups as GroupStartCommand and
GroupEndCommand. This makes it much simpler to iterate the commands
list in order to jump to labels.
Then implement those labels and the commands that use them: b, t, and T.
Also add the s SubstituteCommand, and combine the code for the q and Q
commands.
THe `a.stringOf(' \r\n\t'.split('')),` pattern works fine for small sets
of characters, but is horrible for situations like "any alphanumeric".
Instead, let's make it take a callback function that is run on each
character.
- Detect exit status of Puter apps, now that that's available.
- Store the exit status of each pipeline.
- Display a message when the exit status was non-zero.
That message is temporary, until we have a better way of displaying or
querying it, such as the `$?` shell variable.
A couple of issues here:
- We didn't pass the line number to do_grep_line() so `i` was undefined
- Operator precedence messed with the ternary so when line numbers were
requested, the line wouldn't be output.
Found thanks to this now-solved eslint issue:
/puter/packages/phoenix/src/puter-shell/coreutils/grep.js
100:60 error 'i' is not defined no-undef
This was confusing its fallthrough detection:
/puter/packages/phoenix/src/puter-shell/coreutils/date.js
132:21 error Expected a 'break' statement before 'case' no-fallthrough
Found by this eslint issue:
/puter/packages/phoenix/src/puter-shell/coreutils/coreutil_lib/echo_escapes.js
107:59 error 'hexchars' is not defined no-undef
Also make tmp_value non-const because it gets modified later.
Solves these eslint issues:
/puter/packages/phoenix/src/ansi-shell/ioutil/SignalReader.js
45:14 error Unexpected negating the left operand of 'instanceof' operator no-unsafe-negation
46:13 error 'tmp_value' is constant no-const-assign
Gives CommandProviders a `complete(query, {ctx})` method where they can provide completed command names, and then make use of this in CommandCompleter.
Supported CommandProvider sources:
- Shell built-ins (was supported previously)
- PATH executables (when running under Node)
- Puter app names (when running in Puter)
Script filenames are not yet supported.
`../bin/foo` should only find `foo` relative to the current working
directory, not to directories in PATH.
Also switch to using the Node path library since PathCommandProvider is
Node-only, and this means getting the correct path separator and
delimiter values on Windows.
BetterReader.read_with_cancel() returns both the read promise, and a
function that can be used to cancel the read. A cancelled read is
placed back into the BetterReader's chunk buffer, to be consumed by the
next user that requests a read.
This is used by Coupler so that when the coupler is closed, its pending
read() call does not consume the next batch of input.
This fixes the problem we were having with child applications consuming
one chunk of stdin after they are closed, meaning the first key you
press after an app exits would disappear.
Co-authored-by: KernelDeimos <eric.alex.dube@gmail.com>
After launching an app, if successful, we connect stdio streams to it,
and wait for it to exit before we return to the prompt.
stdio is implemented as regular AppConnection messages:
- stdin: `{ $: 'stdin', data: Uint8Array }` from phoenix -> child
- stdout: `{ $: 'stdout', data: Uint8Array }` from child -> phoenix
Terminal and Phoenix now communicate with each other using the same
style, instead of 'input' and 'output' messages. This will help with
eventually running subshells.
SIGINT currently is not sent. We also suffer from the same "one more
read from stdin happens after app exits" bug that's in
PathCommandProvider where I copied the stdin code from.