3

I'm wanting to create custom syntax highlighting in vim for a task-list.

Task items begin with a hyphen. Two types of task items are relevant: (a) items without an '@done' tag. (b) items with an @done tag. (a) and (b) need to be highlighted differently.

I'm using taskpaper, which works fine, but the issue is, I'm trying to make this to work for task items that span multiple lines. For example:

- Regular item (works)
- Completed item @done (works)
- Multi-line item. This item continues on to 
  the line below. (doesn't work)
- Multi-line completed item. This item continues
  on to the line below. (doesn't work). @done

The highlighting file at taskpaper works for the first two, but not for the second two. As a workaround hack, I tried this for the last case above:

syn region multLineDoneItem start="{" end="}" fold
HiLink multLineDoneItem NonText

But now, I'm forced to mark multi-line done items with braces like so:

- {Multi-line completed item. This item continues
  on to the line below. (workaround works).}

I've already searched stackexchange and elsewhere. I would appreciate any help! :)

1 Answer 1

5

You could try using the \ze regex atom in the end part of your syntax region. This would allow you to match everything up to but not including the next task. I haven't looked at how you do matching but something like this might work.

syn region muiltLineItem     start="^-" end="\(\s*\n)\+\ze^-" fold    
syn region multiLineDoneItem start="^-" end="@done\s*\n\(\s*\n\)*\ze^-" fold
HiLink multiLineItem Normal
HiLink multiLineDoneItem NonText

I haven't tested this at all but I think it, or something like it, should work. If you wish to take indentation into account the \z regex atom will allow you to keep matching lines with the same indent.

UPDATE:

Try this:

syn match multilineItem "^-\_.\{-}\ze\(\n-\|\%$\)" fold
syn match multilineDoneItem "^-\(\%(\_^-\)\@!\_.\)\{-}@done\s*\n\ze" fold
command -nargs=+ HiLink highlight default link <args>
HiLink multilineItem Normal
HiLink multilineDoneItem NonText
delcommand HiLink

Oh, also this should work for all four cases and not just the multi-line items.

Sign up to request clarification or add additional context in comments.

4 Comments

Hmm, thanks, but the problem seems to be that in what you suggested above, everything ends up matching multiLineDoneItem, because it starts with a "^_" . So vim starts a multiLineDoneItem at the very first item (even though it's incomplete), and doesn't stop matching until the end of the file. :(
Ah, yes. I definitely oversimplified this. Try this update and let me know how you get on. I've tested it with your example and it seems to work fine. It could probably do with being expanded a bit more to take care of any other text in the buffer but it should serve as a good starting point.
Whoa, that's a terrific regexp, thanks much! Yes, it is an excellent starting point, and so I'm going to mark this as answered. There're a bunch of cases (none that I've mentioned) that don't work right now though, but I'm going to try out a few things before I ask you more questions. I don't fully understand one thing though: why do you have a '\ze' at the end of the multilineDoneItem regexp? The `(\%(_^-)\@!' should stop matching anyway when the starting pattern is found, right?
Yes, you're right. The final \ze in muiltlineDoneItem isn't necessary it was just left over from a few other things I was trying. Turns out this was trickier than I thought it would be! Glad it works for you though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.