11

Putting on Debian 8.3

stty werase '^H'

or on Arch Linux 2/2016

stty werase '^?'

in .bashrc (for example) makes Ctrl-Backspace delete the last word in the terminal. Still it's not the same behavior as in modern GUI applications (e.g. Firefox): It deletes the last whitespace-separated word, and not the last word separated by whitespace or characters like . : , ; " ' & / ( ).

Is it possible to make Ctrl-Backspace behave in the terminal similar to modern GUI applications? Also, is there any way to make Ctrl-Delete delete the word immediately before the cursor?

  • 1
    Your shell might support those actions, which could be bound to a given key. – Thomas Dickey Feb 21 '16 at 16:23
  • @ThomasDickey: I'm using bash. It's fine if it works just in bash. – wolf-revo-cats Feb 21 '16 at 17:30
21

There are two line editors at play here: the basic line editor provided by the kernel (canonical mode tty line editor), and bash's line editor (implemented via the readline library). Both of these have an erase-to-previous-word command which is bound to Ctrl+W by default. The key can be configured for the canonical mode tty line editor through stty werase; bash imitates the key binding that it finds in the tty setting unless overridden in its own configuration.

The werase action in tty line editor cannot be configured. It always erases (ASCII) whitespace-delimited words. It's rare to interact with the tty line editor — it's what you get e.g. when you type cat with no argument. If you want fancy key bindings there, you can run the command under a tool like rlwrap which uses readline.

Bash provides two commands to delete the previous word: unix-word-rubout (Ctrl+w or as set through stty werase), and backward-kill-word (M-DEL, i.e. Esc Backspace) which treats a word as a sequence of alphanumeric characters in the current locale and _. If you want Ctrl+Backspace to erase the previous sequence of alphanumeric characters, don't set stty werase, and instead put the following line in your .inputrc:

"\C-h": backward-kill-word

Note that this assumes that your terminal sends the Ctrl+H character for Ctrl+Backspace. Unfortunately it's one of those keys with no standard binding (and Backspace in particular is a mess for historical reasons).

There's also a symmetric command kill-word which is bound to M-d (Alt+D) by default. To bind it to Ctrl+Delete, you first need to figure out what escape sequence your terminal sends, then add a corresponding line in your .inputrc. Type Ctrl+V then Ctrl+Delete; this will insert something like ^[[3;5~ where the initial ^[ is a visual representation of the escape character. Then the binding is

"\e[3;5~": kill-word

If you aren't happy with either definition of a word, you can provide your own in bash: see confusing behavior of emacs-style keybindings in bash

  • 2
    excellent explanation ! The Ctrl+Del worked well. However, I cannot get Ctrl+Backspace to work. For Ctrl+v, Ctrl+Backspace my terminal says ^?. What should I put in the .inputrc ? Thank you – Ciprian Tomoiagă Mar 19 '17 at 12:16
  • 3
    @CiprianTomoiaga "\C-?": backward-kill-word or whatever readline function you want. But you can only define a binding for Ctrl+Backspace that's different from the binding for Backspace if they send different characters. If your terminal sends ^? for both Backspace and Ctrl+Backspace, then the application running in the terminal has no way to distinguish them. Some terminals can be configured (e.g. xterm, urxvt), others (e.g. VTE-based terminal emulators) can't. – Gilles Mar 19 '17 at 21:57
  • 3
    it's important to note that defining ~/.inputrc disables the default /etc/inputrc. to fix this you have to include that file: $include /etc/inputrc (from here) – Ciprian Tomoiagă Mar 31 '17 at 22:26
2

The behaviour of the WERASE character in cooked mode terminal processing is hardcoded, at least in Linux:

           if (kill_type == WERASE) {
                   /* Equivalent to BSD's ALTWERASE. */
                   if (isalnum(c) || c == '_')
                           seen_alnums++;
                   else if (seen_alnums)
                           break;
           }

So words are letters, digits, and underscore. This is the way it will be at all times in a terminal on Linux when an application that does its own cooked mode processing is not running.

readline's version (used by bash and others) seems to be a little different than the kernel's version, but it also seems to be hardcoded:

Words are composed of letters and digits.

But this doesn't seem to match what bash actually does for me: foo+bar^W erases everything, not just bar. There is more information about that here.

  • 1. vi user is probably just looking for backward-kill-word (default binding M-DEL) instead of unix-word-rubout. – Gilles Feb 21 '16 at 23:38
2

Try

alt+backspace

In elementary OS it works like the way you want it (just like ctrl+backspace)

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.