Commit Graph
5854 Commits
Author SHA1 Message Date
Cormac Shannon 51b39930ed Fix lush tests to work from testes/ directory (via all.lua)
Tests hardcoded ./lua and assumed CWD was the project root.
Add shared testutil.lua module to derive interpreter path from
arg table, and use temp directories for glob tests instead of
relying on .c files in CWD.
2026-03-22 23:17:17 +00:00
Cormac Shannon cca6749d4d Rename lush Lua API: command→capture, subcmd→run, getenv→envget, setenv→envset
Lua-facing names only; C internals unchanged.

  lush.capture(str)     — return {code, stdout, stderr} table
  lush.run(str)         — return stripped stdout string
  lush.interactive(str) — run with TTY, set _, return result
  lush.envget(name)     — get environment variable
  lush.envset(name,val) — set environment variable
2026-03-22 18:58:59 +00:00
Cormac Shannon daccad3c45 Make lush.interactive() return the result table in addition to setting _
Previously it only set the global _ and returned nothing, which was
surprising when calling it as a function. Now it returns the same
{code, stdout, stderr} table it sets _ to.
2026-03-22 18:49:29 +00:00
Cormac Shannon 917509aa8a Refactor lush tests: remove duplication, fill coverage gaps, wire into all.lua
- Wire all 11 lush test files into testes/all.lua (was only 4)
- Delete dead commands-interactive.lua (disabled via os.exit(0))
- Remove duplicate regression test from piping.lua
- Add user-defined command tests (lush.commands): basic, int return,
  table return, error handling, removal, API call
- Add lush.subcmd() and lush.interactive() direct call tests
- Add argv edge cases: single-quote backslash, \$ escape, unknown
  escape, adjacent quote concatenation
- Add globbing edge cases: brace suffix, no-comma braces, bracket
  glob, mid-word tilde passthrough
- Add signal exit code test (128+9=137)
- Add escaped-pipe and empty interactive command tests
2026-03-22 17:58:09 +00:00
Cormac Shannon 9bc7dc01b7 Refactor: extract lookup_lush_func, reorder helpers, eliminate forward decl
Extract lookup_lush_func() in lcmd.c to deduplicate the registry lookup
pattern shared by try_builtin and exec_user_command. Move exec_user_command
after exec_failed to group helpers together. Move codeenvget definition in
lparser.c to replace its forward declaration.
2026-03-22 17:04:02 +00:00
Cormac Shannon 973dd90d65 Add user-defined commands via lush.commands table (issue #30)
User commands run in forked children like external commands, so they
support piping, redirection, and capture seamlessly.
2026-03-21 19:34:29 +00:00
Cormac Shannon fbb7b441c3 Refactor(builtins): Move luaopen_builtins from linit to lcmd 2026-03-20 23:16:00 +00:00
Cormac Shannon 4c23bc6d87 Update(issue): mark aliases as done 2026-03-20 22:58:35 +00:00
Cormac Shannon 68a5273094 Add shell aliases via lush.aliases table (issue #28)
Aliases rewrite the command string before pipeline splitting, so alias
values may contain pipes (e.g. lush.aliases.foo = "echo hi |"). Expansion
happens once per dispatch to prevent recursion.
2026-03-20 22:58:01 +00:00
Cormac Shannon e115a061bc Remove integer keys from lush table, use string lookups (issue #29)
VM now resolves lush functions via luaH_getshortstr through interned
TString pointers, so wrapping lush.command = my_wrapper is transparently
picked up. The lush table no longer has integer-keyed duplicates.
2026-03-20 21:32:38 +00:00
Cormac Shannon 5c1eca312f Add(issue): lush table cleanup 2026-03-20 00:59:11 +00:00
Cormac Shannon 8a61a47543 Add(plan): aliases 2026-03-20 00:46:12 +00:00
Cormac Shannon 02df45b18f Fix config/prompt tests to use config.lua extension
The tests wrote config as `lush/config` (no extension) but
handle_lushconfig() looks for `config.lua` or `config.lush`.
2026-03-18 09:54:18 +00:00
Cormac Shannon 768de9fe8b Expose lush global as a standard library (issue #26)
Register luaopen_lush() in stdlibs so the lush table is available as a
global. Users can now extend the shell by adding functions to
lush.builtins. The OP_LUSH VM access via integer keys is preserved.
2026-03-18 09:52:56 +00:00
Cormac Shannon 1766e40a68 Implement $(cmd) subcommand syntax in commands (issue #27)
Add $() for inline subcommand substitution that runs a command and
inserts its stdout (trailing newlines stripped) into the outer command
string. Supports nesting, and mixing with ${expr} and $NAME.
2026-03-18 09:29:51 +00:00
Cormac Shannon 42baabde34 Implement $VAR expansion in commands (issue #25)
Extend read_command_body() to detect $NAME and trigger interpolation
using the same fragment-split mechanism as ${expr}. The lexer collects
the identifier into cmd_envvar; the parser's unified parseinterp()
branches on it to emit tostring(getenv(NAME)).
2026-03-18 08:35:46 +00:00
Cormac Shannon 635569961e Fix(lua.c): Accept config.lua/.lush files 2026-03-17 18:59:49 +00:00
Cormac Shannon 8b1b3578ed Fix: c99 compliance issue in llex 2026-03-17 18:57:47 +00:00
Cormac Shannon bad40fb65b Standardize issue status labels to done/open/in progress
Rename resolved→done (#1-4, #11), closed→done (#13, #18),
open (post-core)→open (#7), mark #9 as superseded by #21.
2026-03-15 19:33:49 +00:00
Cormac Shannon 08df164692 Add issues #25, #26, #27; update #7 and #22 statuses
- #25: $VAR expansion in commands
- #26: Shell abbreviations and user-extensible builtins
- #27: $(cmd) subcommand syntax
- #22: Updated with implementation details (in progress)
- #7: Standardize status label
2026-03-15 19:33:19 +00:00
Cormac Shannon 5135b16375 Unify command tokens: remove TK_COMMAND_INTERP and TK_INTERACTIVE_INTERP
Use cmd_mode (already on LexState) to signal whether interpolation
follows, instead of separate *_INTERP token variants. This eliminates
duplicate simple/interpolated code paths in the parser — commandexp()
and interactivestat() now each use a single unified loop that checks
cmd_mode != 0. A shared parseinterp() helper handles each ${expr}
interpolation cycle.
2026-03-12 23:01:31 +00:00
Cormac Shannon f09a033160 Replace upvalue-based shell dispatch with OP_LUSH opcode
Add a dedicated OP_LUSH A B instruction that loads shell C functions
directly from the registry, eliminating the need for upvalue allocation
in mainfunc(), upvalue population in lua_load(), and the fragile
LUSH_NUM_UPVALS heuristic. Every chunk no longer carries 4 extra
upvalues.
2026-03-12 22:47:25 +00:00
Cormac Shannon f88b17959f Hide shell functions from _G using upvalues on the main chunk
Store __command, __interactive, __getenv, __setenv as upvalues
populated by lua_load() from the registry, keeping them invisible
to user code while accessible to the parser's codegen.
2026-03-12 22:46:56 +00:00
Cormac Shannon 34bfabccbd Expand issue #23 with detailed cleanup analysis; close issues #5 and #24
Issue #23 now covers function naming conventions, file organisation,
global namespace cleanup options, and a concrete implementation plan.
2026-03-12 19:26:05 +00:00
Cormac Shannon c556928d0a Add compatibility test script for third-party Lua projects (issue #24)
Tests lua-TestMore, json.lua, and lume against the Lush binary to verify
parser/lexer/runtime changes don't break standard Lua code.
2026-03-12 19:04:21 +00:00
Cormac Shannon 0cfd327180 Update: issue 24 2026-03-10 23:53:08 +00:00
Cormac Shannon ecab5ca6c7 Issue: lua test compatibility 2026-03-10 21:44:37 +00:00
Cormac Shannon f49a73bc52 Close issues #13 and #18 2026-03-10 21:35:48 +00:00
Cormac Shannon a43fd10e64 Implement shell globbing, tilde expansion, and brace expansion (issues #13, #18)
Unquoted tokens are now expanded through a tilde → brace → glob pipeline
in parse_argv. Quoted tokens (single, double, or backslash) suppress all
expansion. Uses glob(3) with GLOB_NOCHECK for wildcard matching and manual
implementations for tilde (~→$HOME) and brace ({a,b,c}) expansion.
2026-03-10 21:31:55 +00:00
Cormac Shannon c96fae90c0 Fix nested commands in interactive mode triggering prompt2 (issue #19)
Save and restore cmd_mode across interpolation parsing so that
luaX_readcommandcont resumes in the correct mode after a nested
backtick command inside ${...}.
2026-03-05 00:13:34 +00:00
Cormac Shannon b3aa1d9c63 Redesign prompt system: revert #09, use standard _PROMPT (issue #21)
Revert the bespoke __prompt()/__prompt2() function mechanism from issue
#09 and return to stock Lua's _PROMPT/_PROMPT2 globals (which already
support dynamic prompts via __tostring metatables). Set default
_PROMPT = "lush> " in doREPL if not already defined by config.
2026-03-04 23:53:04 +00:00
Cormac Shannon 9e75175c79 Add issues #16–#23
#16 multiline shell commands
#17 _ scope (global vs local)
#18 path expansion (~)
#19 nested commands trigger prompt2
#20 simplify backtick return value
#21 prompt redesign
#22 implicit interactive commands (drop ! prefix)
#23 general cleanup and refactor
2026-03-04 23:28:11 +00:00
Cormac Shannon 4cc352cbec Implement shell builtins: cd, exec, umask (issue #15)
Add builtin dispatch in lcmd.c that checks __builtins table before
fork(), so cd/exec/umask operate on the shell process itself.
2026-03-04 19:20:42 +00:00
Cormac Shannon e8756d5d78 Implement programmable prompt (issue #09)
Replace static _PROMPT/_PROMPT2 with dynamic __prompt(exitcode)/__prompt2(exitcode)
functions. Fallback chain: __prompt() → _PROMPT → "> ". Install a default __prompt
that shows the current directory with ~ abbreviation. Track last exit code from the
REPL loop and pass it to the prompt function.
2026-03-03 23:19:09 +00:00
Cormac Shannon bbc0f24009 Implement startup configuration file support (issue #08)
Load ~/.config/lush/config and config.d/*.lua at REPL startup,
respecting XDG_CONFIG_HOME. Suppressed by -E flag.
2026-03-03 22:59:51 +00:00
Cormac Shannon db858b3f68 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=""}.
2026-03-02 22:06:29 +00:00
Cormac Shannon 75098da240 Add issue #14: prefix-based interactive commands via ! 2026-03-02 21:16:06 +00:00
Cormac Shannon 0d23741891 Add issue #13: shell globbing (*, ?, **, {a,b}, [abc]) 2026-03-02 00:37:13 +00:00
Cormac Shannon d0181e685d Implement piping between commands in backtick syntax (issue #06)
Add split_pipeline() to split command strings on unquoted | and
exec_pipeline() to fork N children connected by inter-stage pipes.
Only the last stage's stdout/stderr are captured; middle stages'
stderr is inherited. Exit code comes from the last stage.
2026-03-01 22:17:30 +00:00
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
Cormac Shannon af8300aa40 Make Ctrl-C clear line and re-prompt in REPL instead of exiting
Use sigsetjmp/siglongjmp to catch SIGINT during readline/fgets input
and jump back to the REPL loop with a fresh prompt. Running Lua code
still gets interrupted via the existing laction/lstop mechanism.

Fixes #11.
2026-02-28 23:35:30 +00:00
Cormac Shannon 47abb04921 Rewrite issue #10, add issue #11 (Ctrl-C REPL behaviour)
Rewrite #10 with refined interactive command design: bare-word REPL
fallback instead of ! prefix, result table assigned to _, same shape
as captured commands. Add #11 for Ctrl-C clearing the current line
instead of exiting the REPL.
2026-02-28 23:20:55 +00:00
Cormac Shannon 84b9aeb7e9 Auto-detect platform in makefiles and test runner
Use uname -s to select Linux vs macOS build flags instead of
hardcoding. Add -undefined dynamic_lookup for test shared libs
on macOS. Set _port=true automatically on non-Linux in ./all.
2026-02-28 19:27:14 +00:00
Cormac Shannon 27f16b126d Add lush feature tests and fix /dev/full test for macOS
Add test suite under testes/lush/ covering backtick commands, argv
parsing, ${} interpolation, and $NAME environment variables. Wire
them into testes/all.lua so they run with the full Lua 5.5 suite.

Skip /dev/full test in files.lua when the device doesn't exist
(macOS has no /dev/full).
2026-02-28 19:07:00 +00:00
Cormac Shannon 4b49907ce7 Update project issues: resolve #02-#04, add #08-#10
Mark issues #02 (backtick lexing/parsing), #03 (command execution
runtime), and #04 (argv parsing) as resolved. Add new issues for
configuration (#08), programmable prompt (#09), and interactive
command execution (#10).
2026-02-28 18:27:55 +00:00
Cormac Shannon 39d6cc95cb Add command execution runtime (lcmd.c, lcmd.h)
Implements luaB_command: fork/execvp with pipe-captured stdout/stderr,
argv parsing with quoting/escaping, and non-blocking pipe reading via
select(). Backs the __command() calls emitted by the backtick parser.

Resolves #03 and #04.
2026-02-28 18:27:42 +00:00
Cormac Shannon 882a90be48 Add environment variable access with $NAME syntax
Lexes $NAME as TK_ENVVAR, compiles reads as __getenv("NAME") calls
and writes ($NAME = expr) as __setenv("NAME", expr) calls. Runtime
functions wrap getenv/setenv/unsetenv with automatic tostring coercion.
2026-02-28 18:08:09 +00:00
Cormac Shannon a773398cab Compile backtick commands as __command() calls with ${} interpolation
Backtick expressions now compile as calls to a global __command()
function instead of being treated as plain strings. Interpolation
via ${expr} is supported, with each interpolated value wrapped in
tostring() for type safety. Commands are parsed in primaryexp so
suffix operations like `.stdout` work directly.

Adds a stub __command that returns {code, stdout, stderr} for testing
until the real implementation (issue #03).
2026-02-19 20:00:15 +00:00
Cormac Shannon db6f39a2a4 Add project issues for lush (Lua + shell) features
Defines syntax decisions and implementation plan across 7 issues:
- backtick command execution returning {code, stdout, stderr}
- ${expr} interpolation in backticks
- $SIGIL env var read/write
- argv parsing, piping, and redirection (future)
2026-02-18 19:08:59 +00:00
Roberto I 4cf498210e '__pairs' can also return a to-be-closed object 2025-11-11 15:11:06 -03:00