I have a Ruby code file open in vi, there are lines commented out with #
:
class Search < ActiveRecord::Migration
def self.up
# create_table :searches do |t|
# t.integer :user_id
# t.string :name
# t.string :all_of
# t.string :any_of
# t.string :none_of
# t.string :exact_phrase
#
# t.timestamps
# end
end
def self.down
# drop_table :searches
end
end
Say I want to uncomment all the lines in the first def ... end
section. What's an efficient way to do that in Vim?
In general, I'm looking for an easy and fluid way to comment and uncomment lines. Here I'm dealing with Ruby code, but it could be JavaScript (//
) or Haml (-#
).
Sometimes I'm shelled into a remote box where my plugins and .vimrc cannot help me, or sometimes NerdCommenter gets it wrong (eg JavaScript embedded inside HTML).
In these cases a low-tech alternative is the built-in
norm
command, which just runs any arbitrary vim commands at each line in your specified range. For example:Commenting with
#
:This inserts "#" at the start of each line. Note that when you type : the range will be filled in, so it will really look like
:'<,'>norm i#
Uncommenting
#
:This deletes the first character of each line. If I had used a 2-char comment such as // then I'd simply do
:norm xx
to delete both chars.If the comments are indented as in the OP's question, then you can anchor your deletion like this:
which means "go to the first non-space character, then delete one character". Note that unlike block selection, this technique works even if the comments have uneven indentation!
Note: Since
norm
is literally just executing regular vim commands, you're not limited to comments, you could also do some complex editing to each line. If you need the escape character as part of your command sequence, type ctrl-v then hit the escape key (or even easier, just record a quick macro and then use norm to execute that macro on each line).Note 2: You could of course also add a mapping if you find yourself using
norm
a lot. Eg putting the following line in ~/.vimrc lets you typectrl-n
instead of:norm
after making your visual selectionNote 3: Bare-bones vim sometimes doesn't have the
norm
command compiled into it, so be sure to use the beefed up version, ie typically /usr/bin/vim, not /bin/vi(Thanks to @Manbroski and @rakslice for improvements incorporated into this answer)
To comment out blocks in vim:
%
To uncomment blocks in vim:
If you want to select multiple characters, use one or combine these methods:
I like to use the tcomment plugin: http://www.vim.org/scripts/script.php?script_id=1173
I have mapped gc and gcc to comment a line or a highlighted block of code. It detects the file type and works really well.
Specify which lines to comment in vim:
Reveal the line numbers:
then
or this:
Use Control-V to select rectangles of text: go to the first
#
character, type Ctrl+V, move right once, and then down, up to the end of the comments. Now typex
: you're deleting all the#
characters followed by one space.Here's a basic one-liner based on the
C-v
followed byI
method outlined above.This command (
:Comment
) adds a chosen string to the beginning of any selected lines.Add this line to your
.vimrc
to create a command that accepts a single argument and places the argument at the beginning of every line in the current selection.E.g. if the following text is selected:
and you run this:
:Comment //
, the result will be: