From 976201ca55bb62fb95a8a2a1af416c87512ed40f Mon Sep 17 00:00:00 2001 From: Jeet Sukumaran Date: Sun, 15 Mar 2015 14:34:55 -0400 Subject: [PATCH 1/4] Add 'yank-and-comment' operation. Support for yanking a section of text before commenting them out. By default, mapped to '`gcy`'. --- doc/commentary.txt | 10 ++++++++++ plugin/commentary.vim | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/doc/commentary.txt b/doc/commentary.txt index d6deed0..f026eae 100644 --- a/doc/commentary.txt +++ b/doc/commentary.txt @@ -29,6 +29,16 @@ gcu *:Commentary* :[range]Commentary Comment or uncomment [range] lines +In addition, you can yank a section of text before commenting it out: + +gcy{motion} Yank and then comment or uncomment the lines that + {motion} moves over. + +gcy Yank and then comment or uncomment [count] lines. + +{Visual}gcy Yank and then comment or uncomment the highlighted + lines. + The |User| CommentaryPost autocommand fires after a successful operation and can be used for advanced customization. diff --git a/plugin/commentary.vim b/plugin/commentary.vim index a91cd71..ea1949e 100644 --- a/plugin/commentary.vim +++ b/plugin/commentary.vim @@ -72,6 +72,24 @@ function! s:textobject(inner) abort endif endfunction +function! s:setcommentaryreg(reg) + let s:targetreg = a:reg +endfunction +function! s:yankandcomment(type,...) + " only linewise operations make sense (to me, at least) + " so I am ignoring `type` + if a:0 + let [mark1, mark2] = [a:type, a:1] + let reg = a:2 + else + let [mark1, mark2] = ["'[", "']"] + let reg = get(s:, "targetreg", '"') + endif + execute 'normal! ' . mark1 . '"' . reg . 'y' . mark2 . ']' + call go(line(mark1),line(mark2)) + execute 'normal! ' . mark1 +endfunction + xnoremap Commentary :call go(line("'<"),line("'>")) nnoremap Commentary :set opfunc=gog@ nnoremap CommentaryLine :set opfunc=goexe 'norm! 'v:count1.'g@_' @@ -80,6 +98,11 @@ nnoremap ChangeCommentary c:call textobject(1) nmap CommentaryUndo CommentaryCommentary command! -range -bar Commentary call s:go(,) +xnoremap CommentaryYank :callyankandcomment("'<", "'>", v:register) +nnoremap CommentaryYank :call setcommentaryreg(v:register):set opfunc=yankandcommentg@ +nnoremap CommentaryYankLine :call setcommentaryreg(v:register):set opfunc=yankandcommentexe 'norm! 'v:count1.'g@_' + +xnoremap Commentary :call go(line("'<"),line("'>")) if !hasmapto('Commentary') || maparg('gc','n') ==# '' xmap gc Commentary nmap gc Commentary @@ -87,6 +110,9 @@ if !hasmapto('Commentary') || maparg('gc','n') ==# '' nmap gcc CommentaryLine nmap cgc ChangeCommentary nmap gcu CommentaryCommentary + xmap gcy CommentaryYank + nmap gcy CommentaryYank + nmap gcyy CommentaryYankLine endif if maparg('\\','n') ==# '' && maparg('\','n') ==# '' && get(g:, 'commentary_map_backslash', 1) From c08458342ade8a25a6cdb51d2b22d171525cc4f5 Mon Sep 17 00:00:00 2001 From: Jeet Sukumaran Date: Sun, 15 Mar 2015 15:27:21 -0400 Subject: [PATCH 2/4] Add 'duplicate-and-comment' operation. Support for duplicating a section of text before commenting them out. By default, mapped to '`gcd`'. --- doc/commentary.txt | 10 ++++++++++ plugin/commentary.vim | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/doc/commentary.txt b/doc/commentary.txt index f026eae..cb48b0e 100644 --- a/doc/commentary.txt +++ b/doc/commentary.txt @@ -39,6 +39,16 @@ gcy Yank and then comment or uncomment [count] lines. {Visual}gcy Yank and then comment or uncomment the highlighted lines. +You can also duplicate a section of text before commenting it out: + +gcd{motion} Duplicate and then comment or uncomment the lines that + {motion} moves over. + +gcd Duplicate and then comment or uncomment [count] lines. + +{Visual}gcd Duplicate and then comment or uncomment the highlighted + lines. + The |User| CommentaryPost autocommand fires after a successful operation and can be used for advanced customization. diff --git a/plugin/commentary.vim b/plugin/commentary.vim index ea1949e..60bfc40 100644 --- a/plugin/commentary.vim +++ b/plugin/commentary.vim @@ -90,6 +90,18 @@ function! s:yankandcomment(type,...) execute 'normal! ' . mark1 endfunction +function! s:yankcommentpaste(type,...) + if a:0 + let [mark1, mark2] = [a:type, a:1] + else + let [mark1, mark2] = ["'[", "']"] + endif + let savereg = @" + execute "normal " . mark1 ."gcy" . mark2 . "]" + execute "normal! " . mark2 . "p" . mark1 + let @" = savereg +endfunction + xnoremap Commentary :call go(line("'<"),line("'>")) nnoremap Commentary :set opfunc=gog@ nnoremap CommentaryLine :set opfunc=goexe 'norm! 'v:count1.'g@_' @@ -102,6 +114,10 @@ xnoremap CommentaryYank :callyankandcomment("'<", " nnoremap CommentaryYank :call setcommentaryreg(v:register):set opfunc=yankandcommentg@ nnoremap CommentaryYankLine :call setcommentaryreg(v:register):set opfunc=yankandcommentexe 'norm! 'v:count1.'g@_' +xnoremap CommentaryDupe :callyankcommentpaste("'<", "'>", v:register):normal! '>j +nnoremap CommentaryDupe :call setcommentaryreg(v:register):set opfunc=yankcommentpasteg@ +nnoremap CommentaryDupeLine :call setcommentaryreg(v:register):set opfunc=yankcommentpasteexe 'norm! 'v:count1.'g@_' + xnoremap Commentary :call go(line("'<"),line("'>")) if !hasmapto('Commentary') || maparg('gc','n') ==# '' xmap gc Commentary @@ -113,6 +129,9 @@ if !hasmapto('Commentary') || maparg('gc','n') ==# '' xmap gcy CommentaryYank nmap gcy CommentaryYank nmap gcyy CommentaryYankLine + xmap gcd CommentaryDupe + nmap gcd CommentaryDupe + nmap gcdd CommentaryDupeLine endif if maparg('\\','n') ==# '' && maparg('\','n') ==# '' && get(g:, 'commentary_map_backslash', 1) From ff2a6a2447d64b6a449d36c802a25ee1500b16db Mon Sep 17 00:00:00 2001 From: Jeet Sukumaran Date: Fri, 26 Nov 2021 21:22:30 -0800 Subject: [PATCH 3/4] Remove deprecated mappings --- plugin/commentary.vim | 9 --------- 1 file changed, 9 deletions(-) diff --git a/plugin/commentary.vim b/plugin/commentary.vim index 60bfc40..f6508e0 100644 --- a/plugin/commentary.vim +++ b/plugin/commentary.vim @@ -133,12 +133,3 @@ if !hasmapto('Commentary') || maparg('gc','n') ==# '' nmap gcd CommentaryDupe nmap gcdd CommentaryDupeLine endif - -if maparg('\\','n') ==# '' && maparg('\','n') ==# '' && get(g:, 'commentary_map_backslash', 1) - xmap \\ Commentary:echomsg '\\ is deprecated. Use gc' - nmap \\ :echomsg '\\ is deprecated. Use gc'Commentary - nmap \\\ CommentaryLine:echomsg '\\ is deprecated. Use gc' - nmap \\u CommentaryUndo:echomsg '\\ is deprecated. Use gc' -endif - -" vim:set et sw=2: From 31b27d2b6418a31bc04bffff83d29f2615f8ae7f Mon Sep 17 00:00:00 2001 From: Jeet Sukumaran Date: Fri, 26 Nov 2021 21:49:48 -0800 Subject: [PATCH 4/4] Update to current upstream base --- plugin/commentary.vim | 167 ++++++++++++++++++++++++++---------------- 1 file changed, 103 insertions(+), 64 deletions(-) diff --git a/plugin/commentary.vim b/plugin/commentary.vim index f6508e0..9a61c88 100644 --- a/plugin/commentary.vim +++ b/plugin/commentary.vim @@ -1,48 +1,76 @@ " commentary.vim - Comment stuff out " Maintainer: Tim Pope -" Version: 1.2 +" Version: 1.3 " GetLatestVimScripts: 3695 1 :AutoInstall: commentary.vim -if exists("g:loaded_commentary") || &cp || v:version < 700 +if exists("g:loaded_commentary") || v:version < 700 finish endif let g:loaded_commentary = 1 function! s:surroundings() abort - return split(get(b:, 'commentary_format', substitute(substitute( - \ &commentstring, '\S\zs%s',' %s','') ,'%s\ze\S', '%s ', '')), '%s', 1) + return split(get(b:, 'commentary_format', substitute(substitute(substitute( + \ &commentstring, '^$', '%s', ''), '\S\zs%s',' %s', '') ,'%s\ze\S', '%s ', '')), '%s', 1) endfunction -function! s:go(type,...) abort - if a:0 - let [lnum1, lnum2] = [a:type, a:1] +function! s:strip_white_space(l,r,line) abort + let [l, r] = [a:l, a:r] + if l[-1:] ==# ' ' && stridx(a:line,l) == -1 && stridx(a:line,l[0:-2]) == 0 + let l = l[:-2] + endif + if r[0] ==# ' ' && a:line[-strlen(r):] != r && a:line[1-strlen(r):] == r[1:] + let r = r[1:] + endif + return [l, r] +endfunction + +function! s:go(...) abort + if !a:0 + let &operatorfunc = matchstr(expand(''), '[^. ]*$') + return 'g@' + elseif a:0 > 1 + let [lnum1, lnum2] = [a:1, a:2] else let [lnum1, lnum2] = [line("'["), line("']")] endif let [l, r] = s:surroundings() let uncomment = 2 + let force_uncomment = a:0 > 2 && a:3 for lnum in range(lnum1,lnum2) let line = matchstr(getline(lnum),'\S.*\s\@ 2 && l.r !~# '\\' let line = substitute(line, - \'\M'.r[0:-2].'\zs\d\*\ze'.r[-1:-1].'\|'.l[0].'\zs\d\*\ze'.l[1:-1], + \'\M' . substitute(l, '\ze\S\s*$', '\\zs\\d\\*\\ze', '') . '\|' . substitute(r, '\S\zs', '\\zs\\d\\*\\ze', ''), \'\=substitute(submatch(0)+1-uncomment,"^0$\\|^-\\d*$","","")','g') endif - if uncomment + if force_uncomment + if line =~ '^\s*' . l + let line = substitute(line,'\S.*\s\@go(line(mark1),line(mark2)) - execute 'normal! ' . mark1 -endfunction - -function! s:yankcommentpaste(type,...) - if a:0 - let [mark1, mark2] = [a:type, a:1] - else - let [mark1, mark2] = ["'[", "']"] - endif - let savereg = @" - execute "normal " . mark1 ."gcy" . mark2 . "]" - execute "normal! " . mark2 . "p" . mark1 - let @" = savereg -endfunction - -xnoremap Commentary :call go(line("'<"),line("'>")) -nnoremap Commentary :set opfunc=gog@ -nnoremap CommentaryLine :set opfunc=goexe 'norm! 'v:count1.'g@_' -onoremap Commentary :call textobject(0) +command! -range -bar -bang Commentary call s:go(,,0) +xnoremap Commentary go() +nnoremap Commentary go() +nnoremap CommentaryLine go() . '_' +onoremap Commentary :call textobject(get(v:, 'operator', '') ==# 'c') nnoremap ChangeCommentary c:call textobject(1) -nmap CommentaryUndo CommentaryCommentary -command! -range -bar Commentary call s:go(,) +nmap CommentaryUndo :echoerr "Change your CommentaryUndo map to CommentaryCommentary" -xnoremap CommentaryYank :callyankandcomment("'<", "'>", v:register) -nnoremap CommentaryYank :call setcommentaryreg(v:register):set opfunc=yankandcommentg@ -nnoremap CommentaryYankLine :call setcommentaryreg(v:register):set opfunc=yankandcommentexe 'norm! 'v:count1.'g@_' - -xnoremap CommentaryDupe :callyankcommentpaste("'<", "'>", v:register):normal! '>j -nnoremap CommentaryDupe :call setcommentaryreg(v:register):set opfunc=yankcommentpasteg@ -nnoremap CommentaryDupeLine :call setcommentaryreg(v:register):set opfunc=yankcommentpasteexe 'norm! 'v:count1.'g@_' - -xnoremap Commentary :call go(line("'<"),line("'>")) if !hasmapto('Commentary') || maparg('gc','n') ==# '' xmap gc Commentary nmap gc Commentary omap gc Commentary nmap gcc CommentaryLine - nmap cgc ChangeCommentary + if maparg('c','n') ==# '' && !exists('v:operator') + nmap cgc ChangeCommentary + endif nmap gcu CommentaryCommentary - xmap gcy CommentaryYank - nmap gcy CommentaryYank - nmap gcyy CommentaryYankLine - xmap gcd CommentaryDupe - nmap gcd CommentaryDupe - nmap gcdd CommentaryDupeLine endif + +if !get(g:, "commentary_disable_dupe_and_comment_mappings", 0) + + function! s:setcommentaryreg(reg) + let s:targetreg = a:reg + endfunction + + function! s:yankandcomment(type,...) + " only linewise operations make sense (to me, at least) + " so I am ignoring `type` + if a:0 + let [mark1, mark2] = [a:type, a:1] + let reg = a:2 + else + let [mark1, mark2] = ["'[", "']"] + let reg = get(s:, "targetreg", '"') + endif + execute 'normal! ' . mark1 . '"' . reg . 'y' . mark2 . ']' + call go(line(mark1),line(mark2)) + execute 'normal! ' . mark1 + endfunction + + function! s:yankcommentpaste(type,...) + if a:0 + let [mark1, mark2] = [a:type, a:1] + else + let [mark1, mark2] = ["'[", "']"] + endif + let savereg = @" + execute "normal " . mark1 ."gcy" . mark2 . "]" + execute "normal! " . mark2 . "p" . mark1 + let @" = savereg + endfunction + + xnoremap CommentaryYank :callyankandcomment("'<", "'>", v:register) + nnoremap CommentaryYank :call setcommentaryreg(v:register):set opfunc=yankandcommentg@ + nnoremap CommentaryYankLine :call setcommentaryreg(v:register):set opfunc=yankandcommentexe 'norm! 'v:count1.'g@_' + xnoremap CommentaryDupe :callyankcommentpaste("'<", "'>", v:register):normal! '>j + nnoremap CommentaryDupe :call setcommentaryreg(v:register):set opfunc=yankcommentpasteg@ + nnoremap CommentaryDupeLine :call setcommentaryreg(v:register):set opfunc=yankcommentpasteexe 'norm! 'v:count1.'g@_' + xnoremap Commentary :call go(line("'<"),line("'>")) + + xmap gcy CommentaryYank + nmap gcy CommentaryYank + nmap gcyy CommentaryYankLine + xmap gcd CommentaryDupe + nmap gcd CommentaryDupe + nmap gcdd CommentaryDupeLine + +endif + +" vim:set et sw=2: