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?
Vi and Vim Stack Exchange is a question and answer site for people using the vi and Vim families of text editors. It only takes a minute to sign up.
Sign up to join this communityFirstly 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
endwhile
endfunction
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.
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)
j
/k
to navigate/edit a comment. I would recommend upgrading your motion game. See:h quickref
. Related post: Quickest navigation within a buffer