9

I have a space formatted (yaml) file like the following:

en:
  templates:
    template: "VERYLONGTEXTHEREWITHHUNDREDSOFLINES"
  destination: "I want to jump here"
    other: stuff
  further_destination:
    foo: bar
  yet_more_destinations:
    foo: bar

Is there any easy command to walk through from the beginning of templates: to destination: and ideally be able to continue on to further_destination: and yet_more_destinations:?

1

2 Answers 2

7

I think that some plugins might do what you want: they create text objects based on the indentation and then let you navigate between these text objects.

But installing a plugin just for that is not always the best solution: you could do it by youself with a bit of vimscript to add to your vimrc:

First let's create a function which loops on the lines of the buffer and goes to the first line with the same indentation level:

function! GoToNextIndent(inc)
    " Get the cursor current position
    let currentPos = getpos('.')
    let currentLine = currentPos[1]
    let matchIndent = 0

    " Look for a line with the same indent level whithout going out of the buffer
    while !matchIndent && currentLine != line('$') + 1 && currentLine != -1
        let currentLine += a:inc
        let matchIndent = indent(currentLine) == indent('.')
    endwhile

    " If a line is found go to this line
    if (matchIndent)
        let currentPos[1] = currentLine
        call setpos('.', currentPos)
    endif
endfunction

Note that the argument inc should be 1 or -1 depending on the way (down or up) you want to scan the buffer.

Then you can simply call the function :call GoToNextIndent(1) or create two convenient mappings:

nnoremap ni :call GoToNextIndent(1)<CR>
nnoremap pi :call GoToNextIndent(-1)<CR>

Here ni in normal mode will go to the next line with the same indent level and pi to the previous line.

You might want to change the mapped keys to something which doesn't mess with your configuration

3
  • 1
    Cool, thanks for the code! This is actually the first time I've run into something I thought vim could do natively and it actually can't, and is not just me not knowing how.
    – Drew
    Commented Jul 11, 2017 at 17:32
  • "You might want to change the mapped keys to something which doesn't mess with your configuration" -> This was the gotcha I originally missed. ni and pi end up causing the search functionality to act/delay in a weird manner.
    – horta
    Commented Jun 5 at 18:31
  • 1
    @horta Probably nothing weird about what you observed: usually n goes to the next search occurence directly, if you create a mapping ni when you press n vim has to decide if you just wanted to press n or if it should wait for you to press i after n this creates the delay you observed. You can checkout the help topic for ttimeout, timeoulen and ttimeoutlen if my memory is right. (There's also a bunch of questions about these settings on this site). But yeah usually you want to avoid creating mappings conflicting with existing commands (<leader> is useful for that actually)
    – statox
    Commented Jun 9 at 17:19
4

If your indenting is consistent, as shown above, you can use:

/^  [^ ]

/: search for the next occurrence of

^ : the start of a line, followed by two spaces

[^ ]: followed by any character that's not a space

Since your file is space-formatted, this is sufficient to correctly jump to each of the tags you mentioned. This command will jump you to the first occurrence it finds, and then you can hit n repeatedly to scan through all other occurrences.

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.