Delete last word (Ctrl-W): Make bash shell behave like vim command line

bashcommand linekeyboard shortcutsvim

Among the many useful keyboard shortcuts available in the bash shell, there is CtrlW to delete the word to the left of the cursor. Let's suppose my command line looks like the following:

cp some-file /foo/bar/baz/copy

Now I'd expect to be able to press CtrlW and end up with the following:

cp some-file /foo/bar/baz/

In Vim's command line it actually works this way: Only alphanumeric characters are treated as "word", whereas special characters (like /) serve as delimiters marking the start of a new "word".

But unfortunately it doesn't work like that in all shells I've used so far. Only spaces will delimit a "word", so pressing the shortcut with the command line shown above will give me:

cp some-file

Is there a way to make Bash behave like Vim? Some configuration I can put into my .bashrc?

Best Answer

This has nothing to do with Vim, all editors behave that way (including emacs), they treat non-word characters as delimiters. Anyway, the behavior you are talking about is controlled by readline and its manual lists quite a few commands you can assign shortcuts to. I am pasting a few relevant ones here but I recommend you read man readline for more info:

   backward-word (M-b)
          Move  back  to  the  start  of the current or previous word.  Words 
          are composed of alphanumeric characters (letters and digits).

   kill-line (C-k)
          Kill the text from point to the end of the line.
   kill-word (M-d)
          Kill from point the end of  the  current  word,  or  if  between
          words,  to  the  end  of the next word.  Word boundaries are the
          same as those used by forward-word.
   backward-kill-word (M-Rubout)
          Kill the word behind point.  Word boundaries  are  the  same  as
          those used by backward-word.
   unix-word-rubout (C-w)
          Kill  the  word behind point, using white space as a word bound‐
          ary.  The killed text is saved on the kill-ring.
   unix-filename-rubout
          Kill the word behind point, using  white  space  and  the  slash
          character  as  the word boundaries.  The killed text is saved on
          the kill-ring.

So, the one you want is backward-kill-word, which uses non alphanumeric characters as word boundaries. By default, it is assigned to Alt+Backspace but you can change that by using either the global /etc/inputrc if you want them to apply to all users or (better) your own local $HOME/.inputrc.

As far as I can tell, Ctrl+W seems to be reserved and you can't use that one but you can choose another shortcut, Ctrl+J for example. Create a $HOME/.inputrc file if it doesn't exist and add this line to it:

Control-J: backward-kill-word 

That should be enough for most modern terminal emulators. However, some older terminals use different codes. If you're using xterm, for example, the line above should be written as:

C-J: backward-kill-word