When navigating in normal mode by j or k, I want to skip commented lines.

Is it possible? Is there a vimscript snippet for that?

  • 1
    I feel that it is overly optimistic to never use j/k to navigate/edit a comment. I would recommend upgrading your motion game. See :h quickref. Related post: Quickest navigation within a buffer Commented Aug 17, 2018 at 14:50

1 Answer 1


Firstly I think it would be important that you learn how to move around with motions other than j and k. Being able to use wide range motions, marks and tags is a good way to avoid comments and move efficiently.

However, you can use the following function and mappings:

function! MyVerticalMotions(up)
    " Get the motion to execute based on the parameter
    let motion = a:up ? "k" : "j"

    " Execute the original motion
    execute "normal! " . motion

    " Repeat until we are not on a comment anymore or we reached the end of the buffer
    while synIDattr(synIDtrans(synID(line("."),col("."),1)),"name") == "Comment" && line('.') < line('$') && line('.') > 1
        execute "normal! " . motion

nnoremap <silent> j :call MyVerticalMotions(0)<CR>
nnoremap <silent> k :call MyVerticalMotions(1)<CR>

The function takes one argument indicating if you want to move up or down, it will then repeat j or k until the current line is not a comment or you reach the top or the bottom of the file.

The mappings simply call the function with the correct parameter. Also, you can still use gj and gk if you want to move on the comments.

I used this Wikia post to get the syntax group of the current line.

Note that I tested this code quickly on a Vimscript file and a JS file and it seems like it's working but I may have forgotten some edge cases.

  • I think you need an extra condition breaking the loop when at the end/beginning of a buffer and you are on a comment line. Else you likely create a endless loop Commented Aug 17, 2018 at 13:17
  • @ChristianBrabandt According to my tests it works as is: If I'm on the 3rd line and the first two lines are commented out, I'll do the first k, on the second line the loop starts, the highlighting is "Comment" and line('.') > 1. So I do k again, then the highlighting is still "Comment" but line('.') == 1 so we don't loop anymore. (And the same is true at the end of the buffer)
    – statox
    Commented Aug 17, 2018 at 13:21
  • 1
    ah, i missed that part in the condition Commented Aug 17, 2018 at 15:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.