xpm.vim (4983B)
1 " Vim syntax file 2 " Language: X Pixmap 3 " Maintainer: Ronald Schild <rs@scutum.de> 4 " Last Change: 2023 May 24 5 " Version: 5.4n.2 6 " Jemma Nelson added termguicolors support 7 " Dominique Pellé fixed spelling support 8 " Christian J. Robinson fixed use of global variables, moved 9 " loop into a function 10 11 " quit when a syntax file was already loaded 12 if exists("b:current_syntax") 13 finish 14 endif 15 16 syn spell notoplevel 17 18 syn keyword xpmType char 19 syn keyword xpmStorageClass static 20 syn keyword xpmTodo TODO FIXME XXX contained 21 syn region xpmComment start="/\*" end="\*/" contains=xpmTodo,@Spell 22 syn region xpmPixelString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@xpmColors 23 24 if has("gui_running") || has("termguicolors") && &termguicolors 25 26 function s:CreateSyntax() abort 27 let color = "" 28 let chars = "" 29 let colors = 0 30 let cpp = 0 31 let n = 0 32 let lines = getline(1, '$') 33 34 for line in lines " scanning all lines 35 36 let s = matchstr(line, '".\{-1,}"') 37 38 if s != "" " does line contain a string? 39 40 if n == 0 " first string is the Values string 41 42 let values = split(s[1 : -2]) 43 44 " Values string invalid, bail out 45 if len(values) != 4 && len(values) != 6 && len(values) != 7 46 return 47 endif 48 49 " get the 3rd value: colors = number of colors 50 let colors = str2nr(values[2]) 51 " get the 4th value: cpp = number of character per pixel 52 let cpp = str2nr(values[3]) 53 54 " these values must be positive, nonzero 55 if colors < 1 || cpp < 1 56 return 57 endif 58 59 " Highlight the Values string as normal string (no pixel string). 60 " Only when there is no slash, it would terminate the pattern. 61 if s !~ '/' 62 exe 'syn match xpmValues /' .. s .. '/' 63 endif 64 hi link xpmValues String 65 66 let n = 1 " n = color index 67 68 elseif n <= colors " string is a color specification 69 70 " get chars = <cpp> length string representing the pixels 71 " (first incl. the following whitespace) 72 let chars = substitute(s, '"\(.\{' .. cpp .. '}\s\).*"', '\1', '') 73 74 " now get color, first try 'c' key if any (color visual) 75 let color = substitute(s, '".*\sc\s\+\(.\{-}\)\s*\(\(g4\=\|[ms]\)\s.*\)*\s*"', '\1', '') 76 if color == s 77 " no 'c' key, try 'g' key (grayscale with more than 4 levels) 78 let color = substitute(s, '".*\sg\s\+\(.\{-}\)\s*\(\(g4\|[ms]\)\s.*\)*\s*"', '\1', '') 79 if color == s 80 " next try: 'g4' key (4-level grayscale) 81 let color = substitute(s, '".*\sg4\s\+\(.\{-}\)\s*\([ms]\s.*\)*\s*"', '\1', '') 82 if color == s 83 " finally try 'm' key (mono visual) 84 let color = substitute(s, '".*\sm\s\+\(.\{-}\)\s*\(s\s.*\)*\s*"', '\1', '') 85 if color == s 86 let color = "" 87 endif 88 endif 89 endif 90 endif 91 92 " Vim cannot handle RGB codes with more than 6 hex digits 93 if color =~ '#\x\{10,}$' 94 let color = substitute(color, '\(\x\x\)\x\x', '\1', 'g') 95 elseif color =~ '#\x\{7,}$' 96 let color = substitute(color, '\(\x\x\)\x', '\1', 'g') 97 " nor with 3 digits 98 elseif color =~ '#\x\{3}$' 99 let color = substitute(color, '\(\x\)\(\x\)\(\x\)', '0\10\20\3', '') 100 endif 101 102 " escape meta characters in patterns 103 let s = escape(s, '/\*^$.~[]') 104 let chars = escape(chars, '/\*^$.~[]') 105 106 " now create syntax items 107 " highlight the color string as normal string (no pixel string) 108 exe 'syn match xpmCol' .. n .. 'Def /' .. s .. '/ contains=xpmCol' .. n .. 'inDef' 109 exe 'hi link xpmCol' .. n .. 'Def String' 110 111 " but highlight the first whitespace after chars in its color 112 exe 'syn match xpmCol' .. n .. 'inDef /"' .. chars .. '/hs=s+' .. (cpp + 1) .. ' contained' 113 exe 'hi link xpmCol' .. n .. 'inDef xpmColor' .. n 114 115 " remove the following whitespace from chars 116 let chars = substitute(chars, '.$', '', '') 117 118 " and create the syntax item contained in the pixel strings 119 exe 'syn match xpmColor' .. n .. ' /' .. chars .. '/ contained' 120 exe 'syn cluster xpmColors add=xpmColor' .. n 121 122 " if no color or color = "None" show background 123 if color == "" || substitute(color, '.*', '\L&', '') == 'none' 124 exe 'hi xpmColor' .. n .. ' guifg=bg' 125 exe 'hi xpmColor' .. n .. ' guibg=NONE' 126 elseif color !~ "'" 127 exe 'hi xpmColor' .. n .. " guifg='" .. color .. "'" 128 exe 'hi xpmColor' .. n .. " guibg='" .. color .. "'" 129 endif 130 let n += 1 131 else 132 break " no more color string 133 endif 134 endif 135 endfor 136 endfunction 137 138 call s:CreateSyntax() 139 140 endif " has("gui_running") || has("termguicolors") && &termguicolors 141 142 " Define the default highlighting. 143 " Only when an item doesn't have highlighting yet 144 145 hi def link xpmType Type 146 hi def link xpmStorageClass StorageClass 147 hi def link xpmTodo Todo 148 hi def link xpmComment Comment 149 hi def link xpmPixelString String 150 151 152 let b:current_syntax = "xpm" 153 154 " vim: ts=8:sw=3:noet: