Reputation: 141
Assuming I have the following Perl code open in Vim:
if (@arr = shomething()) {
for (@arr) {
some_function($_->{some_key});
# some
# more
# code
while (some_other_funtion($_)) {
write_log('working');
}
}
}
and the cursor at the beginning of the line with some_function
, how I can move the cursor to any of:
while
{
of the while
while
block (with the call to write_log
)Searching for {
is not an option, because there could be many of {
that do not start new inner code block - for example, see parameter of some_function
.
Upvotes: 6
Views: 9620
Reputation: 173
% , $, and ^ are your best friends. (cursor to matching enclosure, end of line, beginning of line).
At the beginning of your code block there ':1$' , will put your cursor at the first bracket.
% will advance you to the next 'matching' end of your code block, assuming it is balanced. If your code is out of balance, the cursor won't move. It actually counts matching-type opening and closing braces which follow and if there is an imbalance, the cursor will not move. Usually the terminal will beep: as in 'Doh! You have a problem.' It's very useful and it works with '{}[]()'
Good way to check your code and ensure that the end of the block exists. It will skip as many lines as exist between the braces (or parens or brackets) to place the cursor on the matching enclosure.
This file is small but assuming you're on line 1 (:1)
:1$ - end of line first code block
:2 - puts the cursor at the 'f' in 'for' on line 2 rather than the white space preceding.
% - jumps you to the closing ')' on that line.
% - jumps you to the opening '(' on that line.
$ - takes you to the '{' which opens the for loop code
% - jumps the cursor to the ending '}' of the for loop
% - takes you back to the top (% is bi-directional. )
Play with it. There's a reason that Intellij's text editor has a vim mode. It's powerful.
Also, pretty good vim manual here that covers some of this stuff and much more.
https://www.pks.mpg.de/~mueller/docs/suse10.1/suselinux-manual_en/manual/sec.suse.vim.html
Upvotes: 0
Reputation: 30408
It seems you are defining a “code block” to be {
}
that contain at least one line. You can most easily search for those just by searching for a {
at the end of a line:
/{$
/{
means search for a {
, and $
represents an anchor to the end of the line.
There might be cases where a {
opens a block, but is not the last character of a line:
while (some_other_funtion($_)) { # this while is very important
write_log('working');
}
To take this into account, do the following search for a {
that is not closed on the same line:
/{[^}]*$
/
– search for{
– a {
character[^}]
– followed by any character that is not a }
*
– repeated 0 or more times$
– until the end of the line(Vim regexes are not always the same as in Perl, but this particular one is.)
You could define a mapping for that second search by putting this in your .vimrc
:
noremap <Leader>nb /{[^}]*$<CR>
That would let you jump to the next block by pressing <Leader>
(\ by default) n b.
Since it uses :noremap
, it affects Select mode too. You won’t want that if your <Leader>
is a printable character (which it is by default). In that case, add the line sunmap <Leader>nb
below the previous line to fix Select mode.
Upvotes: 4