Redesign issue #10: bare-word commands now work in both scripts and the REPL via a parser-level heuristic (identifier + non-exception-list token → shell command). Add runtime fallback for string-arg syntax (echo "hello"), double-dash flag handling, and classification examples. Add issue #12 for path-based command execution (./script, /bin/ls, ~/bin/deploy). Add testes/lush/commands-interactive.lua as a design playground covering result table structure, exit codes, commands inside Lua blocks, _ behaviour, runtime fallback, Lua variable shadowing, and interleaved Lua/shell.
3.1 KiB
Issue #12 — Path-based command execution
Status: open Related: #10 (interactive command execution)
Problem
Issue #10's parser heuristic detects bare-word commands when an identifier at statement position is followed by a non-exception-list token. This covers ls -la, git status, etc. — but not commands invoked by path, because the first token isn't an identifier:
./script/update -- first token is .
../lua -- first token is .
/bin/ls -- first token is /
~/bin/deploy -- first token is ~
In standard Lua, none of these are valid statement starts, so claiming them for shell commands doesn't steal any Lua syntax.
Proposed heuristic
Add parser rules for path-prefixed commands. When the parser sees one of these tokens at statement position, treat the rest of the line as a shell command:
| First token(s) | Pattern | Example |
|---|---|---|
. / |
dot-slash | ./script.sh |
. . / |
dot-dot-slash | ../other/build |
/ |
absolute path | /bin/ls -la |
~ / |
home-relative path | ~/bin/deploy |
Detection
.at statement position → peek next token:/on same line → path command (./ ...).on same line → peek again:/→ path command (../ ...)- anything else → parse as Lua (
.could be a concat operator fragment, though this isn't valid at statement start anyway)
/at statement position → path command (not valid Lua statement start)~at statement position → peek next token:/on same line → path command (~/ ...)- anything else → parse as Lua (
~is bitwise NOT in Lua 5.4, though~expras a bare statement is already a syntax error)
Argument capture
Same as issue #10: once detected, extract the raw text of the entire line from the source buffer. Emit bytecode equivalent to _ = __interactive("raw line text").
Examples
-- all of these run as shell commands
./configure --prefix=/usr/local
../build/lush test.lua
/usr/bin/env python3 -c "print('hello')"
~/bin/deploy staging
-- check exit code like any other interactive command
./run-tests
if _.code ~= 0 then
print("tests failed")
end
Non-conflicts with Lua
/at statement start: not valid Lua (/is division, needs a left operand)./at statement start:.is concat,/is division —./fooas Lua would be. / foo(concat divided by foo), which needs a left operand. Not valid at statement start.../at statement start: same reasoning, not valid~/at statement start:~is bitwise NOT,/is division —~/fooas Lua would be(~()) / foo, which isn't valid at statement start as a bare expression statement
Open questions
- Should
~without/be supported? (e.g.,~user/bin/script— tilde expansion for other users). Probably not initially. - Should bare
.or..(without/) be treated as commands? In shells,sourceis sometimes aliased to.. Probably not — too ambiguous.
Files touched
| File | Description |
|---|---|
lparser.c |
Add path-prefix detection alongside the identifier heuristic in statement parsing |