xpm2.vim 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. " Vim syntax file
  2. " Language: X Pixmap v2
  3. " Maintainer: Steve Wall (hitched97@velnet.com)
  4. " Last Change: 2017 Feb 01
  5. " (Dominique Pelle added @Spell)
  6. " Version: 5.8
  7. " Jemma Nelson added termguicolors support
  8. "
  9. " Made from xpm.vim by Ronald Schild <rs@scutum.de>
  10. " quit when a syntax file was already loaded
  11. if exists("b:current_syntax")
  12. finish
  13. endif
  14. let s:cpo_save = &cpo
  15. set cpo&vim
  16. syn region xpm2PixelString start="^" end="$" contains=@xpm2Colors
  17. syn keyword xpm2Todo TODO FIXME XXX contained
  18. syn match xpm2Comment "\!.*$" contains=@Spell,xpm2Todo
  19. command -nargs=+ Hi hi def <args>
  20. if has("gui_running") || has("termguicolors") && &termguicolors
  21. let color = ""
  22. let chars = ""
  23. let colors = 0
  24. let cpp = 0
  25. let n = 0
  26. let i = 1
  27. while i <= line("$") " scanning all lines
  28. let s = getline(i)
  29. if match(s,"\!.*$") != -1
  30. let s = matchstr(s, "^[^\!]*")
  31. endif
  32. if s != "" " does line contain a string?
  33. if n == 0 " first string is the Values string
  34. " get the 3rd value: colors = number of colors
  35. let colors = substitute(s, '\s*\d\+\s\+\d\+\s\+\(\d\+\).*', '\1', '')
  36. " get the 4th value: cpp = number of character per pixel
  37. let cpp = substitute(s, '\s*\d\+\s\+\d\+\s\+\d\+\s\+\(\d\+\).*', '\1', '')
  38. if cpp =~ '[^0-9]'
  39. break " if cpp is not made of digits there must be something wrong
  40. endif
  41. " Highlight the Values string as normal string (no pixel string).
  42. " Only when there is no slash, it would terminate the pattern.
  43. if s !~ '/'
  44. exe 'syn match xpm2Values /' . s . '/'
  45. endif
  46. hi def link xpm2Values Statement
  47. let n = 1 " n = color index
  48. elseif n <= colors " string is a color specification
  49. " get chars = <cpp> length string representing the pixels
  50. " (first incl. the following whitespace)
  51. let chars = substitute(s, '\(.\{'.cpp.'}\s\+\).*', '\1', '')
  52. " now get color, first try 'c' key if any (color visual)
  53. let color = substitute(s, '.*\sc\s\+\(.\{-}\)\s*\(\(g4\=\|[ms]\)\s.*\)*\s*', '\1', '')
  54. if color == s
  55. " no 'c' key, try 'g' key (grayscale with more than 4 levels)
  56. let color = substitute(s, '.*\sg\s\+\(.\{-}\)\s*\(\(g4\|[ms]\)\s.*\)*\s*', '\1', '')
  57. if color == s
  58. " next try: 'g4' key (4-level grayscale)
  59. let color = substitute(s, '.*\sg4\s\+\(.\{-}\)\s*\([ms]\s.*\)*\s*', '\1', '')
  60. if color == s
  61. " finally try 'm' key (mono visual)
  62. let color = substitute(s, '.*\sm\s\+\(.\{-}\)\s*\(s\s.*\)*\s*', '\1', '')
  63. if color == s
  64. let color = ""
  65. endif
  66. endif
  67. endif
  68. endif
  69. " Vim cannot handle RGB codes with more than 6 hex digits
  70. if color =~ '#\x\{10,}$'
  71. let color = substitute(color, '\(\x\x\)\x\x', '\1', 'g')
  72. elseif color =~ '#\x\{7,}$'
  73. let color = substitute(color, '\(\x\x\)\x', '\1', 'g')
  74. " nor with 3 digits
  75. elseif color =~ '#\x\{3}$'
  76. let color = substitute(color, '\(\x\)\(\x\)\(\x\)', '0\10\20\3', '')
  77. endif
  78. " escape meta characters in patterns
  79. let s = escape(s, '/\*^$.~[]')
  80. let chars = escape(chars, '/\*^$.~[]')
  81. " change whitespace to "\s\+"
  82. let s = substitute(s, "[ \t][ \t]*", "\\\\s\\\\+", "g")
  83. let chars = substitute(chars, "[ \t][ \t]*", "\\\\s\\\\+", "g")
  84. " now create syntax items
  85. " highlight the color string as normal string (no pixel string)
  86. exe 'syn match xpm2Col'.n.'Def /'.s.'/ contains=xpm2Col'.n.'inDef'
  87. exe 'hi def link xpm2Col'.n.'Def Constant'
  88. " but highlight the first whitespace after chars in its color
  89. exe 'syn match xpm2Col'.n.'inDef /^'.chars.'/hs=s+'.(cpp).' contained'
  90. exe 'hi def link xpm2Col'.n.'inDef xpm2Color'.n
  91. " remove the following whitespace from chars
  92. let chars = substitute(chars, '\\s\\+$', '', '')
  93. " and create the syntax item contained in the pixel strings
  94. exe 'syn match xpm2Color'.n.' /'.chars.'/ contained'
  95. exe 'syn cluster xpm2Colors add=xpm2Color'.n
  96. " if no color or color = "None" show background
  97. if color == "" || substitute(color, '.*', '\L&', '') == 'none'
  98. exe 'Hi xpm2Color'.n.' guifg=bg guibg=NONE'
  99. elseif color !~ "'"
  100. exe 'Hi xpm2Color'.n." guifg='".color."' guibg='".color."'"
  101. endif
  102. let n = n + 1
  103. else
  104. break " no more color string
  105. endif
  106. endif
  107. let i = i + 1
  108. endwhile
  109. unlet color chars colors cpp n i s
  110. endif " has("gui_running") || has("termguicolors") && &termguicolors
  111. " Define the default highlighting.
  112. " Only when an item doesn't have highlighting yet
  113. " The default highlighting.
  114. hi def link xpm2Type Type
  115. hi def link xpm2StorageClass StorageClass
  116. hi def link xpm2Todo Todo
  117. hi def link xpm2Comment Comment
  118. hi def link xpm2PixelString String
  119. delcommand Hi
  120. let b:current_syntax = "xpm2"
  121. let &cpo = s:cpo_save
  122. unlet s:cpo_save
  123. " vim: ts=8:sw=2:noet: