DEV Community

Liz Lam
Liz Lam

Posted on • Edited on

3 Ways to Comment Out Blocks of Code in vi

Learning vi for the first time can be really intimidating. The learning curve is a bit high and there are many ways to do many things in this simple yet powerful editor. There will come a point where you will be comfortable navigating around using the h j k and l keys and going between command mode and insert mode will be second nature. This is where things get real fun and adding more commands to your vi toolbox will make you even more productive.

Have you ever found yourself in vi wanting to comment and uncomment blocks of code? Here are 3 ways to accomplish this.

The Bad Way

Using VI ineffeciently
It may be a little unfair to call this the "bad" way, but it's certainly the most inefficient. You start your editor, navigate down to the beginning row of the block you want to comment out. You hit i to go into insert mode, enter // to comment, hit ESC to go back to command mode, hit j to navigate down to the next row, and then repeat until all the rows are commented out.

To uncomment the rows, you do almost the same thing. Navigate your cursor the beginning of the last row you want to comment. Hit xx to remove the first two characters of the line (in our case the // chars), hit h to navigate up to the next row, and then repeat until all rows are uncommented.

Being able to navigate around and insert and remove characters like this is definitely not something to be scoffed at. It takes time to even get to this point of sufficiency, but there are better ways.

The Better Way

Alt Text
Substitution with regular expressions is a powerful tool in vi.

While in command mode:
Hit : to enter escape mode
Type 11,17s/^/\/\// and then hit ENTER

DONE!

Woh, woh, woh! What just happened here?

Let's break it down in some detail.
11,17 is the range you are interested in. In this case, lines 11-17.

s stands for substitute. The next two arguments are separated by /, the first being the location or old value and the second being the new value.

For example:
s/cat/dog/ takes the first occurrence of the word cat and replaces it with the word dog. This will happen for every line.

Now you may have noticed a little problem. We are trying to substitute nothing with //. Well "nothing" is really the beginning of each line which is represented with ^ (the caret character).

So s/^/dog/ would add the word dog to the beginning of each line.

What about //? Won't vi get confused since substitution uses / to separate the old value from the new value? This is where we need to use \ (backslash) to escape the double back slashes that represent commenting.

/\/\ is the escaped version of //. Escaping these characters tells the command that we literally want to use / twice and not to interpret it as a separator for the command.

We put it all together to get 11,17s/^/\/\//.

Uncommenting uses a similar pattern.

Hit : to enter escape mode and enter 11,17s/\/\///.

Like before, our range is lines 11-17. This time our first argument is the escaped version of // and the second value is left out. This literally means we are substituting escaped // with nothing, and therefore removing it.

Phew! That was a lot to cover! This is definitely a very powerful technique, but like many commands involving regular expressions, it can look very ugly.

The Best Way

Alt Text
There is another mode in vi that can be utilized for our task at hand. Visual block mode allows us to visually block off a section of the editor to perform actions on it. We first start off by navigating down the beginning of the top row we're interested in.

Hit CTRL + v to enter visual block mode.
Use j to navigate and block off the beginning of lines 11-17.
Hit SHIFT + i (capital i) to enter insert mode.
Type // and hit ESC

Uncommenting is just as simple.

Hit CTRL + v to enter visual block mode again.
Navigate and block off the //s in lines 11-17.
Hit x to delete.

The combination of using visual mode and commands is the most practical and best way to comment and uncomment code. Apologies to the regex fans out there!

NOTE: Visual mode is actually a feature of vim and not original vi. Most modern systems actually use vim and the binary is either renamed or aliased to vi.

It's hard to believe this is only the tip of iceberg of things that can be accomplished in vi. Getting pass the initial hump is really the hardest part. More proficiency in vi translates to more efficiency and productivity. I hope this encourages you to explore and have some fun with this awesome little editor.

DISCLAIMER: The criteria used to place the Bad, Better, and Best judgments are based upon my personal tastes.

Top comments (8)

Collapse
 
adriengiboire profile image
Adrien Giboire • Edited

Quick tips:

  • To go to the beginning/end of your function/block, you can use %
  • Instead of typing the line numbers in your s command, you can highlight the lines and type :. It will prompt :'<,'> and you can continue with your command, i.e. s/^/\/\//, then Enter.

Hope I was clear :)

Collapse
 
grepliz profile image
Liz Lam

Thanks for the tip!

Collapse
 
pianocomposer321 profile image
pianocomposer321

Quote:
What about //? Won't vi get confused since substitution uses / to separate the old value from the new value? This is where we need to use \ (forward slash) to escape the double back slashes that represent commenting.

Acutally, / is forward slash and \ is backslash. :)

Collapse
 
grepliz profile image
Liz Lam

Oh yes, you are right! Correcting now!

Collapse
 
moopet profile image
Ben Sinclair

I use a plugin to do this because different languages have different requirements for comments and I'm lazy). I use commentary but there are a few that all do much the same thing.

Out of your options, I prefer #3, but I'd also consider using a macro and repeating it n times if the comments required changing the start and end of the line, like in CSS.

Using ctrl-smilieface to enter pedantic mode I feel the urge to point out that #3 is Vim only and not available in Vi.

Collapse
 
grepliz profile image
Liz Lam

I haven't had a lot of experiences with different plugins, but I will have to check out commentary.

So funny, yes. I tend to use the words 'vi' and 'vim' interchangeably and I was debating if I should make that distinction on this blog.

True story, I used vi proper for almost 10 years and for 8 of those years at work on an old RedHat Workstation distribution. A time came where all our work machines got upgraded to Ubuntu and I ended up with vim on my machine (I think it was vim-tiny). I wasn't familiar with visual mode. Everytime I accidentally hit CTRL + v, I would quickly ESC out because I didn't know what it was doing.

3 months ago, I decided to finally make the small effort to learn visual mode.

I love how you can learn new things all the time even in the tools you've been using forever!

Thanks for the comments!

Collapse
 
pnaranja profile image
Paul

Thanks for sharing!

For your #3, I use relative numbers so it's easy to see you can press "6j" to get to the end of the function.

And interesting code you're editing :)

Collapse
 
grepliz profile image
Liz Lam

Definitely a great shortcut also!

Yes! I will probably start blogging about Rust at some point in the future!