Skip to content

Commit

Permalink
feature: bundle the parentheses into clusters and add shortcut for th…
Browse files Browse the repository at this point in the history
…em in the parentheses config

and fix the warning when contains_prefix is empty
  • Loading branch information
91khr committed Dec 26, 2021
1 parent ae0ef43 commit 1f384f7
Showing 1 changed file with 43 additions and 19 deletions.
62 changes: 43 additions & 19 deletions autoload/rainbow.vim
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fun s:concat(strs)
endfun

fun s:resolve_parenthesis_with(init_state, p)
let [paren, contained, containedin, contains_prefix, contains, op] = a:init_state
let [paren, contained, containedin, contains_prefix, contains, op, cluster] = a:init_state
let p = (type(a:p) == type([])) ?
\ ((len(a:p) == 3) ?
\ printf('start=#%s# step=%s end=#%s#', a:p[0], op, a:p[-1]) :
Expand All @@ -31,25 +31,27 @@ fun s:resolve_parenthesis_with(init_state, p)
let containedin = s:concat([containedin, v])
elseif k == 'contained'
let contained = 1
elseif k == 'cluster'
let cluster = s:concat([cluster, v])
else
let paren .= s
endif
endfor
let rst = [paren, contained, containedin, contains_prefix, contains, op]
let rst = [paren, contained, containedin, contains_prefix, contains, op, cluster]
"echom json_encode(rst)
return rst
endfun

fun s:resolve_parenthesis_from_config(config)
return s:resolve_parenthesis_with(['', 0, '', a:config.contains_prefix, '', a:config.operators], a:config.parentheses_options)
return s:resolve_parenthesis_with(['', 0, '', a:config.contains_prefix, '', a:config.operators, ''], a:config.parentheses_options)
endfun

fun s:synID(prefix, group, lv, id)
return a:prefix.'_lv'.a:lv.'_'.a:group.a:id
endfun

fun s:synGroupID(prefix, group, lv)
return a:prefix.a:group.'_lv'.a:lv
fun s:synGroupID(prefix, group, lv, cluster)
return a:prefix.a:group.'_lv'.a:lv.'_'.a:cluster
endfun

fun rainbow#syn(config)
Expand All @@ -59,31 +61,53 @@ fun rainbow#syn(config)

let glob_paran_opts = s:resolve_parenthesis_from_config(conf)
let b:rainbow_loaded = cycle
let cluster_list = {}
for id in range(len(conf.parentheses))
let [paren, contained, containedin, contains_prefix, contains, op] = s:resolve_parenthesis_with(glob_paran_opts, conf.parentheses[id])
let [paren, contained, containedin, contains_prefix, contains, op, cluster] = s:resolve_parenthesis_with(glob_paran_opts, conf.parentheses[id])

let cluster = split(cluster, ',') ?? ['default']
for k in cluster
let cluster_list[k] = get(cluster_list, k, [])->add(id)
endfor
let containedin_items = split(containedin, ',')
let upcluster = filter(copy(containedin_items), 'v:val =~ "#.*"')->map('v:val[1:]') ?? cluster
let containedin = filter(containedin_items, 'v:val !~ "#.*"')->join(',')
let contains_items = (contains_prefix != '' ? [contains_prefix] : []) + split(contains, ',')

for lv in range(cycle)
let lv2 = ((lv + cycle - 1) % cycle)
let [rid, pid, gid2] = [s:synID(prefix, 'r', lv, id), s:synID(prefix, 'p', lv, id), s:synGroupID(prefix, 'Regions', lv2)]
let uplv = ((lv + cycle - 1) % cycle)
let [rid, pid, upid] = [s:synID(prefix, 'r', lv, id), s:synID(prefix, 'p', lv, id),
\ mapnew(upcluster, '"@".s:synGroupID(prefix, "Regions", uplv, v:val)')->join(',')]

if len(op) > 2
exe 'syn match '.s:synID(prefix, 'o', lv, id).' '.op.' containedin='.s:synID(prefix, 'r', lv, id).' contained'
endif

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_containedin = (lv == 0)? s:concat([containedin, upid]) : upid
let real_contains = mapnew(contains_items,
\ 'v:val =~ "#.*" ? "@".s:synGroupID(prefix, "Regions", uplv, v:val[1:]) : v:val')
\ ->flatten()->join(',')
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)
exe 'syn cluster '.s:synGroupID(prefix, 'Regions', lv).' contains='.join(map(range(len(conf.parentheses)), 's:synID(prefix, "r", lv, v:val)'), ',')
exe 'syn cluster '.s:synGroupID(prefix, 'Parentheses', lv).' contains='.join(map(range(len(conf.parentheses)), 's:synID(prefix, "p", lv, v:val)'), ',')
exe 'syn cluster '.s:synGroupID(prefix, 'Operators', lv).' contains='.join(map(range(len(conf.parentheses)), 's:synID(prefix, "o", lv, v:val)'), ',')

for [kind, abbr] in [['Regions', 'r'], ['Parentheses', 'p'], ['Operators', 'o']]
for [cluster, ids] in items(cluster_list)
for lv in range(cycle)
exe 'syn cluster '.s:synGroupID(prefix, kind, lv, cluster).' contains='.
\ mapnew(ids, 's:synID(prefix, abbr, lv, v:val)')->join(',')
endfor
exe 'syn cluster '.prefix.kind.'_'.cluster.' contains='.
\ map(range(cycle), '"@".s:synGroupID(prefix, kind, v:val, cluster)')->join(',')
endfor
exe 'syn cluster '.prefix.kind.' contains='.map(keys(cluster_list), 'prefix.kind."_".v:val')->join(',')
endfor

for cmd in conf->get('after', [])
exe cmd
endfor
exe 'syn cluster '.prefix.'Regions contains='.join(map(range(cycle), '"@".s:synGroupID(prefix, "Regions", v:val)'), ',')
exe 'syn cluster '.prefix.'Parentheses contains='.join(map(range(cycle), '"@".s:synGroupID(prefix, "Parentheses", v:val)'), ',')
exe 'syn cluster '.prefix.'Operators contains='.join(map(range(cycle), '"@".s:synGroupID(prefix, "Operators", v:val)'), ',')
if has_key(conf, 'after') | for cmd in conf.after | exe cmd | endfor | endif
endfun

fun rainbow#syn_clear(config)
Expand Down

0 comments on commit 1f384f7

Please sign in to comment.