Skip to content

Latest commit

 

History

History
153 lines (114 loc) · 4.6 KB

File metadata and controls

153 lines (114 loc) · 4.6 KB

Tutorial

A guided walk through exp, one recording per section. Every command here runs against the vendored fixture pages, so you can follow along on any machine with:

cargo build --release
export MANPATH="$PWD/tests/fixtures/man"
export PATH="$PWD/target/release:$PATH"

Drop the MANPATH line to explain the tools actually installed on your system, which is the normal way to use it.

1. A first explanation

exp explaining tar -xzvf and a sudo xargs rm pipeline

▶ demos/01-explain.cast, asciinema play for a real terminal
exp 'tar -xzvf a.tgz'

The command line comes back with every span underlined and numbered. -xzvf is four options, so it gets four spans; f takes an argument, so a.tgz shares its footnote. Under the line, one table row per footnote: the tokens that share it, the page and section they come from, and the paragraph text.

exp 'sudo xargs -0 rm -f < list.txt'

sudo and xargs are wrappers: after their own options, the first operand starts a new command that gets its own page. rm -f is explained from rm(1), and the redirect from the shell.

2. Shell grammar

exp explaining a git pipeline and find -exec

▶ demos/02-pipeline.cast
exp 'git log --oneline | head -n 5 > out.txt'

git is explained from git(1), log from git-log(1), and --oneline from that page's options. The pipe and the redirect get built-in explanations, not page lookups.

exp "find . -name '*.log' -exec rm {} \;"

Everything between -exec and \; is a command in its own right, so rm gets rm(1). The terminator points back at -exec.

3. The ugly tail

exp explaining ps aux, dd, and ssh -o

▶ demos/03-ugly-tail.cast
exp 'ps aux'
exp 'dd if=/dev/zero of=out.img bs=4M count=10'

BSD-style aux is three bare tags in ps(1); bs=4M matches dd's bs=BYTES paragraph. Both grammars live in knowledge/commands.toml, not in code.

exp 'ssh -p 2222 -o StrictHostKeyChecking=no user@host'

The whole StrictHostKeyChecking=no argument belongs to -o; the key inside it gets a second footnote from ssh_config(5), where it is documented.

4. Output formats

exp text, markdown, and JSON output

▶ demos/04-formats.cast
exp --format text 'rsync -avz --delete src/ dst/'
exp --format markdown 'rsync -avz --delete src/ dst/'
exp --json 'rsync -avz --delete src/ dst/' | jq '.spans[] | [.text, .kind, .footnote]'

text is the ruler plus plain footnotes; markdown pastes into an issue; json carries byte offsets and full provenance and is the format the snapshot tests freeze.

5. Search

exp search by tool, category, regex, and fuzzy

▶ demos/05-search.cast
exp search --tool rsync checksum
exp categories
exp search --category archive exclude
exp search --tool grep --zone any --regex 'binary file'
exp search --tool tar --fuzzy 'exclde vcs'

Search runs over the SQLite cache that explaining fills as a side effect. Named tools are indexed on demand; exp index --all indexes the whole manpath (about 20 seconds for 21,000 pages) so --all and categories with git-* patterns see everything.

6. Make it yours

Explain the previous command from fish:

function explain --description 'explain the last command'
    exp (history --max 1)
end
funcsave explain

From bash or zsh:

alias explain='fc -ln -1 | exp'

Add a wrapper, an arity override, or a category in ~/.config/exp/:

# ~/.config/exp/commands.toml
[commands.run-as]
wraps = true

[[overrides]]
command = "mytool"
option = "-t"
arg_policy = "required"
# ~/.config/exp/categories.toml
[categories]
backup = ["restic", "borg", "rsync", "tar"]

When an explanation is wrong, exp page TOOL shows what was extracted, and exp index --all --report lists pages the extractor could not make sense of. A fix that survives the golden corpus becomes a rule or a TOML entry, never an inline special case; see DESIGN.md.