tags:

views:

58

answers:

2

I have a YAML formatted text file, and would like to define custom folding for VIM, but I'm not sure how to go about it (despite reading the VIM documentation for folding). The file consists of YAML "documents", like so:

---
title: My Title
attr1: value1
attr2: value2
---
title: Next Item
attr1: value3
---
title: One More Item
...

I would like the resulting folded text to look something like this:

+---- 2 lines: My Title ----
+---- ? lines: Next Item ---

Any suggestions are appreciated! Thanks!

A: 

If you want to use a foldmethod other than "manual" all the time, add this line to your ~/.vimrc:
set foldmethod=foldoption

I would recommend using foldmethod=indent. This will fold based on any indent. Then if you change your input to include the indents where you want folds to happen. For instance if you change your input to

---
title: My Title
    other attrs: other values
---
title: Next Item
---
title: One More Item
...

It will fold as you described

Eric LaForce
Thanks for the response, Eric. When I tested this method, I didn't quite get the output I wanted.Folding this (My original example lacked enough lines.):`---``title: My Title` attr1: val1 attr2: val2 ---Resulted in: --- title: My Title +-- 2 lines: attr1: val1 ----- ---I would like the folding to be a little more aggressive.Also, since YAML uses indentation to define nested relationships, I believe that doing this will change how the file is parsed (or result in invalid YAML syntax). But I haven't tested this yet.
wkranec
Sorry about the last comment. I'm new to SO and didn't know that inline code wouldn't work (I can't edit anymore for some reason).
wkranec
Yeah that was my fault, I misread your original input. I was thinking it already had a nested relationship. You can use set foldmethod=marker instead. In conjunction with that you can use set foldmarker=mmm,nnn where mmm is the start marker and nnn is the ending marker. So I would try set foldmarker=---,--- (assuming --- in YAML is OK marker/delimeter for folds). Hope this helps.
Eric LaForce
Thanks again, Eric. I have tried the marker method before as you described, but then VIM folds the entire document (or all items until the end of the file if you try to make a fold in the middle of the document (since there really isn't a closing "---").
wkranec
You can indent the whole YAML document (`---\n\ \ \ \ title: 1\n\ \ \ \ other attr: other value\n---\n\ \ \ \ title: 2\n...`), which will result in `---\n+-- 2 lines: title: 1---\n---\n+-- 2 lines: title: 2---`. And this still will be a valid YAML document, while @Eric LaForce's answer will render your document invalid.
ZyX
+1  A: 

Do

%s/---\(.*\)\(\_.\{-}title: \)\(.*\)/---\1 #{{{1 \3\2\3/g
set foldmethod=marker

or

%s/\(---\_.\{-}title: \)\(.*\)/#{{{1 \2\r\1\2/g
set foldmethod=marker

That will add comment with title to the beginning of every YAML document and leave document still valid. foldmarker option must be left untouched.

Result:

1.

--- #{{{1 My Title
title: My Title
attr1: value1
attr2: value2
--- #{{{1 Next Item
title: Next Item
attr1: value3
--- #{{{1 One More Item
title: One More Item
...

Folded:

+--  4 строк: --- My Title-----------------------------
+--  3 строк: --- Next Item----------------------------
+--  3 строк: --- One More Item------------------------

2.

#{{{1 My Title
---
title: My Title
attr1: value1
attr2: value2
#{{{1 Next Item
---
title: Next Item
attr1: value3
#{{{1 One More Item
---
title: One More Item
...

Folded:

+--  5 строк: My Title--------------------------------
+--  4 строк: Next Item-------------------------------
+--  4 строк: One More Item---------------------------
ZyX
Thanks for the answer! I wasn't clear on how to use markers, and this definitely solved the problem. However, in the interest of not duplicating data, is there a way for VIM to use the regexp you gave to automatically determine fold levels, with a title?
wkranec
@wkranec I think it may be done using `foldmethod=expr` with proper `foldexpr` and `foldtext` set, but I have never used it.
ZyX