6

I want to comment out a piece of code. For instance this snippet:

foo
bar
foo

Should become this:

<!--foo
bar
foo-->

So I type the following sequence:

vap:norm '<i<!--<C-v><Esc>'>A-->

This give me the following result, which is unexpected for me:

<!--<!--<!--foo
bar
foo-->-->-->

I understand that a Normal mode command on a range is executed on each line of this range, right?

My question is: is it possible to execute the Normal mode command only on the first/last line of a range and if so, how can I do this?

4

As I said in the comments I strongly recommend a plugin like nerdcommenter or vim-commentary to do stuff like this because they are well tested and handle a lot of corner cases.

Now if you want to do it by yourself a solution could be the following. First create a function which takes two numbers as arguments and uses these numbers as the lines on which it should make the substitutions:

function! HTMLCommentFunction(line1, line2)
    execute "normal! " . a:line1 . "GI<!--"
    execute "normal! " . a:line2 . "GA-->"
endfunction

Then create a command accepting a range and which will send the lines of this range to your function:

command! -range HTMLComment call HTMLCommentFunction(<line1>, <line2>)

And you're done you can then use :'<,'>HTMLComment to get your result.

And to make all of it easier to use you can create the following mapping:

vnoremap <key> :HTMLComment<CR>

So you can just press you key in visual mode to get your comment.

  • Wow - that's exact, what I'm looking for! Thanks! Most of my comment stuff could done with with visual select block mode, to install only for HTML or CSS comments a whole plugin, seems a little bit overdoing. I like it small, so this is a good solution! – oliver Jan 30 '17 at 14:59
  • I totally agree with your idea to get as few plugins as possible I recommended them because they are a part of the few plugins I use :-) – statox Jan 30 '17 at 15:09
2

When surrounding with this trick, always start by appending, then you can insert the head.

Moreover, I'd play with visual mode for this, no range, no :normal.

 " untested
 vnoremap <buffer> µ `>a--><esc>`<i<!--<esc>

Another approach (that needs to modify one register) is:

 vnoremap <buffer> µ s<!--<c-r>="--><esc>
1

You can use the following command:

vapk<Esc>A--><Esc>vapo<Esc>I<!--<Esc><CR>

Explanation: vap visually selects a paragraph, k move cursor one like up, <Esc> escape from visual to normal mode, A jump to end of line and go into insert mode, --> type in text -->, <Esc> escape from insert to normal mode, vap visually select a paragraph, o jump to other end of visual selection, <Esc> escape from visual to normal mode, I jump to beginning of line and go into insert mode, <!-- type in text <Esc> escape from insert mode to normal mode, <CR> carriage return to end the whole command.

Above it is not really simple to type. Maybe you should create a keyboard mapping like for example to map spacebar (you can use any other key combination if you like) to comment out current paragraph and save this setting in your .vimrc file.

noremap <space> vapk<Esc>A--><Esc>vapo<Esc>I<!--<Esc><CR>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.