Completion Authoring Guide
CJ's Shell ships with a hybrid completion engine: built-ins are documented in-code, while external commands learn their options and subcommands automatically by reading their manual pages. This guide explains how that pipeline works and how to author or override completion data when you need to fill in gaps or add custom behaviour.
How automatic completions are generated
- On-demand scraping: The first time you request completions for an external command that
resolves in
PATH, cjsh invokesman -P cat <command>(falling back toman <command>) and scrapes the result. The parser looks forOPTIONS,COMMANDS, orSUBCOMMANDSsections, pulls out option switches and subcommand names, and condenses their descriptions to a single line. - Caching: Parsed data is written to
~/.cache/cjsh/generated_completions/<command>.txt. The next completion request loads this cache instead of invokingmanagain. Cache entries also store a short summary that feeds inline help and completion source hints. - Nested commands: When a completion entry includes subcommands, cjsh will look for additional
caches named
<command>-<subcommand>.txtand merge their contents. This is howgit-remotecompletions are chained intogit. - Bulk generation: The
generate-completionsbuiltin pre-populates caches for an entirePATHor a list of commands. By default it forces regeneration (--force); pass--no-forceto keep existing manual edits. Use-j/--jobsto parallelise scraping and--quietto suppress per command status output.
If a man page cannot be read (missing man, atypical formatting, or sandbox restrictions), cjsh
creates an empty cache entry. You can delete that file or replace it with a manual definition.
Cache layout and file format
Each cache file is plain text:
generated by cjsh from man page for git
summary: the stupid content tracker
S add Record changes to the repository
S commit Record changes to the repository
O --amend Reuse and edit the last commit
O --patch Interactively choose hunks to stage
Key points:
- The header line must stay exactly
generated by cjsh from man page for <command>or cjsh will ignore the file. - The second line contains the summary. Leave it blank after
summary:if you do not want one. - Subsequent lines are tab separated. Use
Sfor subcommands andOfor options. - Values are case-insensitive in matching but should be written the way you want them to appear to users. Tabs inside descriptions are converted to spaces.
- File names are normalised to lower-case with non-alphanumeric characters translated to
_. Letgenerate-completionscreate the skeleton once if you are unsure about the exact spelling.
Authoring or overriding completions manually
- Create the cache directory (once):
generate-completionsor the first automatic scrape will do this, but you can alsomkdir -p ~/.cache/cjsh/generated_completionsyourself. - Seed a template (optional): Run
generate-completions --no-force <command>to create the cache without overwriting existing edits. Even if scraping fails, the command establishes the correct file name for you to edit. - Edit the cache file: Open
~/.cache/cjsh/generated_completions/<sanitised-name>.txtand adjust the summary or add new lines using the format above. - Add multi-level entries: For subcommand specific completions (e.g.
kubectl get), create a second file namedkubectl-get.txtwith its own header, summary, and entries. cjsh stitches these together automatically when you tab complete. - Preserve your changes: Future runs of
generate-completionsdefault to--force. Usegenerate-completions --no-force ...when you want to refresh other commands without clobbering manual content, or keep a copy of the file under version control and reapply as needed.
You can delete a cache file to force cjsh to rescrape the man page on the next completion request. This is useful after upgrading a tool with new options.
Tips and troubleshooting
- Commands without man pages: Some utilities only provide
--help. Create the cache file manually or pointgenerate-completionsat a packaged man page (for example, install the corresponding*-docpackage). - Unusual formatting: If the parser misses options, check the rendered man page. Options that do
not start with
-or subcommands listed outside dedicated sections may need to be added manually. - Custom summaries: Inline help uses the summary line. Tailor it to the way you present the command in your prompts or completion preview.
- Refreshing everything: Remove
~/.cache/cjsh/generated_completionsor rungenerate-completions --forceto rebuild all caches. Beware this overwrites manual edits. - Sandboxed environments: If
manis unavailable, completions fall back to whatever data already exists. Consider bundling cache files with your dotfiles so they can be copied into the cache directory during provisioning.
With these tools you can match or exceed the curated completion sets provided by fish, bash, or zsh while keeping cjsh's zero-dependency footprint.