6

When working with larger or rather deeply nested yaml files (Hi Rails), it happens quickly that I loose sight of where I am with regards to the indentation hierarchy of the file.

A very simple example to illustrate my point:

1| en:
2|   activerecord:
3|     errors:
4|       messages:
5|         parse_error: is syntactically not correct

When the cursor is on the line 5, I would like to somehow get the info
en -> activerecord -> errors -> messages -> parse_error via a command or the likes.

6

The right way to do it would be to use an external program if the markup language presents a complex structure or particular edge cases, like the bunch or tools you can find for JSON.

Though YAML seems to be pretty straightforward Even if YAML seems to be pretty complex, I started with a one liner working on your snippet to end up with this Vim script you could place in ftplugin/yaml.vim:

function! YAMLTree()
    let l:list = []
    let l:cur = getcurpos()[1]
    " Retrieve the current line indentation
    let l:indent = indent(l:cur) + 1
    " Loop from the cursor position to the top of the file
    for l:n in reverse(range(1, l:cur))
        let l:i = indent(l:n)
        let l:line = getline(l:n)
        let l:key = substitute(l:line, '^\s*\(\<\w\+\>\):.*', "\\1", '')
        " If the indentation decreased and the pattern matched
        if (l:i < l:indent && l:key !=# l:line)
            let l:list = add(l:list, l:key)
            let l:indent = l:i
        endif
    endfor
    let l:list = reverse(l:list)
    echo join(l:list, ' -> ')
endfunction

nnoremap <F5> :call YAMLTree()<CR>

It loops on each line from the cursor to the top looking for a word \w+ between zero or more spaces \s* and a colon :, followed by anything. It also checks for indentation to recognize the keys hierarchy.

P.S. My first thought was about indent highlighting plugins like indentLine or vim-indent-guides. That's something I initially missed on Vim, but I think the heavy slow-down it can cause cured me.

| improve this answer | |
  • 3
    YAML seems to be pretty straightforward -> actually, YAML is a lot more complicated than JSON. The YAML spec is 23,449 words, the JSON spec 1,969 words. It's one of the problems I wrote about here. Most Rails files (which the OP mentioned) are limited to a very small part of YAML, so your snippet is probably fine for that, but there are plenty of YAML files out there for which this snippet won't work. – Martin Tournoij Sep 8 '17 at 20:19
  • Wow, I wasn't aware of the variety of syntax in YAML, it should allow basic markdown?! I should have added that the snippet only works on "standard" and properly formatted YAML, and would fail if \w: is found earlier in a multi-line block for example. Thanks for the input. – LEI Sep 8 '17 at 20:35
  • 1
    Thanks so much, this works very well for my usecase and is more than fast enough on a 2k line yaml file. – Benjamin Reitzammer Sep 11 '17 at 14:02
2

I'm using the yaml plugin by Meijvogel and that has a YamlDisplayFullPath function which he recommends putting into autodisplay mode though I prefer it on InsertLeave like so:

autocmd! InsertLeave *.yml YamlDisplayFullPath  
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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