(Fix typos) |
(Remove html character entities) |
||
Line 17: | Line 17: | ||
<pre> |
<pre> |
||
" lhs comments |
" lhs comments |
||
− | map ,# :s/^/#/ |
+ | map ,# :s/^/#/<CR> |
− | map ,/ :s/^/\/\// |
+ | map ,/ :s/^/\/\//<CR> |
− | map , |
+ | map ,> :s/^/> /<CR> |
− | map ," :s/^/\"/ |
+ | map ," :s/^/\"/<CR> |
− | map ,% :s/^/%/ |
+ | map ,% :s/^/%/<CR> |
− | map ,! :s/^/!/ |
+ | map ,! :s/^/!/<CR> |
− | map ,; :s/^/;/ |
+ | map ,; :s/^/;/<CR> |
− | map ,- :s/^/--/ |
+ | map ,- :s/^/--/<CR> |
− | map ,c :s/^\/\/\\|^--\\|^ |
+ | map ,c :s/^\/\/\\|^--\\|^> \\|^[#"%!;]//<CR> |
" wrapping comments |
" wrapping comments |
||
− | map ,* :s/^\(.*\)$/\/\* \1 \*\// |
+ | map ,* :s/^\(.*\)$/\/\* \1 \*\//<CR> |
− | map ,( :s/^\(.*\)$/\(\* \1 \*\)/ |
+ | map ,( :s/^\(.*\)$/\(\* \1 \*\)/<CR> |
− | map , |
+ | map ,< :s/^\(.*\)$/<!-- \1 -->/<CR> |
− | map ,d :s/^\([/(]\*\\| |
+ | map ,d :s/^\([/(]\*\\|<!--\) \(.*\) \(\*[/)]\\|-->\)$/\2/<CR> |
</pre> |
</pre> |
||
Line 38: | Line 38: | ||
,# shell, perl, etc |
,# shell, perl, etc |
||
,/ c++ |
,/ c++ |
||
− | , |
+ | ,> email quote |
," vim |
," vim |
||
,% latex, prolog |
,% latex, prolog |
||
Line 51: | Line 51: | ||
,* c |
,* c |
||
,( Standard ML |
,( Standard ML |
||
− | , |
+ | ,< 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/^/'/ |
+ | map ,' :s/^/'/<CR> :let @/=""<CR> |
</pre> |
</pre> |
||
---- |
---- |
||
− | Just add :nohlsearch |
+ | 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/^/#/ |
+ | map ,# :s/^/#/<CR> <Esc>:nohlsearch <CR> |
− | map ,/ :s/^/\/\// |
+ | map ,/ :s/^/\/\//<CR> <Esc>:nohlsearch <CR> |
− | map , |
+ | map ,> :s/^/> /<CR> <Esc>:nohlsearch<CR> |
− | map ," :s/^/\"/ |
+ | map ," :s/^/\"/<CR> <Esc>:nohlsearch<CR> |
− | map ,% :s/^/%/ |
+ | map ,% :s/^/%/<CR> <Esc>:nohlsearch<CR> |
− | map ,! :s/^/!/ |
+ | map ,! :s/^/!/<CR> <Esc>:nohlsearch<CR> |
− | map ,; :s/^/;/ |
+ | map ,; :s/^/;/<CR> <Esc>:nohlsearch<CR> |
− | map ,- :s/^/--/ |
+ | map ,- :s/^/--/<CR> <Esc>:nohlsearch<CR> |
− | map ,c :s/^\/\/\\|^--\\|^ |
+ | map ,c :s/^\/\/\\|^--\\|^> \\|^[#"%!;]//<CR> <Esc>:nohlsearch<CR> |
" wrapping comments |
" wrapping comments |
||
− | map ,* :s/^\(.*\)$/\/\* \1 \*\// |
+ | map ,* :s/^\(.*\)$/\/\* \1 \*\//<CR> <Esc>:nohlsearch<CR> |
− | map ,( :s/^\(.*\)$/\(\* \1 \*\)/ |
+ | map ,( :s/^\(.*\)$/\(\* \1 \*\)/<CR><Esc>:nohlsearch <CR> |
− | map , |
+ | map ,< :s/^\(.*\)$/<!-- \1 -->/<CR> <Esc>:nohlsearch<CR> |
− | map ,d :s/^\([/(]\*\\| |
+ | map ,d :s/^\([/(]\*\\|<!--\) \(.*\) \(\*[/)]\\|-->\)$/\2/<CR> <Esc>:nohlsearch<CR> |
</pre> |
</pre> |
||
---- |
---- |
||
− | Adding :nohlsearch |
+ | 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/^/#/ |
+ | map ,# :s/^/#/<CR>:nohlsearch<CR> |
− | map ,/ :s/^/\/\// |
+ | map ,/ :s/^/\/\//<CR>:nohlsearch<CR> |
− | map , |
+ | map ,> :s/^/> /<CR>:nohlsearch<CR> |
− | map ," :s/^/\"/ |
+ | map ," :s/^/\"/<CR>:nohlsearch<CR> |
− | map ,% :s/^/%/ |
+ | map ,% :s/^/%/<CR>:nohlsearch<CR> |
− | map ,! :s/^/!/ |
+ | map ,! :s/^/!/<CR>:nohlsearch<CR> |
− | map ,; :s/^/;/ |
+ | map ,; :s/^/;/<CR>:nohlsearch<CR> |
− | map ,- :s/^/--/ |
+ | map ,- :s/^/--/<CR>:nohlsearch<CR> |
− | map ,c :s/^\/\/\\|^--\\|^ |
+ | map ,c :s/^\/\/\\|^--\\|^> \\|^[#"%!;]//<CR>:nohlsearch<CR> |
" wrapping comments |
" wrapping comments |
||
− | map ,* :s/^\(.*\)$/\/\* \1 \*\// |
+ | map ,* :s/^\(.*\)$/\/\* \1 \*\//<CR>:nohlsearch<CR> |
− | map ,( :s/^\(.*\)$/\(\* \1 \*\)/ |
+ | map ,( :s/^\(.*\)$/\(\* \1 \*\)/<CR>:nohlsearch<CR> |
− | map , |
+ | map ,< :s/^\(.*\)$/<!-- \1 -->/<CR>:nohlsearch<CR> |
− | map ,d :s/^\([/(]\*\\| |
+ | map ,d :s/^\([/(]\*\\|<!--\) \(.*\) \(\*[/)]\\|-->\)$/\2/<CR>:nohlsearch<CR> |
</pre> |
</pre> |
||
Line 121: | Line 121: | ||
let @/=hls |
let @/=hls |
||
endfun |
endfun |
||
− | map ,/ :call CppstyleQuote() |
+ | map ,/ :call CppstyleQuote()<CR> |
</pre> |
</pre> |
||
Line 134: | Line 134: | ||
endif |
endif |
||
endfunction |
endfunction |
||
− | nmap |
+ | 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 |
" 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 |
+ | vmap <buffer> <Esc>d a*/gvoi/* |
</pre> |
</pre> |
||
Line 149: | Line 149: | ||
<pre> |
<pre> |
||
− | :vmenu PopUp.Comments.Add :s/^/\/\// |
+ | :vmenu PopUp.Comments.Add :s/^/\/\//<CR> |
− | :vmenu PopUp.Comments.Remove :s/^..// |
+ | :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 |
+ | while n< commpos |
− | if line[n]!= " " & |
+ | if line[n]!= " " && line[n]!= "\t" |
break |
break |
||
endif |
endif |
||
let n= n+1 |
let n= n+1 |
||
endwhile |
endwhile |
||
− | if n== commpos & |
+ | 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 |
+ | map <M-c> :call MyComm()<CR> |
− | imap |
+ | 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 |
+ | 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/^/# / |
+ | map - :s/^/# /<CR> |
− | map _ :s/^\s*# \=// |
+ | map _ :s/^\s*# \=//<CR> |
set comments=:# |
set comments=:# |
||
endfunction |
endfunction |
||
function! SlashComment() |
function! SlashComment() |
||
− | map - :s/^/\/\/ / |
+ | map - :s/^/\/\/ /<CR> |
− | map _ :s/^\s*\/\/ \=// |
+ | map _ :s/^\s*\/\/ \=//<CR> |
endfunction |
endfunction |
||
Line 219: | Line 219: | ||
<pre> |
<pre> |
||
− | map \# :call Comment() |
+ | map \# :call Comment()<CR> |
− | map \-# :call Uncomment() |
+ | map \-# :call Uncomment()<CR> |
− | map \--# :call UncommentBlock() |
+ | map \--# :call UncommentBlock()<CR> |
" Comments range (handles multiple file types) |
" Comments range (handles multiple file types) |
||
function! Comment() range |
function! Comment() range |
||
− | if & |
+ | if &filetype == "c" || &filetype == "php" || &filetype == "css" |
execute ":" . a:firstline . "," . a:lastline . 's/^\(.*\)$/\/\* \1 \*\//' |
execute ":" . a:firstline . "," . a:lastline . 's/^\(.*\)$/\/\* \1 \*\//' |
||
− | elseif & |
+ | elseif &filetype == "html" || &filetype == "xml" || &filetype == "xslt" || &filetype == "xsd" |
− | execute ":" . a:firstline . "," . a:lastline . 's/^\(.*\)$/ |
+ | execute ":" . a:firstline . "," . a:lastline . 's/^\(.*\)$/<!-- \1 -->/' |
else |
else |
||
− | if & |
+ | if &filetype == "java" || &filetype == "cpp" || &filetype == "cs" |
let commentString = "//" |
let commentString = "//" |
||
− | elseif & |
+ | 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 & |
+ | if &filetype == "c" || &filetype == "php" || &filetype == "css" || &filetype == "html" || &filetype == "xml" || &filetype == "xslt" || &filetype == "xsd" |
" [[VimTip271]] |
" [[VimTip271]] |
||
− | execute ":" . a:firstline . "," . a:lastline . 's/^\([/(]\*\| |
+ | execute ":" . a:firstline . "," . a:lastline . 's/^\([/(]\*\|<!--\) \(.*\) \(\*[/)]\|-->\)$/\2/' |
else |
else |
||
− | if & |
+ | if &filetype == "java" || &filetype == "cpp" || &filetype == "cs" |
let commentString = "//" |
let commentString = "//" |
||
− | elseif & |
+ | 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 & |
+ | 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 & |
+ | if &filetype == "java" || &filetype == "cpp" || &filetype == "cs" |
let commentString = '\/\/' |
let commentString = '\/\/' |
||
let firstChar = '/' |
let firstChar = '/' |
||
− | elseif & |
+ | elseif &filetype == "vim" |
let commentString = '"' |
let commentString = '"' |
||
let firstChar = '"' |
let firstChar = '"' |
||
Line 273: | Line 273: | ||
let firstChar = '#' |
let firstChar = '#' |
||
endif |
endif |
||
− | if version |
+ | 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() |
+ | 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.
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.