1
0

csv.vim 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. " A simple syntax highlighting, simply alternate colors between two
  2. " adjacent columns
  3. " Init {{{2
  4. let s:cpo_save = &cpo
  5. set cpo&vim
  6. scriptencoding utf8
  7. if version < 600
  8. syn clear
  9. elseif exists("b:current_syntax")
  10. finish
  11. endif
  12. " Helper functions "{{{2
  13. fu! <sid>Warning(msg) "{{{3
  14. " Don't redraw, so we are not overwriting messages from the ftplugin
  15. " script
  16. "redraw!
  17. echohl WarningMsg
  18. echomsg "CSV Syntax:" . a:msg
  19. echohl Normal
  20. endfu
  21. fu! <sid>Esc(val, char) "{{2
  22. return '\V'.escape(a:val, '\\'.a:char).'\m'
  23. endfu
  24. fu! <sid>CheckSaneSearchPattern() "{{{3
  25. let s:del_def = ','
  26. let s:col_def = '\%([^' . s:del_def . ']*' . s:del_def . '\|$\)'
  27. " First:
  28. " Check for filetype plugin. This syntax script relies on the filetype
  29. " plugin, else, it won't work properly.
  30. redir => s:a |sil filetype | redir end
  31. let s:a=split(s:a, "\n")[0]
  32. if match(s:a, '\cplugin:off') > 0
  33. call <sid>Warning("No filetype support, only simple highlighting using"
  34. \ . s:del_def . " as delimiter! See :h csv-installation")
  35. endif
  36. " Check Comment setting
  37. if !exists("g:csv_comment")
  38. let b:csv_cmt = split(&cms, '%s')
  39. else
  40. let b:csv_cmt = split(g:csv_comment, '%s')
  41. endif
  42. " Second: Check for sane defaults for the column pattern
  43. " Not necessary to check for fixed width columns
  44. if exists("b:csv_fixed_width_cols")
  45. return
  46. endif
  47. " Try a simple highlighting, if the defaults from the ftplugin
  48. " don't exist
  49. let s:col = exists("b:col") && !empty(b:col) ? b:col
  50. \ : s:col_def
  51. let s:del = exists("b:delimiter") && !empty(b:delimiter) ? b:delimiter
  52. \ : s:del_def
  53. let s:cmts = exists("b:csv_cmt") ? b:csv_cmt[0] : split(&cms, '&s')[0]
  54. let s:cmte = exists("b:csv_cmt") && len(b:csv_cmt) == 2 ? b:csv_cmt[1]
  55. \ : ''
  56. if line('$') > 1 && (!exists("b:col") || empty(b:col))
  57. " check for invalid pattern, ftplugin hasn't been loaded yet
  58. call <sid>Warning("Invalid column pattern, using default pattern " . s:col_def)
  59. endif
  60. endfu
  61. " Syntax rules {{{2
  62. fu! <sid>DoHighlight() "{{{3
  63. if has("conceal") && !exists("g:csv_no_conceal") &&
  64. \ !exists("b:csv_fixed_width_cols")
  65. " old val
  66. "\ '\%(.\)\@=/ms=e,me=e contained conceal cchar=' .
  67. " Has a problem with the last line!
  68. exe "syn match CSVDelimiter /" . s:col .
  69. \ '\n\=/ms=e,me=e contained conceal cchar=' .
  70. \ (&enc == "utf-8" ? "│" : '|')
  71. "exe "syn match CSVDelimiterEOL /" . s:del .
  72. " \ '\?$/ contained conceal cchar=' .
  73. " \ (&enc == "utf-8" ? "│" : '|')
  74. hi def link CSVDelimiter Conceal
  75. hi def link CSVDelimiterEOL Conceal
  76. elseif !exists("b:csv_fixed_width_cols")
  77. " The \%(.\)\@<= makes sure, the last char won't be concealed,
  78. " if it isn't a delimiter
  79. "exe "syn match CSVDelimiter /" . s:col . '\%(.\)\@<=/ms=e,me=e contained'
  80. exe "syn match CSVDelimiter /" . s:col . '\n\=/ms=e,me=e contained'
  81. "exe "syn match CSVDelimiterEOL /" . s:del . '\?$/ contained'
  82. if has("conceal")
  83. hi def link CSVDelimiter Conceal
  84. hi def link CSVDelimiterEOL Conceal
  85. else
  86. hi def link CSVDelimiter Ignore
  87. hi def link CSVDelimiterEOL Ignore
  88. endif
  89. endif " There is no delimiter for csv fixed width columns
  90. if !exists("b:csv_fixed_width_cols")
  91. exe 'syn match CSVColumnEven nextgroup=CSVColumnOdd /'
  92. \ . s:col . '/ contains=CSVDelimiter,CSVDelimiterEOL'
  93. exe 'syn match CSVColumnOdd nextgroup=CSVColumnEven /'
  94. \ . s:col . '/ contains=CSVDelimiter,CSVDelimiterEOL'
  95. exe 'syn match CSVColumnHeaderEven nextgroup=CSVColumnHeaderOdd /\%1l'
  96. \. s:col . '/ contains=CSVDelimiter,CSVDelimiterEOL'
  97. exe 'syn match CSVColumnHeaderOdd nextgroup=CSVColumnHeaderEven /\%1l'
  98. \. s:col . '/ contains=CSVDelimiter,CSVDelimiterEOL'
  99. else
  100. for i in range(len(b:csv_fixed_width_cols))
  101. let pat = '/\%' . b:csv_fixed_width_cols[i] . 'c.*' .
  102. \ ((i == len(b:csv_fixed_width_cols)-1) ? '/' :
  103. \ '\%' . b:csv_fixed_width_cols[i+1] . 'c/')
  104. let group = "CSVColumn" . (i%2 ? "Odd" : "Even" )
  105. let ngroup = "CSVColumn" . (i%2 ? "Even" : "Odd" )
  106. exe "syn match " group pat " nextgroup=" . ngroup
  107. endfor
  108. endif
  109. " Comment regions
  110. exe 'syn match CSVComment /'. <sid>Esc(s:cmts, '/'). '.*'.
  111. \ (!empty(s:cmte) ? '\%('. <sid>Esc(s:cmte, '/'). '\)\?'
  112. \: ''). '/'
  113. hi def link CSVComment Comment
  114. endfun
  115. fu! <sid>DoSyntaxDefinitions() "{{{3
  116. syn spell toplevel
  117. " Not really needed
  118. syn case ignore
  119. if &t_Co < 88
  120. if !exists("b:csv_fixed_width_cols")
  121. hi default CSVColumnHeaderOdd ctermfg=DarkRed ctermbg=15
  122. \ guibg=grey80 guifg=black term=underline cterm=standout,bold
  123. \ gui=bold,underline
  124. endif
  125. hi default CSVColumnOdd ctermfg=DarkRed ctermbg=15 guibg=grey80
  126. \ guifg=black term=underline cterm=bold gui=underline
  127. else
  128. if !exists("b:csv_fixed_width_cols")
  129. hi default CSVColumnHeaderOdd ctermfg=darkblue ctermbg=white
  130. \ guibg=grey80 guifg=black cterm=standout,underline
  131. \ gui=bold,underline
  132. endif
  133. hi default CSVColumnOdd ctermfg=darkblue ctermbg=white guibg=grey80
  134. \ guifg=black cterm=reverse,underline gui=underline
  135. endif
  136. " ctermbg=8 should be safe, even in 8 color terms
  137. if !exists("b:csv_fixed_width_cols")
  138. hi default CSVColumnHeaderEven ctermfg=white ctermbg=darkgrey
  139. \ guibg=grey50 guifg=black term=bold cterm=standout,underline
  140. \ gui=bold,underline
  141. endif
  142. hi default CSVColumnEven ctermfg=white ctermbg=darkgrey guibg=grey50
  143. \ guifg=black term=bold cterm=underline gui=bold,underline
  144. endfun
  145. " Main: {{{2
  146. " Make sure, we are using a sane, valid pattern for syntax
  147. " highlighting
  148. call <sid>CheckSaneSearchPattern()
  149. " Define all necessary syntax groups
  150. call <sid>DoSyntaxDefinitions()
  151. " Highlight the file
  152. call <sid>DoHighlight()
  153. " Set the syntax variable {{{2
  154. let b:current_syntax="csv"
  155. let &cpo = s:cpo_save
  156. unlet s:cpo_save