Skip to content

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 invokes man -P cat <command> (falling back to man <command>) and scrapes the result. The parser looks for OPTIONS, COMMANDS, or SUBCOMMANDS sections, 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 invoking man again. 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>.txt and merge their contents. This is how git-remote completions are chained into git.
  • Bulk generation: The generate-completions builtin pre-populates caches for an entire PATH or a list of commands. By default it forces regeneration (--force); pass --no-force to keep existing manual edits. Use -j/--jobs to parallelise scraping and --quiet to 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 S for subcommands and O for 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 _. Let generate-completions create the skeleton once if you are unsure about the exact spelling.

Authoring or overriding completions manually

  1. Create the cache directory (once): generate-completions or the first automatic scrape will do this, but you can also mkdir -p ~/.cache/cjsh/generated_completions yourself.
  2. 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.
  3. Edit the cache file: Open ~/.cache/cjsh/generated_completions/<sanitised-name>.txt and adjust the summary or add new lines using the format above.
  4. Add multi-level entries: For subcommand specific completions (e.g. kubectl get), create a second file named kubectl-get.txt with its own header, summary, and entries. cjsh stitches these together automatically when you tab complete.
  5. Preserve your changes: Future runs of generate-completions default to --force. Use generate-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 point generate-completions at a packaged man page (for example, install the corresponding *-doc package).
  • 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_completions or run generate-completions --force to rebuild all caches. Beware this overwrites manual edits.
  • Sandboxed environments: If man is 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.