I started a new project called Zyne – a minimal shell written in Zig, with its own syntax ideas.
Why
I wanted to understand how shells work from the ground up – fork, execve, waitpid, raw terminal mode, line editing. Writing it yourself is the only way to really get it.
Also, I had some syntax ideas I haven’t seen elsewhere.
The [] operator
The main syntax idea so far is the [] list operator – it expands a command across multiple arguments:
git [ add . ; commit -m "Update, and add the []"; push ]
expands to:
git add .
git commit -m "Update, and add the []"
git push
Items are separated by ; inside the brackets. The parser builds a cartesian product when multiple [] appear in one command, so things like:
cp [file.txt; backup.txt] /dst/
expand correctly to separate commands. This already works and I used it to make the last two git commits from inside zyne itself.
What’s implemented
- Interactive loop – prompt, raw mode, flush
- Raw mode –
tcgetattr/tcsetattr, reads byte by byte - Line editing – cursor movement with arrow keys, backspace with correct redraw
- History – arrow up/down cycles through last 10 commands
[]spreading – full parser with cartesian product expansion, nested brackets, quoted strings- Command execution –
fork+execveviastd.process.spawn - Builtins –
cd,exit,:q - CLI skeleton –
zn run,zn plugin,zn path,zn help
Stack
- Zig 0.17-dev – using the new
std.Io,std.process.Init,std.process.spawnAPIs - No libc dependencies, no external libraries
- Linux for now, macOS support planned
What’s next
@async operator – run commands asynchronously{}block syntax for scriptsplugins.conf– declarative plugin list withgitandpathsources- User-friendly path config
- Customization – prompt, aliases, startup scripts
- Security settings
- Tab completion
- Config file at
~/.config/zyne/
Source: zyne