Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions vim/autoload/rainbow.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
if exists('s:loaded') | finish | endif | let s:loaded = 1
fun s:resolve_parenthesis(p)
let ls = split(a:p, '\v%(%(start|step|end)\=(.)%(\1@!.)*\1[^ ]*|\w+%(\=[^ ]*)?) ?\zs', 0)
let [paren, containedin, contains, op] = ['', '', 'TOP', '']
for s in ls
let [k, v] = [matchstr(s, '^[^=]\+\ze='), matchstr(s, '^[^=]\+=\zs.*')]
if k == 'step'
let op = v
elseif k == 'contains'
let contains = v
elseif k == 'containedin'
let containedin = v
else
let paren .= s
endif
endfor
return [paren, containedin, contains, op]
endfun

fun rainbow#syn(config)
let conf = a:config
let prefix = conf.syn_name_prefix
let maxlvl = has('gui_running')? len(conf.guifgs) : len(conf.ctermfgs)
for i in range(len(conf.parentheses))
let p = conf.parentheses[i]
if type(p) == type([])
let op = len(p)==3? p[1] : has_key(conf, 'operators')? conf.operators : ''
let conf.parentheses[i] = op != ''? printf('start=#%s# step=%s end=#%s#', p[0], op, p[-1]) : printf('start=#%s# end=#%s#', p[0], p[-1])
endif
endfor
let def_rg = 'syn region %s matchgroup=%s containedin=%s contains=%s %s'
let def_op = 'syn match %s %s containedin=%s contained'

let b:rainbow_loaded = maxlvl
for parenthesis_args in conf.parentheses
let [paren, containedin, contains, op] = s:resolve_parenthesis(parenthesis_args)
if op == '' |let op = conf.operators |endif
for lvl in range(maxlvl)
if op != '' |exe printf(def_op, prefix.'_o'.lvl, op, prefix.'_r'.lvl) |endif
if lvl == 0
if containedin == ''
exe printf(def_rg, prefix.'_r0', prefix.'_p0', prefix.'_r'.(maxlvl - 1), contains, paren)
endif
else
exe printf(def_rg, prefix.'_r'.lvl, prefix.'_p'.lvl.(' contained'), prefix.'_r'.((lvl + maxlvl - 1) % maxlvl), contains, paren)
endif
endfor
if containedin != ''
exe printf(def_rg, prefix.'_r0', prefix.'_p0 contained', containedin.','.prefix.'_r'.(maxlvl - 1), contains, paren)
endif
endfor
exe 'syn cluster '.prefix.'Regions contains='.join(map(range(maxlvl), '"'.prefix.'_r".v:val'),',')
exe 'syn cluster '.prefix.'Parentheses contains='.join(map(range(maxlvl), '"'.prefix.'_p".v:val'),',')
exe 'syn cluster '.prefix.'Operators contains='.join(map(range(maxlvl), '"'.prefix.'_o".v:val'),',')
if has_key(conf, 'after') | for cmd in conf.after | exe cmd | endfor | endif
endfun

fun rainbow#syn_clear(config)
let conf = a:config
let prefix = conf.syn_name_prefix
let maxlvl = has('gui_running')? len(conf.guifgs) : len(conf.ctermfgs)

for id in range(maxlvl)
exe 'syn clear '.prefix.'_r'.id
exe 'syn clear '.prefix.'_o'.id
endfor
endfun

fun rainbow#hi(config)
let conf = a:config
let prefix = conf.syn_name_prefix
let maxlvl = has('gui_running')? len(conf.guifgs) : len(conf.ctermfgs)

for id in range(maxlvl)
let ctermfg = conf.ctermfgs[id % len(conf.ctermfgs)]
let guifg = conf.guifgs[id % len(conf.guifgs)]
exe 'hi '.prefix.'_p'.id.' ctermfg='.ctermfg.' guifg='.guifg
exe 'hi '.prefix.'_o'.id.' ctermfg='.ctermfg.' guifg='.guifg
endfor
endfun

fun rainbow#hi_clear(config)
let conf = a:config
let prefix = conf.syn_name_prefix
let maxlvl = has('gui_running')? len(conf.guifgs) : len(conf.ctermfgs)

for id in range(maxlvl)
exe 'hi clear '.prefix.'_p'.id
exe 'hi clear '.prefix.'_o'.id
endfor
endfun

