A structured-data shell in Gleam, inspired by Nushell
0

Configure Feed

Select the types of activity you want to include in your feed.

gleshell / README.md
5.4 kB 156 lines
1# gleshell 2 3A **structured-data shell** written in [Gleam](https://gleam.run), inspired by [Nushell](https://www.nushell.sh). 4 5Instead of piping opaque text between programs, gleshell pipelines pass typed values: strings, numbers, lists, records, and tables. Built-in commands like `ls`, `where`, and `select` work on that structure. 6 7```text 8~/code/gleshell on  main 9❯ ls | where type == file | select name size | first 5 10╭──────┬──────╮ 11│ name │ size │ 12├──────┼──────┤ 13│ … │ … │ 14╰──────┴──────╯ 15``` 16 17The interactive prompt is zero-config and Starship-inspired: full path with `~`, 18optional git branch (read from `.git`, no external tools), and a `❯` character 19that turns red after a non-zero exit. 20 21## Quick start 22 23Requires [Gleam](https://gleam.run/getting-started/) and Erlang (or use Nix): 24 25```bash 26# install a self-contained `gle` (Erlang shipment in the Nix store — no repo checkout) 27nix profile install . 28gle -c 'ls | first 3' 29 30# one-shot without installing 31nix run . -- -c 'ls | first 3' 32 33# dev shell (source tree; gleam, erlang, rebar3) 34# --no-pure-eval lets devenv use the real project dir (not /nix/store) 35nix develop --no-pure-eval 36gleam run # interactive REPL 37gleam run -- -c 'ls | first 3' 38gleam test 39``` 40 41### REPL editing 42 43On a TTY the interactive REPL uses a **raw-mode line editor** with 44**Nushell-style syntax highlighting** as you type (commands cyan, strings 45green, numbers purple, pipes purple, flags blue, variables purple, …). 46 47| Key | Action | 48|-----|--------| 49| ↑ / ↓ | History | 50| **Tab** | Command completion (builtins + `PATH`) at the start of a pipeline stage; filename completion for arguments (common prefix; list matches if ambiguous) | 51| **Ctrl+R** | Reverse-i-search through history (Enter accepts onto the line) | 52| Ctrl+A / Ctrl+E | Beginning / end of line | 53| Ctrl+W | Delete previous word | 54| Ctrl+U / Ctrl+K | Kill to start / end of line | 55| Ctrl+L | Clear screen | 56| **Ctrl+C** | Cancel current line at the prompt; while an external command runs, send SIGINT to that process (does not exit the shell) | 57| Ctrl+D | EOF (empty line) or delete under cursor | 58 59History is persisted under the user cache as `gleshell-history/lines`. 60Non-TTY input falls back to Erlang’s `edlin`/`get_until` path. 61 62## Examples 63 64```nu 65# list files as a table, filter, project columns 66ls | where type == file | select name size 67ls | find toml md 68echo [moe larry curly] | find l 69 70# ranges and list ops 71range 10 | reverse | first 3 72range 5 | length 73 74# records and JSON 75echo {name: "gleshell", cool: true} 76echo "{\"a\": 1}" | from json | get a 77open data.json | get users | first 78range 3 | to json 79 80# variables 81let n = range 3 | length 82echo $n 83 84# process environment (Nushell-style) 85$env.HOME 86$env | get PATH 87$env.MY_VAR = hello 88echo $env.MY_VAR 89 90# external programs (stdout captured as a string) 91^uname -a 92which ls 93which -a ls 94``` 95 96## Language sketch 97 98| Feature | Syntax | 99|--------|--------| 100| Pipeline | `cmd \| cmd \| cmd` | 101| Strings | `"hello"` or bare words `hello` | 102| Numbers | `42`, `3.14` | 103| Bools | `true` / `false` | 104| Nothing | `null` / `nothing` | 105| Lists | `[1 2 3]` | 106| Records | `{name: alice, age: 30}` | 107| Variables | `let x = …` then `$x` (pipeline input is `$in`) | 108| Env | `$env`, `$env.HOME`, `$env.FOO = value` | 109| Flags | `--flag` / `--flag value` | 110| Force external | `^command args…` | 111| Comments | `# …` | 112 113## Built-ins 114 115Filesystem: `ls`, `cd`, `pwd`, `cat`, `open`, `save` 116 117Table/list: `where`/`filter`, `find`, `select`, `get`, `first`, `last`, `take`, `skip`, `sort-by`, `reverse`, `length`, `columns`, `table`, `flatten`, `uniq`, `wrap`, `unwrap`, `keys`, `values` 118 119Data: `echo`, `range`, `lines`, `to`/`from` (subcommand `json`), `type`, `describe`, `env`, `sys`, `which`, `help`, `exit` 120 121Unknown command names fall through to external executables on `PATH`. 122 123## Layout 124 125```text 126src/ 127 gleshell.gleam # entry + REPL 128 gleshell_ffi.erl # line editor (Ctrl+R), cwd, process spawn 129 gleshell/ 130 value.gleam # structured Value type 131 lexer.gleam / parser.gleam 132 eval.gleam # pipeline evaluator 133 builtins.gleam # Nu-inspired commands 134 display.gleam # table pretty-printer 135 color.gleam # Nushell-style ANSI colors 136 highlight.gleam # live input syntax highlighting 137 env.gleam / sys.gleam 138``` 139 140Input and output are colorized on a TTY (Nu-like shapes on the command line; 141headers bold green, numbers purple, bools cyan, dirs blue, errors red, …). 142External tools (`jj`, `git`, `fastfetch`, …) keep their own colors: final-stage 143commands inherit the real TTY (or get `FORCE_COLOR` when output is captured), and 144pre-colored text is not re-painted by the shell. While the raw line editor is 145active, the TTY is switched to cooked mode for those children so LF-only 146output does not staircase. Paginated output gets `LESS=FRX` when unset so 147`less` passes ANSI through. 148Disable with `NO_COLOR=1`; force with `FORCE_COLOR=1`. 149 150## Status 151 152Early but usable: core pipeline model, tables, filters, JSON, and external commands work. Not a full Nushell clone (no closures/plugins yet). Contributions and experiments welcome. 153 154## License 155 156Apache-2.0 (same as the Gleam project template unless you change it).