In-snap tab completion
Yesterday we landed in-snap tab completion into snapd. This means that really soon (it’s in the edge channel already, and should be part of the 2.26 release which should be in stable in a few weeks’ time) you’ll be able to add tab completion to apps you ship in snaps, and that this tab completion will be run inside the sandbox, confined to have the same view of your system as the app itself does.
Quoting myself:
For a snap app to tab complete, it needs to include a
completerkey, that points to the bash snippet that would usually live in/usr/share/bash-completion/completions. Completion is run confined, and marshalled out. There’s an example snap, used in tests, undertests/lib/snaps/complexion.Furthermore, at this stage to enable snap completions you need to source
/usr/lib/snapd/complete.shafter sourcing/etc/bash_completion(or/usr/share/bash-completion/bash_completion). It adds a default completion handler that overrides and falls back to the usual one.Note that while the snap-side support is for bash completion, if you want to add, say, zsh completion all you need to do is write something like
complete.shthat works for bash. This is the unmarshaller.Also note that because the completion is confined, if the snap can’t reach it it can’t complete it. If you need to complete hosts, for example, you’ll have to override the usual hosts/known hosts file inside the snap. If you want to complete filenames, the snap needs to be able to access the directory path. This usually is what’s wanted, as you don’t want to complete things you can then not access.
Lastly, I expect there will be issues with this that need refining. The whole edifice of tab completion is a tower of toothpicks stood on end, and this work is about adding a pipe to the middle of it. In other words, please report bugs about this!
making the whole thing work feels a lot like black magic (and I’m not an arcane mage of bash, so I’m sure I missed some things), but it works :-)
future work
I still need to properly sync with Sergio to get support for this into snapcraft, so if you want to poke at it either play with the in-tree complexion snap that we use for testing, or manually add a completer key to your snap’s app in the snap.yaml itself. That’s the one snapcraft generates, not the snapcraft.yaml it takes as input.
I want to push the complete.sh script up into the bash-completion project itself, to make activating this just work (instead of a user having to edit their ~/.bashrc). Haven’t spoken to them about this yet though, so we’ll see.
I also need to figure out why it doesn’t quite work properly when the input string to be completed has spaces in it. Outpupt, no problem. Input, no joy. Needs digging.
testable tab completion
I’ll probably split this out to a separate post, but the really exciting thing that comes out of this work, for me at least, is the ability to intercept tab completion, and thus create testable and/or instrumentable tab completion. Imagine, unit tests for your tab completers! I don’t think anybody’s doing that without using kludgy things like expect. Yes, we also have integration tests for in-snap tab completion that use expect, but … unit tests for your completion snippets! Whoa.