Wednesday, September 25, 2013

Improve context syntax file

" Vim syntax file
" Language: ConTeXt typesetting engine
" Maintainer: Nikolai Weibull <now@bitwi.se>
" Latest Revision: 2006-08-10

if exists("b:current_syntax")
finish
endif

runtime! syntax/plaintex.vim
unlet b:current_syntax

let s:cpo_save = &cpo
set cpo&vim

if !exists('g:context_include')
let g:context_include = [
\ 'c',
\ 'cpp',
\ 'gnuplot',
\ 'javascript',
\ 'lua',
\ 'mp',
\ 'ruby',
\ 'xml',
\ ]
endif

syn spell toplevel

syn match contextBlockDelim display '\\\%(start\|stop\)\a\+'
\ contains=@NoSpell

syn region contextEscaped display matchgroup=contextPreProc
\ start='\\type\z(\A\)' end='\z1'
syn region contextEscaped display matchgroup=contextPreProc
\ start='\\type\={' end='}'
syn region contextEscaped display matchgroup=contextPreProc
\ start='\\type\=<<' end='>>'
syn region contextEscaped matchgroup=contextPreProc
\ start='\\start\z(\a*\%(typing\|typen\)\)'
\ end='\\stop\z1' contains=plaintexComment keepend
syn region contextEscaped display matchgroup=contextPreProc
\ start='\\\h\+Type{' end='}'
syn region contextEscaped display matchgroup=contextPreProc
\ start='\\Typed\h\+{' end='}'

syn match contextBuiltin display contains=@NoSpell
\ '\\\%(unprotect\|protect\|unexpanded\)'

syn match contextPreProc '^\s*\\\%(start\|stop\)\=\%(component\|environment\|project\|product\).*$'
\ contains=@NoSpell

if index(g:context_include, 'mp') != -1
syn include @mpTop syntax/mp.vim
unlet b:current_syntax

syn region contextMPGraphic transparent matchgroup=contextBlockDelim
\ start='\\start\z(\a*MPgraphic\|MP\%(page\|definitions\|extensions\|inclusions\|initializations\|run\|code\)\)'
\ end='\\stop\z1'
\ contains=@mpTop
endif

if index(g:context_include, 'lua') != -1
syn include @luaTop syntax/lua.vim
unlet b:current_syntax

syn region contextLua transparent matchgroup=contextBlockDelim
\ start='\\start\z(\%(lua\w*code\|\%(third\|user\|isolated\)code\)\)'
\ end='\\stop\z1'
\ contains=@luaTop
endif

if index(g:context_include, 'gnuplot') != -1
syn include @gnuplotTop syntax/gnuplot.vim
unlet b:current_syntax

syn region contextGnuplot transparent matchgroup=contextBlockDelim
\ start='\\start\z(\cgnuplot\a*\)'
\ end='\\stop\z1'
\ contains=@gnuplotTop
endif


" TODO: also need to implement this for \\typeC or something along those
" lines.
function! s:include_syntax(name, group)
if index(g:context_include, a:name) != -1
execute 'syn include @' . a:name . 'Top' 'syntax/' . a:name . '.vim'
unlet b:current_syntax
execute 'syn region context' . a:group . 'Code'
\ 'transparent matchgroup=contextBlockDelim'
\ 'start=+\\\<start' . a:group . '\>+ end=+\\stop' . a:group . '+'
\ 'contains=@' . a:name . 'Top'
endif
endfunction

call s:include_syntax('c', 'C')
call s:include_syntax('cpp', 'CPP')
call s:include_syntax('ruby', 'Ruby')
call s:include_syntax('javascript', 'JS')
call s:include_syntax('xml', 'XML')

syn match contextSectioning '\\chapter\>' contains=@NoSpell
syn match contextSectioning '\\\%(sub\)*section\>' contains=@NoSpell
syn match contextSectioning display '\\\%(start\|stop\)\%(part\|chapter\|title\|\%(sub\)*section\%(level\)\|\%(sub\)*subject*\)'
\ contains=@NoSpell

syn match contextSpecial '\\crlf\>\|\\par\>\|-\{2,3}\||[<>/]\=|'
\ contains=@NoSpell
syn match contextSpecial /\\[`'"]/
syn match contextSpecial +\\char\%(\d\{1,3}\|'\o\{1,3}\|"\x\{1,2}\)\>+
\ contains=@NoSpell
syn match contextSpecial '\^\^.'
syn match contextSpecial '`\%(\\.\|\^\^.\|.\)'

syn match contextStyle '\\\%(em\|ss\|hw\|cg\|mf\|sans\|bold\|mono\)\>'
\ contains=@NoSpell
syn match contextFont '\\\%(CAP\|Cap\|cap\|Caps\|kap\|nocap\)\>'
\ contains=@NoSpell
syn match contextFont '\\\%(Word\|WORD\|Words\|WORDS\)\>'
\ contains=@NoSpell
syn match contextFont '\\\%(vi\{1,3}\|ix\|xi\{0,2}\|smallbodyfont\|bigbodyfont\)\>'
\ contains=@NoSpell
syn match contextFont '\\\%(tf\|b[si]\|s[cl]\|os\)\%(xx\|[xabcd]\)\=\>'
\ contains=@NoSpell

hi def link contextBlockDelim Keyword
hi def link contextBuiltin Keyword
hi def link contextDelimiter Delimiter
hi def link contextPreProc PreProc
hi def link contextSectioning PreProc
hi def link contextSpecial Special
hi def link contextType Type
hi def link contextStyle contextType
hi def link contextFont contextType

let b:current_syntax = "context"

let &cpo = s:cpo_save
unlet s:cpo_save
Hi,

the context syntax file is rather outdated. I have never tinkered
with syntax files and I don't really have a clue how they work.
However, I managed to improve the existing one. I contacted the
maintainer Nikolai Weibull, but I didn't get a response. So I post
my improvements to this list.

The changes I made:

1) additional syntax languages in g:context_include.
2) support for all MetaPost environments, e.g. \startMPcode
3) support for Lua highlighting for MkIV
4) support for the gnuplot module
5) add C++ syntax highlighting (since C is there as well)
6) support for the MkIV start-stop structuring commands, e.g. \startsection
7) add more font switches
8) a fix, so that \startCSV is not recognised as C code

Unsolved problems which I couldn't fix myself:

- having the underscore correctly recognised, e.g. the following
results in wrong syntax highlighting

\unprotect
\def\foo_bar{whatever}
\def\foo@bar{whatever}
\protect

\starttexcode
\def\foo_bar{whatever}
\def\foo@bar{whatever}
\stoptexcode

- correct commentstring in Lua code (e.g. in combination with Tim
Pope's vim-commentary)

\starttext
\startluacode
foo="bar"
\stopluacode
\stoptext

Pressing gcc (with vim-commentary) while being on the line
"foo="bar"" leads to

%% foo="bar"

instead of

-- foo="bar"

- I have set commentstring to %%\ %s for ConTeXt in my .vimrc.
Can this be set automatically?

Does someone have a solution for the three unsolved problems?

Marco

No comments: