" ============================================================================= " commentop.vim - commands and operators to comment/uncomment lines "============================================================================= " " Author: Takahiro SUZUKI " Version: 1.1.0 (Vim 7.1) " Licence: MIT Licence " URL: http://www.vim.org/scripts/script.php?script_id=2708 " "============================================================================= " Document: {{{1 " "----------------------------------------------------------------------------- " Description: " This plugin provides a set of commands and operators to comment or " uncomment lines. Linewise comment token (such as double quote in vim " script) is detected automatically by looking up filetype of the file. " Filetypes working well by default: " vim, python, perl, ruby, haskell, sh, bash, zsh, java, javascript, " Makefile, tex " With definition in this script, these also work: " (c), cpp, csharp, php, matlab " " You can also easily define your own comment token for filetype. Add below " in your .vimrc: " CommentopSetCommentType FILETYPE REMOVEPATTERN INSERTSTRING " " plugin keymaps: " CommentopToggleNV " (n/v) toggle comment [count] or visual lines " CommentopAppendNV " (n/v) comment out [count] or visual lines " CommentopRemoveNV " (n/v) uncomment [count] or visual lines " " CommentopToggleOP " (n op) toggle comment {motion} " CommentopAppendOP " (n op) comment out {motion} " CommentopRemoveOP " (n op) uncomment {motion}Re " " default mapping: " co CommentopToggleNV " cO CommentopAppendNV " c CommentopRemoveNV " " go CommentopToggleOP " gO CommentopAppendOP " g CommentopRemoveOP " "----------------------------------------------------------------------------- " Installation: " Place this file in /usr/share/vim/vim*/plugin or ~/.vim/plugin/ " "----------------------------------------------------------------------------- " Examples: " in normal mode: " co " toggle comment for this line " 3cO " comment out 3 lines " " in normal mode (operator): " goip " toggle comment for this paragraph " gOa{ " comment out this {} block " " in visual mode: " c " remove comments in visual selection " "----------------------------------------------------------------------------- " ChangeLog: " 1.1.0: " - simplified maps (no backward compatibility for 1.0.2 or before) " - determine the comment string automatically (using 'commentstring') " 1.0.2: " - bug fix (wrong comment string with ft=vim) " 1.0.1: " - bug fix (gO was mapped to comment out operator) " 1.0: " - Initial release " "----------------------------------------------------------------------------- " Special Thanks: " Andy Woukla " " }}}1 "============================================================================= function! s:CountHeadSpace() let p = getpos('.') if p[2]==1 | return 0 | endif let line = getline('.')[0:p[2]-2] let len = 0 while len < strlen(line) if line[len]=~"[ \]" | let len += 1 | else | break | endif endwhile return len endfunction "mode 0:off 1:on 2:toggle function! s:Comment(mode, count) " determine the comment type if has_key(s:comment_types, &ft) let commentmatch = s:comment_types[&ft]['match'] let commentinsertstr = s:comment_types[&ft]['insert'] else " generate it from filetype let pat = split(&commentstring, '%s') " something linke '#%s' if len(pat)==1 let commentmatch = '^' . pat[0] . "[ \]\\{,1}" let commentinsertstr = pat[0] . ' ' let s:comment_types[&ft] = {'match': commentmatch, 'insert': commentinsertstr} else return endif endif let c = a:count " count head spaces normal! ^ let p = getpos('.') let mh = -1 while c>0 let hs = s:CountHeadSpace() if hs0 let iscomment = getline('.')[mh :] =~ commentmatch let prevstr = (mh>0) ? getline('.')[0:mh-1] : '' if a:mode==0 || (a:mode==2 && iscomment) " remove call setline('.', prevstr . substitute(getline('.')[mh :], commentmatch, '', '')) else " insert call setline('.', prevstr . commentinsertstr . getline('.')[mh :]) endif normal! j let c -= 1 endwhile call setpos('.', p) endfunction " normal / visual mode function! s:LinewiseComment(mode) if exists('s:lastmode') && s:lastmode =~ "[vV\]" call s:Comment(a:mode, getpos("'>")[1]-getpos("'<")[1]+1) else call s:Comment(a:mode, v:count1) endif endfunction " toggle / append / remove comment operator function! s:SetCommentMode(mode) let s:commentmode = a:mode endfunction function! s:LinewiseCommentOperator(type) call s:Comment(s:commentmode, getpos("']")[1]-getpos("'[")[1]+1) endfunction " save mode function! SaveMode() let s:lastmode = mode() return ':' endfunction noremap : SaveMode() " function and command to set the comment type from file type let s:comment_types = {} function! s:SetCommentType(...) " 1:filetype, 2:match, 3:insert let s:comment_types[a:1] = {'match': a:2, 'insert': a:3} endfunction " We do not need this for most filetypes because v1.2.0 or later " determines it automatically from &comments. " If you want to override the default comment string, adding like these: " :CommentopSetCommentType vim ^\"[\ ]\\{,1} "\ " :CommentopSetCommentType python ^#[\ ]\\{,1} #\ " in your .vimrc will do. command! -nargs=* CommentopSetCommentType :call s:SetCommentType() CommentopSetCommentType cpp ^//[\ ]\\{,1} //\ CommentopSetCommentType cs ^//[\ ]\\{,1} //\ CommentopSetCommentType matlab ^%[\ ]\\{,1} %\ CommentopSetCommentType php ^//[\ ]\\{,1} //\ " not correct, but for pragmatism: CommentopSetCommentType c ^//[\ ]\\{,1} //\ " default keymaps (you can override this in your .vimrc) if !hasmapto('CommentopToggleNV', 'nv') map co CommentopToggleNV endif if !hasmapto('CommentopAppendNV', 'nv') map cO CommentopAppendNV endif if !hasmapto('CommentopRemoveNV', 'nv') map c CommentopRemoveNV endif if !hasmapto('CommentopToggleOP', 'n') nmap go CommentopToggleOP endif if !hasmapto('CommentopAppendOP', 'n') nmap gO CommentopAppendOP endif if !hasmapto('CommentopRemoveOP', 'n') nmap g CommentopRemoveOP endif " === plugin keymaps " normal and visual noremap