Different bash commands use different notions of word. Check the description of each command in the manual.
C-w
kills to the previous whitespace. M-DEL
(usually Alt+BackSpace) kills to the previous word boundary where words contain only letters and digits (the same as M-b
and M-f
), and M-d
kills forward similarly.
Bash uses the Readline library to process user input, and can be configured either via ~/.inputrc
or via the bind
builtin in ~/.bashrc
. You can bind a key to a different readline command if you wish. You can also use bind -x
to bind a key to a bash functions that modifies the READLINE_LINE
variable.
For example, to make M-d
kill a shell word, bind it to shell-kill-word
in your .bashrc
:
bind '"\M-d": shell-kill-word'
To make M-d
delete a whitespace-delimited word, there is no built-in function, so you need to write either a macro or a shell function. Since there is no motion command that goes by whitespace-delimited words, you need a function at least for that part.
delete_whitespace_word () {
local suffix="${READLINE_LINE:$READLINE_POINT}"
if [[ $suffix =~ ^[[:space:]]*[^[:space:]]+ ]]; then
local -i s=READLINE_POINT+${#BASH_REMATCH[0]}
READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}${READLINE_LINE:$s}"
fi
}
bind -x '"\ed": delete_whitespace_word'
To make M-d
kill a whitespace-delimited word is more complicated because as far as I know, there is no way to access the kill ring from bash code. So this requires a function to find the end of the portion to kill, and a macro to follow this by the actual killing.
forward_whitespace_word () {
local suffix="${READLINE_LINE:$READLINE_POINT}"
if [[ $suffix =~ ^[[:space:]]*[^[:space:]]+ ]]; then
((READLINE_POINT += ${#BASH_REMATCH[0]}))
else
READLINE_POINT=${#READLINE_LINE}
fi
}
bind -x '"\C-xF": forward_whitespace_word'
bind '"\C-x\C-w": kill-region'
bind '"\ed": "\e \C-xF\C-x\C-w"'
All of this would be a lot easier in zsh.