Bash's sadly flawed smart (programmable) completion

April 9, 2024

Bash has an interesting and broadly useful feature called 'programmable completion' (this has sort of come up before). Programmable completion makes it possible for Bash to auto-complete things like command line options for the current program for you. Unfortunately one flaw in Bash's programmable completion is that it doesn't understand enough Bash command line syntax and so can get in your way.

Suppose, not hypothetically, that you are typing the following on the Bash command line on a Debian-based Linux system, with the bits in bold being what you typed before you hit tab:

# apt-get install $(grep -v '^#' somefi<TAB>

When you hit TAB to complete the file name, nothing will happen. This is because Bash has been told what the arguments to apt-get are and so 'knows' that they don't include files (this is actually wrong these days, but never mind). Bash isn't smart enough to recognize that by typing '$(' you've started writing a command substitution and are now in a completely different completion context, that of grep, where you definitely should be allowed to complete file names.

Bash could in theory be this smart but there are probably a number of obstacles to doing that in practice. For example, we don't have a well-formed command substitution here, since we haven't typed the closing ')' yet; Bash would effectively have to do something like the sort of on the fly parsing of incomplete code that editor autocompletion does. It's possible that Bash could do better with some heuristics, but the current situation is broadly easy to explain and reason about, even if the result is sometimes frustrating.

There are at least two ways to disable these programmable completions in Bash. You can turn off the feature entirely with 'shopt -u progcomp' or you can flush all of the registered programmable completions with 'complete -r'. In theory you can see the list of current completions with 'complete -p' and then remove just one of them with 'complete -r <name>', but in practice 'complete -p' doesn't always list a program until I've started trying to do completions with it.

(Where the shell snippets that define completions go is system dependent, but Linux systems will often put them in '/usr/share/bash-completion/completions'.)

People with better memories than me can also use M-/ instead to force completion of a filename no matter what Bash's programmable completion thinks should go there. M-! will complete command names, M-$ will complete variable names, and M-~ will complete user names. You can find these in the Bash manual page as the various 'complete-*' readline (key binding) command names.

(Another general flaw on programmable completion is that it relies on the people who provide the completion definitions for commands getting it right and they don't always do that, as I've seen in the past.)


Comments on this page:

By ramiro at 2024-04-10 14:12:18:

Something in Debian's bash-completion package, at least, breaks wildcard completion. When it's disabled, you can, for example, type "echo /*bin" and press tab; and you'll see "/bin /sbin" as possibilities. With completion enabled and loaded, no results are given, which for me is annoying enough to make me disable the feature entirely. I'd love to be able to tab-complete long options, but so far haven't put in the debugging effort.

Note that flushing the completions gives a subtly different result. It causes bash to print "bin/ sbin/" instead of "/bin /sbin". The difference seems purely cosmetic; both refer to the root directory, even if the leading slash isn't shown, and both expand the same way when the command's executed.

By Ian Z aka nobrowser at 2024-04-11 21:55:12:

I just remove the bash-completion package from all my systems. That's another way to get rid of it. I don't know which of the other two ways it resembles more closely.

By verglasz at 2024-04-15 09:15:33:

(fwiw, Zsh with my config handles your example "correctly", i.e., autocompleting files)

Written on 09 April 2024.
« Don't require people to change 'source code' to configure your programs
It's far from clear how grub package updates work on Ubuntu »

Page tools: View Source, View Normal.
Search:
Login: Password:

Last modified: Tue Apr 9 23:32:37 2024
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.