DEV Community

Cover image for 3 Vim commands for blazingly fast navigation between brackets ⚡
Max Shen
Max Shen

Posted on • Originally published at m4xshen.dev

3 Vim commands for blazingly fast navigation between brackets ⚡

There are often lots of brackets within a programming file. Therefore the efficiency of navigating between them becomes crucial for the overall productivity. I'll introduce you to three types of commands that allows you to navigate between brackets blazingly fast!

1. %

Let's begin with an example first (the arrow pointing to your cursor position):

( example )
↑
Enter fullscreen mode Exit fullscreen mode

Press %:

( example )
          ↑
Enter fullscreen mode Exit fullscreen mode

Press % again:

( example )
↑
Enter fullscreen mode Exit fullscreen mode

This demonstrates that % jumps between the matched brackets. However the actual behavior is more than that. % find the next item in this line after or under the cursor and jump to its match.

% not only works on (), it also works with:

  • pairs: () or [] or {} (this can be changed with the 'matchpairs' option)
  • C-style comment: /* */.
  • HTML tag: <div></div>

It's crucial to note the emphasis on after or under the cursor, which means that you can use it even when bracket is not under the cursor.

Example:

some text (( example )) some text
↑
Enter fullscreen mode Exit fullscreen mode

Let's say you want to go to the last ). You might initially think to use f(% in the following steps:

Press f(:

some text (( example )) some text
          ↑
Enter fullscreen mode Exit fullscreen mode

Press %:

some text (( example )) some text
                      ↑
Enter fullscreen mode Exit fullscreen mode

However the f( is unnecessary. You can achieve the same navigation with just %.

This is because of % works like this under the hood:

  1. Finds the first pair after or under the cursor which is (.
  2. Jump to its match which is ).

It might not be that intuitive to use % when bracket not under the cursor, but after you get more familiar with it you can achieve some magic movement with it!

2. [( and [{

  • [( jumps backward to the first unmatched (
  • [{ jumps backward to the first unmatched {

Example:

{

  example

  text
  ↑
}
Enter fullscreen mode Exit fullscreen mode

Press [{:

{
↑
  example

  text

}
Enter fullscreen mode Exit fullscreen mode

In addition to [( and [{, there's also ]) and ]}:

  • ]) jumps forward to unmatched )
  • ]} jumps forward to unmatched }

Let's see a practical example. Imagine you're navigating inside a large function:

function example() {
  const sum = 0;
   
  for (let i = 0; i < 10; i++) {
    sum += i;
  }

  // some other operation, which takes many lines
  // ...

  return sum;
}
Enter fullscreen mode Exit fullscreen mode

Let's say you want to jump to the closing } of that function. There are several ways to do this:

  1. Use relative jump such as 12j to jump to the } directly:
    This approach works for smaller functions. However in the example this is impossible because the function is too big and the last line of the function is outside the screen.

  2. Use /} to search the }:
    This might work if there's no other } inside the function. However in the example there's other }, and you need to press n multiple times to get to the last }.

  3. Use ]}:
    The most efficient method is to use ]}, which directly takes you to the closing } of the function without the need for counting lines or repeated searching.

3. ][ and []

  • ][: jump forward to the next } in the first column.
  • []: jump backward to the next } in the first column.

Example:

{
↑ example
}

{
  {
    example
  }
}

{
  example
}
Enter fullscreen mode Exit fullscreen mode

Press ][:

{
  example
}
↑
{
  {
    example
  }
}

{
  example
}
Enter fullscreen mode Exit fullscreen mode

Press ][ again:

{
  example
}

{
  {
    example
  }
}
↑
{
  example
}
Enter fullscreen mode Exit fullscreen mode

Press ][ again:

{
  example
}

{
  {
    example
  }
}

{
  example
}
↑
Enter fullscreen mode Exit fullscreen mode

This is useful when in files containing multiple functions. In most languages, the end of a function is a } at the start of a line (first column). You can then use ][ to jump to the end of next function and [] to jump to the end of previous function.

There's also:

  • ]]: jump forward to the next { in the first column.
  • [[: jump backward to the next { in the first column.

Though in practice, the { character appearing in the first column is less common. I personally rarely find an occasion to use them. If you can think of scenarios where ]] and [[ would be particularly useful, please share them in the comments below!

Conclusion

In conclusion, mastering Vim commands such as %, [(, [{, ][, and [] boosts navigation efficiency in programming files. Each command offers unique advantages under different situation, enabling us to move through code with precision and ease!

Top comments (7)

Collapse
 
mirzalazuardi profile image
Mirzalazuardi Hermawan

Thats why i use vim

Collapse
 
alxwnth profile image
Alex

How didn’t I know about this before… Okay, time to do some practice!

Collapse
 
jonathan_leffler_336f14e5 profile image
Jonathan Leffler • Edited

The usefulness of [[ and ]] depends on the coding conventions you work with. In C, K&R style places the opening brace of a function at the start of a line. If you follow that part of K&R style, then [[ and ]] are useful for jumping to the previous/next function (and a repeat count works for jumping N functions). If you follow the { at the end of a line, even on function definitions, then the [[ and ]] operations are much less useful.

If you're working in a language with different conventions, especially if the conventions are enforced by a formatter (gofmt, rustfmt, etc), then they aren't as helpful. You may be reduced to using []% and ][% — jump to the end of the function and bounce back to the start — and heaven help you if you have stray unmatched curly braces in the function.

Thanks for the article. I wasn't aware of [] or ][, nor of ]) or [(, nor of [{ or ]}.

Collapse
 
sytranvn profile image
Sy Tran Dung

Python dev sit in corner.

Collapse
 
dairdev profile image
Dennis

Great plugins to improve handling brackets are:
Old but good, this Tim Pope's plugin: github.com/tpope/vim-surround
If you are in the Neovim world using Lua plugins: github.com/kylechui/nvim-surround

Collapse
 
gokayburuc profile image
Gokay Buruc

Year 2024 and which-key.nvim is still the best plugin.

Which-key.nvim

Collapse
 
ibconcept profile image
william maina

Honestly for me the % is not working, please advice