vimtricks.wiki Concise Vim tricks, one at a time.

How do I select or operate on a block of code based on its indentation level in Vim?

Answer

ii / ai

Explanation

The vim-indent-object plugin by Michael Smith adds text objects based on indentation level, giving you ii (inner indent) and ai (an indent) to select, delete, change, or yank blocks of code that share the same indentation. This is a game-changer for languages like Python, YAML, and CoffeeScript where indentation defines code structure, but it works brilliantly in any language.

How it works

The plugin provides four text objects:

ii    " inner indent — select all lines at the same indent level
ai    " an indent — select all lines at the same indent level PLUS one line above
aI    " an Indent — select all lines at the same indent level PLUS one line above AND below
iI    " inner Indent — same as ii (alias)

Example: Python function body

Given this Python code with the cursor anywhere inside the function body:

def calculate(x, y):
    result = x + y
    if result > 100:
        result = 100
    return result

def other():
    pass

Pressing vii selects the four indented lines (the entire function body) without selecting the def line or the blank line after.

Pressing vai selects the same four lines plus the def calculate(x, y): line above — the complete function.

Common operations

dii    " delete the indented block
cii    " change the indented block (delete and enter insert mode)
yii    " yank the indented block
>ii    " indent the block one more level
<ii    " unindent the block one level
gUii   " uppercase the entire indented block
vii    " visually select the indented block

Example: YAML structure

In a YAML file with the cursor on any line under database::

server:
  port: 8080
  host: localhost
database:
  host: db.example.com
  port: 5432
  name: myapp
cache:
  ttl: 300

Pressing dii deletes the three database configuration lines. Pressing dai deletes those three lines plus the database: header.

Why indentation beats braces

In brace-delimited languages, you have i} and a} to work with blocks. But in Python, YAML, Haml, Pug, CoffeeScript, and other indentation-sensitive languages, there are no braces to target. The indent text object fills this gap perfectly.

Even in languages with braces, ii is often faster because you do not need your cursor to be inside the braces — just anywhere on an indented line.

Tips

  • Combine with vim-commentary: gcii comments out an entire indented block in one keystroke
  • Works with counts: v2ii selects the current indent block and the parent block above it
  • Pairs naturally with > and < for adjusting indentation of logical code blocks
  • The ai object is perfect for selecting a complete Python function or class (body + header) for moving or deleting
  • Works in all visual modes: characterwise, linewise, and blockwise

Next

How do I edit multiple lines at once using multiple cursors in Vim?