summaryrefslogtreecommitdiffstats
path: root/docs/adr
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-01 13:14:07 +0200
committersalmonik <salmonik@tuta.io>2026-08-01 13:14:07 +0200
commit6eb14b64209b9d24554c587f610d7e300ef809ea (patch)
treec308507a2140680eb82fdb8b360aa346e7c5c9fe /docs/adr
parentBump workspace to edition 2024 (diff)
downloadrs-dos-6eb14b64209b9d24554c587f610d7e300ef809ea.tar.gz
rs-dos-6eb14b64209b9d24554c587f610d7e300ef809ea.zip
shell: keyword redirection + post-filter flags (ADR 0002)
Implement the shell experience redesign: one canonical grammar for every command — 'cmd args [USE src] [TIL marker] [filters...] [output kw dst]'. - Keyword redirection (uppercase-only, aliases valid, fully reserved): WRITING/WRITE overwrite, TO append, USE/USING input source, TIL/UNTIL heredoc/terminator (exact full-line marker). > >> < << are removed; '>' is plain text. - Post-filter stages applied left to right over a line stream, each repeatable: -h N (head kills the upstream), -t N (tail holds a rolling window, flushes at EOF/^C), -g PAT (smart-case literal substring), -p (screenful pager, terminal only). A file sink replaces the screen; -p is a no-op with one. - C-style quoting: "..." groups and literalizes, \x escapes one char; quoted/escaped text is never an operator, never split. - Input consumers: cat/hexdump, path-less only (stdin until ^D, USE f, TIL m heredoc, USE f TIL m truncation). Other commands reject input keywords; paths + input keyword is a syntax error. - ^D is EOF everywhere and never powers off; poweroff/exit are the only shutdown verbs. - help rewritten; test-disk.sh and sendkeys.py use the keyword syntax. Verified in QEMU: 26 grammar checks on fresh and reused disks, disk round trip, pager pacing, -h stopping /dev/mem at N lines, ^C flushing a -t window. Two bugs found during verification and fixed: 1. WRITING over an existing file wrote after stale NUL padding — fs::size() is stale after set_len(0); the sink writes at offset 0 after truncation. 2. USE f TIL m leaked the post-marker remainder — the final partial-line emit ran after the marker break; guarded with a stopped flag.
Diffstat (limited to 'docs/adr')
-rw-r--r--docs/adr/0002-keyword-redirection-and-post-filters.md76
1 files changed, 76 insertions, 0 deletions
diff --git a/docs/adr/0002-keyword-redirection-and-post-filters.md b/docs/adr/0002-keyword-redirection-and-post-filters.md
new file mode 100644
index 0000000..1584077
--- /dev/null
+++ b/docs/adr/0002-keyword-redirection-and-post-filters.md
@@ -0,0 +1,76 @@
1# ADR 0002 — Keyword Redirection and Post-Filter Flags Instead of Pipes
2
3## Status
4
5Accepted.
6
7## Context
8
9The shell (a freestanding, no_std kernel component) needs the data-flow
10features every shell has: redirecting command output to files, feeding
11input from files or typed blocks, and trimming output to `head`/`tail`/
12`grep`/pager views. The obvious model — Unix pipes plus `> < << >>`
13operators — was considered and rejected. The project is explicitly
14not POSIX-compatible, is TempleOS-inspired, and values minimal machinery
15and natural-language-flavoured input over familiarity. The old shell
16had only an ad-hoc `>`/`>>` parse baked into `cmd_echo`, no head/tail/
17grep at all, and ^D at the prompt powered the machine off.
18
19## Decision
20
21One canonical command-line grammar, applied uniformly to every command:
22
23```
24cmd args [USE src] [TIL marker] [filters…] [output kw dst]
25```
26
27- **Redirection uses reserved uppercase keywords**, never symbols:
28 `WRITING`/`WRITE` overwrite, `TO` appends, `USE`/`USING` names the
29 input source, `TIL`/`UNTIL` truncates the input at an exact full-line
30 marker (marker and everything after it is discarded). At most one
31 input keyword (USE and TIL may pair, USE first) and one output
32 keyword; input keywords precede the filters, the output keyword
33 comes last.
34- **Filters are trailing flags** applied left to right as stages over a
35 line stream: `-h N` (emit first N lines, then kill the upstream
36 command), `-t N` (hold back a rolling window of the last N lines;
37 emit only when the stream ends — EOF or ^C, which flushes),
38 `-g PAT` (smart-case literal substring match: case-insensitive unless
39 PAT contains an uppercase letter), `-p` (pause at each screenful,
40 `more`-style, only when output exceeds one screenful). Every flag
41 may repeat; each instance is another stage. After `-g`, the next
42 token is the pattern verbatim.
43- **There are no pipes.** The four built-in filters cover the cases
44 pipes are usually built for; arbitrary command composition is
45 deliberately out of scope.
46- **`> >> < <<` are removed** — `>` is now ordinary text. The shell
47 prints to both GOP and serial; a file sink replaces terminal output
48 entirely.
49- **^D is EOF everywhere and no longer powers off** (^C keeps its
50 line-cancel / stream-abort role; `poweroff`/`exit` are the only
51 shutdown verbs).
52- **Quoting (`"..."` groups and literalizes, `\x` escapes one char)**
53 is the escape hatch: quoted/escaped text is never an operator, which
54 makes keywords expressible as data and enables spaces in filenames.
55
56## Consequences
57
58- **Positive:** One grammar, one parser — the per-command redirection
59 hacks (`cmd_echo`'s `>` scan) disappear. Filters compose uniformly
60 with any command and with each other, including intermediate views
61 (`-h N -p -g pat -p` shows each stage's result). No pipe machinery,
62 no process/stream abstraction to build. Lowercase text can never
63 collide with operators, so ordinary words stay ordinary.
64- **Positive:** `tail` on an infinite stream (`cat /dev/mem -g 100
65 -t 10`) is expressible without a pipe; ^C flushes the held-back
66 window instead of losing it.
67- **Negative:** Breaks existing muscle memory and tooling: POSIX users
68 must learn the keywords; `scripts/test-disk.sh` and the `help` text
69 must be rewritten from `echo >` to the keyword syntax.
70- **Negative:** Keywords are reserved, so printing text like `WRITING`
71 requires quoting; unknown commands cannot be filtered with flags
72 beyond the four built-ins; there is no way to compose arbitrary
73 commands (accepted — the shell has no external commands today).
74- **Negative:** `-t` on a stream that never ends shows nothing until
75 the user ^C's — an intentional trade-off for simplicity (no pager
76 machinery, no infinite buffering beyond the window).