97 changes: 97 additions & 0 deletions vim/autoload/rainbow_main.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
let s:rainbow_conf = {
\ 'guifgs': ['royalblue3', 'darkorange3', 'seagreen3', 'firebrick'],
\ 'ctermfgs': ['lightblue', 'lightyellow', 'lightcyan', 'lightmagenta'],
\ 'operators': '_,_',
\ 'parentheses': ['start=/(/ end=/)/ fold', 'start=/\[/ end=/\]/ fold', 'start=/{/ end=/}/ fold'],
\ 'separately': {
\ '*': {},
\ 'lisp': {
\ 'guifgs': ['royalblue3', 'darkorange3', 'seagreen3', 'firebrick', 'darkorchid3'],
\ },
\ 'haskell': {
\ 'parentheses': ['start=/(/ end=/)/ fold', 'start=/\[/ end=/\]/ fold', 'start=/\v\{\ze[^-]/ end=/}/ fold'],
\ },
\ 'tex': {
\ 'parentheses': ['start=/(/ end=/)/', 'start=/\[/ end=/\]/'],
\ },
\ 'vim': {
\ 'parentheses': ['start=/(/ end=/)/', 'start=/\[/ end=/\]/', 'start=/{/ end=/}/ fold', 'start=/(/ end=/)/ containedin=vimFuncBody', 'start=/\[/ end=/\]/ containedin=vimFuncBody', 'start=/{/ end=/}/ fold containedin=vimFuncBody'],
\ },
\ 'xml': {
\ 'syn_name_prefix': 'xmlRainbow',
\ 'parentheses': ['start=/\v\<\z([-_:a-zA-Z0-9]+)(\s+[-_:a-zA-Z0-9]+(\=("[^"]*"|'."'".'[^'."'".']*'."'".'))?)*\>/ end=#</\z1># fold'],
\ },
\ 'xhtml': {
\ 'parentheses': ['start=/\v\<\z([-_:a-zA-Z0-9]+)(\s+[-_:a-zA-Z0-9]+(\=("[^"]*"|'."'".'[^'."'".']*'."'".'))?)*\>/ end=#</\z1># fold'],
\ },
\ 'html': {
\ 'parentheses': ['start=/\v\<((script|style|area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)[ >])@!\z([-_:a-zA-Z0-9]+)(\s+[-_:a-zA-Z0-9]+(\=("[^"]*"|'."'".'[^'."'".']*'."'".'|[^ '."'".'"><=`]*))?)*\>/ end=#</\z1># fold'],
\ },
\ 'perl': {
\ 'syn_name_prefix': 'perlBlockFoldRainbow',
\ },
\ 'php': {
\ 'syn_name_prefix': 'phpBlockRainbow',
\ 'parentheses': ['start=/\v\<((area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)[ >])@!\z([-_:a-zA-Z0-9]+)(\s+[-_:a-zA-Z0-9]+(\=("[^"]*"|'."'".'[^'."'".']*'."'".'|[^ '."'".'"><=`]*))?)*\>/ end=#</\z1># fold', 'start=/(/ end=/)/ containedin=@htmlPreproc contains=@phpClTop', 'start=/\[/ end=/\]/ containedin=@htmlPreproc contains=@phpClTop', 'start=/{/ end=/}/ containedin=@htmlPreproc contains=@phpClTop'],
\ },
\ 'stylus': {
\ 'parentheses': ['start=/{/ end=/}/ fold contains=@colorableGroup'],
\ },
\ 'css': 0,
\ 'sh': 0,
\ }
\}

fun s:eq(x, y)
return type(a:x) == type(a:y) && a:x == a:y
endfun

fun rainbow_main#gen_config(ft)
let g = exists('g:rainbow_conf')? g:rainbow_conf : {}
"echom 'g:rainbow_conf:' string(g)
let s = get(g, 'separately', {})
"echom 'g:rainbow_conf.separately:' string(s)
let dft_conf = extend(copy(s:rainbow_conf), g) | unlet dft_conf.separately
"echom 'default config options:' string(dft_conf)
let dx_conf = s:rainbow_conf.separately['*']
"echom 'default star config:' string(dx_conf)
let ds_conf = get(s:rainbow_conf.separately, a:ft, dx_conf)
"echom 'default separately config:' string(ds_conf)
let ux_conf = get(s, '*', ds_conf)
"echom 'user star config:' string(ux_conf)
let us_conf = get(s, a:ft, ux_conf)
"echom 'user separately config:' string(us_conf)
let conf = (s:eq(us_conf, 'default') ? ds_conf : us_conf)
"echom 'almost finally config:' string(conf)
return s:eq(conf, 0) ? 0 : extend(extend({'syn_name_prefix': substitute(a:ft, '\v\A+(\a)', '\u\1', 'g').'Rainbow'}, dft_conf), conf)
endfun

fun rainbow_main#gen_configs(ft)
return filter(map(split(a:ft, '\v\.'), 'rainbow_main#gen_config(v:val)'), 'type(v:val) == type({})')
endfun

fun rainbow_main#load()
let b:rainbow_confs = rainbow_main#gen_configs(&ft)
for conf in b:rainbow_confs
call rainbow#syn(conf)
call rainbow#hi(conf)
endfor
endfun

fun rainbow_main#clear()
if !exists('b:rainbow_confs') | return | endif
for conf in b:rainbow_confs
call rainbow#hi_clear(conf)
call rainbow#syn_clear(conf)
endfor
unlet b:rainbow_confs
endfun

fun rainbow_main#toggle()
if exists('b:rainbow_confs')
call rainbow_main#clear()
else
call rainbow_main#load()
endif
endfun

10 changes: 10 additions & 0 deletions vim/plugin/rainbow_main.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
if exists('s:loaded') || !(exists('g:rainbow_active') || exists('g:rainbow_conf')) | finish | endif | let s:loaded = 1

command! RainbowToggle call rainbow_main#toggle()
command! RainbowToggleOn call rainbow_main#load()
command! RainbowToggleOff call rainbow_main#clear()

if (exists('g:rainbow_active') && g:rainbow_active)
auto syntax * call rainbow_main#load()
auto colorscheme * call rainbow_main#load()
endif
Loading