Vim Tips Wiki
(Fix typos)
(Remove html character entities)
 
Line 17: Line 17:
 
<pre>
 
<pre>
 
" lhs comments
 
" lhs comments
map ,# :s/^/#/&lt;CR&gt;
+
map ,# :s/^/#/<CR>
map ,/ :s/^/\/\//&lt;CR&gt;
+
map ,/ :s/^/\/\//<CR>
map ,&gt; :s/^/&gt; /&lt;CR&gt;
+
map ,> :s/^/> /<CR>
map ," :s/^/\"/&lt;CR&gt;
+
map ," :s/^/\"/<CR>
map ,% :s/^/%/&lt;CR&gt;
+
map ,% :s/^/%/<CR>
map ,! :s/^/!/&lt;CR&gt;
+
map ,! :s/^/!/<CR>
map ,; :s/^/;/&lt;CR&gt;
+
map ,; :s/^/;/<CR>
map ,- :s/^/--/&lt;CR&gt;
+
map ,- :s/^/--/<CR>
map ,c :s/^\/\/\\|^--\\|^&gt; \\|^[#"%!;]//&lt;CR&gt;
+
map ,c :s/^\/\/\\|^--\\|^> \\|^[#"%!;]//<CR>
   
 
" wrapping comments
 
" wrapping comments
map ,* :s/^\(.*\)$/\/\* \1 \*\//&lt;CR&gt;
+
map ,* :s/^\(.*\)$/\/\* \1 \*\//<CR>
map ,( :s/^\(.*\)$/\(\* \1 \*\)/&lt;CR&gt;
+
map ,( :s/^\(.*\)$/\(\* \1 \*\)/<CR>
map ,&lt; :s/^\(.*\)$/&lt;!-- \1 --&gt;/&lt;CR&gt;
+
map ,< :s/^\(.*\)$/<!-- \1 -->/<CR>
map ,d :s/^\([/(]\*\\|&lt;!--\) \(.*\) \(\*[/)]\\|--&gt;\)$/\2/&lt;CR&gt;
+
map ,d :s/^\([/(]\*\\|<!--\) \(.*\) \(\*[/)]\\|-->\)$/\2/<CR>
 
</pre>
 
</pre>
   
Line 38: Line 38:
 
,# shell, perl, etc
 
,# shell, perl, etc
 
,/ c++
 
,/ c++
,&gt; email quote
+
,> email quote
 
," vim
 
," vim
 
,% latex, prolog
 
,% latex, prolog
Line 51: Line 51:
 
,* c
 
,* c
 
,( Standard ML
 
,( Standard ML
,&lt; html
+
,< html
 
,d clears any of the wrapping comments
 
,d clears any of the wrapping comments
 
</pre>
 
</pre>
Line 59: Line 59:
 
In e.g. MapBasic which I'm trying to figure out right now, I use:
 
In e.g. MapBasic which I'm trying to figure out right now, I use:
 
<pre>
 
<pre>
map ,' :s/^/'/&lt;CR&gt; :let @/=""&lt;CR&gt;
+
map ,' :s/^/'/<CR> :let @/=""<CR>
 
</pre>
 
</pre>
   
 
----
 
----
Just add :nohlsearch &lt;CR&gt; at the end of the mapping and it would remove the highlight. Highlighting would be re-enabled when you do the next search. I checked it out it works
+
Just add :nohlsearch <CR> at the end of the mapping and it would remove the highlight. Highlighting would be re-enabled when you do the next search. I checked it out it works
   
 
<pre>
 
<pre>
 
" lhs comments
 
" lhs comments
map ,# :s/^/#/&lt;CR&gt; &lt;Esc&gt;:nohlsearch &lt;CR&gt;
+
map ,# :s/^/#/<CR> <Esc>:nohlsearch <CR>
map ,/ :s/^/\/\//&lt;CR&gt; &lt;Esc&gt;:nohlsearch &lt;CR&gt;
+
map ,/ :s/^/\/\//<CR> <Esc>:nohlsearch <CR>
map ,&gt; :s/^/&gt; /&lt;CR&gt; &lt;Esc&gt;:nohlsearch&lt;CR&gt;
+
map ,> :s/^/> /<CR> <Esc>:nohlsearch<CR>
map ," :s/^/\"/&lt;CR&gt; &lt;Esc&gt;:nohlsearch&lt;CR&gt;
+
map ," :s/^/\"/<CR> <Esc>:nohlsearch<CR>
map ,% :s/^/%/&lt;CR&gt; &lt;Esc&gt;:nohlsearch&lt;CR&gt;
+
map ,% :s/^/%/<CR> <Esc>:nohlsearch<CR>
map ,! :s/^/!/&lt;CR&gt; &lt;Esc&gt;:nohlsearch&lt;CR&gt;
+
map ,! :s/^/!/<CR> <Esc>:nohlsearch<CR>
map ,; :s/^/;/&lt;CR&gt; &lt;Esc&gt;:nohlsearch&lt;CR&gt;
+
map ,; :s/^/;/<CR> <Esc>:nohlsearch<CR>
map ,- :s/^/--/&lt;CR&gt; &lt;Esc&gt;:nohlsearch&lt;CR&gt;
+
map ,- :s/^/--/<CR> <Esc>:nohlsearch<CR>
map ,c :s/^\/\/\\|^--\\|^&gt; \\|^[#"%!;]//&lt;CR&gt; &lt;Esc&gt;:nohlsearch&lt;CR&gt;
+
map ,c :s/^\/\/\\|^--\\|^> \\|^[#"%!;]//<CR> <Esc>:nohlsearch<CR>
   
 
" wrapping comments
 
" wrapping comments
map ,* :s/^\(.*\)$/\/\* \1 \*\//&lt;CR&gt; &lt;Esc&gt;:nohlsearch&lt;CR&gt;
+
map ,* :s/^\(.*\)$/\/\* \1 \*\//<CR> <Esc>:nohlsearch<CR>
map ,( :s/^\(.*\)$/\(\* \1 \*\)/&lt;CR&gt;&lt;Esc&gt;:nohlsearch &lt;CR&gt;
+
map ,( :s/^\(.*\)$/\(\* \1 \*\)/<CR><Esc>:nohlsearch <CR>
map ,&lt; :s/^\(.*\)$/&lt;!-- \1 --&gt;/&lt;CR&gt; &lt;Esc&gt;:nohlsearch&lt;CR&gt;
+
map ,< :s/^\(.*\)$/<!-- \1 -->/<CR> <Esc>:nohlsearch<CR>
map ,d :s/^\([/(]\*\\|&lt;!--\) \(.*\) \(\*[/)]\\|--&gt;\)$/\2/&lt;CR&gt; &lt;Esc&gt;:nohlsearch&lt;CR&gt;
+
map ,d :s/^\([/(]\*\\|<!--\) \(.*\) \(\*[/)]\\|-->\)$/\2/<CR> <Esc>:nohlsearch<CR>
 
</pre>
 
</pre>
   
 
----
 
----
Adding :nohlsearch&lt;cr&gt; to the end of each pattern clears up the highlighting. Note that this doesn't turn off search highlighting, it just removes the highlighting that's there. Here are the amended regexs:
+
Adding :nohlsearch<CR> to the end of each pattern clears up the highlighting. Note that this doesn't turn off search highlighting, it just removes the highlighting that's there. Here are the amended regexs:
   
 
<pre>
 
<pre>
 
" lhs comments
 
" lhs comments
map ,# :s/^/#/&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ,# :s/^/#/<CR>:nohlsearch<CR>
map ,/ :s/^/\/\//&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ,/ :s/^/\/\//<CR>:nohlsearch<CR>
map ,&gt; :s/^/&gt; /&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ,> :s/^/> /<CR>:nohlsearch<CR>
map ," :s/^/\"/&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ," :s/^/\"/<CR>:nohlsearch<CR>
map ,% :s/^/%/&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ,% :s/^/%/<CR>:nohlsearch<CR>
map ,! :s/^/!/&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ,! :s/^/!/<CR>:nohlsearch<CR>
map ,; :s/^/;/&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ,; :s/^/;/<CR>:nohlsearch<CR>
map ,- :s/^/--/&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ,- :s/^/--/<CR>:nohlsearch<CR>
map ,c :s/^\/\/\\|^--\\|^&gt; \\|^[#"%!;]//&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ,c :s/^\/\/\\|^--\\|^> \\|^[#"%!;]//<CR>:nohlsearch<CR>
   
 
" wrapping comments
 
" wrapping comments
map ,* :s/^\(.*\)$/\/\* \1 \*\//&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ,* :s/^\(.*\)$/\/\* \1 \*\//<CR>:nohlsearch<CR>
map ,( :s/^\(.*\)$/\(\* \1 \*\)/&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ,( :s/^\(.*\)$/\(\* \1 \*\)/<CR>:nohlsearch<CR>
map ,&lt; :s/^\(.*\)$/&lt;!-- \1 --&gt;/&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ,< :s/^\(.*\)$/<!-- \1 -->/<CR>:nohlsearch<CR>
map ,d :s/^\([/(]\*\\|&lt;!--\) \(.*\) \(\*[/)]\\|--&gt;\)$/\2/&lt;CR&gt;:nohlsearch&lt;CR&gt;
+
map ,d :s/^\([/(]\*\\|<!--\) \(.*\) \(\*[/)]\\|-->\)$/\2/<CR>:nohlsearch<CR>
 
</pre>
 
</pre>
   
Line 121: Line 121:
 
let @/=hls
 
let @/=hls
 
endfun
 
endfun
map ,/ :call CppstyleQuote()&lt;CR&gt;
+
map ,/ :call CppstyleQuote()<CR>
 
</pre>
 
</pre>
   
Line 134: Line 134:
 
endif
 
endif
 
endfunction
 
endfunction
nmap &lt;buffer&gt; &lt;Esc&gt;d :call C_CommentLine()&lt;LF&gt;
+
nmap <buffer> <Esc>d :call C_CommentLine()<LF>
   
" &lt;Esc&gt;d on my term means &lt;M-D&gt; or Alt-D
+
" <Esc>d on my term means <M-D> or Alt-D
   
 
" This mapping comments the visual selection, You have to perform a selection from left to
 
" This mapping comments the visual selection, You have to perform a selection from left to
 
" right or from top to bottom. If you do a linewise selection, the cursor
 
" right or from top to bottom. If you do a linewise selection, the cursor
 
" position, not the end of selection matters.
 
" position, not the end of selection matters.
vmap &lt;buffer&gt; &lt;Esc&gt;d a*/gvoi/*
+
vmap <buffer> <Esc>d a*/gvoi/*
 
</pre>
 
</pre>
   
Line 149: Line 149:
   
 
<pre>
 
<pre>
:vmenu PopUp.Comments.Add :s/^/\/\//&lt;CR&gt;
+
:vmenu PopUp.Comments.Add :s/^/\/\//<CR>
:vmenu PopUp.Comments.Remove :s/^..//&lt;CR&gt;
+
:vmenu PopUp.Comments.Remove :s/^..//<CR>
 
</pre>
 
</pre>
   
Line 164: Line 164:
 
let commpos= match(line, "//")
 
let commpos= match(line, "//")
 
let n = 0
 
let n = 0
while n&lt; commpos
+
while n< commpos
if line[n]!= " " &amp;&amp; line[n]!= "\t"
+
if line[n]!= " " && line[n]!= "\t"
 
break
 
break
 
endif
 
endif
 
let n= n+1
 
let n= n+1
 
endwhile
 
endwhile
if n== commpos &amp;&amp; commpos!= -1
+
if n== commpos && commpos!= -1
 
let line= strpart(line, 0, commpos).strpart(line, commpos+2)
 
let line= strpart(line, 0, commpos).strpart(line, commpos+2)
 
else
 
else
Line 177: Line 177:
 
let err= setline(linenum, line)
 
let err= setline(linenum, line)
 
endfunction
 
endfunction
map &lt;M-c&gt; :call MyComm()&lt;CR&gt;
+
map <M-c> :call MyComm()<CR>
imap &lt;M-c&gt; &lt;esc&gt;:call MyComm()&lt;CR&gt;i
+
imap <M-c> <Esc>:call MyComm()<CR>i
   
 
" for the /* */ pair, I use visual mode, an then alt-v:
 
" for the /* */ pair, I use visual mode, an then alt-v:
vmap &lt;M-v&gt; v`&lt;I&lt;CR&gt;&lt;esc&gt;k0i/*&lt;ESC&gt;`&gt;I&lt;CR&gt;&lt;esc&gt;k0i*/&lt;ESC&gt;
+
vmap <M-v> v`<I<CR><Esc>k0i/*<Esc>`>I<CR><Esc>k0i*/<Esc>
 
</pre>
 
</pre>
   
Line 195: Line 195:
 
" Define functions
 
" Define functions
 
function! PoundComment()
 
function! PoundComment()
map - :s/^/# /&lt;CR&gt;
+
map - :s/^/# /<CR>
map _ :s/^\s*# \=//&lt;CR&gt;
+
map _ :s/^\s*# \=//<CR>
 
set comments=:#
 
set comments=:#
 
endfunction
 
endfunction
   
 
function! SlashComment()
 
function! SlashComment()
map - :s/^/\/\/ /&lt;CR&gt;
+
map - :s/^/\/\/ /<CR>
map _ :s/^\s*\/\/ \=//&lt;CR&gt;
+
map _ :s/^\s*\/\/ \=//<CR>
 
endfunction
 
endfunction
   
Line 219: Line 219:
   
 
<pre>
 
<pre>
map \# :call Comment()&lt;CR&gt;
+
map \# :call Comment()<CR>
map \-# :call Uncomment()&lt;CR&gt;
+
map \-# :call Uncomment()<CR>
map \--# :call UncommentBlock()&lt;CR&gt;
+
map \--# :call UncommentBlock()<CR>
   
 
" Comments range (handles multiple file types)
 
" Comments range (handles multiple file types)
 
function! Comment() range
 
function! Comment() range
if &amp;filetype == "c" || &amp;filetype == "php" || &amp;filetype == "css"
+
if &filetype == "c" || &filetype == "php" || &filetype == "css"
 
execute ":" . a:firstline . "," . a:lastline . 's/^\(.*\)$/\/\* \1 \*\//'
 
execute ":" . a:firstline . "," . a:lastline . 's/^\(.*\)$/\/\* \1 \*\//'
elseif &amp;filetype == "html" || &amp;filetype == "xml" || &amp;filetype == "xslt" || &amp;filetype == "xsd"
+
elseif &filetype == "html" || &filetype == "xml" || &filetype == "xslt" || &filetype == "xsd"
execute ":" . a:firstline . "," . a:lastline . 's/^\(.*\)$/&lt;!-- \1 --&gt;/'
+
execute ":" . a:firstline . "," . a:lastline . 's/^\(.*\)$/<!-- \1 -->/'
 
else
 
else
if &amp;filetype == "java" || &amp;filetype == "cpp" || &amp;filetype == "cs"
+
if &filetype == "java" || &filetype == "cpp" || &filetype == "cs"
 
let commentString = "//"
 
let commentString = "//"
elseif &amp;filetype == "vim"
+
elseif &filetype == "vim"
 
let commentString = '"'
 
let commentString = '"'
 
else
 
else
Line 243: Line 243:
 
" Uncomments range (handles multiple file types)
 
" Uncomments range (handles multiple file types)
 
function! Uncomment() range
 
function! Uncomment() range
if &amp;filetype == "c" || &amp;filetype == "php" || &amp;filetype == "css" || &amp;filetype == "html" || &amp;filetype == "xml" || &amp;filetype == "xslt" || &amp;filetype == "xsd"
+
if &filetype == "c" || &filetype == "php" || &filetype == "css" || &filetype == "html" || &filetype == "xml" || &filetype == "xslt" || &filetype == "xsd"
 
" [[VimTip271]]
 
" [[VimTip271]]
execute ":" . a:firstline . "," . a:lastline . 's/^\([/(]\*\|&lt;!--\) \(.*\) \(\*[/)]\|--&gt;\)$/\2/'
+
execute ":" . a:firstline . "," . a:lastline . 's/^\([/(]\*\|<!--\) \(.*\) \(\*[/)]\|-->\)$/\2/'
 
else
 
else
if &amp;filetype == "java" || &amp;filetype == "cpp" || &amp;filetype == "cs"
+
if &filetype == "java" || &filetype == "cpp" || &filetype == "cs"
 
let commentString = "//"
 
let commentString = "//"
elseif &amp;filetype == "vim"
+
elseif &filetype == "vim"
 
let commentString = '"'
 
let commentString = '"'
 
else
 
else
Line 260: Line 260:
 
" Uncomments from current line up to last line that's commented
 
" Uncomments from current line up to last line that's commented
 
function! UncommentBlock()
 
function! UncommentBlock()
if &amp;filetype == "c" || &amp;filetype == "php" || &amp;filetype == "css" || &amp;filetype == "html" || &amp;filetype == "xml" || &amp;filetype == "xslt" || &amp;filetype == "xsd"
+
if &filetype == "c" || &filetype == "php" || &filetype == "css" || &filetype == "html" || &filetype == "xml" || &filetype == "xslt" || &filetype == "xsd"
 
echoerr "TODO: haven't implemented UncommentBlock; use Uncomment instead"
 
echoerr "TODO: haven't implemented UncommentBlock; use Uncomment instead"
 
else
 
else
if &amp;filetype == "java" || &amp;filetype == "cpp" || &amp;filetype == "cs"
+
if &filetype == "java" || &filetype == "cpp" || &filetype == "cs"
 
let commentString = '\/\/'
 
let commentString = '\/\/'
 
let firstChar = '/'
 
let firstChar = '/'
elseif &amp;filetype == "vim"
+
elseif &filetype == "vim"
 
let commentString = '"'
 
let commentString = '"'
 
let firstChar = '"'
 
let firstChar = '"'
Line 273: Line 273:
 
let firstChar = '#'
 
let firstChar = '#'
 
endif
 
endif
if version &lt; 600 &amp;&amp; strlen( commentString ) &gt; 1
+
if version < 600 && strlen( commentString ) > 1
 
echoerr "TODO: haven't implemented multi-character comment block"
 
echoerr "TODO: haven't implemented multi-character comment block"
 
else
 
else
Line 300: Line 300:
 
endif
 
endif
 
endfunction
 
endfunction
map k :call Komment()&lt;CR&gt;
+
map k :call Komment()<CR>
 
</pre>
 
</pre>
   

Latest revision as of 05:30, 29 September 2008

Duplicate tip

This tip is very similar to the following:

These tips need to be merged – see the merge guidelines.

Tip 271 Printable Monobook Previous Next

created June 30, 2002 · complexity intermediate · author jmpatton · version 5.7


Something that I do quite a lot is comment out blocks of text, only to uncomment that same block later. The following mappings have proven useful to me. They can be applied using visually selected blocks, or with motion keys.

" lhs comments
map ,# :s/^/#/<CR>
map ,/ :s/^/\/\//<CR>
map ,> :s/^/> /<CR>
map ," :s/^/\"/<CR>
map ,% :s/^/%/<CR>
map ,! :s/^/!/<CR>
map ,; :s/^/;/<CR>
map ,- :s/^/--/<CR>
map ,c :s/^\/\/\\|^--\\|^> \\|^[#"%!;]//<CR>

" wrapping comments
map ,* :s/^\(.*\)$/\/\* \1 \*\//<CR>
map ,( :s/^\(.*\)$/\(\* \1 \*\)/<CR>
map ,< :s/^\(.*\)$/<!-- \1 -->/<CR>
map ,d :s/^\([/(]\*\\|<!--\) \(.*\) \(\*[/)]\\|-->\)$/\2/<CR>

The commands to comment a selection of text are as follows, beginning with beginning-of-line comments:

 ,# shell, perl, etc
 ,/ c++
 ,> email quote
 ," vim
 ,% latex, prolog
 ,! assembly/X-resources
 ,; scheme
 ,- sql, ada
 ,c clears any of the previous comments

Here are the wrapping comments, each line wrapped individually:

,* c
,( Standard ML
,< html
,d clears any of the wrapping comments

Comments[]

After executing this tip, the content of "/ is highlighted in my gvim; which is rather annoying. In e.g. MapBasic which I'm trying to figure out right now, I use:

map ,' :s/^/'/<CR> :let @/=""<CR>

Just add :nohlsearch <CR> at the end of the mapping and it would remove the highlight. Highlighting would be re-enabled when you do the next search. I checked it out it works

" lhs comments
map ,# :s/^/#/<CR> <Esc>:nohlsearch <CR>
map ,/ :s/^/\/\//<CR> <Esc>:nohlsearch <CR>
map ,> :s/^/> /<CR> <Esc>:nohlsearch<CR>
map ," :s/^/\"/<CR> <Esc>:nohlsearch<CR>
map ,% :s/^/%/<CR> <Esc>:nohlsearch<CR>
map ,! :s/^/!/<CR> <Esc>:nohlsearch<CR>
map ,; :s/^/;/<CR> <Esc>:nohlsearch<CR>
map ,- :s/^/--/<CR> <Esc>:nohlsearch<CR>
map ,c :s/^\/\/\\|^--\\|^> \\|^[#"%!;]//<CR> <Esc>:nohlsearch<CR>

" wrapping comments
map ,* :s/^\(.*\)$/\/\* \1 \*\//<CR> <Esc>:nohlsearch<CR>
map ,( :s/^\(.*\)$/\(\* \1 \*\)/<CR><Esc>:nohlsearch <CR>
map ,< :s/^\(.*\)$/<!-- \1 -->/<CR> <Esc>:nohlsearch<CR>
map ,d :s/^\([/(]\*\\|<!--\) \(.*\) \(\*[/)]\\|-->\)$/\2/<CR> <Esc>:nohlsearch<CR>

Adding :nohlsearch<CR> to the end of each pattern clears up the highlighting. Note that this doesn't turn off search highlighting, it just removes the highlighting that's there. Here are the amended regexs:

" lhs comments
map ,# :s/^/#/<CR>:nohlsearch<CR>
map ,/ :s/^/\/\//<CR>:nohlsearch<CR>
map ,> :s/^/> /<CR>:nohlsearch<CR>
map ," :s/^/\"/<CR>:nohlsearch<CR>
map ,% :s/^/%/<CR>:nohlsearch<CR>
map ,! :s/^/!/<CR>:nohlsearch<CR>
map ,; :s/^/;/<CR>:nohlsearch<CR>
map ,- :s/^/--/<CR>:nohlsearch<CR>
map ,c :s/^\/\/\\|^--\\|^> \\|^[#"%!;]//<CR>:nohlsearch<CR>

" wrapping comments
map ,* :s/^\(.*\)$/\/\* \1 \*\//<CR>:nohlsearch<CR>
map ,( :s/^\(.*\)$/\(\* \1 \*\)/<CR>:nohlsearch<CR>
map ,< :s/^\(.*\)$/<!-- \1 -->/<CR>:nohlsearch<CR>
map ,d :s/^\([/(]\*\\|<!--\) \(.*\) \(\*[/)]\\|-->\)$/\2/<CR>:nohlsearch<CR>

A more intelligent way is to save the search pattern highlighted. let hls=@/|s ... |let @/=hls


The problem with that is that it thwarts motion keys. The way it stands you can do something like '3,#' and it will comment 3 lines. Ranges don't work with 'let ...', unfortunately.


This function is based on the various comments here, and seems to work.

fun CppstyleQuote()
  let hls=@/
  s/^/\/\//
  let @/=hls
endfun
map ,/ :call CppstyleQuote()<CR>

" I use a single mapping, which can comment/uncomment line:
function! C_CommentLine()
  if getline(".") =~ '/\*.*\*/'
    normal ^2x$xx
  else
    normal I/*A*/
  endif
endfunction
nmap <buffer> <Esc>d :call C_CommentLine()<LF>

" <Esc>d on my term means <M-D> or Alt-D

" This mapping comments the visual selection, You have to perform a selection from left to
" right or from top to bottom. If you do a linewise selection, the cursor
" position, not the end of selection matters.
vmap <buffer> <Esc>d a*/gvoi/*

I use the mouse to select the lines I want to comment/uncomment and have this on the right click menu to insert/delete // at the start of the line:

:vmenu PopUp.Comments.Add :s/^/\/\//<CR>
:vmenu PopUp.Comments.Remove :s/^..//<CR>

those are great, but I don't like the highlighted search and also i like my // always at the very beginning of the line, so I've wrote this function (very newbie and unoptimized, but it works)

It comments and uncomments the current line:

function! MyComm()
  let linenum= line('.')
  let line = getline('.')
  let commpos= match(line, "//")
  let n = 0
  while n< commpos
    if line[n]!= " " && line[n]!= "\t"
      break
    endif
    let n= n+1
  endwhile
  if n== commpos && commpos!= -1
    let line= strpart(line, 0, commpos).strpart(line, commpos+2)
  else
    let line= "//".line
  endif
  let err= setline(linenum, line)
endfunction
map <M-c> :call MyComm()<CR>
imap <M-c> <Esc>:call MyComm()<CR>i

" for the /* */ pair, I use visual mode, an then alt-v:
vmap <M-v> v`<I<CR><Esc>k0i/*<Esc>`>I<CR><Esc>k0i*/<Esc>

Using visual block selection at the start of the lines you want to comment, along with 'I' (CAPS-EYE), and the comment character is also very handy. Decommenting would be to select the comments in a visual block and delete them.


A few people have said something like this, but I have found it more useful to not need to remember a different mapping for each language I'm editing. To this end, I have several different functions that set up commands based on which language I'm editing. Like so:

" Define functions
function! PoundComment()
  map - :s/^/# /<CR>
  map _ :s/^\s*# \=//<CR>
  set comments=:#
endfunction

function! SlashComment()
  map - :s/^/\/\/ /<CR>
  map _ :s/^\s*\/\/ \=//<CR>
endfunction

" And then later...
autocmd FileType perl call PoundComment()
autocmd FileType cgi call PoundComment()
autocmd FileType csh call PoundComment()
autocmd FileType sh call PoundComment()
autocmd FileType java call SlashComment()

You get the idea. Now, I can always comment a line/range of lines with - (hyphen), and uncomment it with _ (underscore).


These will handle the :nohl search highlighting case nicely (nothing's changed, it's automatic)

map \# :call Comment()<CR>
map \-# :call Uncomment()<CR>
map \--# :call UncommentBlock()<CR>

" Comments range (handles multiple file types)
function! Comment() range
  if &filetype == "c" || &filetype == "php" || &filetype == "css"
    execute ":" . a:firstline . "," . a:lastline . 's/^\(.*\)$/\/\* \1 \*\//'
  elseif &filetype == "html" || &filetype == "xml" || &filetype == "xslt" || &filetype == "xsd"
    execute ":" . a:firstline . "," . a:lastline . 's/^\(.*\)$/<!-- \1 -->/'
  else
    if &filetype == "java" || &filetype == "cpp" || &filetype == "cs"
      let commentString = "//"
    elseif &filetype == "vim"
      let commentString = '"'
    else
      let commentString = "#"
    endif
    execute ":" . a:firstline . "," . a:lastline . 's,^,' . commentString . ','
  endif
endfunction

" Uncomments range (handles multiple file types)
function! Uncomment() range
  if &filetype == "c" || &filetype == "php" || &filetype == "css" || &filetype == "html" || &filetype == "xml" || &filetype == "xslt" || &filetype == "xsd"
    " [[VimTip271]]
    execute ":" . a:firstline . "," . a:lastline . 's/^\([/(]\*\|<!--\) \(.*\) \(\*[/)]\|-->\)$/\2/'
  else
    if &filetype == "java" || &filetype == "cpp" || &filetype == "cs"
      let commentString = "//"
    elseif &filetype == "vim"
      let commentString = '"'
    else
      let commentString = "#"
    endif
    execute ":" . a:firstline . "," . a:lastline . 's,^' . commentString . ',,'
  endif
endfunction

" Uncomments from current line up to last line that's commented
function! UncommentBlock()
  if &filetype == "c" || &filetype == "php" || &filetype == "css" || &filetype == "html" || &filetype == "xml" || &filetype == "xslt" || &filetype == "xsd"
    echoerr "TODO: haven't implemented UncommentBlock; use Uncomment instead"
  else
    if &filetype == "java" || &filetype == "cpp" || &filetype == "cs"
      let commentString = '\/\/'
      let firstChar = '/'
    elseif &filetype == "vim"
      let commentString = '"'
      let firstChar = '"'
    else
      let commentString = '#'
      let firstChar = '#'
    endif
    if version < 600 && strlen( commentString ) > 1
      echoerr "TODO: haven't implemented multi-character comment block"
    else
      " TODO: doesn't handle case where the block ends at end of file
      execute ':.,/^\(\(' . commentString . '\)\@!\|[^' . firstChar . ']\|$\)/-1s/^' . commentString . "//"
    endif
  endif
endfunction

Based on the above and having 4 things in mind: (1) single keystroke (2) no highlighting (3) C language (4) being simple - my version became:

function! Komment()
  if getline(".") =~ '\/\*'
    let hls=@/
    s/^\/\*//
    s/*\/$//
    let @/=hls
  else
    let hls=@/
    s/^/\/*/
    s/$/*\//
    let @/=hls
  endif
endfunction
map k :call Komment()<CR>

So pressing k will comment out the current line if it is not already so and will uncomment it if it is commented already. Really handy :)


See script#955 I "improved" the original tip a little:

  • no "remove comment" key, but the comment-status of a line is toogled
  • no hlsearch-problem
  • commenting uses the original indentation, not the first column

I found the Nerd commenter script very valuable: Nerd Commenter


I like Enhanced Commentify. It has a lot of functionality and options.

If you want simplicity, ToggleCommentify is available.


To do this quickly with a visual selection you could just type shift-i and then the comment character(s) followed by Esc or ctrl-c which will insert the characters at the start of the selection at every line.