In VSCode I can comment my code with Ctrl+KCtrl+C and uncomment with Ctrl+KCtrl+U.
Is there any way to do the same in Vim?
Because "commenting out" is context-dependent, the behavior is left to plugins rather than the core Vim editor.
Many plugins reuse the sequence gc to comment.
<Leader>cc
)Remark: With Neovim 0.10 (16th of May 2024) the commenting functionality is builtin in Neovim (bind to the gc
command).
Remark: With Vim 9.1.0375 (26th of April 2024) Vim comes with a builtin commenting plugin (activated using the packadd comment
command) [thanks to @Friedrich to pointing me this and to @MaximKim to make it possible]
comment
plugin (see :help comment-install
). This gives us a nice, built-in way to comment stuff. You might want to add it to your list.
Commented
May 24 at 20:51
The standard and advised approach is to use a plugin, like Vivian wrote.
If you feel like not using a plugin, you can do it in a few lines of code using autocmd like the snippet below. Select several lines in visual mode with V
and press Ctrl-Slash or Shift-Ctrl-Slash to comment/uncomment.
The idea is simple. The buffer-local variable b:comment_symbol
is defined corresponding to the file type (you can see with echo &ft
). If you substitute b:comment_symbol
for start-of-line, you comment a line. If you substitute nothing for b:comment_symbol
at start-of-line, you uncomment a line.
(This is standard vim, sorry idk if it works in neovim or lunarvim)
augroup visual_commenting
autocmd!
autocmd FileType c,cpp,java,rust let b:comment_symbol = '//'
autocmd FileType vim let b:comment_symbol = '"'
autocmd FileType sh,vim,python let b:comment_symbol = '#'
autocmd FileType tex let b:comment_symbol = '%'
autocmd BufEnter * silent! vnoremap <silent> <C-_> :<C-u>keepp '<,'>s@^@\=b:comment_symbol<CR>
autocmd BufEnter * silent! exec 'vnoremap <silent> <C-?> :<C-u>keepp ''<,''>s@^' . b:comment_symbol . '@<CR>'
augroup END
I feel the existing answers still miss something: you don't have this in Vim because you don't need it.
Turning a line of code into a comment is just a special case of line-wise text manipulation, which is something Vim is extremely powerful in.
The :substitute
command to comment out a line is :s/^/#
.
This is the analogue to VSCode's Ctrl-KCtrl-C.
A workflow similar to what one would do in VSCode would be to use a text object to quickly span a visual selection and call :'<,'>s/^/#
on it.
This may look a bit clunky but you can always recall the command from history. Something like :s<Up>
may suffice.
For example, to turn an entire paragraph into a comment using the #
comment marker usually supported by scripting languages, you'd do:
vap:'<,'>s/^/#
See :help text-objects
for all of them.
Uncommenting can be done likewise with :s/#\s*//
to strip a comment marker followed by any number of white space. The improved version is :s/^\s*\zs#\s*//
which will only trigger on a comment marker at the beginning of the line.
The alternative would be to use visual-block mode to select the column containing the comment markers and x
them all away at once.
Another important property of Vim is that you can create mappings for recurring actions. If you frequently comment stuff, you'd create a pair of mappings (for normal and visual modes) in your vimrc
or a filetype dependent .vim/after/ftplugin/<some filetype>.vim
.
You can write all this yourself and stay in total control. I would guess every Vim veteran has, at some point in time, written a mapping related to commenting.
Some community members were nice enough to polish their solutions to work across all filetypes, toggle comments with a single command (really, why have two?) and work gracefully in corner cases. This is the origin of the plugins linked to in Vivian's answer.