3

The word/WORD motions w, W, e, and E will overshoot to the next line when the cursor reaches the end of the current one.

The word/WORD motions b, B, ge, and gE will overshoot to the previous line when the cursor reaches the beginning of the current one.

Is there a way to disable this feature, so the cursor stops at the beginning/end of the line when using word/WORD motions?

3

As a general advice I would recommend to get used to the built-in behavior. I strongly believe that if you want to avoid any trouble your customization should extend vim's features and not modify them. However here is a solution:

There is no built-in mechanism to prevent these motions from changing lines, but you could hack something yourself! For example your can create a function like this:

function! MyMotion(motion)
    let pos=getpos('.')
    execute 'normal! ' . a:motion
    if (pos[1] != getcurpos()[1])
        call setpos('.', pos)
    endif
endfunction

The function takes one motion (w, ge, ...) as argument. It saves the current position of the cursor with :h getpos(), executes the motion and if the cursor is on a different line then it moves back the cursor to the previous position.

Now you will also need to create mappings like these:

nnoremap <silent> w :call MyMotion('w')<CR>
nnoremap <silent> W :call MyMotion('W')<CR>
nnoremap <silent> e :call MyMotion('e')<CR>
...

This way w and W will call your new function.

But since there is a lot of mappings to create you can use the following code:

let motions = ['w', 'W', 'b', 'B', 'e', 'E', 'ge', 'gE']
for motion in motions
    execute "nnoremap <silent> " . motion . " :call MyMotion('" . motion . "')<CR>"
endfor

You create a list of the keys you want to remap and with a simple loop and the help of :h :execute you create the relevant mappings.

I tested this solution very quickly and at first sight it seems to work but maybe there are some edge cases I didn't see.


Edit

I read your question again and realized that you want the cursor to end up on the beginning or end of the line rather than staying in the same position. You could easily do that by replacing the call to setpos by normal! k$ or normal! j0 depending on the value of pos[1] - getcurpos()[1]. That will be left as an exercise for the reader :)

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.