neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

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: