35

Bash behaviour

I've just migrated from bash to zsh. In bash, I had the following line in ~/.inputrc.

"\e\C-?": unix-filename-rubout

Hence, Alt+Backspace would delete back to the previous slash, which was useful for editing paths.

Separately, bash defaults to making Ctrl+w delete to the previous space, which is useful for deleting whole arguments (presuming they don't have spaces). Hence, there two slightly different actions performed with each key combination.

Zsh behaviour

In zsh, both Alt+Backspace and Ctrl+w do the same thing. They both delete the previous word, but they are too liberal with what constitutes a word-break, deleting up to the previous - or _. Is there a way to make zsh behave similarly to bash, with two independent actions? If it's important, I have oh-my-zsh installed.

3
  • 1
    Do you want to change zsh's definition of what constitutes a word? If so: unix.stackexchange.com/questions/48577/… Or do you want to define a new command with a different definition of word? – Gilles 'SO- stop being evil' Jan 30 '16 at 13:22
  • @Gilles I guess a combination of both. In bash, I'd use the two distinct commands regularly: i.e. delete to the last / and delete to the last ` `. They have different functions. – Sparhawk Jan 30 '16 at 13:24
  • 1
    @Gilles So yes, that link works for my bash-like Alt+Backspace behaviour, but I'd still like the (different) bash-like Ctrl+w behaviour, i.e. delete to last space. – Sparhawk Jan 30 '16 at 13:35
18

Edit: The next google result after your question was this one with same solution : zsh: make ALT+BACKSPACE stop at non-alphanumeric characters

This answer was provided by /nick FoH from #zsh on freenode.

backward-kill-dir () {
    local WORDCHARS=${WORDCHARS/\/}
    zle backward-kill-word
}
zle -N backward-kill-dir
bindkey '^[^?' backward-kill-dir

This way you can use ctrl+w for deleting a Word (in vim lingo) and alt+bkspc to delete a word

3
  • Brilliant! Thanks for taking the time to investigate and answer. – Sparhawk Oct 30 '16 at 10:00
  • Re Google: except I asked my question nine months ago, and they asked theirs less than a month ago. – Sparhawk Oct 30 '16 at 10:06
  • 1
    time is just a social construct man!.. but seriously, fair point. – JunkMechanic Oct 10 '19 at 13:43
25

A similar question was asked here: zsh: stop backward-kill-word on directory delimiter

and a workable solution given: add these settings to your zshrc:

autoload -U select-word-style
select-word-style bash
7
  • 1
    Thanks for the answer. However, none of those answers work for me. (Specifically, the one you quoted makes no change.) Possibly, it's because I have oh-my-zsh installed. In any case, this doesn't seem to address the two different functions and key bindings as per my question. (And if my question were it dupe it should be closed as a dupe. Which it is not.) – Sparhawk Jan 30 '16 at 3:15
  • 2
    You need to tweak WORDCHARS variable. In zsh it's easy vared WORDCHARS – Jshura Jan 30 '16 at 4:34
  • It would only be a duplicate if we matched it against an answered question in this forum. – Thomas Dickey Jan 30 '16 at 12:19
  • @ThomasDickey Oh yes, apologies, I didn't notice I'd swapped SE sites. – Sparhawk Jan 30 '16 at 13:24
  • 2
    @Jshura No, as per the question, I'd like two different functions, which is possible in bash. – Sparhawk Jan 30 '16 at 13:28
8

Expanding on JunkMechanic's answer, I wanted that

  • existing zsh shortcuts (CtrlW, Ctrl and Ctrl) works as in zsh defaults
  • Alt-based shortcuts (AltW, Alt and Alt) work similarly, but "finer grained", e.g. up to the closest /

Here's what I use now:

# Alt+Backspace
backward-kill-dir () {
    local WORDCHARS=${WORDCHARS/\/}
    zle backward-kill-word
}
zle -N backward-kill-dir
bindkey '^[^?' backward-kill-dir


# Alt+Left
backward-word-dir () {
    local WORDCHARS=${WORDCHARS/\/}
    zle backward-word
}
zle -N backward-word-dir
bindkey "^[[1;3D" backward-word-dir

# Alt+Right
forward-word-dir () {
    local WORDCHARS=${WORDCHARS/\/}
    zle forward-word
}
zle -N forward-word-dir
bindkey "^[[1;3C" forward-word-dir
1

I achieved your desired result by sticking the following in $ZDOTDIR/.zshrc:

# Use bash-like word definitions for navigation and operations
autoload -Uz select-word-style
select-word-style bash

# Use C-w to kill back to the previous space
zle -N backward-kill-space-word backward-kill-word-match
zstyle :zle:backward-kill-space-word word-style space
bindkey '^W' backward-kill-space-word

This has an advantage over other answers by not limiting the target delimiter of Alt+Backspace to /; for example, it will delete back to -, as well. Still, Ctrl+w will delete back to the previous space. This is more bash-like than other answers.

I am using zsh 5.8 on macOS, without oh-my-zsh or any other configuration framework.

Reference: http://zsh.sourceforge.net/Doc/Release/User-Contributions.html#index-backward_002dkill_002dword_002dmatch


Bonus: The following makes zsh even more bash-like:

# Use C-u to kill to the beginning of the line
bindkey '^U' backward-kill-line

# Use C-x C-e to edit the current command line in $VISUAL
autoload -Uz edit-command-line
zle -N edit-command-line
bindkey '^X^E' edit-command-line
0

Just wanted to add this in nh2's answer

  • alt + left/right arrow to move
  • alt + delete/w for deleting word forward/backward

# Alt+Delete
forward-kill-dir () {
    local WORDCHARS=${WORDCHARS/\/}
    zle kill-word
}
zle -N forward-kill-dir
bindkey '^[[3;3~' forward-kill-dir

# Alt+w
backward-kill-dir () {
    local WORDCHARS=${WORDCHARS/\/}
    zle backward-kill-word
}
zle -N backward-kill-dir
bindkey '^[w' backward-kill-dir

# Alt+Left
backward-word-dir () {
    local WORDCHARS=${WORDCHARS/\/}
    zle backward-word
}
zle -N backward-word-dir
bindkey "^[[1;3D" backward-word-dir

# Alt+Right
forward-word-dir () {
    local WORDCHARS=${WORDCHARS/\/}
    zle forward-word
}
zle -N forward-word-dir
bindkey "^[[1;3C" forward-word-dir

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.