lirantal/nodejs-cli-apps-best-practices

[author required] New Practice: Support shell completion

jasonkarns opened this issue · 7 comments

[author required] New Practice: Support shell completion

hey @jasonkarns do you have any good references or specific call-outs in the JS ecosystem of how to follow this one?

Unfortunately, I don't. commander has no (or poor) support for completion, and I haven't found any cli utilities that provide it (yet). It's a bummer, because there are a load of cli utilities, and none that I'm aware of support completion out of the box. (Though it has been a while since I've looked.) The only resource I would point to is: https://github.com/scop/bash-completion but that's for registering completion scripts into the shell, not for helping create completion scripts.

Gotcha. I think it's more of a shell thing than the CLI itself so I'll close for now.

I don't think i'd go that far. In order to support shell completion, the CLI needs to do stuff.

Most integrations require the CLI to accept a flag (like --complete or similar) which instructs the CLI to print to STDOUT all available options/args/subcommands. It must also be contextual, so that when a user has already provided a subcommand, the CLI only emits options/flags/further-subcommands that are relevant to what has already been typed thus far. (and to not emit flags that have already been passed)

Other times, the completion can be a standalone script; but to be sure it keeps sync with the features of the CLI, it must be owned and maintained by the CLI team itself. (3rd-party completion scripts are perpetually out of date because the CLI evolves without regard to keeping the completion script current)

Whether the CLI itself operates as the completion script (via a --complete flag) or ships with a bundled completion script, in both cases the CLI owner is "responsible" for supporting completion capability.

Ahh interesting! is that --complete thing documented anywhere?

No, it's mostly just a convention. The CLI needs to either:

  • ship a standalone completion script that can be registered into the shell as the completion handler
  • OR support a flag that can be wrapped by a function which is registered into the shell as the completion handler

Many CLI utilities ship a companion script for completion (if you're a homebrew/linuxbrew user, have a look at ls -al /usr/local/etc/bash_completion.d/ to see the completion scripts that homebrew installs for you). But all those completion scripts essentially boil down to invoking the shell complete utility and registering a function to invoke when completion is necessary. It just so happens that a CLI can do double-duty as its own completion script if it looks for a particular flag and behaves as a completion script when the flag is present. It's only a minor convention that the flag itself be --complete (since it's never typed by users by hand, the flag name itself is immaterial. As long as the correct flag is used when the registration is first done with the complete utility).

Yep, I think this is a pretty decent practice to have. Less like the fact that it isn't cross-platform in an easy manner (standardization). I've seen evidence of only a few packages that handle this well, maybe just one (tabtab) on npmjs that is useful.

I'll re-open incase someone will want to pick it up.