Implement prefix-based interactive commands via ! (issue #14)
Add !command syntax that runs commands with inherited terminal (no
capture). The lexer treats ! as a statement-starting token, reading
to end-of-line with the same interpolation/escape/pipe support as
backtick commands. The C function sets _ = {code=N, stdout="", stderr=""}.
This commit is contained in:
@@ -124,9 +124,12 @@ lexerror([['alo \98]], "<eof>")
|
||||
-- valid characters in variable names
|
||||
for i = 0, 255 do
|
||||
local s = string.char(i)
|
||||
-- skip '!' which is now a valid statement starter (interactive commands)
|
||||
if s == '!' then goto continue end
|
||||
assert(not string.find(s, "[a-zA-Z_]") == not load(s .. "=1", ""))
|
||||
assert(not string.find(s, "[a-zA-Z_0-9]") ==
|
||||
not load("a" .. s .. "1 = 1", ""))
|
||||
::continue::
|
||||
end
|
||||
|
||||
|
||||
|
||||
97
testes/lush/interactive.lua
Normal file
97
testes/lush/interactive.lua
Normal file
@@ -0,0 +1,97 @@
|
||||
-- testes/lush/interactive.lua
|
||||
-- Tests for prefix-based interactive command execution (issue #14).
|
||||
|
||||
print "testing interactive commands"
|
||||
|
||||
-- ===== BASIC: _ IS SET CORRECTLY =====
|
||||
|
||||
-- basic interactive command sets _
|
||||
!true
|
||||
assert(type(_) == "table")
|
||||
assert(_.code == 0)
|
||||
assert(_.stdout == "")
|
||||
assert(_.stderr == "")
|
||||
|
||||
-- exit code preserved
|
||||
!false
|
||||
assert(_.code == 1)
|
||||
|
||||
-- specific exit code
|
||||
!sh -c "exit 42"
|
||||
assert(_.code == 42)
|
||||
|
||||
-- command not found
|
||||
!nonexistent_command_xyz_999
|
||||
assert(_.code == 127)
|
||||
|
||||
-- ===== INTERPOLATION =====
|
||||
|
||||
do
|
||||
local name = "hello"
|
||||
!echo ${name}
|
||||
assert(_.code == 0)
|
||||
assert(_.stdout == "")
|
||||
end
|
||||
|
||||
-- interpolation with expression
|
||||
do
|
||||
local x = 21
|
||||
!sh -c "exit ${x * 2}"
|
||||
assert(_.code == 42)
|
||||
end
|
||||
|
||||
-- ===== PIPING =====
|
||||
|
||||
-- exit code from last stage
|
||||
!echo hello | sh -c "exit 7"
|
||||
assert(_.code == 7)
|
||||
|
||||
-- piping: first stage output goes to second
|
||||
!echo hello | cat
|
||||
assert(_.code == 0)
|
||||
|
||||
-- ===== _ IS OVERWRITTEN =====
|
||||
|
||||
!true
|
||||
assert(_.code == 0)
|
||||
!false
|
||||
assert(_.code == 1)
|
||||
|
||||
-- ===== INSIDE LUA BLOCKS =====
|
||||
|
||||
do
|
||||
!true
|
||||
assert(_.code == 0)
|
||||
end
|
||||
|
||||
do
|
||||
if true then
|
||||
!true
|
||||
assert(_.code == 0)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
for i = 1, 3 do
|
||||
!true
|
||||
assert(_.code == 0)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local function run_cmd()
|
||||
!true
|
||||
return _.code
|
||||
end
|
||||
assert(run_cmd() == 0)
|
||||
end
|
||||
|
||||
-- ===== EMPTY COMMAND (just whitespace after !) =====
|
||||
|
||||
do
|
||||
-- set _ to something first, then run empty interactive
|
||||
!true
|
||||
assert(_.code == 0)
|
||||
end
|
||||
|
||||
print "OK"
|
||||
Reference in New Issue
Block a user