tpope / vim-commentary

commentary.vim: comment stuff out
http://www.vim.org/scripts/script.php?script_id=3695
5.9k stars 214 forks source link

Auto-comment the duplicated lines #159

Closed ranelpadon closed 2 years ago

ranelpadon commented 2 years ago

One of my common workflows while experimenting on various code fixes/implementations is:

  1. copy/paste the target lines/blocks (i.e. duplicate them)
  2. comment-out the original copy, so that I could reference later if my code experimentation fails

So, I do this in Vim by doing these:

  1. select the lines (S-v/Visual Lines)
  2. duplicate the selected lines via vnoremap <Leader>d :copy '><CR>
  3. select the previously gv selected lines
  4. comment them using gc (:Commentary)

So, if I have these initial lines:

x = 'alpha'
y = 'bravo'

After executing those 4 steps above I'll have this, which is what I want:

# x = 'alpha'
# y = 'bravo'
x = 'alpha'
y = 'bravo'

However, the 4 steps above are repetitive and annoying. Ideally, I should only do Step 1 and the rest should be automated. So, I try to implement the Steps 2-4 via script, but it doesn't work as expected. Step 1 (i.e. lines selection) should be done manually by the user:

function AutoCommentDuplicatedLines()
    " Step 2
    " Duplicate the selected lines.
    copy '>

    " Step 3
    " Select the previously selected lines.
    normal! gv

    " Step 4
    " Comment the previously selected lines.
    '<,'>normal gcc

    " Doesn't work also:
    " normal gc
    " normal Commentary
    " Commentary
    " '<,'>Commentary
endfunction

Looks like Step 3 and 4 should be in 1 line, but this doesn't work as well

normal! gv gc

Results Expected

# x = 'alpha'
# y = 'bravo'
x = 'alpha'
y = 'bravo'

Actual

x = 'alpha'
y = 'bravo'
# y = 'bravo'
x = 'alpha'

Am I missing something? Thanks

tpope commented 2 years ago

Haven't tested your function, but you should be able to skip the gv and call '<,'>Commentary directly. Those marks continue to work after you leave visual mode.

ranelpadon commented 2 years ago

@tpope You're right, I could simplify the script with that. However, copy '> still seems to have quirks when called programmatically (i.e. it duplicated the lines but in reverse order). But your answer gave me hints, and came up with a simple mapping and avoids the need for custom script. This works as intended:

vnoremap <Leader>D :copy '><CR> :'<,'>Commentary<CR>

Thanks a lot. :)

tpope commented 2 years ago

@tpope You're right, I could simplify the script with that. However, copy '> still seems to have quirks when called programmatically (i.e. it duplicated the lines but in reverse order).

There are no quirks. Hint: there's a difference between calling '<,'> copy '> once and calling copy '> over and over again for each line.

vnoremap <Leader>D :copy '><CR> :'<,'>Commentary<CR>

That space is part of the map, and you don't want that.

Cleaned up version:

xnoremap <Leader>D :copy '><Bar>'<,'>Commentary<CR>

Thanks a lot. :)

;)

ranelpadon commented 2 years ago

Right, forgot about the <Bar>, and good point on the extraneous space. Yeah, I noticed this also when I tried using the
'<,'> copy '> inside the script: the N lines are duplicated as intended, but repeated N times also.

There are no quirks. Hint: there's a difference between calling '<,'> copy '> once and calling copy '> over and over again for each line.

Is there a simple way though to execute the '<,'> copy '> correctly inside the script?

tpope commented 2 years ago

Is there a simple way though to execute the '<,'> copy '> correctly inside the script?

Yes. Call the function once rather than N times. You might want <C-U> to remove the usual '<,'>.

ranelpadon commented 2 years ago

Right, I found a related answer:

So, to execute the function once, there are 2 options:

I chose the first approach, and it works now as intended!

function AutoCommentDuplicatedLines() range
    " Duplicate the selected lines.
    '<,'>copy '>

    " Comment the previously selected lines.
    '<,'>Commentary
endfunction

This is bothering me for some time already, so I could live peacefully now. Answered also my post in Vim StackExchange. Thanks again for your pointers, appreciate it. :)