Discussion:
[Help-bash] vim mode changes
Chadwick Rogers
2017-08-11 03:25:53 UTC
Permalink
I found this old thread:
http://lists.gnu.org/archive/html/help-bash/2016-11/msg00004.html

But my scenario is slightly different. Run bash in vi-mode, type "echo
hello world", press enter, press up arrow on your keyboard, press the home
key to jump to the beginning of the line followed by the right arrow to the
end of 'hello' or press the left arrow to the end of 'hello', press ctrl+w,
the word will not delete. Go back to the end of the line, press ctrl+w
three times and deleting works fine all the way to the beginning of the
line. Adding "set bind-tty-special-chars off" to my inputrc has no effect
on this.

Any help would be appreciated.
Greg Wooledge
2017-08-11 12:14:07 UTC
Permalink
Post by Chadwick Rogers
But my scenario is slightly different. Run bash in vi-mode, type "echo
hello world", press enter, press up arrow on your keyboard, press the home
key to jump to the beginning of the line followed by the right arrow to the
end of 'hello' or press the left arrow to the end of 'hello', press ctrl+w,
the word will not delete.
Those just are not vi editing commands or paradigms. Those are emacs
editing paradigms. You haven't even hit Esc at any point to switch
to command mode, let alone used a vi command like "dw" to delete a
word.

Here's how it works in vi mode, using vi editing paradigms:

echo hello world (Enter)
Esc k # now you are on the previous command, at start of line
w # now you are at the start of "hello". Shift-W would also work.
dw # delete the word "hello". dW would also work.
Enter # execute the command

Note the difference between "w" words and "W" Words. The latter includes
all non-whitespace characters, while the former stops at many of the
punctuation characters.

The only time Ctrl-w does anything in vi mode is when you're typing
merrily along in insert/append mode, and you realize that you have
seriously mangled the previous word, to the point where you feel it
would be quicker to nuke the entire word and retype it, than to
backspace and correct it. So you press Ctrl-w while you are still
in insert/append mode, and it acts like "pressing backspace a whole
bunch of times". Then you can retype that word.

You don't use Ctrl-w after entering command mode and moving the cursor.

Don't believe me? Go into an actual vi or vi-clone editor and try
it out. Open a file with some text in it. Go to the end of a line
with multiple words. Press Ctrl-w. Nothing happens! Nothing is
supposed to happen. Ctrl-w is not a command-mode command. It's
cribbed from the "werase" feature of the terminal driver, and only
applies to insert/append mode.
Chadwick Rogers
2017-08-11 13:10:58 UTC
Permalink
Thanks for the reply. Perhaps my description is wrong. The behaviour I
describe only happens when inputrc has in editing-mode vi, and the
behaviour seems to have changed in a recent version.
Post by Chadwick Rogers
Post by Chadwick Rogers
But my scenario is slightly different. Run bash in vi-mode, type "echo
hello world", press enter, press up arrow on your keyboard, press the
home
Post by Chadwick Rogers
key to jump to the beginning of the line followed by the right arrow to
the
Post by Chadwick Rogers
end of 'hello' or press the left arrow to the end of 'hello', press
ctrl+w,
Post by Chadwick Rogers
the word will not delete.
Those just are not vi editing commands or paradigms. Those are emacs
editing paradigms. You haven't even hit Esc at any point to switch
to command mode, let alone used a vi command like "dw" to delete a
word.
echo hello world (Enter)
Esc k # now you are on the previous command, at start of line
w # now you are at the start of "hello". Shift-W would also work.
dw # delete the word "hello". dW would also work.
Enter # execute the command
Note the difference between "w" words and "W" Words. The latter includes
all non-whitespace characters, while the former stops at many of the
punctuation characters.
The only time Ctrl-w does anything in vi mode is when you're typing
merrily along in insert/append mode, and you realize that you have
seriously mangled the previous word, to the point where you feel it
would be quicker to nuke the entire word and retype it, than to
backspace and correct it. So you press Ctrl-w while you are still
in insert/append mode, and it acts like "pressing backspace a whole
bunch of times". Then you can retype that word.
You don't use Ctrl-w after entering command mode and moving the cursor.
Don't believe me? Go into an actual vi or vi-clone editor and try
it out. Open a file with some text in it. Go to the end of a line
with multiple words. Press Ctrl-w. Nothing happens! Nothing is
supposed to happen. Ctrl-w is not a command-mode command. It's
cribbed from the "werase" feature of the terminal driver, and only
applies to insert/append mode.
Bob Proulx
2017-08-11 18:47:57 UTC
Permalink
Post by Chadwick Rogers
Post by Greg Wooledge
Post by Chadwick Rogers
But my scenario is slightly different. Run bash in vi-mode,
type "echo hello world", press enter, press up arrow on your
keyboard, press the home key to jump to the beginning of the
line followed by the right arrow to the end of 'hello' or press
the left arrow to the end of 'hello', press ctrl+w, the word
will not delete.
Those just are not vi editing commands or paradigms. Those are emacs
editing paradigms.
They aren't Emacs editing paradigms. Control-W is a tty driver
editing character. Nothing emacs about it at all. (In Emacs C-w
actually does something different.)

