13

Does anybody know the command for moving to an outer block of brackets/parentheses?

Lets say that my cursor is in the innermost bracket. I know that % moves to a matching bracket, but is there a command to move from say, bracket 1 to bracket 2?

3   {
2     {
1        { }
2     }
3   }
2
  • So how do you jump from the outer bracket to the inner bracket ?Is there a shortcut key? Commented May 17, 2020 at 10:37
  • @GavinBruce Welcome to Vi and Vim! Note that this is not really an answer to this question. A comment would have been a more appropriate for this follow up, but you need your reputation points to be higher to post a comment. Try to participate with the site, by asking questions, posting answers or suggesting edits to get your reputation a little bit higher, so you'll be able to post comments then. I have now converted your answer into a comment. Again, welcome to the site!
    – filbranden
    Commented May 17, 2020 at 12:32

4 Answers 4

16

[% and ]% provided by matchit or match-up

The answer by Mass suggesting [{ and ]} works perfectly for unmatched curly brackets but only for curly brackets. This should be considered as an advantage. However, not all blocks are defined by curly brackets and the wish to handle other situations is also important.

Parentheses

Vim provides additionally [( and ]) to do the same for parentheses (e.g. useful for lisp):

3   (
2     (
1        ( )
2     )
3   )

Note also the text objects ib and ab (analogue to iB and aB for curly brackets).

Square Brackets

Unfortunately, the situation for square brackets is different. Consider following python matrix using nested lists

matrix = [
     [1, 2, 3, 4],
     [5, 6, 7, 8],
     [9, 10, 11, 12],
]

One might guess [[ and ]] would move to an unmatched square bracket, but they do something different (see :h ]] and https://vi.stackexchange.com/a/14115/1292). There is actually no builtin motion for unmatched square brackets. However, the builtin text objects i[ and a[ to operate on blocks defined by square brackets exist.

Blocks specific to languages

Also if you want to move to other types of blocks often specific to languages (e.g. nested xml/html tags, nested if-blocks, nested LaTeX environments), there is no builtin motion for this. Again note the existence of the dedicated text objects for xml/html tags it and at.

Swiss Army knife: [% and ]%

The plugins matchit and match-up provide the motions [% and ]% which can handle all situations and IMHO perfectly enhance the builtin set of motions together with the text objects i% and a%.

A drawback is that they consider all types of blocks and also matched brackets which can mean that you have to press [% more often and is less precise than [{ and [( which therefore have their place.

Note matchit is distributed with vim and can be loaded with :packadd! matchit (:h matchit-install). match-up has to be installed from the internet available on github and vim.org.

Ninja-feet

Another interesting vim plugin for this situation is https://github.com/tommcdo/vim-ninja-feet. If you want to add a new first/last row to the python matrix, you can press z[2i[/z]2i] to immediately jump to the outer square bracket block and open a new line.

Summary

========================================================================================
  Block Type       Move to previous   Move to next   Inner text obj.   Outer text obj.  
========================================================================================
  curly bracket    [{                 ]}             iB                aB               
----------------------------------------------------------------------------------------
  parentheses      [(                 ])             ib                ab               
----------------------------------------------------------------------------------------
  square bracket                                     i[                a[               
----------------------------------------------------------------------------------------
  xml/html                                           it                at               
----------------------------------------------------------------------------------------
  paragraph        {                  }              ip                ap               
----------------------------------------------------------------------------------------
  section          [[ []              ]] ][                                             
----------------------------------------------------------------------------------------
  method           [m [M              ]m ]M                                             
----------------------------------------------------------------------------------------
  matchit/-up      [%                 ]%             i%                a%               
----------------------------------------------------------------------------------------
  ninja-feet       z[<text object>    z]<text obj>                                      
7

Use [{ and ]} to go to the next outer curly braces. You can use a count such as 3[{. See :help [{.

3
  • Are you sure about [B and ]B? My vim does not define [B and ]B. vim-unimpaired uses them to jump to :bfirst and :blast.
    – Hotschke
    Commented Jul 23, 2018 at 7:15
  • @Hotschke you're absolutely right, I was confusing it with iB and aB.
    – Mass
    Commented Jul 23, 2018 at 13:50
  • The iB and aB is for visual mod. Like vib, vaB
    – foxiris
    Commented Dec 9, 2022 at 8:02
2

You can use [m to move to beginning of matched brackets, then sequentially up levels.

Using ]m goes to next inner brackets, but not to the innermost level (in my tests anyway).

2
1

Here is possible solution without plugins: take advantage of visual selection.

Using your example text: if the cursor is in the innermost block between the curly brackets, va{a{a{ will put the cursor on the outermost closing curly bracket. Typing % will move to the outermost opening curly bracket.

Notice that you need one a{ for each nesting level.

This solution may be not very straightforward but it has two advantages:

  • you don't need any plugin
  • it works also for ( ) and { } (i.e., va( resp. va<. Bonus: the same method works for XML and HTML at tag level: vat

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.