I have a mapping that comments/uncomments lines like 5gc
to comment/uncomment five lines, and I would like to make it repeatable with .
.
Here is my mapping and the function it uses:
function! Comment() range
let l:prefix = split(&commentstring, '%s', 1)[0]
let l:suffix = split(&commentstring, '%s', 1)[1]
let l:pattern = '\V\s\*'.escape(trim(l:prefix), '\').'\.\*'.escape(trim(l:suffix), '\').'\s\*'
let l:iscomment = 1
for l:line in getline(a:firstline, a:lastline)
if len(trim(l:line)) && l:line !~# l:pattern
let l:iscomment = 0
break
endif
endfor
if l:iscomment
for l:n in range(a:firstline, a:lastline)
if len(trim(getline(l:n)))
call setline(l:n, getline(l:n)[len(l:prefix):len(getline(l:n))-len(l:suffix)-1])
endif
endfor
else
for l:n in range(a:firstline, a:lastline)
if len(trim(getline(l:n)))
call setline(l:n, l:prefix . getline(l:n) . l:suffix)
endif
endfor
endif
endfunction
" 5gc to comment/uncomment five lines
" gc to comment/uncomment the visual selection
noremap gc :call Comment()<CR>
I tried using tpope's vim-repeat plugin like this:
nnoremap <silent> <Plug>CommentMap :call Comment()<CR>
\:call repeat#set("\<Plug>CommentMap", v:count)<CR>
nmap gc <Plug>CommentMap
But it only repeats one line as if the count is one, and I'm not sure why.
The only examples I found are just mappings with no functions. How could I do this? If it can be done without plugins that would be even better.
g@
about but I wasn't sure if it was applicable. I think the more examples of it the better. I'll accept your answer if you post one. Oh and say if you think my answer has something stupid.