spacepaste

  1.  
  2. "==============================================================================
  3. "Script Title: rainbow parentheses improved
  4. "Script Version: 3.3.1
  5. "Author: luochen1990
  6. "Last Edited: 2014 Nov 27
  7. "Simple Configuration:
  8. " first, put "rainbow.vim"(this file) to dir vimfiles/plugin or vim73/plugin
  9. " second, add the follow sentences to your .vimrc or _vimrc :
  10. " let g:rainbow_active = 1
  11. " third, restart your vim and enjoy coding.
  12. "Advanced Configuration:
  13. " an advanced configuration allows you to define what parentheses to use
  14. " for each type of file . you can also determine the colors of your
  15. " parentheses by this way (read file vim73/rgb.txt for all named colors).
  16. " READ THE SOURCE FILE FROM LINE 25 TO LINE 50 FOR EXAMPLE.
  17. "User Command:
  18. " :RainbowToggle --you can use it to toggle this plugin.
  19. "==============================================================================
  20. if exists('s:loaded') || !(exists('g:rainbow_active') || exists('g:rainbow_conf'))
  21. finish
  22. endif
  23. let s:loaded = 1
  24. let s:rainbow_conf = {
  25. \ 'guifgs': ['royalblue3', 'darkorange3', 'seagreen3', 'firebrick'],
  26. \ 'ctermfgs': ['lightblue', 'lightyellow', 'lightcyan', 'lightmagenta'],
  27. \ 'operators': '_,_',
  28. \ 'parentheses': ['start=/(/ end=/)/ fold', 'start=/\[/ end=/\]/ fold', 'start=/{/ end=/}/ fold'],
  29. \ 'separately': {
  30. \ '*': {},
  31. \ 'tex': {
  32. \ 'parentheses': ['start=/(/ end=/)/', 'start=/\[/ end=/\]/'],
  33. \ },
  34. \ 'vim': {
  35. \ 'parentheses': ['start=/(/ end=/)/', 'start=/\[/ end=/\]/', 'start=/{/ end=/}/ fold', 'start=/(/ end=/)/ containedin=vimFuncBody', 'start=/\[/ end=/\]/ containedin=vimFuncBody', 'start=/{/ end=/}/ fold containedin=vimFuncBody'],
  36. \ },
  37. \ 'xml': {
  38. \ 'parentheses': ['start=/\v\<\z([-_:a-zA-Z0-9]+)(\s+[-_:a-zA-Z0-9]+(\=("[^"]*"|'."'".'[^'."'".']*'."'".'))?)*\>/ end=#</\z1># fold'],
  39. \ },
  40. \ 'xhtml': {
  41. \ 'parentheses': ['start=/\v\<\z([-_:a-zA-Z0-9]+)(\s+[-_:a-zA-Z0-9]+(\=("[^"]*"|'."'".'[^'."'".']*'."'".'))?)*\>/ end=#</\z1># fold'],
  42. \ },
  43. \ 'html': {
  44. \ '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'],
  45. \ },
  46. \ 'php': {
  47. \ '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'],
  48. \ },
  49. \ 'css': 0,
  50. \ }
  51. \}
  52. func s:resolve_parenthesis(p)
  53. let ls = split(a:p, '\v%(%(start|step|end)\=(.)%(\1@!.)*\1[^ ]*|\w+%(\=[^ ]*)?) ?\zs', 0)
  54. let [paren, containedin, contains, op] = ['', '', 'TOP', '']
  55. for s in ls
  56. let [k, v] = [matchstr(s, '^[^=]\+\ze='), matchstr(s, '^[^=]\+=\zs.*')]
  57. if k == 'step'
  58. let op = v
  59. elseif k == 'contains'
  60. let contains = v
  61. elseif k == 'containedin'
  62. let containedin = v
  63. else
  64. let paren .= s
  65. endif
  66. endfor
  67. return [paren, containedin, contains, op]
  68. endfunc
  69. func rainbow#load()
  70. let conf = b:rainbow_conf
  71. let maxlvl = has('gui_running')? len(conf.guifgs) : len(conf.ctermfgs)
  72. for i in range(len(conf.parentheses))
  73. let p = conf.parentheses[i]
  74. if type(p) == type([])
  75. let op = len(p)==3? p[1] : has_key(conf, 'operators')? conf.operators : ''
  76. 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])
  77. endif
  78. endfor
  79. let def_rg = 'syn region %s matchgroup=%s containedin=%s contains=%s,@Spell %s'
  80. let def_op = 'syn match %s %s containedin=%s contained'
  81. call rainbow#clear()
  82. let b:rainbow_loaded = maxlvl
  83. for parenthesis_args in conf.parentheses
  84. let [paren, containedin, contains, op] = s:resolve_parenthesis(parenthesis_args)
  85. for lvl in range(maxlvl)
  86. if op != '' |exe printf(def_op, 'rainbow_o'.lvl, op, 'rainbow_r'.lvl) |endif
  87. if lvl == 0
  88. if containedin == ''
  89. exe printf(def_rg, 'rainbow_r0', 'rainbow_p0', 'rainbow_r'.(maxlvl - 1), contains, paren)
  90. endif
  91. else
  92. exe printf(def_rg, 'rainbow_r'.lvl, 'rainbow_p'.lvl.(' contained'), 'rainbow_r'.((lvl + maxlvl - 1) % maxlvl), contains, paren)
  93. endif
  94. endfor
  95. if containedin != ''
  96. exe printf(def_rg, 'rainbow_r0', 'rainbow_p0 contained', containedin.',rainbow_r'.(maxlvl - 1), contains, paren)
  97. endif
  98. endfor
  99. call rainbow#show()
  100. endfunc
  101. func rainbow#clear()
  102. call rainbow#hide()
  103. if exists('b:rainbow_loaded')
  104. for each in range(b:rainbow_loaded)
  105. exe 'syn clear rainbow_r'.each
  106. exe 'syn clear rainbow_o'.each
  107. endfor
  108. unlet b:rainbow_loaded
  109. endif
  110. endfunc
  111. func rainbow#show()
  112. if exists('b:rainbow_loaded')
  113. let b:rainbow_visible = 1
  114. for id in range(b:rainbow_loaded)
  115. let ctermfg = b:rainbow_conf.ctermfgs[id % len(b:rainbow_conf.ctermfgs)]
  116. let guifg = b:rainbow_conf.guifgs[id % len(b:rainbow_conf.guifgs)]
  117. exe 'hi default rainbow_p'.id.' ctermfg='.ctermfg.' guifg='.guifg
  118. exe 'hi default rainbow_o'.id.' ctermfg='.ctermfg.' guifg='.guifg
  119. endfor
  120. endif
  121. endfunc
  122. func rainbow#hide()
  123. if exists('b:rainbow_visible')
  124. for each in range(b:rainbow_loaded)
  125. exe 'hi clear rainbow_p'.each
  126. exe 'hi clear rainbow_o'.each
  127. endfor
  128. unlet b:rainbow_visible
  129. endif
  130. endfunc
  131. func rainbow#toggle()
  132. if exists('b:rainbow_loaded')
  133. call rainbow#clear()
  134. else
  135. if exists('b:rainbow_conf')
  136. call rainbow#load()
  137. else
  138. call rainbow#hook()
  139. endif
  140. endif
  141. endfunc
  142. func rainbow#hook()
  143. let g_conf = extend(copy(s:rainbow_conf), exists('g:rainbow_conf')? g:rainbow_conf : {}) |unlet g_conf.separately
  144. let separately = extend(copy(s:rainbow_conf.separately), exists('g:rainbow_conf.separately')? g:rainbow_conf.separately : {})
  145. let b_conf = has_key(separately, &ft)? separately[&ft] : separately['*']
  146. if type(b_conf) == type({})
  147. let b:rainbow_conf = extend(g_conf, b_conf)
  148. call rainbow#load()
  149. endif
  150. endfunc
  151. command! RainbowToggle call rainbow#toggle()
  152. if (exists('g:rainbow_active') && g:rainbow_active)
  153. auto syntax * call rainbow#hook()
  154. auto colorscheme * call rainbow#show()
  155. endif
  156.