The Vim commentary plugin lets you toggle comments on and off for any selection of code with a single keystroke, streamlining your workflow and reducing the cognitive load of manual commenting.

Let’s see it in action. Imagine you’re writing some Python code and want to temporarily disable a block:

def greet(name):
    # This is a greeting function
    message = f"Hello, {name}!"
    print(message)

greet("World")

You’d navigate your cursor to the start of the def greet line, press v to enter visual mode, and then move your cursor down to the greet("World") line. Now, the entire block is highlighted. With the block selected, you press gc.

# def greet(name):
#     # This is a greeting function
#     message = f"Hello, {name}!"
#     print(message)
#
# greet("World")

Every line in the selection is now commented out, with the specific comment character for Python (#) prepended. To uncomment, you simply repeat the process: select the same block visually and press gc again.

def greet(name):
    # This is a greeting function
    message = f"Hello, {name}!"
    print(message)

greet("World")

This plugin, often tpope/vim-commentary, works by intelligently detecting the comment syntax for the current file type and applying it to the selected lines. It’s not just about adding a character; it’s about understanding context. For instance, in JavaScript, it would use // or /* */, and in Ruby, it would use #.

The core problem it solves is the tediousness of manually adding and removing comment characters, especially for multi-line blocks or when rapidly experimenting with code. Instead of reaching for the mouse or executing multiple keystrokes (<ESC>VjjjI#<Space><ESC>), you have a single, intuitive command.

Internally, vim-commentary maps a key (commonly gc) to a function that iterates over the lines in the current visual selection. For each line, it determines the appropriate comment string for the buffer’s filetype using Vim’s built-in getffiletype() and syntax commands. It then either prepends the comment string (if the line isn’t already commented) or removes it (if it is). This toggle behavior is what makes it so powerful for quick experimentation.

The exact comment string is determined by Vim’s syntax highlighting engine. For example, in a Python file, :echo syntastic#CommentString() might return # , while in a JavaScript file, it might return // . vim-commentary leverages this information.

A common misconception is that gc simply prepends a fixed character. In reality, it respects existing comments and the filetype’s specific commenting style. If a line is already commented with the correct syntax, gc will uncomment it. If a line has mixed or incorrect commenting, it might behave unexpectedly, but for standard code, it’s remarkably robust.

The next concept you’ll likely explore is how to customize the comment toggling behavior, such as defining custom comment strings or mapping gc to different key combinations.

Want structured learning?

Take the full Vim course →