summaryrefslogtreecommitdiff
path: root/mnv/runtime/syntax/xpm.mnv
diff options
context:
space:
mode:
Diffstat (limited to 'mnv/runtime/syntax/xpm.mnv')
-rw-r--r--mnv/runtime/syntax/xpm.mnv154
1 files changed, 154 insertions, 0 deletions
diff --git a/mnv/runtime/syntax/xpm.mnv b/mnv/runtime/syntax/xpm.mnv
new file mode 100644
index 0000000000..aa6e6ff706
--- /dev/null
+++ b/mnv/runtime/syntax/xpm.mnv
@@ -0,0 +1,154 @@
+" MNV syntax file
+" Language: X Pixmap
+" Maintainer: Ronald Schild <rs@scutum.de>
+" Last Change: 2023 May 24
+" Version: 5.4n.2
+" Jemma Nelson added termguicolors support
+" Dominique Pellé fixed spelling support
+" Christian J. Robinson fixed use of global variables, moved
+" loop into a compiled function
+
+" quit when a syntax file was already loaded
+if exists("b:current_syntax")
+ finish
+endif
+
+syn spell notoplevel
+
+syn keyword xpmType char
+syn keyword xpmStorageClass static
+syn keyword xpmTodo TODO FIXME XXX contained
+syn region xpmComment start="/\*" end="\*/" contains=xpmTodo,@Spell
+syn region xpmPixelString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@xpmColors
+
+if has("gui_running") || has("termguicolors") && &termguicolors
+
+def s:CreateSyntax(): void
+ var color = ""
+ var chars = ""
+ var colors = 0
+ var cpp = 0
+ var n = 0
+ var lines = getline(1, '$')
+
+ for line in lines # scanning all lines
+
+ var s = matchstr(line, '".\{-1,}"')
+
+ if s != "" # does line contain a string?
+
+ if n == 0 # first string is the Values string
+
+ var values = split(s[1 : -2])
+
+ # Values string invalid, bail out
+ if len(values) != 4 && len(values) != 6 && len(values) != 7
+ return
+ endif
+
+ # get the 3rd value: colors = number of colors
+ colors = str2nr(values[2])
+ # get the 4th value: cpp = number of character per pixel
+ cpp = str2nr(values[3])
+
+ # these values must be positive, nonzero
+ if colors < 1 || cpp < 1
+ return
+ endif
+
+ # Highlight the Values string as normal string (no pixel string).
+ # Only when there is no slash, it would terminate the pattern.
+ if s !~ '/'
+ exe 'syn match xpmValues /' .. s .. '/'
+ endif
+ hi link xpmValues String
+
+ n = 1 # n = color index
+
+ elseif n <= colors # string is a color specification
+
+ # get chars = <cpp> length string representing the pixels
+ # (first incl. the following whitespace)
+ chars = substitute(s, '"\(.\{' .. cpp .. '}\s\).*"', '\1', '')
+
+ # now get color, first try 'c' key if any (color visual)
+ color = substitute(s, '".*\sc\s\+\(.\{-}\)\s*\(\(g4\=\|[ms]\)\s.*\)*\s*"', '\1', '')
+ if color == s
+ # no 'c' key, try 'g' key (grayscale with more than 4 levels)
+ color = substitute(s, '".*\sg\s\+\(.\{-}\)\s*\(\(g4\|[ms]\)\s.*\)*\s*"', '\1', '')
+ if color == s
+ # next try: 'g4' key (4-level grayscale)
+ color = substitute(s, '".*\sg4\s\+\(.\{-}\)\s*\([ms]\s.*\)*\s*"', '\1', '')
+ if color == s
+ # finally try 'm' key (mono visual)
+ color = substitute(s, '".*\sm\s\+\(.\{-}\)\s*\(s\s.*\)*\s*"', '\1', '')
+ if color == s
+ color = ""
+ endif
+ endif
+ endif
+ endif
+
+ # MNV cannot handle RGB codes with more than 6 hex digits
+ if color =~ '#\x\{10,}$'
+ color = substitute(color, '\(\x\x\)\x\x', '\1', 'g')
+ elseif color =~ '#\x\{7,}$'
+ color = substitute(color, '\(\x\x\)\x', '\1', 'g')
+ # nor with 3 digits
+ elseif color =~ '#\x\{3}$'
+ color = substitute(color, '\(\x\)\(\x\)\(\x\)', '0\10\20\3', '')
+ endif
+
+ # escape meta characters in patterns
+ s = escape(s, '/\*^$.~[]')
+ chars = escape(chars, '/\*^$.~[]')
+
+ # now create syntax items
+ # highlight the color string as normal string (no pixel string)
+ exe 'syn match xpmCol' .. n .. 'Def /' .. s .. '/ contains=xpmCol' .. n .. 'inDef'
+ exe 'hi link xpmCol' .. n .. 'Def String'
+
+ # but highlight the first whitespace after chars in its color
+ exe 'syn match xpmCol' .. n .. 'inDef /"' .. chars .. '/hs=s+' .. (cpp + 1) .. ' contained'
+ exe 'hi link xpmCol' .. n .. 'inDef xpmColor' .. n
+
+ # remove the following whitespace from chars
+ chars = substitute(chars, '.$', '', '')
+
+ # and create the syntax item contained in the pixel strings
+ exe 'syn match xpmColor' .. n .. ' /' .. chars .. '/ contained'
+ exe 'syn cluster xpmColors add=xpmColor' .. n
+
+ # if no color or color = "None" show background
+ if color == "" || substitute(color, '.*', '\L&', '') == 'none'
+ exe 'hi xpmColor' .. n .. ' guifg=bg'
+ exe 'hi xpmColor' .. n .. ' guibg=NONE'
+ elseif color !~ "'"
+ exe 'hi xpmColor' .. n .. " guifg='" .. color .. "'"
+ exe 'hi xpmColor' .. n .. " guibg='" .. color .. "'"
+ endif
+ n += 1
+ else
+ break # no more color string
+ endif
+ endif
+ endfor
+enddef
+
+call s:CreateSyntax()
+
+endif " has("gui_running") || has("termguicolors") && &termguicolors
+
+" Define the default highlighting.
+" Only when an item doesn't have highlighting yet
+
+hi def link xpmType Type
+hi def link xpmStorageClass StorageClass
+hi def link xpmTodo Todo
+hi def link xpmComment Comment
+hi def link xpmPixelString String
+
+
+let b:current_syntax = "xpm"
+
+" mnv: ts=8:sw=3:noet: