mattb
mattb

Reputation: 3063

Vim foldexpr matching pattern1 OR pattern2?

I want vim to create folds for my markdown files based on the header lines such that for all lines below a particular header will be folded. E.g:

# Header
some lines of
text here

## Sub-header
some more lines of
text here # and a comment for some reason
    # and an indented comment for good measure

# Another header
A new set of lines with a blank line(!)

for this header

## Another sub-header
yet more text

Should be folded like so:

# Header
+-- 2 lines: - some lines of -------------------

## Sub-header
+-- 3 lines: - some more lines of --------------

# Another header
+-- 3 lines: - A new set of lines --------------

## Another sub-header
yet more text

(I don't know what happens for a fold on a single line, so I'm happy with whatever vim's default is - i.e. if vim doesn't do folds for single lines, that's fine by me)

I've tried coming up with different regular expressions for this... I can match all non-header lines except for blank lines:

autocmd FileType markdown setlocal foldexpr=getline(v:lnum)=~'^[^#]'

So I tried adding a second pattern to capture blank lines with variation of ^[^#]\|^\s*$ (which does match everything but non-header lines when I use it in a simple search with /) but then no folds are produced and I don't know why (I tried different amounts of escape slashes but to no avail):

" none of these work
autocmd FileType markdown setlocal foldexpr=getline(v:lnum)=~'^[^#]\|^\s*$'
autocmd FileType markdown setlocal foldexpr=getline(v:lnum)=~'^[^#]\\|^\\s*$'

Upvotes: 2

Views: 202

Answers (1)

David784
David784

Reputation: 7464

You were almost there...you need 3 backslashes:

foldexpr=getline(v:lnum)=~'^[^#]\\\|^\\s*$'

Your regex string needs to end up having both a backslash and a vertical bar. Both of these characters need to be escaped in the expression. So you end up with \\ and \|...or 3 backslashes total.

source / additional reading

(side note: you could also switch to "very magic" mode with \\v, which would result in '\\v^[^#]\|^\\s*$'. If you had multiple "very magic" characters (e.g. |(){}+) this would be super helpful...but with a single vertical bar the only thing it might do is help with readability.)

Upvotes: 3

Related Questions