Tip #271: easy (un)commenting out of source code
tip karma |
Rating 214/73, Viewed by 14507
|
Read and edit this tip on the
Vim tip wiki.
The wiki may have a more recent version of this tip.
created: |
|
June 30, 2002 22:57 |
|
complexity: |
|
intermediate |
author: |
|
[email protected] |
|
as of Vim: |
|
5.7 |
Something that I do quite alot 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, begining with begining-of-line comments:
,# shell, perl, etc
,/ c++
,> email quote
," vim
,% latex, prolog
,! assembly?... add single !
,; scheme
,- don't remember this one... add --
,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
<< Insert a single character |
automaticaly formating pasted text (p=`]) >>
Additional Notes
Anonymous,
July 1, 2002 6:28
|
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>
Leo
|
alinets<at>yahoo.com,
July 1, 2002 13:26
|
I am having the same problem,
I have hlsearch option on (highlight search) and when I use one of the mappings to add comment it leaves me with a lot of hihjlighting that is not required/intended. Is there a way to turn off highlight search for these command only ?
|
alinets<at>yahoo.com,
July 1, 2002 14:40
|
OK, figured it out.
Just add :nohlsearch <CR> at the end of the mapping and it would remove the highlight.
Highlighting would be reenabled 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>
|
[email protected],
July 1, 2002 14:50
|
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 ammended 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>
|
[email protected],
July 1, 2002 14:52
|
Jinx!
|
[email protected],
July 3, 2002 2:53
|
A more intelligent way is to save the search pattern highlighted.
let hls=@/|s ... |let @/=hls
|
[email protected],
July 3, 2002 5:52
|
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.
|
[email protected],
July 3, 2002 12:16
|
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>
Leo
|
[email protected],
July 6, 2002 17:23
|
" 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/*
|
[email protected],
September 23, 2002 19:22
|
i use the mouse the 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>
seems to work ok
|
[email protected],
September 28, 2002 16:02
|
The comment whose language you forgot (in your notes), ,-, is for SQL comments....
|
[email protected],
October 12, 2002 11:30
|
hi all!!
those are great, but i don't like the highlighted search and also i like my // allways at the very begining of the line, so i've wrote this function (very newbie and unoptimized, but it works XD )
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
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"and use this keybindings:
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>
hope u find useful :)
|
[email protected],
October 25, 2002 3:04
|
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 (ofcourse!) to select the comments in a visual
block and delete them.
|
[email protected],
February 8, 2003 13:37
|
the '--' comments are also for ADA95 if anyone has has the pleasure of coding in it.
|
[email protected],
March 19, 2003 23:02
|
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).
There's More Than One Way To Do It.
|
Anonymous,
November 10, 2003 14:07
|
-- is also for sql, silly boy
|
Anonymous,
November 10, 2003 16:35
|
Ok, my turn:
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" || &filetyle; == "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" || &filetyle; == "xsd"
" https://www.vim8.org/tips/tip.php?tip_id=271
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" || &filetyle; == "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
|
[email protected],
November 12, 2003 19:04
|
Your script works well, but has little bugs:
1. mistype some 'filetype' to 'filetyle'
2. mistype some '||' to '|||"
|
Dani,
January 30, 2004 6:27
|
All this was very useful, thanks!
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 :)
Dani
|
Anonymous,
March 31, 2004 0:31
|
[email protected], i love you
|
[email protected],
April 6, 2004 9:32
|
You might have a look at vimscript #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
|
Anonymous,
November 25, 2005 5:57
|
I found the Nerd commenter script very valuable: vimscript #1218
|
Anonymous,
December 21, 2005 23:10
|
I settled on using vimscript #23, called Enhanced Commentify
It has a lot of functionality and options.
If you want simplicity, vimscript #4 is available.
|
[email protected],
February 7, 2006 19:08
|
Dani, that tip worked for me in 30 seconds- thanks!
|
Anonymous,
March 16, 2006 18:32
|
! is used for X resources
|
Anonymous,
May 17, 2006 3:23
|
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.
|
|