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.
78 lines
3.1 KiB
Markdown
78 lines
3.1 KiB
Markdown
# 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 `~expr` as 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
|
|
|
|
```lua
|
|
-- 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 — `./foo` as 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 — `~/foo` as 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, `source` is sometimes aliased to `.`. Probably not — too ambiguous.
|
|
|
|
## Files touched
|
|
|
|
| File | Description |
|
|
|------|-------------|
|
|
| `lparser.c` | Add path-prefix detection alongside the identifier heuristic in statement parsing |
|