luochen1990 / rainbow

Rainbow Parentheses Improved, shorter code, no level limit, smooth and fast, powerful configuration.
Apache License 2.0
1.79k stars 97 forks source link

[Bug] contains_prefix 'TOP' messing things up #161

Open rickalex21 opened 3 years ago

rickalex21 commented 3 years ago

Problem

Rainbow was highlighting all of my code block in white. This is mostly because the 'contains_prefix' in the plugin is 'TOP'. Is there a way to change this? I don't know but I did come up with a hack/solution.

Example hugo html code block.

{{$folders := (where .Pages ".IsPage" false)}}

In the hugo syntax that I created I need to contain everything like this or else it will appear everywhere in my markdown documents. This is because I include a lot of syntax when documenting code.

Hugo syntax, must have contained.

syn keyword hugoKeywords if define else end block partial range template where with containedin=hugoCodeBlock contained

Solution

  1. I need to know how to remove TOP and add my own contains. I want TOP for vim files and custom contains for my html files.

  2. Add a contains or contains_prefix in separately entry to override this

'cointains_prefix': '@hugoLang',
  1. Do what I did which is a temp hack. This is only temporary so it can work properly in vim files and html files.
diff --git a/autoload/rainbow.vim b/autoload/rainbow.vim
index 10551c5..a5ff02a 100644
--- a/autoload/rainbow.vim
+++ b/autoload/rainbow.vim
@@ -67,8 +67,9 @@ fun rainbow#syn(config)

            let real_contained = (lv == 0)? (contained? 'contained ' : '') : 'contained '
            let real_containedin = (lv == 0)? s:concat([containedin, '@'.gid2]) : '@'.gid2
-           let real_contains = s:concat([contains_prefix, contains])
-           exe 'syn region '.rid.' matchgroup='.pid.' '.real_contained.'containedin='.real_containedin.' contains='.real_contains.' '.paren
+           "let real_contains = s:concat([contains_prefix, contains])
+           let real_contains =   &ft =~ 'html' ? '@hugo' : 'TOP'
+           exe 'syn region '.rid.' matchgroup='.pid.' '.real_contained.'containedin='.real_containedin.' contains='.real_contains.' '.paren.' '
        endfor
    endfor
    for lv in range(cycle)
91khr commented 2 years ago

Maybe something like this can help?:

let g:rainbow_conf = #{
            \     separately: #{
            \         html: #{
            \             contains_prefix: '',
            \             parentheses: [
            "\                The default config of HTML should be copied too with contains=TOP appended if HTML tags
            "\                still need to be highlighted by rainbow
            \                 'start=/(/ end=/)/ contained containedin=@hugoCode contains=@hugoCode',
            \             ],
            \         },
            \     },
            \ }

And bundle the things of hugo in a syntax cluster named hugoCode:

syn region hugoCodeBrace start=/{{/ end=/}}/ contains=@hugoCode
syn cluster hugoCode contains=hugoKeywords,more

However, in current version of rainbow, setting contains_prefix to empty may raise an warning about empty contains list in syntax rule declaration. Following patch may fix this:

From f45569a7ac6d9da72eb06962d0d1d32034219884 Mon Sep 17 00:00:00 2001
From: Virginia Senioria <91khr@users.noreply.github.com>
Date: Sun, 5 Dec 2021 11:01:35 +0800
Subject: [PATCH] fix: fixed empty contains list when contains is empty

---
 autoload/rainbow.vim | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/autoload/rainbow.vim b/autoload/rainbow.vim
index 10551c5..c60cdee 100644
--- a/autoload/rainbow.vim
+++ b/autoload/rainbow.vim
@@ -68,7 +68,8 @@ fun rainbow#syn(config)
            let real_contained = (lv == 0)? (contained? 'contained ' : '') : 'contained '
            let real_containedin = (lv == 0)? s:concat([containedin, '@'.gid2]) : '@'.gid2
            let real_contains = s:concat([contains_prefix, contains])
-           exe 'syn region '.rid.' matchgroup='.pid.' '.real_contained.'containedin='.real_containedin.' contains='.real_contains.' '.paren
+           let real_contains = real_contains == '' ? '' : ' contains='.real_contains
+           exe 'syn region '.rid.' matchgroup='.pid.' '.real_contained.'containedin='.real_containedin.real_contains.' '.paren
        endfor
    endfor
    for lv in range(cycle)
-- 
2.34.1

BTW, this fix is included in Senioriae fork... >< And there wouldn't be the same issue for containedin, since it's always not empty.