# A Text Editor as a User Interface (Dave Gauer)

Dave Gauer ([[ratfactor]]) writes a card-format post on a pattern he's been using more and more: when a CLI tool needs more than a few flags but doesn't deserve a full [[editor-as-ui|TUI]], hand the user a temp file and shell out to `$EDITOR`. The framing is the gap itself. Argument parsing is cheap. A real TUI takes "years" of effort. The middle is where most personal tooling actually lives, and Unix has been quietly sitting on a solution since the early days.

The precedents are familiar: `crontab -e` for the cron table, `git commit` for the commit message, `visudo` for `/etc/sudoers`, `vipw` for `/etc/passwd`. All four open a temp file, let the user edit, then validate and apply. `vipw` is the cleanest demonstration because consistency-checking is its whole purpose — the man page advertises that it "will not allow a password file with a 'mangled' entry to be installed."

## The three-line version

The minimal demo is a shell script that runs `rev` on whatever you type:

```sh
FILE=$(mktemp)
$EDITOR $FILE
rev < $FILE
```

Three lines, and the user gets the entire expressive surface of their editor — search, syntax highlighting, multi-cursor, paste from clipboard, anything they've already configured. Gauer's point: the cost of giving the user that power is one line of script. Building a TUI text-input widget that approached the same capability would take a year and need its own documentation.

## The yt-dlp example

The richer example is a Ruby wrapper around `yt-dlp` that downloads a video to a chosen subdirectory under `/media/video`. The script:

1. Globs the destination directory to enumerate available subdirs.
2. Reads the previous run's settings from a fixed path (`download.txt`) — it persists across invocations, not a `mktemp`.
3. Writes a four-line file: a comment listing the available subdirs, then the chosen subdir, base filename, and URL on three following lines.
4. Shells out to `vim` on the file.
5. Reads the file back, validates, and runs `yt-dlp` with a timestamp-suffixed output name.

```
# cs_lectures film howto sketchbooks watercolor
howto
fix_toilet
https://example.com/how-to/fix-a-toilet.html
```

Two design choices are worth pulling out. The available subdirectories appear as a comment header so you don't have to remember them — the editor screen becomes the documentation. And the settings file is reused, not random, so the previous run's URL/subdir are sitting there as defaults the next time you launch.

The timestamp suffix on the filename (`fix_toilet_1777324491.mp4`) sidesteps having to compute "next sequence number" — sorting by mtime or filename gives you the same ordering for free.

## When the pattern fits

Gauer ends with a working rule: if the parameter set grows past three or four lines, switch to a structured format inside the same file — `.ini`, `.conf`, `.toml`. The point is that the format stays trivial to parse without a library. The whole technique loses its appeal once you need a parser more elaborate than `each_with_index`.

He calls out `find`, `ffmpeg`, and `rsync` as natural candidates — tools whose CLIs are dense enough that even regular users keep a notes file of working invocations. An editor-as-UI wrapper turns that notes file into the actual interface.

## Why it works

A few things about the pattern are easy to miss:

- **Zero documentation.** The user already knows their editor. There's nothing to teach about navigation, undo, or autocomplete.
- **Composable.** The temp file is just text, so it works with version control, diffs, and shell pipes if you want to inspect what was actually run.
- **Stateful by default.** A persistent settings file (versus `mktemp`) means the second invocation is one keystroke away from the first.
- **Unprivileged.** No curses, no terminal modes, no signal handling. The script can be killed, resumed, or piped, and the editor handles all the terminal complexity.

The pattern is most famous from `git commit`, which also demonstrates the validation step — an empty message aborts the commit. Gauer's own scripts do the same with explicit existence and directory checks after the editor returns.

## Related

- [[editor-as-ui]] — the broader concept page
- [[clean-code-coding-agents]] — the same minimum-context philosophy applied to the LLM era
- [[ratfactor]] — Dave Gauer's "card" blog
