diff options
| author | Adam Stankiewicz <sheerun@sher.pl> | 2013-09-12 17:17:14 +0200 | 
|---|---|---|
| committer | Adam Stankiewicz <sheerun@sher.pl> | 2013-09-12 17:17:14 +0200 | 
| commit | 35433aa23c6f7753fe96c67ed2ffdbb5291085a0 (patch) | |
| tree | f6265a18bb6c6955ab77313f5cdc6cd8af7ac103 | |
| parent | 0a4fcd12b6227ae9975d64353025e55e2e0caddf (diff) | |
| download | vim-polyglot-35433aa23c6f7753fe96c67ed2ffdbb5291085a0.tar.gz vim-polyglot-35433aa23c6f7753fe96c67ed2ffdbb5291085a0.zip | |
vim-haskell -> hasksyn
| -rw-r--r-- | after/ftplugin/haskell.vim | 9 | ||||
| -rwxr-xr-x | build.sh | 2 | ||||
| -rw-r--r-- | ftdetect/haskell.vim | 2 | ||||
| -rw-r--r-- | ftplugin/haskell.vim | 13 | ||||
| -rw-r--r-- | indent/haskell.vim | 325 | ||||
| -rw-r--r-- | syntax/cabal.vim | 147 | ||||
| -rw-r--r-- | syntax/haskell.vim | 467 | 
7 files changed, 559 insertions, 406 deletions
| diff --git a/after/ftplugin/haskell.vim b/after/ftplugin/haskell.vim new file mode 100644 index 00000000..536e84bb --- /dev/null +++ b/after/ftplugin/haskell.vim @@ -0,0 +1,9 @@ +" Vim ftplugin file +" Language: Haskell +" Maintainer: Tristan Ravitch + +" I don't fully understand what the vim-default ftplugin does, but I do know +" that the three-part comment entry really messes up this indenter (I also +" hate the leading '-'s it puts in on each line).  Disable it here. +setlocal comments& +setlocal comments=:-- @@ -49,7 +49,6 @@ syntax 'groenewege/vim-less' &  syntax 'wavded/vim-stylus' &  syntax 'tpope/vim-cucumber' &  syntax 'jrk/vim-ocaml' & -syntax 'wlangstroth/vim-haskell' &  syntax 'slim-template/vim-slim' &  syntax 'vim-scripts/XSLT-syntax' &  syntax 'vim-scripts/python.vim--Vasiliev' & @@ -59,6 +58,7 @@ syntax 'spf13/PIV' &  syntax 'briancollins/vim-jst' &  syntax 'derekwyatt/vim-scala' &  syntax 'derekwyatt/vim-sbt' & +syntax 'travitch/hasksyn' &  wait diff --git a/ftdetect/haskell.vim b/ftdetect/haskell.vim deleted file mode 100644 index 1f511415..00000000 --- a/ftdetect/haskell.vim +++ /dev/null @@ -1,2 +0,0 @@ -" autocommand -au BufRead,BufNewFile *.hs set comments=sl:{-,mb:--,elx:-} diff --git a/ftplugin/haskell.vim b/ftplugin/haskell.vim deleted file mode 100644 index 9025b0e0..00000000 --- a/ftplugin/haskell.vim +++ /dev/null @@ -1,13 +0,0 @@ -" -" general Haskell source settings -" (shared functions are in autoload/haskellmode.vim) -" -" (Claus Reinke, last modified: 28/04/2009) -" -" part of haskell plugins: http://projects.haskell.org/haskellmode-vim -" please send patches to <claus.reinke@talk21.com> - -" try gf on import line, or ctrl-x ctrl-i, or [I, [i, .. -setlocal include=^import\\s*\\(qualified\\)\\?\\s* -setlocal includeexpr=substitute(v:fname,'\\.','/','g').'.' -setlocal suffixesadd=hs,lhs,hsc
\ No newline at end of file diff --git a/indent/haskell.vim b/indent/haskell.vim index 4e6a1eff..c584e940 100644 --- a/indent/haskell.vim +++ b/indent/haskell.vim @@ -1,85 +1,296 @@  " Vim indent file -" Language:     Haskell -" Author:       motemen <motemen@gmail.com> -" Version:      0.1 -" Last Change:  2007-07-25 -" -" Modify g:haskell_indent_if and g:haskell_indent_case to -" change indentation for `if'(default 3) and `case'(default 5). -" Example (in .vimrc): -" > let g:haskell_indent_if = 2 +" Language: Haskell +" Maintainer: Tristan Ravitch  if exists('b:did_indent') -    finish +  finish  endif  let b:did_indent = 1 -if !exists('g:haskell_indent_if') -    " if bool -    " >>>then ... -    " >>>else ... -    let g:haskell_indent_if = 2 +if !exists('g:hasksyn_indent_search_backward') +  let g:hasksyn_indent_search_backward = 100 +endif + +if !exists('g:hasksyn_dedent_after_return') +  let g:hasksyn_dedent_after_return = 1 +endif + +if !exists('g:hasksyn_dedent_after_catchall_case') +  let g:hasksyn_dedent_after_catchall_case = 1  endif -if !exists('g:haskell_indent_case') -    " case xs of -    " >>>>>[] -> ... -    " >>>>>(y:ys) -> ... -    let g:haskell_indent_case = 2 +setlocal noautoindent +setlocal indentexpr=HIndent(v:lnum) +setlocal indentkeys+=0=where +setlocal indentkeys+=0=-> +setlocal indentkeys+=0==> +setlocal indentkeys+=0=in +setlocal indentkeys+=0=class,0=instance,0=import +setlocal indentkeys+=<Bar> +setlocal indentkeys+=0\, + +if exists("*HIndent") +  finish  endif -setlocal indentexpr=GetHaskellIndent() -setlocal indentkeys=!^F,o,O -function! GetHaskellIndent() -    let line = substitute(getline(getpos('.')[1] - 1), '\t', repeat(' ', &tabstop), 'g') +function! HIndent(lnum) +  " Don't do anything boneheaded if we are inside of a block comment +  if s:IsInBlockComment() +    return -1 +  endif + +  let plnum = s:PrevNonCommentLineNum(a:lnum) +  if plnum == 0 +    return 0 +  endif + +  let prevl = s:GetAndStripTrailingComments(plnum) +  let thisl = s:GetAndStripTrailingComments(a:lnum) +  let previ = indent(plnum) -    if line =~ '[!#$%&*+./<=>?@\\^|~-]$\|\<do$' -        return match(line, '\s*where \zs\|\S') + &shiftwidth +  " If this is a bare where clause, indent it one step.  where as part of an +  " instance should be unaffected unless you put it in an odd place. +  " This is the wrong thing if you are deeply indented already and want to put +  " a where clause on the top-level construct, but there isn't much that can +  " be done about that case... +  if thisl =~ '^\s*where\s*$' +    return previ + &sw +  endif + +  " If we start a new line for a type signature, see if we can line it up with +  " the previous line. +  if thisl =~ '^\s*\(->\|=>\)\s*' +    let tokPos = s:BackwardPatternSearch(a:lnum, '\(::\|->\|=>\)') +    if tokPos != -1 +      return tokPos      endif +  endif + +  if prevl =~ '\Wof\s*$' || prevl =~ '\Wdo\s*$' +    return previ + &sw +  endif -    if line =~ '{$' -        return match(line, '\s*where \zs\|\S') + &shiftwidth +  " Now for commas.  Commas will align pretty naturally for simple pattern +  " guards, so don't worry about that for now.  If we see the line is just a +  " comma, search up for something to align it to.  In the easy case, look +  " for a [ or { (the last in their line).  Also consider other commas that +  " are preceeded only by whitespace.  This isn't just a previous line check +  " necessarily, though that would cover most cases. +  if thisl =~ '^\s*,' +    let cmatch = match(prevl, '\(^\s*\)\@<=,') +    if cmatch != -1 +      return cmatch      endif -    if line =~ '^\(instance\|class\).*\&.*where$' -        return &shiftwidth +    let bmatch = match(prevl, '\({\|\[\)') +    if bmatch != -1 +      return bmatch      endif +  endif -    if line =~ ')$' -        let pos = getpos('.') -        normal k$ -        let paren_end   = getpos('.') -        normal % -        let paren_begin = getpos('.') -        call setpos('.', pos) -        if paren_begin[1] != paren_end[1] -            return paren_begin[2] - 1 -        endif +  " Match an 'in' keyword with the corresponding let.  Unfortunately, if the +  " name of your next binding happens to start with 'in', this will muck with +  " it.  Not sure if there is a workaround because we can't force an +  " auto-indent after 'in ' as far as I can see. +  if thisl =~ '\s*in$' +    let letStart = s:BackwardPatternSearch(a:lnum, '\(\W\)\@<=let\W') +    if letStart != -1 +      return letStart      endif +  endif -    if line !~ '\<else\>' -        let s = match(line, '\<if\>.*\&.*\zs\<then\>') -        if s > 0 -            return s -        endif +  " We don't send data or type to column zero because they can be indented +  " inside of 'class' definitions for data/type families +  if thisl =~ '^\s*\(class\|instance\|newtype\|import\)' +    return 0 +  endif -        let s = match(line, '\<if\>') -        if s > 0 -            return s + g:haskell_indent_if -        endif +  " FIXME: Only do this if the previous line was not already indented for the +  " same reason.  Also be careful of -> in type signatures.  Make sure we have +  " an earlier rule to line those up properly. +  if prevl =~ '[=>\$\.\^+\&`(-]\s*$' +    return previ + &sw +  endif + +  " We have a special case for dealing with trailing '*' operators.  If the * +  " is the end of a kind signature in a type family/associated type, we don't +  " want to indent the next line.  We do if it is just being a * operator in +  " an expression, though. +  if prevl =~ '\(\(type\|data\).*\)\@<!\*\s*$' +    return previ + &sw +  endif + +  " If the previous line ends in a where, indent us a step +  if prevl =~ '\Wwhere\s*$' +    return previ + &sw +  endif + +  " If we see a |, first try to line it up with the pipe on the previous line. +  " Search backward on nearby lines, giving up if we hit a line with a \w at +  " column 0. Otherwise, indent it relative to the previous line +  " +  " Here we can also handle the case of lining up data declarations.  The +  " backwards pipe search will fail for a data declaration (since data is at +  " column 0), so we can have an extra check after the pipe search for +  " data..=. +  if thisl =~ '^\s*|$' +    let nearestPipeIndex = s:BackwardPatternSearch(a:lnum, '\(^\s*\)\@<=|') +    if nearestPipeIndex != -1 +      return nearestPipeIndex +    endif + +    let dataEquals = match(prevl, '\(data.*\)\@<==') +    if dataEquals != -1 +      return dataEquals      endif -    let s = match(line, '\<do\s\+\zs[^{]\|\<where\s\+\zs\w\|\<let\s\+\zs\S\|^\s*\zs|\s') -    if s > 0 -        return s +    return previ + &sw +  endif + +  " If the previous line has a let, line the cursor up with the start of the +  " first binding name.  Autoindent handles subsequent cases. +  " +  " This should come after the 'in' aligner so that 'in' is not treated as +  " just something to be aligned to the previous binding. +  let lbindStart = match(prevl, '\(\Wlet\s\+\)\@<=\w') +  if lbindStart != -1 +    return lbindStart +  endif + +  " If requested, dedent from a bare return (presumably in a do block). +  " This comes after the trailing operator case - hopefully that will avoid +  " returns on lines by themselves but not really in a do block.  This is a +  " heuristic. +  if g:hasksyn_dedent_after_return && prevl =~ '^\s*return\W' +    return previ - &sw +  endif + +  " Similar to the return dedent - after a catchall case _ -> ..., we can +  " almost certainly dedent.  Again, it comes after the line continuation +  " heuristic so we don't dedent while someone is making an obviously +  " multi-line construct +  if g:hasksyn_dedent_after_catchall_case && prevl =~ '^\s*_\s*->\W' +    return previ - &sw +  endif + +  " On the other hand, if the previous line is a where with some bindings +  " following it on the same line, accommodate and align with the first non-ws +  " char after the where +  if prevl =~ '\Wwhere\s\+\w' +    let bindStart = match(prevl, '\(\Wwhere\s\+\)\@<=\w') +    if bindStart != -1 +      return bindStart +    endif + +    return previ + &sw +  endif + +  return previ +endfunction + +" Search backwards for a token from the cursor position +function! s:FindTokenNotInCommentOrString(tok) +  return search('\(--.*\|"\([^"]\|\\"\)*\)\@<!' . tok, 'bcnW') +endfunction + +" Should return -1 if the given line is inside of an unclosed block comment. +" This is meant to let us exit early from the indenter if we are in a comment. +" Look for the nearest -} and {- such that they are not between "" or in a +" line comment +" +" Note: we may need to restrict how far back this will search.  On the other +" hand, the native vim 'search' function might be efficient enough to support +" entire buffers. +function! s:IsInBlockComment() +  let openCommPos = s:FindTokenNotInCommentOrString('{-') +  " If there is no open comment, then we don't have to look for a close +  if openCommPos == 0 +    return 0 +  endif + +  " Or if there is a close comment marker that comes after the open marker, we +  " are not in a comment.  Note that we potentially need to check the position +  " in the line if they are both on the same line.  I'll fix it later. +  let closeCommPos = s:FindTokenNotInCommentOrString('-}') +  if closeCommPos >= openCommPos +    return 0 +  endif + +  return 1 +endfunction + +" Get the previous line that is not a comment.  Pass in the *current* line +" number.  Also skips blank lines. +function! s:PrevNonCommentLineNum(lnum) +  if a:lnum <= 1 +    return 0 +  endif + +  let lnum = a:lnum - 1 + +  while 1 +    if lnum == 0 +      return 0 +    endif + +    let aline = getline(lnum) +    if aline =~ '^\s*--' +      let lnum = lnum - 1 +    else +      return lnum +    endif +  endwhile +endfunction + +function! s:GetAndStripTrailingComments(lnum) +  let aline = getline(a:lnum) +  " We can't just remove the string literal since that leaves us with a +  " trailing operator (=), so replace it with a fake identifier +  let noStrings = substitute(aline, '"\([^"]\|\\"\)*"', 's', '') +  let noLineCom = substitute(noStrings, '--.*$', '', '') + +  " If there are no fancy block comments involved, skip some of this extra +  " work +  if noLineCom !~ '\({-\|-}\)' +    return noLineCom +  endif + +  " We stripped line comments, now we need to strip out any relevant multiline +  " comments.  This includes comments starting much earlier but ending on this +  " line or comments starting on this line and continuing to the next.  This +  " is probably easiest in two steps: {- to (-}|$) and then ^ to -}. +  " Note we are using a non-greedy match here so that only the minimal {- -} +  " pair is consumed. +  let noBlock1 = substitute(noLineComm, '{-.\{-}-}', '', '') +  let noBlock2 = substitute(noBlock1, '{-.\{-}$', '', '') +  let noBlock3 = substitute(noBlock2, '^.\{-}-}', '', '') +  return noBlock3 +endfunction + +" Search backwards from lnum for pat, returning the starting index if found +" within the search range or -1 if not found.  Stops searching at lines +" starting at column 0 with an identifier character. +function! s:BackwardPatternSearch(lnum, pat) +  let lnum = s:PrevNonCommentLineNum(a:lnum) +  while 1 +    let aline = s:GetAndStripTrailingComments(lnum) +    if a:lnum - lnum > g:hasksyn_indent_search_backward +      return -1      endif -    let s = match(line, '\<case\>') -    if s > 0 -        return s + g:haskell_indent_case +    let theMatch = match(aline, a:pat) +    if theMatch != -1 +      return theMatch +    else +      " We want to be able to consider lines starting in column 0, but we don't +      " want to search back past them. +      if aline =~ '^\w' +        return -1 +      endif +      let lnum = s:PrevNonCommentLineNum(lnum)      endif +  endwhile +endfunction -    return match(line, '\S') -endfunction
\ No newline at end of file diff --git a/syntax/cabal.vim b/syntax/cabal.vim new file mode 100644 index 00000000..d0510097 --- /dev/null +++ b/syntax/cabal.vim @@ -0,0 +1,147 @@ +" Vim syntax file +" Language: Cabal +" Author: Tristan Ravitch +" Version: 0.0.1 + +if version < 600 +  syntax clear +elseif exists('b:current_syntax') +  finish +endif + +syn sync minlines=50 maxlines=200 +syn case ignore + +" Top-level package keywords +syn match cabalKey '^name:' +syn match cabalKey '^version:' +syn match cabalKey '^cabal-version:' +syn match cabalKey '^build-type:' +syn match cabalKey '^license:' +syn match cabalKey '^license-file:' +syn match cabalKey '^copyright:' +syn match cabalKey '^author:' +syn match cabalKey '^maintainer:' +syn match cabalKey '^stability:' +syn match cabalKey '^homepage:' +syn match cabalKey '^bug-reports:' +syn match cabalKey '^package-url:' +syn match cabalKey '^synopsis:' +syn match cabalKey '^description:' +syn match cabalKey '^category:' +syn match cabalKey '^tested-with:' +syn match cabalKey '^data-files:' +syn match cabalKey '^data-dir:' +syn match cabalKey '^extra-source-files:' +syn match cabalKey '^extra-tmp-files:' + +" Other keywords +syn match cabalLit '\(:\s*\)\@<=\(true\|false\)' + +" Library-specifics +syn region cabalLibraryR start='^library\(\s\|$\)\@=' end='^\w' transparent keepend contains=cabalLibrayKey,cabalBuildKey,cabalCondition,cabalOperator +syn match cabalLibraryKey '^library\(\s\|$\)\@=' +syn match cabalLibraryKey '\(^\s\+\)\@<=exposed-modules:' +syn match cabalLibraryKey '\(^\s\+\)\@<=exposed:' + +" Executable-specifics +syn region cabalExeR start='^executable\s\@=' end='^\w' transparent keepend contains=cabalExeKey,cabalBuildKey,cabalCondition,cabalOperator,cabalBuildableName +syn match cabalExeKey '^executable\s\@=' +syn match cabalExeKey '\(^\s\+\)\@<=main-is:' + +" Test-specifics +syn region cabalTestR start='^test-suite\s\@=' end='^\w' transparent keepend contains=cabalTestKey,cabalBuildKey,cabalCondition,cabalOperator,cabalBuildableName +syn match cabalTestKey '^test-suite\s\@=' +syn match cabalTestKey '\(^\s\+\)\@<=type:' +syn match cabalTestKey '\(^\s\+\)\@<=main-is:' +syn match cabalTestKey '\(^\s\+\)\@<=test-module:' + +" Benchmark-specifics +syn region cabalBenchR start='^benchmark\s\@=' end='^\w' transparent keepend contains=cabalBenchKey,cabalBuildKey,cabalCondition,cabalOperator,cabalBuildableName +syn match cabalBenchKey '^benchmark\s\@=' +syn match cabalBenchKey '\(^\s\+\)\@<=type:' +syn match cabalBenchKey '\(^\s\+\)\@<=main-is:' + +syn match cabalBuildableName '\(^\(^benchmark\|test-suite\|executable\)\s\+\)\@<=\w\+' + +" General build info +syn match cabalBuildKey '\(^\s\+\)\@<=default-language:' +syn match cabalBuildKey '\(^\s\+\)\@<=build-depends:' +syn match cabalBuildKey '\(^\s\+\)\@<=other-modules:' +syn match cabalBuildKey '\(^\s\+\)\@<=hs-source-dirs:' +syn match cabalBuildKey '\(^\s\+\)\@<=extensions:' +syn match cabalBuildKey '\(^\s\+\)\@<=build-tools:' +syn match cabalBuildKey '\(^\s\+\)\@<=buildable:' +syn match cabalBuildKey '\(^\s\+\)\@<=ghc-options:' +syn match cabalBuildKey '\(^\s\+\)\@<=ghc-prof-options:' +syn match cabalBuildKey '\(^\s\+\)\@<=ghc-shared-options:' +syn match cabalBuildKey '\(^\s\+\)\@<=hugs-options:' +syn match cabalBuildKey '\(^\s\+\)\@<=nch98-options:' +syn match cabalBuildKey '\(^\s\+\)\@<=includes:' +syn match cabalBuildKey '\(^\s\+\)\@<=install-includes:' +syn match cabalBuildKey '\(^\s\+\)\@<=include-dirs:' +syn match cabalBuildKey '\(^\s\+\)\@<=c-sources:' +syn match cabalBuildKey '\(^\s\+\)\@<=extra-libraries:' +syn match cabalBuildKey '\(^\s\+\)\@<=extra-lib-dirs:' +syn match cabalBuildKey '\(^\s\+\)\@<=cc-options:' +syn match cabalBuildKey '\(^\s\+\)\@<=cpp-options:' +syn match cabalBuildKey '\(^\s\+\)\@<=ld-options:' +syn match cabalBuildKey '\(^\s\+\)\@<=pkgconfig-depends:' +syn match cabalBuildKey '\(^\s\+\)\@<=frameworks:' + +syn region cabalFlagR start='^flag\s\@=' end='^\w' transparent keepend contains=cabalFlagKey,cabalCondition,cabalFlag +syn match cabalFlagKey '^flag\s\@=' +syn match cabalFlagKey '\(^\s\+\)\@<=description:' +syn match cabalFlagKey '\(^\s\+\)\@<=default:' +syn match cabalFlagKey '\(^\s\+\)\@<=manual:' +syn match cabalFlag '\(flag\s\+\)\@<=\w\+' +syn match cabalFlag '\(flag(\)\@<=\w\+)\@=' + +syn region cabalSourceR start='^source-repository' end='^\w' transparent keepend contains=cabalSourceKey +syn match cabalSourceKey '^source-repository\s\@=' +syn match cabalSourceKey '\(^\s\+\)\@<=type:' +syn match cabalSourceKey '\(^\s\+\)\@<=location:' +syn match cabalSourceKey '\(^\s\+\)\@<=module:' +syn match cabalSourceKey '\(^\s\+\)\@<=branch:' +syn match cabalSourceKey '\(^\s\+\)\@<=tag:' +syn match cabalSourceKey '\(^\s\+\)\@<=subdir:' + +syn match cabalCondition '\(^\s\+\)\@<=if\((\|\s\)\@=' +syn match cabalCondition '\(^\s\+\)\@<=else\($\|\s\)\@=' +syn match cabalCondition '\(^\s\+\)\@<=if\((\|\s\)\@=' +syn match cabalCondition '\(^\s\+\)\@<=else\($\|\s\)\@=' +syn match cabalOperator '\W\@<=os\((.\+)\)\@=' +syn match cabalOperator '\W\@<=arch\((.\+)\)\@=' +syn match cabalOperator '\W\@<=impl\((.\+)\)\@=' +syn match cabalOperator '\W\@<=flag\((.\+)\)\@=' +syn match cabalOperator '\(^\s*--.*\)\@<!\(<\|>\|=\|||\|&&\)' + +syn match cabalComment '\s\@<=--.*$' + +if version >= 508 || !exists('did_cabal_syntax_inits') +  if version < 508 +    let did_cabal_syntax_inits = 1 +    command -nargs=+ HiLink hi link <args> +  else +    command -nargs=+ HiLink hi def link <args> +  endif + +  HiLink cabalBuildableName Structure +  HiLink cabalFlag Special +  HiLink cabalComment Comment +  HiLink cabalCondition Conditional +  HiLink cabalSourceKey Keyword +  HiLink cabalOperator Operator +  HiLink cabalKey Keyword +  HiLink cabalLibraryKey Keyword +  HiLink cabalTestKey Keyword +  HiLink cabalExeKey Keyword +  HiLink cabalBenchKey Keyword +  HiLink cabalBuildKey Keyword +  HiLink cabalFlagKey Keyword +  HiLink cabalLit Constant + +  delcommand HiLink +endif + +let b:current_syntax = 'cabal' diff --git a/syntax/haskell.vim b/syntax/haskell.vim index 7ac0fe26..17f48178 100644 --- a/syntax/haskell.vim +++ b/syntax/haskell.vim @@ -1,265 +1,115 @@  " Vim syntax file -" -" Modification of vims Haskell syntax file: -"   - match types using regular expression -"   - highlight toplevel functions -"   - use "syntax keyword" instead of "syntax match" where appropriate -"   - functions and types in import and module declarations are matched -"   - removed hs_highlight_more_types (just not needed anymore) -"   - enable spell checking in comments and strings only -"   - FFI highlighting -"   - QuasiQuotation -"   - top level Template Haskell slices -"   - PackageImport -" -" TODO: find out which vim versions are still supported -" -" From Original file: -" =================== -" -" Language:		    Haskell -" Maintainer:		Haskell Cafe mailinglist <haskell-cafe@haskell.org> -" Last Change:		2010 Feb 21 -" Original Author:	John Williams <jrw@pobox.com> -" -" Thanks to Ryan Crumley for suggestions and John Meacham for -" pointing out bugs. Also thanks to Ian Lynagh and Donald Bruce Stewart -" for providing the inspiration for the inclusion of the handling -" of C preprocessor directives, and for pointing out a bug in the -" end-of-line comment handling. -" -" Options-assign a value to these variables to turn the option on: -" -" hs_highlight_delimiters - Highlight delimiter characters--users -"			    with a light-colored background will -"			    probably want to turn this on. -" hs_highlight_boolean - Treat True and False as keywords. -" hs_highlight_types - Treat names of primitive types as keywords. -" hs_highlight_debug - Highlight names of debugging functions. -" hs_allow_hash_operator - Don't highlight seemingly incorrect C -"			   preprocessor directives but assume them to be -"			   operators -"  -"  +" Language: Haskell +" Author: Tristan Ravitch +" Maintainer: Tristan Ravitch +" Version: 0.0.1  if version < 600 -  syn clear -elseif exists("b:current_syntax") +  syntax clear +elseif exists('b:current_syntax')    finish  endif -"syntax sync fromstart "mmhhhh.... is this really ok to do so? -syntax sync linebreaks=15 minlines=50 maxlines=500 - -syn match  hsSpecialChar	contained "\\\([0-9]\+\|o[0-7]\+\|x[0-9a-fA-F]\+\|[\"\\'&\\abfnrtv]\|^[A-Z^_\[\\\]]\)" -syn match  hsSpecialChar	contained "\\\(NUL\|SOH\|STX\|ETX\|EOT\|ENQ\|ACK\|BEL\|BS\|HT\|LF\|VT\|FF\|CR\|SO\|SI\|DLE\|DC1\|DC2\|DC3\|DC4\|NAK\|SYN\|ETB\|CAN\|EM\|SUB\|ESC\|FS\|GS\|RS\|US\|SP\|DEL\)" -syn match  hsSpecialCharError	contained "\\&\|'''\+" -sy region  hsString		start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=hsSpecialChar,@Spell -sy match   hsCharacter		"[^a-zA-Z0-9_']'\([^\\]\|\\[^']\+\|\\'\)'"lc=1 contains=hsSpecialChar,hsSpecialCharError -sy match   hsCharacter		"^'\([^\\]\|\\[^']\+\|\\'\)'" contains=hsSpecialChar,hsSpecialCharError - -" (Qualified) identifiers (no default highlighting) -syn match ConId "\(\<[A-Z][a-zA-Z0-9_']*\.\)\=\<[A-Z][a-zA-Z0-9_']*\>" -syn match VarId "\(\<[A-Z][a-zA-Z0-9_']*\.\)\=\<[a-z][a-zA-Z0-9_']*\>" - -" Infix operators--most punctuation characters and any (qualified) identifier -" enclosed in `backquotes`. An operator starting with : is a constructor, -" others are variables (e.g. functions). -syn match hsVarSym "\(\<[A-Z][a-zA-Z0-9_']*\.\)\=[-!#$%&\*\+/<=>\?@\\^|~.][-!#$%&\*\+/<=>\?@\\^|~:.]*" -syn match hsConSym "\(\<[A-Z][a-zA-Z0-9_']*\.\)\=:[-!#$%&\*\+./<=>\?@\\^|~:]*" -syn match hsVarSym "`\(\<[A-Z][a-zA-Z0-9_']*\.\)\=[a-z][a-zA-Z0-9_']*`" -syn match hsConSym "`\(\<[A-Z][a-zA-Z0-9_']*\.\)\=[A-Z][a-zA-Z0-9_']*`" - -" Toplevel Template Haskell support -"sy match hsTHTopLevel "^[a-z]\(\(.\&[^=]\)\|\(\n[^a-zA-Z0-9]\)\)*" -sy match hsTHIDTopLevel "^[a-z]\S*"  -sy match hsTHTopLevel "^\$(\?" nextgroup=hsTHTopLevelName  -sy match hsTHTopLevelName "[a-z]\S*" contained - -" Reserved symbols--cannot be overloaded. -syn match hsDelimiter  "(\|)\|\[\|\]\|,\|;\|_\|{\|}" - -sy region hsInnerParen start="(" end=")" contained contains=hsInnerParen,hsConSym,hsType,hsVarSym -sy region hs_InfixOpFunctionName start="^(" end=")\s*[^:`]\(\W\&\S\&[^'\"`()[\]{}@]\)\+"re=s -    \ contained keepend contains=hsInnerParen,hs_HlInfixOp - -sy match hs_hlFunctionName "[a-z_]\(\S\&[^,\(\)\[\]]\)*" contained  -sy match hs_FunctionName "^[a-z_]\(\S\&[^,\(\)\[\]]\)*" contained contains=hs_hlFunctionName -sy match hs_HighliteInfixFunctionName "`[a-z_][^`]*`" contained -sy match hs_InfixFunctionName "^\S[^=]*`[a-z_][^`]*`"me=e-1 contained contains=hs_HighliteInfixFunctionName,hsType,hsConSym,hsVarSym,hsString,hsCharacter -sy match hs_HlInfixOp "\(\W\&\S\&[^`(){}'[\]]\)\+" contained contains=hsString -sy match hs_InfixOpFunctionName "^\(\(\w\|[[\]{}]\)\+\|\(\".*\"\)\|\('.*'\)\)\s*[^:]=*\(\W\&\S\&[^='\"`()[\]{}@]\)\+" -    \ contained contains=hs_HlInfixOp,hsCharacter - -sy match hs_OpFunctionName        "(\(\W\&[^(),\"]\)\+)" contained -"sy region hs_Function start="^["'a-z_([{]" end="=\(\s\|\n\|\w\|[([]\)" keepend extend -sy region hs_Function start="^["'a-zA-Z_([{]\(\(.\&[^=]\)\|\(\n\s\)\)*=" end="\(\s\|\n\|\w\|[([]\)"  -        \ contains=hs_OpFunctionName,hs_InfixOpFunctionName,hs_InfixFunctionName,hs_FunctionName,hsType,hsConSym,hsVarSym,hsString,hsCharacter - -sy match hs_TypeOp "::" -sy match hs_DeclareFunction "^[a-z_(]\S*\(\s\|\n\)*::" contains=hs_FunctionName,hs_OpFunctionName,hs_TypeOp - -" hi hs_TypeOp guibg=red - -" hi hs_InfixOpFunctionName guibg=yellow -" hi hs_Function guibg=green -" hi hs_InfixFunctionName guibg=red -" hi hs_DeclareFunction guibg=red - -sy keyword hsStructure data family class where instance default deriving -sy keyword hsTypedef type newtype - -sy keyword hsInfix infix infixl infixr -sy keyword hsStatement  do case of let in -sy keyword hsConditional if then else - -"if exists("hs_highlight_types") -  " Primitive types from the standard prelude and libraries. -  sy match hsType "\<[A-Z]\(\S\&[^,.]\)*\>" -  sy match hsType "()" -"endif - -" Not real keywords, but close. -if exists("hs_highlight_boolean") -  " Boolean constants from the standard prelude. -  syn keyword hsBoolean True False -endif - -syn region	hsPackageString	start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=cSpecial contained -sy match   hsModuleName  excludenl "\([A-Z]\w*\.\?\)*" contained  - -sy match hsImport "\<import\>\s\+\(qualified\s\+\)\?\(\<\(\w\|\.\)*\>\)"  -    \ contains=hsModuleName,hsImportLabel -    \ nextgroup=hsImportParams,hsImportIllegal skipwhite -sy keyword hsImportLabel import qualified contained - -sy match hsImportIllegal "\w\+" contained - -sy keyword hsAsLabel as contained -sy keyword hsHidingLabel hiding contained - -sy match hsImportParams "as\s\+\(\w\+\)" contained -    \ contains=hsModuleName,hsAsLabel -    \ nextgroup=hsImportParams,hsImportIllegal skipwhite -sy match hsImportParams "hiding" contained -    \ contains=hsHidingLabel -    \ nextgroup=hsImportParams,hsImportIllegal skipwhite  -sy region hsImportParams start="(" end=")" contained -    \ contains=hsBlockComment,hsLineComment, hsType,hsDelimTypeExport,hs_hlFunctionName,hs_OpFunctionName -    \ nextgroup=hsImportIllegal skipwhite - -" hi hsImport guibg=red -"hi hsImportParams guibg=bg -"hi hsImportIllegal guibg=bg -"hi hsModuleName guibg=bg - -"sy match hsImport		"\<import\>\(.\|[^(]\)*\((.*)\)\?"  -"         \ contains=hsPackageString,hsImportLabel,hsImportMod,hsModuleName,hsImportList -"sy keyword hsImportLabel import contained -"sy keyword hsImportMod		as qualified hiding contained -"sy region hsImportListInner start="(" end=")" contained keepend extend contains=hs_OpFunctionName -"sy region  hsImportList matchgroup=hsImportListParens start="("rs=s+1 end=")"re=e-1 -"        \ contained  -"        \ keepend extend -"        \ contains=hsType,hsLineComment,hsBlockComment,hs_hlFunctionName,hsImportListInner - - - -" new module highlighting -syn region hsDelimTypeExport start="\<[A-Z]\(\S\&[^,.]\)*\>(" end=")" contained -   \ contains=hsType - -sy keyword hsExportModuleLabel module contained -sy match hsExportModule "\<module\>\(\s\|\t\|\n\)*\([A-Z]\w*\.\?\)*" contained contains=hsExportModuleLabel,hsModuleName - -sy keyword hsModuleStartLabel module contained -sy keyword hsModuleWhereLabel where contained - -syn match hsModuleStart "^module\(\s\|\n\)*\(\<\(\w\|\.\)*\>\)\(\s\|\n\)*"  -  \ contains=hsModuleStartLabel,hsModuleName -  \ nextgroup=hsModuleCommentA,hsModuleExports,hsModuleWhereLabel - -syn region hsModuleCommentA start="{-" end="-}" -  \ contains=hsModuleCommentA,hsCommentTodo,@Spell contained -  \ nextgroup=hsModuleCommentA,hsModuleExports,hsModuleWhereLabel skipwhite skipnl - -syn match hsModuleCommentA "--.*\n" -  \ contains=hsCommentTodo,@Spell contained -  \ nextgroup=hsModuleCommentA,hsModuleExports,hsModuleWhereLabel skipwhite skipnl - -syn region hsModuleExports start="(" end=")" contained -   \ nextgroup=hsModuleCommentB,hsModuleWhereLabel skipwhite skipnl -   \ contains=hsBlockComment,hsLineComment,hsType,hsDelimTypeExport,hs_hlFunctionName,hs_OpFunctionName,hsExportModule - -syn match hsModuleCommentB "--.*\n" -  \ contains=hsCommentTodo,@Spell contained -  \ nextgroup=hsModuleCommentB,hsModuleWhereLabel skipwhite skipnl - -syn region hsModuleCommentB start="{-" end="-}" -   \ contains=hsModuleCommentB,hsCommentTodo,@Spell contained -   \ nextgroup=hsModuleCommentB,hsModuleWhereLabel skipwhite skipnl -" end module highlighting - -" FFI support -sy keyword hsFFIForeign foreign contained -"sy keyword hsFFIImportExport import export contained -sy keyword hsFFIImportExport export contained -sy keyword hsFFICallConvention ccall stdcall contained -sy keyword hsFFISafety safe unsafe contained -sy region  hsFFIString		start=+"+  skip=+\\\\\|\\"+  end=+"+  contained contains=hsSpecialChar -sy match hsFFI excludenl "\<foreign\>\(.\&[^\"]\)*\"\(.\)*\"\(\s\|\n\)*\(.\)*::" -  \ keepend -  \ contains=hsFFIForeign,hsFFIImportExport,hsFFICallConvention,hsFFISafety,hsFFIString,hs_OpFunctionName,hs_hlFunctionName - - -sy match   hsNumber		"\<[0-9]\+\>\|\<0[xX][0-9a-fA-F]\+\>\|\<0[oO][0-7]\+\>" -sy match   hsFloat		"\<[0-9]\+\.[0-9]\+\([eE][-+]\=[0-9]\+\)\=\>" - -" Comments -sy keyword hsCommentTodo    TODO FIXME XXX TBD contained -sy match   hsLineComment      "---*\([^-!#$%&\*\+./<=>\?@\\^|~].*\)\?$" contains=hsCommentTodo,@Spell -sy region  hsBlockComment     start="{-"  end="-}" contains=hsBlockComment,hsCommentTodo,@Spell -sy region  hsPragma	       start="{-#" end="#-}" - -" QuasiQuotation -sy region hsQQ start="\[\$" end="|\]"me=e-2 keepend contains=hsQQVarID,hsQQContent nextgroup=hsQQEnd -sy region hsQQNew start="\[\(.\&[^|]\&\S\)*|" end="|\]"me=e-2 keepend contains=hsQQVarIDNew,hsQQContent nextgroup=hsQQEnd -sy match hsQQContent ".*" contained -sy match hsQQEnd "|\]" contained -sy match hsQQVarID "\[\$\(.\&[^|]\)*|" contained -sy match hsQQVarIDNew "\[\(.\&[^|]\)*|" contained - -if exists("hs_highlight_debug") -  " Debugging functions from the standard prelude. -  syn keyword hsDebug undefined error trace -endif - - -" C Preprocessor directives. Shamelessly ripped from c.vim and trimmed -" First, see whether to flag directive-like lines or not -if (!exists("hs_allow_hash_operator")) -    syn match	cError		display "^\s*\(%:\|#\).*$" -endif -" Accept %: for # (C99) -syn region	cPreCondit	start="^\s*\(%:\|#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" end="//"me=s-1 contains=cComment,cCppString,cCommentError -syn match	cPreCondit	display "^\s*\(%:\|#\)\s*\(else\|endif\)\>" -syn region	cCppOut		start="^\s*\(%:\|#\)\s*if\s\+0\+\>" end=".\@=\|$" contains=cCppOut2 -syn region	cCppOut2	contained start="0" end="^\s*\(%:\|#\)\s*\(endif\>\|else\>\|elif\>\)" contains=cCppSkip -syn region	cCppSkip	contained start="^\s*\(%:\|#\)\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\(%:\|#\)\s*endif\>" contains=cCppSkip -syn region	cIncluded	display contained start=+"+ skip=+\\\\\|\\"+ end=+"+ -syn match	cIncluded	display contained "<[^>]*>" -syn match	cInclude	display "^\s*\(%:\|#\)\s*include\>\s*["<]" contains=cIncluded -syn cluster	cPreProcGroup	contains=cPreCondit,cIncluded,cInclude,cDefine,cCppOut,cCppOut2,cCppSkip,cCommentStartError -syn region	cDefine		matchgroup=cPreCondit start="^\s*\(%:\|#\)\s*\(define\|undef\)\>" skip="\\$" end="$" -syn region	cPreProc	matchgroup=cPreCondit start="^\s*\(%:\|#\)\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend - -syn region	cComment	matchgroup=cCommentStart start="/\*" end="\*/" contains=cCommentStartError,cSpaceError contained -syntax match	cCommentError	display "\*/" contained -syntax match	cCommentStartError display "/\*"me=e-1 contained -syn region	cCppString	start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=cSpecial contained - - -if version >= 508 || !exists("did_hs_syntax_inits") +syn sync minlines=50 maxlines=200 + +" These basic lexical definitions are taken from the orignal haskell syntax +" description from vim 7.3. +syn match  hsSpecialChar      contained "\\\([0-9]\+\|o[0-7]\+\|x[0-9a-fA-F]\+\|[\"\\'&\\abfnrtv]\|^[A-Z^_\[\\\]]\)" +syn match  hsSpecialChar      contained "\\\(NUL\|SOH\|STX\|ETX\|EOT\|ENQ\|ACK\|BEL\|BS\|HT\|LF\|VT\|FF\|CR\|SO\|SI\|DLE\|DC1\|DC2\|DC3\|DC4\|NAK\|SYN\|ETB\|CAN\|EM\|SUB\|ESC\|FS\|GS\|RS\|US\|SP\|DEL\)" +syn match  hsSpecialCharError contained "\\&\|'''\+" +syn region hsString           start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=hsSpecialChar +syn match  hsCharacter        "[^a-zA-Z0-9_']'\([^\\]\|\\[^']\+\|\\'\)'"lc=1 contains=hsSpecialChar,hsSpecialCharError +syn match  hsCharacter        "^'\([^\\]\|\\[^']\+\|\\'\)'" contains=hsSpecialChar,hsSpecialCharError +syn match  hsNumber           "\<[0-9]\+\>\|\<0[xX][0-9a-fA-F]\+\>\|\<0[oO][0-7]\+\>" +syn match  hsFloat            "\<[0-9]\+\.[0-9]\+\([eE][-+]\=[0-9]\+\)\=\>" + +" This case matches the names of types and constructors: names beginning with +" a capital letter.  Note that this also handles the case of @M.lookup@ where +" M is a qualified import.  There is a big negative lookbehind assertion here +" so that we don't highlight import and module statements oddly.  +syn match hsTypeName "\(^import\s.*\|^module\s.*\)\@<!\([^a-zA-Z0-9]\)\@<=[A-Z][a-zA-Z0-9_]*" +" Also make unit and the empty list easy to spot - they are constructors too. +syn match hsTypeName "()" +syn match hsTypeName "\[\]" + +" These are keywords that are only highlighted if they are in comments. +syn keyword hsFIXME contained FIXME TODO XXX BUG NOTE + +" Comment stuff +syn region hsPragma start='{-#' end='#-}' +syn region hsBlockComment start='{-' end='-}' fold contains=hsFIXME,hsBlockComment +" FIXME: haddock block comments should be able to contain hsBlockComments, but +" it doesn't seem to work at the moment. +syn region hsHaddockComment start='{-|' end='-}' contains=hsFIXME +syn match hsLineComment "--.*$" contains=hsFIXME +" Line-based haddock comments are trickier - they continue until +" the next line that isn't part of the same block of comments. +syn region hsHaddockComment start='-- |' end='^\(\s*--\)\@!' contains=hsFIXME +syn region hsHaddockComment start='-- \$\w\+' end='^\(\s*--\)\@!' contains=hsFIXME +syn region hsHaddockComment start='-- ^' end='^\(\s*--\)\@!' contains=hsFIXME +" Haddock sections for import lists +syn match hsHaddockSection '-- \*.*$' +" Named documentation chunks (also for import lists) +syn match hsHaddockSection '-- \$.*$' + + +" Keywords appearing in expressions, plus a few top-level keywords +syn keyword hsKeyword do let in _ where +syn keyword hsKeyword infix infixl infixr +syn keyword hsKeyword forall foreign +syn match hsKeyword '\(^\(data\|type\)\s\+\)\@<=family\(\W\)\@=' + +" Vim has a special syntax category for conditionals, so here are all of the +" haskell conditionals.  These are just keywords with a slightly more flexible +" coloring. +syn keyword hsConditional case of if then else + +" We define a region for module NNNN (...) where so that haddock section +" headers (-- *) can be highlighted specially only within this context. +syn region hsModuleHeader start="^module\s" end="where" contains=hsHaddockSection keepend fold transparent +" Treat Module imports as the #include category; it maps reasonably well +syn keyword hsImport import qualified as hiding module + +syn keyword hsTypeDecls class instance data newtype type deriving default +" FIXME: Maybe we can do something fancy for data/type families?  'family' is +" only a keyword if it follows data/type... + +" This is uglier than I'd like.  We want to let '-' participate in operators, +" but we can't let it match '--' because that interferes with comments.  Hacks +" for now - just include some common operators with '-'. +syn match hsOperator "<-\|->\|-->\|-\(-\)\@!\|[%\~\&\*/\$\^|@:+<!>=#!\?]\+" +" A bare . is an operator (but not surrounded by alnum chars) +syn match hsOperator "\s\@<=\.\s\@=" +" . is also an operator if adjacent to some other operator char +syn match hsOperator "[%\~\&\*\$\^|@:+<!>=#!\?]\+\.[%\~\&\*\$\^|@:+<\.!>=#!\?]*" +syn match hsOperator "[%\~\&\*\$\^|@:+<!>=#!\?]*\.[%\~\&\*\$\^|@:+\.<!>=#!\?]\+" +" Include support for infix functions as operators +syn match hsOperator "`[a-zA-Z0-9\.]\+`" + +" Highlight function/value names in type signatures.  Looks ahead to find a :: +" after a name.  This allows whitespace before the name so that it can match +" in a 'where,' but it won't match local type annotations on random little +" things. +syn match hsFunctionList "^\s*\([a-z][a-zA-Z0-9']*[[:space:]\n,]\+\)*[a-z][a-zA-Z0-9']*[[:space:]\n]*::" contains=hsFunction +syn match hsFunction "\s*[a-z][a-zA-Z0-9']*[[:space:]\n]*\(::\|,\)\@=" contained +" Also support the style where the first where binding is on the same line as +" the where keyword. +syn match hsFunction "\(^\s\+where\s\+\)\@<=[a-z][a-zA-Z0-9']*\(\s*::\)\@=" + +" FIXME Ignoring proc for now, also mdo and rec + +" Give undefined a bit of special treatment +syn keyword hsScary undefined + +" C Preprocessor stuff +syn match hsCPP '\(^\s*\)\@<=#\(warning\|pragma\|error\)\W\@=' +syn match hsCPPCond '\(^\s*\)\@<=#\(if\|ifdef\|elif\)\W\@=' +syn match hsCPPCond '\(^\s*\)\@<=#\(endif\|else\)\(\s*$\|\W\)\@=' +syn match hsCPPInclude '\(^\s*\)\@<=#include\W\@=' +syn match hsCPPDefine '\(^\s*\)\@<=#define\W\@=' +syn match hsCPPDefined '\(^\s*.*\W\)\@<=defined(\w\+)' + +if version >= 508 || !exists('did_hs_syntax_inits')    if version < 508      let did_hs_syntax_inits = 1      command -nargs=+ HiLink hi link <args> @@ -267,91 +117,42 @@ if version >= 508 || !exists("did_hs_syntax_inits")      command -nargs=+ HiLink hi def link <args>    endif -  HiLink hs_hlFunctionName    Function -  HiLink hs_HighliteInfixFunctionName Function -  HiLink hs_HlInfixOp       Function -  HiLink hs_OpFunctionName  Function -  HiLink hsTypedef          Typedef -  HiLink hsVarSym           hsOperator -  HiLink hsConSym           hsOperator -  if exists("hs_highlight_delimiters") -    " Some people find this highlighting distracting. -	HiLink hsDelimiter        Delimiter -  endif - -  HiLink hsModuleStartLabel Structure -  HiLink hsExportModuleLabel Keyword -  HiLink hsModuleWhereLabel Structure -  HiLink hsModuleName       Normal -   -  HiLink hsImportIllegal    Error -  HiLink hsAsLabel          hsImportLabel -  HiLink hsHidingLabel      hsImportLabel -  HiLink hsImportLabel      Include -  HiLink hsImportMod        Include -  HiLink hsPackageString    hsString - -  HiLink hsOperator         Operator +  " CPP +  HiLink hsCPP PreProc +  HiLink hsCPPCond PreCondit +  HiLink hsCPPInclude Include +  HiLink hsCPPDefine Define +  HiLink hsCPPDefined PreProc -  HiLink hsInfix            Keyword -  HiLink hsStructure        Structure -  HiLink hsStatement        Statement -  HiLink hsConditional      Conditional +  " Comments +  HiLink hsLineComment Comment +  HiLink hsBlockComment Comment +  HiLink hsPragma Comment +  HiLink hsHaddockComment SpecialComment +  HiLink hsHaddockSection SpecialComment -  HiLink hsSpecialCharError Error -  HiLink hsSpecialChar      SpecialChar -  HiLink hsString           String -  HiLink hsFFIString        String -  HiLink hsCharacter        Character -  HiLink hsNumber           Number -  HiLink hsFloat            Float - -  HiLink hsLiterateComment		  hsComment -  HiLink hsBlockComment     hsComment -  HiLink hsLineComment      hsComment -  HiLink hsModuleCommentA   hsComment -  HiLink hsModuleCommentB   hsComment -  HiLink hsComment          Comment -  HiLink hsCommentTodo      Todo -  HiLink hsPragma           SpecialComment -  HiLink hsBoolean			  Boolean - -  if exists("hs_highlight_types") -      HiLink hsDelimTypeExport  hsType -      HiLink hsType             Type -  endif +  HiLink hsKeyword Keyword +  HiLink hsConditional Conditional +  HiLink hsImport Include +  HiLink hsTypeDecls Keyword -  HiLink hsDebug            Debug +  HiLink hsFIXME Todo -  HiLink hs_TypeOp          hsOperator +  HiLink hsOperator Operator -  HiLink cCppString         hsString -  HiLink cCommentStart      hsComment -  HiLink cCommentError      hsError -  HiLink cCommentStartError hsError -  HiLink cInclude           Include -  HiLink cPreProc           PreProc -  HiLink cDefine            Macro -  HiLink cIncluded          hsString -  HiLink cError             Error -  HiLink cPreCondit         PreCondit -  HiLink cComment           Comment -  HiLink cCppSkip           cCppOut -  HiLink cCppOut2           cCppOut -  HiLink cCppOut            Comment +  HiLink hsModuleQualifier StorageClass -  HiLink hsFFIForeign       Keyword -  HiLink hsFFIImportExport  Structure -  HiLink hsFFICallConvention Keyword -  HiLink hsFFISafety         Keyword +  HiLink hsFunction Function +  HiLink hsTypeName Type -  HiLink hsTHIDTopLevel   Macro -  HiLink hsTHTopLevelName Macro +  " Literals +  HiLink hsSpecialChar SpecialChar +  HiLink hsFloat Float +  HiLink hsNumber Number +  HiLink hsCharacter Character +  HiLink hsString String -  HiLink hsQQVarID Keyword -  HiLink hsQQVarIDNew Keyword -  HiLink hsQQEnd   Keyword -  HiLink hsQQContent String +  HiLink hsScary Todo    delcommand HiLink  endif | 
