block commenting?

topic posted Wed, April 14, 2004 - 8:53 AM by  Gabriel
Share/Save/Bookmark
Advertisement
is there a way to block-comment a bunch of lines easily? today i was in the apache conf for a site and I was commenting (#) out a lot of lines by having the # on the buffer and just typing "P-down-P-down-P-down" over and over.

It occurs to me as I type this that I could have done a regexp to replace \n with \n# since it did happen to be at the beginning of a line... any better ideas? what if it had been at, say, the 50th character of every line? ;)
posted by:
Gabriel
Advertisement
Advertisement
  • Re: block commenting?

    Wed, April 14, 2004 - 11:39 AM
    I typically use marks a and e to hold the start and end of a range (go to the line and hit m{CHAR} to put a mark in {CHAR}), then I can operate on that range with s/// like so, eg for pound commmenting:

    :'a,'e s/^/# /

    You can also use line numbers, 1 to $ ($ is the last line), a solitary % for everyline, and . or blank for the current line. To illustrate the "blank", these two commands do the same thing:

    :,$ s/^/# /
    :.,$ s/^/# /

    Your idea to match on the end of the line is good, but won't work as you expect. The ^ meta character matches the begining of the line, the $ meta character matches the end of the line. (Vim is smart about guessing when you want to match $ exactly instead of end of line, regular vi is less smart.)

    To replace the new lines themselves, first place anything you want at the end/start of the lines with a regular "s///" then use the ":'a,'e join!" to remove the newlines. (Regular join, ie no exclamation mark, will join lines with whitespace styled for English text, eg one space normally, but two spaces after a period.)

    You can get very fancy with the "addresses" for the line range of any ":". To use an apache conf example:

    :?^NameVirtualHost?+1,/^<\/VirtualHost>/ s/^/# /

    This states search backwards for a line that starts with "NameVirtualHost", then start on the line after it (+1), and search forwards for the end of a virtual host (</VirtualHost> at the start of a line), and on that range put "# " at the start of every line. Essentially, comment out the first virtual host entry when I am on some line past the NameVirtualHost declaration.

    That's a bit ugly in it's results though, since I always have a blank line after the NameVirtualHost, and it will be "commented out". So here is a more complicated one that won't comment out blank lines:

    :?^NameVirtualHost?+1,/^<\/VirtualHost>/ g/[^ ]/ s/^/# /

    The global (g/regexp/) in there says on the lines in this range operate if the character class of anything except space (and newline) matches. "g/re/p" where p is print, is the origin of the "grep" command. Another way to do roughly the same thing is:

    :?^NameVirtualHost?+1,/^<\/VirtualHost>/ v/^$/ s/^/# /

    The "v" is just like global, except the substition will only happen on lines that don't match. In this case, the regexp matches lines that begin and end at the same spot, ie blank, so the s/// runs on the non-blank lines. You'll see a difference if you have spaces on your blank lines though.
    • Re: block commenting?

      Thu, April 15, 2004 - 2:43 PM
      wow... yeah... that'll do. ;)

      You're right about my example grabbing newlines... though I did get it to work in my bass-ackwards way. I replaced \n's with \r's and it worked just fine ;) pretty weird, huh? when I replaced \n's with \n's I had a bunch of ^@ symbols all over everywhere. ;)

      As soon as I saw the ^ in your regexp I realized how lame my idea was. Thanks for the in-depth answer. ;) Very cool.
      • Re: block commenting?

        Thu, April 15, 2004 - 5:46 PM
        Vim does this weird thing internally with nulls and newlines. I forget the details, but that's what your ^@s were all about.
    • Re: block commenting?

      Thu, April 15, 2004 - 7:36 PM
      To make Eli's idea a little easier yet, you don't *need* to use your own marks. You can also use a "visual block":

      1. Go to the first line you want commented, and hit V.
      2. Use your favorite method to reach the last line of the block.
      3. Type:
      :s/^/# /

      Note that visual blocks in vim uses the special marks < and >, so hitting that colon just causes vim to generate the range-specifier for you.
      Note #2: you can also start a visual block at the last line, and move up to the top. Step 3 remains the same.

Recent topics in "Vi"

Topic Author Replies Last Post
Capitalises last entered letter Bearterrible 5 December 16, 2008
I love VI!! Steven 2 December 22, 2007
How many people use VI-style keybindings with readline (inc. B... Steven 2 December 18, 2007
slightly n00b question Alex 24 August 27, 2007