vim-haskell -> hasksyn

This commit is contained in:
Adam Stankiewicz 2013-09-12 17:17:14 +02:00
parent 0a4fcd12b6
commit 35433aa23c
7 changed files with 544 additions and 391 deletions

View File

@ -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=:--

View File

@ -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

View File

@ -1,2 +0,0 @@
" autocommand
au BufRead,BufNewFile *.hs set comments=sl:{-,mb:--,elx:-}

View File

@ -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

View File

@ -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:haskell_indent_case')
" case xs of
" >>>>>[] -> ...
" >>>>>(y:ys) -> ...
let g:haskell_indent_case = 2
if !exists('g:hasksyn_dedent_after_return')
let g:hasksyn_dedent_after_return = 1
endif
setlocal indentexpr=GetHaskellIndent()
setlocal indentkeys=!^F,o,O
if !exists('g:hasksyn_dedent_after_catchall_case')
let g:hasksyn_dedent_after_catchall_case = 1
endif
function! GetHaskellIndent()
let line = substitute(getline(getpos('.')[1] - 1), '\t', repeat(' ', &tabstop), 'g')
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 line =~ '[!#$%&*+./<=>?@\\^|~-]$\|\<do$'
return match(line, '\s*where \zs\|\S') + &shiftwidth
if exists("*HIndent")
finish
endif
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 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
" 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 =~ '{$'
return match(line, '\s*where \zs\|\S') + &shiftwidth
let bmatch = match(prevl, '\({\|\[\)')
if bmatch != -1
return bmatch
endif
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
" 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
" 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
if line =~ '^\(instance\|class\).*\&.*where$'
return &shiftwidth
let dataEquals = match(prevl, '\(data.*\)\@<==')
if dataEquals != -1
return dataEquals
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
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
if line !~ '\<else\>'
let s = match(line, '\<if\>.*\&.*\zs\<then\>')
if s > 0
return s
endif
return previ + &sw
endif
let s = match(line, '\<if\>')
if s > 0
return s + g:haskell_indent_if
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 s = match(line, '\<do\s\+\zs[^{]\|\<where\s\+\zs\w\|\<let\s\+\zs\S\|^\s*\zs|\s')
if s > 0
return s
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

147
syntax/cabal.vim Normal file
View File

@ -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'

View File

@ -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 sync minlines=50 maxlines=200
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
" 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]\+\)\=\>"
" (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_']*\>"
" 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 "\[\]"
" 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_']*`"
" These are keywords that are only highlighted if they are in comments.
syn keyword hsFIXME contained FIXME TODO XXX BUG NOTE
" 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
" 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\)\@='
" new module highlighting
syn region hsDelimTypeExport start="\<[A-Z]\(\S\&[^,.]\)*\>(" end=")" contained
\ contains=hsType
" 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
sy keyword hsExportModuleLabel module contained
sy match hsExportModule "\<module\>\(\s\|\t\|\n\)*\([A-Z]\w*\.\?\)*" contained contains=hsExportModuleLabel,hsModuleName
" 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
sy keyword hsModuleStartLabel module contained
sy keyword hsModuleWhereLabel where contained
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...
syn match hsModuleStart "^module\(\s\|\n\)*\(\<\(\w\|\.\)*\>\)\(\s\|\n\)*"
\ contains=hsModuleStartLabel,hsModuleName
\ nextgroup=hsModuleCommentA,hsModuleExports,hsModuleWhereLabel
" 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\.]\+`"
syn region hsModuleCommentA start="{-" end="-}"
\ contains=hsModuleCommentA,hsCommentTodo,@Spell contained
\ nextgroup=hsModuleCommentA,hsModuleExports,hsModuleWhereLabel skipwhite skipnl
" 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*::\)\@="
syn match hsModuleCommentA "--.*\n"
\ contains=hsCommentTodo,@Spell contained
\ nextgroup=hsModuleCommentA,hsModuleExports,hsModuleWhereLabel skipwhite skipnl
" FIXME Ignoring proc for now, also mdo and rec
syn region hsModuleExports start="(" end=")" contained
\ nextgroup=hsModuleCommentB,hsModuleWhereLabel skipwhite skipnl
\ contains=hsBlockComment,hsLineComment,hsType,hsDelimTypeExport,hs_hlFunctionName,hs_OpFunctionName,hsExportModule
" Give undefined a bit of special treatment
syn keyword hsScary undefined
syn match hsModuleCommentB "--.*\n"
\ contains=hsCommentTodo,@Spell contained
\ nextgroup=hsModuleCommentB,hsModuleWhereLabel skipwhite skipnl
" 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\+)'
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")
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
" CPP
HiLink hsCPP PreProc
HiLink hsCPPCond PreCondit
HiLink hsCPPInclude Include
HiLink hsCPPDefine Define
HiLink hsCPPDefined PreProc
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
" Comments
HiLink hsLineComment Comment
HiLink hsBlockComment Comment
HiLink hsPragma Comment
HiLink hsHaddockComment SpecialComment
HiLink hsHaddockSection SpecialComment
HiLink hsOperator Operator
HiLink hsKeyword Keyword
HiLink hsConditional Conditional
HiLink hsImport Include
HiLink hsTypeDecls Keyword
HiLink hsInfix Keyword
HiLink hsStructure Structure
HiLink hsStatement Statement
HiLink hsConditional Conditional
HiLink hsFIXME Todo
HiLink hsSpecialCharError Error
HiLink hsSpecialChar SpecialChar
HiLink hsString String
HiLink hsFFIString String
HiLink hsCharacter Character
HiLink hsNumber Number
HiLink hsFloat Float
HiLink hsOperator Operator
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
HiLink hsModuleQualifier StorageClass
if exists("hs_highlight_types")
HiLink hsDelimTypeExport hsType
HiLink hsType Type
endif
HiLink hsFunction Function
HiLink hsTypeName Type
HiLink hsDebug Debug
" Literals
HiLink hsSpecialChar SpecialChar
HiLink hsFloat Float
HiLink hsNumber Number
HiLink hsCharacter Character
HiLink hsString String
HiLink hs_TypeOp hsOperator
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 hsFFIForeign Keyword
HiLink hsFFIImportExport Structure
HiLink hsFFICallConvention Keyword
HiLink hsFFISafety Keyword
HiLink hsTHIDTopLevel Macro
HiLink hsTHTopLevelName Macro
HiLink hsQQVarID Keyword
HiLink hsQQVarIDNew Keyword
HiLink hsQQEnd Keyword
HiLink hsQQContent String
HiLink hsScary Todo
delcommand HiLink
endif