10

I have followed the guidance in Is there any way in the OS X Terminal to move the cursor word by word? and now in terminal I can move cursor word by word.

However, in Vim, I am only able to move backward word by word. I cannot move forward word by word, no matter I set \033f to option+cursor-right or shift+cursor-right. The only workaround I figured out is to go to normal mode and click <w> to move to next word. Any idea about how to fix that? Thanks.

Community
  • 1
  • 1
ximyu
  • 2,489
  • 3
  • 19
  • 16

3 Answers3

12

w is not a workaround. It's the primary way to move word by word (see also: W, b, B, e, E). What you want is a workaround that won't help you learn Vim at all.

romainl
  • 186,200
  • 21
  • 280
  • 313
3

Some may argue that moving around with VIM native keyboard shortcuts is not a workaround, but for me it sure is both very inconvenient and very inefficient. Especially the part where you need to switch between insert mode and normal mode just to move to the next word.

That's why I came up with a solution based on this answer on SuperUser. The idea is to map input provided by the Terminal.app directly in VIM. The answer on SU shows what to put into your vimrc file for the Home/End keys to work as expected.

My tweaked version below includes the Option+arrow (or Alt+arrow) navigation on words. I've tried to mimic the behavior of Terminal's moving around as close as I could get. So pressing Option+Right (Alt+Right) will move the caret to the next character after the word (as opposed to the last character of the word, which is VIMs w native bahavior).

let tp=$TERM_PROGRAM
if tp == 'Apple_Terminal'
  :" map Mac OS X Terminal.app

  " map Home/End:
  :map <ESC>[H <Home>
  :map <ESC>[F <End>
  " small 'o' letter in <C-o> means no exit from the insert mode
  :imap <ESC>[H <C-o><Home>
  :imap <ESC>[F <C-o><End>
  :cmap <ESC>[H <Home>
  :cmap <ESC>[F <End>

  " map Option+Left/Option+Right:
  " for this to work you must have the bindings in Settings > Keyboard set
  " as follows:
  " 'option cursor left' to '\033b'
  " 'option cursor right' to '\033f'
  :map <ESC>f el
  :imap <ESC>b <C-o>b
  :imap <ESC>f <C-o>el
  :cmap <ESC>f el
endif

As a small, but significant bonus you get Home/End navigation without exiting the insert mode. Tested on 10.8.5.

Community
  • 1
  • 1
Maciej Sz
  • 11,151
  • 7
  • 40
  • 56
  • 1
    This is fantastic, but i've noticed in insert mode I'll get an extra "l" appended to the move. Ex if `[x]` cursor.. `[x]foo bar` then ⌥ --> `fool[x] bar` --> ⌥ `folo balr[x]` – skilbjo Aug 10 '16 at 18:05
  • ^^ update to the above... just make `:imap f e`... the `l` is unnecessary – skilbjo Aug 11 '16 at 00:41
1

Let me clear a few things up for you. Bash (the shell program running inside the terminal) has the behavior you are used to. (Using Alt+f to move forward by word, and Alt+b to move backward by word.) This was originally done to be like Emacs. You can use the command

set -o vi

to switch to vim behavior. In this mode, you can use Esc to switch to normal mode, and move around like in vim; then press i to go back to insert mode.

So don't be surprised that Vim isn't trying to act like Emacs. The whole power behind vim lies behind these simple motions.