Bowling for madducks
A long time ago, I had the idea of improving the interface between shell completion and the programs being completed. The result of this was the bzr shell-complete
command (or bzr s-c
for short), which was never fully fleshed out, and has since fallen into disrepair.
The principles behind this are + the program is the best place to store up-to-date and accurate information + the program already knows all these things (albeit usually in unparseable forms) + duplicating information and effort is annoying
Here is an excerpt from bzr s-c
, which was intended to give a comprehensive list of subcommands, paired with short descriptions:
diff:show differences in the working tree, between revisions or branches
export:export current or past revision to a destination directory or archive
get:create a new copy of a branch
help:show help on a command or other topic
ignore:ignore specified files or patterns
ignored:list ignored files and the patterns that matched them
info:show information about a working tree, branch or repository
init:make a directory into a versioned branch
There is one subcommand per line, separated from its description by a colon. Next you can invoke something like bzr s-c diff
to get the possible options and arguments for the diff
subcommand, although the output you would see today is broken and nearly useless.
Since I've lost faith in bzr, I'll illustrate what the output might be corresponding to topgit's tg remote
if topgit supported this kind of thing:
--populate
REMOTE
This would mean that tg remote
can understand the option --populate
, which takes no argument, and that the first non-option argument should be a REMOTE
.
REMOTE
would then be defined, for example, in zsh's _topgit
function as some kind of git remote which is completed in the same way you might complete a git remote for git.
The exciting part then, is that if tg remote
starts taking a --decimate
option, the topgit completion helper subsystem will start outputting it and _topgit
will do the right thing without having to be altered.
For tg export
, things are a bit more complicated, so let's have it be described in the style of the zsh completion system:
'(--collapse)--quilt:directory:_directories'
'(--collapse -b --branch)'{-b,--branch=}':branches:BRANCHES'
'(--quilt)--collapse:branch:BRANCH'
This means that --collapse
and --quilt
are exclusive, that -b
and --branch
cannot be used with --collapse
, that -b
and --branch
are equivalent, that -b and --branch
take an argument in the form of BRANCHES
, that --collapse
takes an argument in the form of BRANCH
, and that --quilt
takes an argument that's a real directory in the filesystem.
Then _topgit
would have logic to interpret BRANCH
as a branch, and BRANCHES
as a comma-separated list of branches.
A similar idea is the one used by axp. If you invoke axp self completion zsh
, it will output zsh completion functions for you. To me this seems more onerous on both the developers and the end users, but I suppose it gives you immediate flexibility that a more generic interface would lack.