150

How can I select a bunch of text and comment it all out?

Currently I go to the first line, go to insert mode then type # left-arrowdown-arrow and then I repeat that sequence, perhaps saving a few keystrokes by using the . repeat feature to do each line.

Is there anyway I could (for instance) select either multiple lines in visual mode or by using a range of lines and an ex ('colon') command and for that range comment out all the lines with a # to make them a "block comment".

The ability to quickly 'de-comment' (remove the #'s) for a block comment would also be nice.

Braiam
  • 35,991
  • 1
    http://stackoverflow.com/questions/2462794/indent-or-comment-several-text-lines-with-vi – Ramesh Mar 20 '14 at 16:18
  • sed '/START/i <<"COMMENT" \ /END/a\COMMENT\n' - you only change two lines. And to see what you commented add cat to the beginning. – mikeserv Mar 21 '14 at 03:38

6 Answers6

247

Visual Block Mode

  • First, move the cursor to the first char of the first line in block code you want to comment, then type Ctrl + v.

    Then vim will go into VISUAL BLOCK mode.

  • Use j to move the cursor down until you reach the last line of your code block. Then type: Shift + i

  • Now vim goes to INSERT mode and the cursor is at the first char of the first line. Finally, type # then ESC and the code block is now commented.

Note that at first sight, the editing does not seem to differ from changing a single line. The changes will only be applied to the whole block after hitting ESC.

To uncomment, do the same things but instead of type Shift + i, you just type x to remove all # after highlight them in VISUAL BLOCK mode.

AdminBee
  • 22,803
cuonglm
  • 153,898
  • 3
    Or even use / to jump to the endpoint, or % if the endpoint is a matching } (or { if jumping backwards). I like the visual modes so much more than specifying ranges... – Izkata Mar 20 '14 at 18:55
  • 38
    Doesn't seem to work. +1 for visual mode, -1 because Shift I opens an INSERT only on the first line of the selection. Could just be an OSX issue though, as it's VERY common with this OS that is completely inconsistent with Unix. – Matt Clark Jun 29 '15 at 20:32
  • 22
    @MattClark: You tried it, didn't you? That how it suppose to work. After editing the first line, press ESC to quit insert mode, everything was applied to the rest of selected line. – cuonglm Jun 30 '15 at 02:39
  • 22
    Works with MacVim. Important to note that it only works with VISUAL BLOCK, not VISUAL or VISUAL LINE mode. – atamanroman Jan 12 '16 at 09:58
  • 1
    @atamanroman: Yes, that's how the title is! – cuonglm Jan 12 '16 at 10:03
  • 2
    @cuonglm that information was for those it does not seem to work for. Your answer ist correct. I just wanted to add that it does indeed only work with VISUAL BLOCK. – atamanroman Jan 12 '16 at 10:18
  • @atamanroman: I don't get your point. The title is stated that is's visual block mode. – cuonglm Jan 12 '16 at 10:20
  • 10
    read the comment from @MattClark: "+1 for visual mode" and then he states it does not work on his machine (OSX). I tried it on OSX with macvim and it works, but you've got to use visual block, not visual (nor visual line). – atamanroman Jan 12 '16 at 10:32
  • @cuonglm helped in VISUAL BLOCK mode ,thanks – karthik Nov 25 '18 at 06:12
  • 3
    On OSX with VISUAL LINE, I just have to press ESC two times to propagate to every selected line. – jblanche Jul 12 '19 at 08:40
  • 2
    I tried this serveral times and it did not work for me. Until i realized, that I used shift + v and not ctrl + v. Thx @atamanroman – abuzze Oct 29 '19 at 14:37
  • 1
    You can also use Ctrl + v and then jump down to the line number you want to include, e.g.: 50G to jump to line 50. Then Shift + I etc. – SO_fix_the_vote_sorting_bug Feb 16 '20 at 09:46
177

Ranges:

You can do it with the following commands:

for commenting:

:66,70s/^/#

for uncommenting:

:66,70s/^#/

Obviously, here we're commenting lines from 66 to 70 (inclusive).

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
periket2000
  • 2,368
37

Substitute

For the sake of completeness here's another way:

  1. Enter visual mode by pressing v
  2. select the lines you like to comment (up/down arrow or j/k)
  3. enter :s/^/# / which translates to: in selection (:) replace beginning of line (^) with `# '
reto
  • 557
12

Markers:

The following steps are done in command mode:

  1. go to first line and set the marker with mt
  2. go to the line till which you want range
  3. issue the command :'t,.s/^/#/

Explanation

  • m#, where # denotes any letter, puts a marker at your current location. The location can later be referred to using '#, where # is the same letter as before. In our case we used the letter t
  • The command :'t,.s/^/#/ reads as follows:
    • : the prefix for complex commands
    • 't,. defines the range at which the following command should apply. In our case, it is from marker 't till current line .
    • s/^/#/ is a substitution formula, replacing all beginning-of-line ^ with literal character #
5

Plugin

There is a plugin, which offers an efficient way of commenting out based on the file system being used.

Also, this answer discusses how to use the NERD commenter for vim. Few more basic instructions on how to use the plugin are discussed here.

Ramesh
  • 39,297
1

Use either NERDCommenter as mentioned, but if that's not available to me I use the visual modes. I go into Visual Line mode, make my selection, often its blocks of whitespace, so I go V{ then change to Visual Block mode with Ctrl+Q and then insert the comment symbol at the start of the lines with I, so to comment out a block of text, I'd do

V{<C-Q>I#<Esc>
TankorSmash
  • 850
  • 6
  • 8