In bash, pressing Tab invokes the programmable completion feature and either (a) expands to a unique path or command matching what's typed or (b) a list of possible options.
Is it possible to undo the entire expansion made by pressing Tab?
Example:
- My current command is
ls application/views/
. - There are two possible expansions on that command:
helpers/
andscripts/
. - I type heTab, which expands to
helpers/
. - I realize I meant the other one
scripts
. - Now I have to delete the entire expansion "helpers/".
I usually just backspace over the entire path (helpers/
in this case), because I find striking readline undo Control+_ tedious. What I'd like is a single key sequence that deletes the full match of the expansion, regardless of any characters I initially typed and any spaces or slashes added to the end.
Running list of key sequences suggested by comments or my own read of the GNU reference. None of these accomplish the goal:
- Meta+b — Moves back to the previous
/
or, but doesn't delete.
- Meta+Del — Deletes one character, not the entire word.
- Meta+Backspace — Moves back one character without deleting.
- Control+W — Deletes the entire path, not just the expansion. So in my example, after pressing Tab, bash expands that to
ls application/views/helpers
, then when I press Control+W, bash deletesapplication/views/helpers
.
If relevant, I'm using the vi editing mode on a Gentoo Linux box. I've checked my configuration and I've not remapped any characters.
Best Answer
You're giving the keystrokes, but not the readline bindings, this can explain differences in observed behaviour (try
bind -p
).The only way I can think of to do exactly what you ask is to use a custom completion function that saves the buffer state, and a separate key binding which invokes a companion shell function to restore it.
In addition to @Mark Plotnick's excellent suggestion to use
menu-complete
, other readline/bash options are:shell-backward-kill-word
this removes a "shell word" which in the case of an expanded file or path will be the complete file or path namebackward-kill-word
this removes a "readline word", which in the case of a file or path will be a file or directory name component, including the trailing/
undo
which undoes each change atomically, but this almost certainly requires several attempts to fully remove a complete expansion, this is almost certainly the function you have bound to to ctrl-_ (bash default)set-mark
andkill-region
are lesser used readline features,set-mark
marks the current cursor position, andkill-region
deletes from the mark to the cursor. This requires you to invokeset-mark
(default meta-space) in advance so that you can later usekill-region
to delete back to it (no default binding)possible-completions
(bound to meta-=) which lists the completions without modifying the command bufferYou could also write your own function to modify the input buffer, and bind it to a function (here's one I made earlier) but I don't see how that would be very much better than
backward-kill-word
in this case.You can test bindings on the fly without using
.inputrc
using bash'sbind
command, e.g.:backward-kill-word
is the best fit, default binding is metactrl-h.set-mark
/kill-region
would be better, but I can't think of a neat way to automate the use of this though.