How to make zsh forward-word behaviour same as in bash/emacs
I have this in my .zshrc
for exactly that purpose:
# Bash-like navigation
autoload -U select-word-style
select-word-style bash
Edit: Ah, I remember what was missing in order to get everything working as I wanted to. I also overwrote forward-word-match
by putting the following content into $ZDOTDIR/functions/forward-word-match
(assuming your $ZDOTDIR/functions
directory is in $fpath
; otherwise put it into one or modify the $fpath
array as well):
emulate -L zsh
setopt extendedglob
autoload match-words-by-style
local curcontext=":zle:$WIDGET" word
local -a matched_words
integer count=${NUMERIC:-1}
if (( count < 0 )); then
(( NUMERIC = -count ))
zle ${WIDGET/forward/backward}
return
fi
while (( count-- )); do
match-words-by-style
# For some reason forward-word doesn't work like the other word
# commands; it skips whitespace only after any matched word
# characters.
if [[ -n $matched_words[4] ]]; then
# just skip the whitespace and the following word
word=$matched_words[4]$matched_words[5]
else
# skip the word but not the trailing whitespace
word=$matched_words[5]
fi
if [[ -n $word ]]; then
(( CURSOR += ${#word} ))
else
return 1
fi
done
return 0
To get your desired behavior with Emacs keybindings, all I had to do is:
bindkey '\ef' emacs-forward-word
This part of Moriz Bunkus' answer seems to work by itself now, too:
autoload -U select-word-style
select-word-style bash
It seems to perform even better in some edge cases (e.g. it treats ?
as a word boundary while the above does not.)