Files
lush/issues/12-path-based-command-execution.md
Cormac Shannon 41b2095ed9 Rewrite issue #10 for scripts+REPL, add issue #12, add interactive command tests
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.
2026-03-01 19:35:09 +00:00

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 ~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

-- 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