3

I have a file that uses 4-space indentation. By default, when I move horizontally, Vim moves over those spaces one by one.

How can I configure Vim so that it moves 4 spaces horizontally when moving over indentation whitespace?

  • 2
    I asked this question on SO last year: How can I get the same behaviour navigating tabs if I use expandtab, but never really got a satisfactory answer other than "use w or ^ to skip the indentation". – Martin Tournoij Aug 14 '15 at 10:58
  • Use noexpandtab, configure 4-space tabs, and :retab. At the end, if you must, re-enable expandtab and :retab again. – VanLaser Aug 15 '15 at 14:53
  • I think all possible situations where one would need to move by sw are covered by other vim commands. For example, if one would need to move one indent level back and start inserting code there, we could instead de-indent first with << and then press I to insert in the beginning of the line. – Vitor Aug 18 '15 at 11:07
4

Maybe you can add the following functions to your .vimrc. They compare the current position of the cursor to the position of the first character and if necessary they skip the non printed characters before the first non blank one.

function! MyLMotion()
    let cursorPosition=getpos(".")
    normal ^
    let firstChar=getpos(".")

    if cursorPosition[2] < firstChar[2]
        normal ^
    else
        call setpos('.', cursorPosition)
        normal! l
    endif
endfunction

This one goes on the right: if the cursor is before the first non blank character, then we use normal ^ to skip the whitespaces. If we are already on the line we use normal! l to move on the right. Note the use of !which allows to use the original l motion even if we remap the key (this will be necessary otherwise we create a recursive function).

function! MyHMotion()
    let cursorPosition=getpos(".")
    normal ^
    let firstChar=getpos(".")

    if cursorPosition[2] <= firstChar[2]
        normal 0
    else
        call setpos('.', cursorPosition)
        normal! h
    endif
endfunction

This one goes on the left, this time if the cursor is on the first non blank character we use normal 0 to go on the beginning of the line and skip the white spaces.

You then have to create these mappings:

nnoremap <silent> h :call MyHMotion()<CR>
nnoremap <silent> l :call MyLMotion()<CR>

Note the use of silent to prevent the messages call MyXMotion to be output in the status line each time you press h or l

And you can use your h and l keyslike before but they'll skip the unwanted space at the beginning of your line.

Note that the advantage of this solution is that the functions should work whatever your configuration is (tabs of whitespaces).

| improve this answer | |
  • 1
    Added this to my .vimrc. To me, this solves the problem the OP describes. It is also a nice&simple example of several vim scripting techniques. I'm keeping this :) – Alex Stragies Aug 16 '15 at 10:25
  • @AlexStragies: I'm glad you keep it! :) – statox Aug 16 '15 at 11:11

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.