Zsh+QTerminal: Backspace deletes word instead of characters when browsing history or suggestions

When I press Arrow Up or Ctrl+R ... Zsh is displaying commands from the history, just like I’m used to from Bash. But when I press backspace, it doesn’t delete the last character from the displayed command. Instead it deletes everything until it hits a space. This is especially annoying (to me) if you pull up an item from history and then start typing because backspace will still delete the entire last word, even if you wrote it yourself. I don’t like that behavior because it is inconsistent with how it behaves when you write the entire command yourself without using a history item as a template.

It also happens when typing a command normally and then accepting a suggestion using Arrow Right btw.

How can I disable that behavior so that Backspace always only deletes one character (unless of course Ctrl is held down at the same time)?

Hi @0x0,

AFAIK this behaviour is terminal emulator dependent, and not ZSH itself. Or it might be oh-my-zsh, I’m unsure. Because mine doesn’t behave like this, and it’s a non-standard ZSH configuration, so it’s not ZSH itself.

I might have been wrong about this. AFAI can see, it can be configured in ZSH itself.

Which terminal emulator are you using?

Edit:

Please provide the output of:

bindkey
1 Like

I’m using QTerminal drop down.

$ bindkey
"^@" set-mark-command
"^A" beginning-of-line
"^B" backward-char
"^D" delete-char-or-list
"^E" end-of-line
"^F" forward-char
"^G" send-break
"^H" backward-kill-word
"^I" expand-or-complete
"^J" accept-line
"^K" kill-line
"^L" clear-screen
"^M" accept-line
"^N" down-line-or-history
"^O" accept-line-and-down-history
"^P" up-line-or-history
"^Q" push-line
"^R" history-incremental-search-backward
"^S" history-incremental-search-forward
"^T" transpose-chars
"^U" kill-whole-line
"^V" quoted-insert
"^W" backward-kill-word
"^X^B" vi-match-bracket
"^X^F" vi-find-next-char
"^X^J" vi-join
"^X^K" kill-buffer
"^X^N" infer-next-history
"^X^O" overwrite-mode
"^X^R" _read_comp
"^X^U" undo
"^X^V" vi-cmd-mode
"^X^X" exchange-point-and-mark
"^X*" expand-word
"^X=" what-cursor-position
"^X?" _complete_debug
"^XC" _correct_filename
"^XG" list-expand
"^Xa" _expand_alias
"^Xc" _correct_word
"^Xd" _list_expansions
"^Xe" _expand_word
"^Xg" list-expand
"^Xh" _complete_help
"^Xm" _most_recent_file
"^Xn" _next_tags
"^Xr" history-incremental-search-backward
"^Xs" history-incremental-search-forward
"^Xt" _complete_tag
"^Xu" undo
"^X~" _bash_list-choices
"^Y" yank
"^[^D" list-choices
"^[^G" send-break
"^[^H" backward-kill-word
"^[^I" self-insert-unmeta
"^[^J" self-insert-unmeta
"^[^L" clear-screen
"^[^M" self-insert-unmeta
"^[^_" copy-prev-word
"^[ " expand-history
"^[!" expand-history
"^[\"" quote-region
"^[\$" spell-word
"^['" quote-line
"^[," _history-complete-newer
"^[-" neg-argument
"^[." insert-last-word
"^[/" _history-complete-older
"^[0" digit-argument
"^[1" digit-argument
"^[2" digit-argument
"^[3" digit-argument
"^[4" digit-argument
"^[5" digit-argument
"^[6" digit-argument
"^[7" digit-argument
"^[8" digit-argument
"^[9" digit-argument
"^[<" beginning-of-buffer-or-history
"^[>" end-of-buffer-or-history
"^[?" which-command
"^[A" accept-and-hold
"^[B" backward-word
"^[C" capitalize-word
"^[D" kill-word
"^[F" forward-word
"^[G" get-line
"^[H" run-help
"^[L" down-case-word
"^[N" history-search-forward
"^[OA" history-substring-search-up
"^[OB" history-substring-search-down
"^[OC" forward-char
"^[OD" backward-char
"^[OF" end-of-line
"^[OH" beginning-of-line
"^[Oc" forward-word
"^[Od" backward-word
"^[P" history-search-backward
"^[Q" push-line
"^[S" spell-word
"^[T" transpose-words
"^[U" up-case-word
"^[W" copy-region-as-kill
"^[[1;5C" forward-word
"^[[1;5D" backward-word
"^[[200~" bracketed-paste
"^[[2~" overwrite-mode
"^[[3~" delete-char
"^[[5~" history-beginning-search-backward
"^[[6~" history-beginning-search-forward
"^[[7~" beginning-of-line
"^[[8~" end-of-line
"^[[A" history-substring-search-up
"^[[B" history-substring-search-down
"^[[C" forward-char
"^[[D" backward-char
"^[[F" end-of-line
"^[[H" beginning-of-line
"^[[Z" undo
"^[_" insert-last-word
"^[a" accept-and-hold
"^[b" backward-word
"^[c" capitalize-word
"^[d" kill-word
"^[f" forward-word
"^[g" get-line
"^[h" run-help
"^[l" down-case-word
"^[n" history-search-forward
"^[p" history-search-backward
"^[q" push-line
"^[s" spell-word
"^[t" transpose-words
"^[u" up-case-word
"^[w" copy-region-as-kill
"^[x" execute-named-cmd
"^[y" yank-pop
"^[z" execute-last-named-cmd
"^[|" vi-goto-column
"^[~" _bash_complete-word
"^[^?" backward-kill-word
"^_" undo
" "-"~" self-insert
"^?" backward-delete-char
"\M-^@"-"\M-^?" self-insert

In Gnome Terminal the behavior appears to be correct.

Edit:
My QTerminal Settings:

Edit2:
This only happens with Zsh+QTerminal btw. Using Bash in Qterminal, backspace deletes only one character.

OK, let’s try the following:

See if it’s better after executing:

bindkey -r "^H"

Test it. If that helps, we’ll make it persistent.

1 Like

If I do that, backspace stops working entirely until I source my .zshrc again.

OK, I’m guessing about the keycodes as well now. Please try:

keybind -r "^W"
1 Like

Backspace is still deleting the last word.

Try:

bindkey -r "^[^?"

Edit:

I’ve got to go, so perhaps someone else might know.

Edit #2:

Just tested, and this seemed to work for me:

I could Backspace but not Ctrl+Backspace

1 Like

If you’re using GNOME, then why not use guake? qterminal was developed for Qt-based environments.

3 Likes

Another option is tilix which has a Quake-style mode. It’s my favorite terminal because it’s the only VTE terminal with tiling. :grinning:

1 Like