$ stty -a | grep werase
werase = ^W; ...

Dates back to the beginning of time before command line editing using
either emacs or vi modes existed.
Post by Chadwick Rogers
Post by Greg Wooledge
You haven't even hit Esc at any point to switch to command mode,
let alone used a vi command like "dw" to delete a word.
The up arrow is the ESC k here. There is an escape in the up arrow
terminal sequence (ESC O A on my terminal). After hitting up arrow
you are in command mode.
Post by Chadwick Rogers
Thanks for the reply. Perhaps my description is wrong. The behaviour I
describe only happens when inputrc has in editing-mode vi, and the
behaviour seems to have changed in a recent version.
Your description was okay. I confirm that something has changed in
recent versions of bash.

On my Debian system with bash 4.3.30 this works as you want. The ^W
character anywhere on the line will erase the previous word. In more
recent bash 4.4.12 it now behaves differently as you are describing
and only deletes the previous word if at the end of the line.
Definitely a behavior change between the bash versions.

Bob
Clark Wang
2017-08-13 15:56:11 UTC
Permalink
Post by Chadwick Rogers
http://lists.gnu.org/archive/html/help-bash/2016-11/msg00004.html
But my scenario is slightly different. Run bash in vi-mode, type "echo
hello world", press enter, press up arrow on your keyboard, press the home
key to jump to the beginning of the line followed by the right arrow to the
end of 'hello' or press the left arrow to the end of 'hello', press ctrl+w,
the word will not delete. Go back to the end of the line, press ctrl+w
three times and deleting works fine all the way to the beginning of the
line. Adding "set bind-tty-special-chars off" to my inputrc has no effect
on this.
Any help would be appreciated.
I have the following in my bashrc:

bind 'set bind-tty-special-chars off'
bind -m vi-insert '"\C-w": unix-word-rubout'

Not sure if it works for you. (I'm on a Mac now and have no idea which key
combo is equal to Home. Will try your problem later on a Linux.)
Clark Wang
2017-08-14 02:19:59 UTC
Permalink
Post by Clark Wang
Post by Chadwick Rogers
http://lists.gnu.org/archive/html/help-bash/2016-11/msg00004.html
But my scenario is slightly different. Run bash in vi-mode, type "echo
hello world", press enter, press up arrow on your keyboard, press the home
key to jump to the beginning of the line followed by the right arrow to the
end of 'hello' or press the left arrow to the end of 'hello', press ctrl+w,
the word will not delete. Go back to the end of the line, press ctrl+w
three times and deleting works fine all the way to the beginning of the
line. Adding "set bind-tty-special-chars off" to my inputrc has no effect
on this.
Any help would be appreciated.
bind 'set bind-tty-special-chars off'
bind -m vi-insert '"\C-w": unix-word-rubout'
Just found a Debian 9 Linux and reproduced your problem. And my settings
seem to have fixed it.
Post by Clark Wang
Not sure if it works for you. (I'm on a Mac now and have no idea which key
combo is equal to Home. Will try your problem later on a Linux.)
Chet Ramey
2017-08-14 15:30:40 UTC
Permalink
Post by Chadwick Rogers
http://lists.gnu.org/archive/html/help-bash/2016-11/msg00004.html
But my scenario is slightly different. Run bash in vi-mode, type "echo
hello world", press enter, press up arrow on your keyboard, press the home
key to jump to the beginning of the line followed by the right arrow to the
end of 'hello' or press the left arrow to the end of 'hello', press ctrl+w,
the word will not delete. Go back to the end of the line, press ctrl+w
three times and deleting works fine all the way to the beginning of the
line. Adding "set bind-tty-special-chars off" to my inputrc has no effect
on this.
This is another change resulting from readline's new implementation of the
Posix vi-mode editing standard. ^W now uses the Posix definition of word
boundaries. You can bind ^W to its old command name (unix-word-rubout) to
get the old behavior back in addition to unsetting bind-tty-special-chars.

bind -m vi-insert '"\C-w":unix-word-rubout'
bind 'set bind-tty-special-chars off'
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU ***@case.edu http://cnswww.cns.cwru.edu/~chet/
Loading...