mirror of
https://github.com/sheerun/vim-polyglot.git
synced 2025-11-08 11:33:52 -05:00
Changed haskell provider to raichoo/haskell-vim, closes #63
This commit is contained in:
@@ -43,7 +43,7 @@ Optionally download one of the [releases](https://github.com/sheerun/vim-polyglo
|
|||||||
- [go](https://github.com/fatih/vim-go) (syntax, indent, ftdetect)
|
- [go](https://github.com/fatih/vim-go) (syntax, indent, ftdetect)
|
||||||
- [haml](https://github.com/tpope/vim-haml) (syntax, indent, compiler, ftplugin, ftdetect)
|
- [haml](https://github.com/tpope/vim-haml) (syntax, indent, compiler, ftplugin, ftdetect)
|
||||||
- [handlebars](https://github.com/mustache/vim-mustache-handlebars) (syntax, ftplugin, ftdetect)
|
- [handlebars](https://github.com/mustache/vim-mustache-handlebars) (syntax, ftplugin, ftdetect)
|
||||||
- [haskell](https://github.com/travitch/hasksyn) (syntax, indent, ftplugin)
|
- [haskell](https://github.com/raichoo/haskell-vim) (syntax, indent, ftplugin, ftdetect)
|
||||||
- [haxe](https://github.com/yaymukund/vim-haxe) (syntax, ftdetect)
|
- [haxe](https://github.com/yaymukund/vim-haxe) (syntax, ftdetect)
|
||||||
- [html5](https://github.com/othree/html5.vim) (syntax, indent, autoload, ftplugin)
|
- [html5](https://github.com/othree/html5.vim) (syntax, indent, autoload, ftplugin)
|
||||||
- [jade](https://github.com/digitaltoad/vim-jade) (syntax, indent, ftplugin, ftdetect)
|
- [jade](https://github.com/digitaltoad/vim-jade) (syntax, indent, ftplugin, ftdetect)
|
||||||
|
|||||||
8
after/ftplugin/cabal.vim
Normal file
8
after/ftplugin/cabal.vim
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
||||||
|
|
||||||
|
setlocal comments=s1fl:{-,mb:-,ex:-},:--
|
||||||
|
setlocal formatoptions-=cro formatoptions+=j
|
||||||
|
setlocal iskeyword+=-,.,*
|
||||||
|
setlocal commentstring=--\ %s
|
||||||
|
|
||||||
|
endif
|
||||||
@@ -1,13 +1,7 @@
|
|||||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
||||||
|
|
||||||
" Vim ftplugin file
|
setlocal comments=s1fl:{-,mb:-,ex:-},:--
|
||||||
" Language: Haskell
|
setlocal formatoptions-=cro formatoptions+=j
|
||||||
" Maintainer: Tristan Ravitch
|
setlocal iskeyword+='
|
||||||
|
|
||||||
" 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=:--
|
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
2
build
2
build
@@ -114,7 +114,7 @@ PACKS="
|
|||||||
go:fatih/vim-go:_BASIC
|
go:fatih/vim-go:_BASIC
|
||||||
haml:tpope/vim-haml
|
haml:tpope/vim-haml
|
||||||
handlebars:mustache/vim-mustache-handlebars
|
handlebars:mustache/vim-mustache-handlebars
|
||||||
haskell:travitch/hasksyn
|
haskell:raichoo/haskell-vim
|
||||||
haxe:yaymukund/vim-haxe
|
haxe:yaymukund/vim-haxe
|
||||||
html5:othree/html5.vim
|
html5:othree/html5.vim
|
||||||
jade:digitaltoad/vim-jade
|
jade:digitaltoad/vim-jade
|
||||||
|
|||||||
@@ -110,6 +110,10 @@ autocmd BufNewFile,BufRead *.haml,*.hamlbars,*.hamlc setf haml
|
|||||||
autocmd BufNewFile,BufRead *.sass setf sass
|
autocmd BufNewFile,BufRead *.sass setf sass
|
||||||
autocmd BufNewFile,BufRead *.scss setf scss
|
autocmd BufNewFile,BufRead *.scss setf scss
|
||||||
endif
|
endif
|
||||||
|
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
||||||
|
|
||||||
|
au BufRead,BufNewFile *.hsc set filetype=haskell
|
||||||
|
endif
|
||||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haxe') == -1
|
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haxe') == -1
|
||||||
|
|
||||||
autocmd BufNewFile,BufRead *.hx setf haxe
|
autocmd BufNewFile,BufRead *.hx setf haxe
|
||||||
|
|||||||
69
ftplugin/cabal.vim
Normal file
69
ftplugin/cabal.vim
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
||||||
|
|
||||||
|
if exists("g:loaded_haskellvim_cabal")
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
let g:loaded_haskellvim_cabal = 1
|
||||||
|
|
||||||
|
function! s:makeSection(content)
|
||||||
|
return "\n" . join(a:content, "\n")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:exeTmpl(name, src)
|
||||||
|
let l:exetmpl = [ 'executable ' . a:name,
|
||||||
|
\ '-- ghc-options:',
|
||||||
|
\ 'main-is: ' . a:src,
|
||||||
|
\ '-- other-modules:',
|
||||||
|
\ '-- other-extensions:',
|
||||||
|
\ 'build-depends: base',
|
||||||
|
\ '-- hs-source-dirs:',
|
||||||
|
\ 'default-language: Haskell2010'
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
return s:makeSection(l:exetmpl)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:libTmpl()
|
||||||
|
let l:libtmpl = [ 'library',
|
||||||
|
\ '-- ghc-options:',
|
||||||
|
\ '-- other-modules:',
|
||||||
|
\ '-- other-extensions:',
|
||||||
|
\ 'build-depends: base',
|
||||||
|
\ '-- hs-source-dirs:',
|
||||||
|
\ 'default-language: Haskell2010'
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
return s:makeSection(l:libtmpl)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:flagTmpl(name)
|
||||||
|
let l:flagtmpl = [ 'flag ' . a:name,
|
||||||
|
\ 'description:',
|
||||||
|
\ 'default: False',
|
||||||
|
\ 'manual: True',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
return s:makeSection(l:flagtmpl)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! cabal#addExecutable()
|
||||||
|
let l:name = input("Enter executable name: ")
|
||||||
|
let l:src = input("Enter source file: ")
|
||||||
|
exe "normal Go" . s:exeTmpl(l:name, l:src)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! cabal#addLibrary()
|
||||||
|
exe "normal Go" . s:libTmpl()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! cabal#addFlag()
|
||||||
|
let l:name = input("Enter flag name: ")
|
||||||
|
exe "normal Go" . s:flagTmpl(l:name)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
command! -buffer CabalAddExecutable call cabal#addExecutable()
|
||||||
|
command! -buffer CabalAddLibrary call cabal#addLibrary()
|
||||||
|
command! -buffer CabalAddFlag call cabal#addFlag()
|
||||||
|
|
||||||
|
endif
|
||||||
25
ftplugin/haskell.vim
Normal file
25
ftplugin/haskell.vim
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
||||||
|
|
||||||
|
if exists("g:loaded_haskellvim_haskell")
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
let g:loaded_haskellvim_haskell = 1
|
||||||
|
|
||||||
|
function! haskell#makeModuleCommentBlock()
|
||||||
|
let l:commenttmpl = [ '{-|',
|
||||||
|
\ 'Module : ',
|
||||||
|
\ 'Description : ',
|
||||||
|
\ 'Copyright : ',
|
||||||
|
\ 'License : ',
|
||||||
|
\ 'Maintainer : ',
|
||||||
|
\ 'Stability : ',
|
||||||
|
\ 'Portability : ',
|
||||||
|
\ '-}']
|
||||||
|
|
||||||
|
exe "normal ggO" . join(l:commenttmpl, "\n")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
command! -buffer -nargs=0 HaskellAddModuleComment call haskell#makeModuleCommentBlock()
|
||||||
|
|
||||||
|
endif
|
||||||
35
indent/cabal.vim
Normal file
35
indent/cabal.vim
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
||||||
|
|
||||||
|
" indentation for cabal
|
||||||
|
"
|
||||||
|
" author: raichoo (raichoo@googlemail.com)
|
||||||
|
"
|
||||||
|
if exists('b:did_indent')
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
let b:did_indent = 1
|
||||||
|
|
||||||
|
if !exists('g:cabal_indent_section')
|
||||||
|
"executable name
|
||||||
|
">>main-is: Main.hs
|
||||||
|
">>hs-source-dirs: src
|
||||||
|
let g:cabal_indent_section = 2
|
||||||
|
elseif exists('g:cabal_indent_section') && g:cabal_indent_section > 4
|
||||||
|
let g:cabal_indent_section = 4
|
||||||
|
endif
|
||||||
|
|
||||||
|
setlocal indentexpr=GetCabalIndent()
|
||||||
|
setlocal indentkeys=!^F,o,O,<CR>
|
||||||
|
|
||||||
|
function! GetCabalIndent()
|
||||||
|
let l:prevline = getline(v:lnum - 1)
|
||||||
|
|
||||||
|
if l:prevline =~ '\C^\(executable\|library\|flag\|source-repository\|test-suite\|benchmark\)'
|
||||||
|
return g:cabal_indent_section
|
||||||
|
else
|
||||||
|
return match(l:prevline, '\S')
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endif
|
||||||
@@ -1,8 +1,15 @@
|
|||||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
||||||
|
|
||||||
" Vim indent file
|
" indentation for haskell
|
||||||
" Language: Haskell
|
"
|
||||||
" Maintainer: Tristan Ravitch
|
" Based on idris indentation
|
||||||
|
"
|
||||||
|
" author: raichoo (raichoo@googlemail.com)
|
||||||
|
"
|
||||||
|
" 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
|
||||||
|
|
||||||
if exists('b:did_indent')
|
if exists('b:did_indent')
|
||||||
finish
|
finish
|
||||||
@@ -10,291 +17,164 @@ endif
|
|||||||
|
|
||||||
let b:did_indent = 1
|
let b:did_indent = 1
|
||||||
|
|
||||||
if !exists('g:hasksyn_indent_search_backward')
|
if !exists('g:haskell_indent_if')
|
||||||
let g:hasksyn_indent_search_backward = 100
|
" if bool
|
||||||
|
" >>>then ...
|
||||||
|
" >>>else ...
|
||||||
|
let g:haskell_indent_if = 3
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if !exists('g:hasksyn_dedent_after_return')
|
if !exists('g:haskell_indent_case')
|
||||||
let g:hasksyn_dedent_after_return = 1
|
" case xs of
|
||||||
|
" >>[] -> ...
|
||||||
|
" >>(y:ys) -> ...
|
||||||
|
let g:haskell_indent_case = 2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if !exists('g:hasksyn_dedent_after_catchall_case')
|
if !exists('g:haskell_indent_let')
|
||||||
let g:hasksyn_dedent_after_catchall_case = 1
|
" let x = 0 in
|
||||||
|
" >>>>x
|
||||||
|
let g:haskell_indent_let = 4
|
||||||
endif
|
endif
|
||||||
|
|
||||||
setlocal noautoindent
|
if !exists('g:haskell_indent_where')
|
||||||
setlocal indentexpr=HIndent(v:lnum)
|
" where f :: Int -> Int
|
||||||
setlocal indentkeys+=0=where
|
" >>>>>>f x = x
|
||||||
setlocal indentkeys+=0=->
|
let g:haskell_indent_where = 6
|
||||||
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
|
endif
|
||||||
|
|
||||||
|
if !exists('g:haskell_indent_do')
|
||||||
|
" do x <- a
|
||||||
|
" >>>y <- b
|
||||||
|
let g:haskell_indent_do = 3
|
||||||
|
endif
|
||||||
|
|
||||||
function! HIndent(lnum)
|
if !exists('g:haskell_indent_in')
|
||||||
" Don't do anything boneheaded if we are inside of a block comment
|
" let x = 1
|
||||||
if s:IsInBlockComment()
|
" >in x
|
||||||
return -1
|
let g:haskell_indent_in = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
setlocal indentexpr=GetHaskellIndent()
|
||||||
|
setlocal indentkeys=!^F,o,O,0\|,0=where,0=in,0=let,0=deriving,0=->,0=\=>,<CR>,0}
|
||||||
|
|
||||||
|
function! GetHaskellIndent()
|
||||||
|
let l:prevline = getline(v:lnum - 1)
|
||||||
|
|
||||||
|
if l:prevline =~ '^\s*--'
|
||||||
|
return match(l:prevline, '\S')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let plnum = s:PrevNonCommentLineNum(a:lnum)
|
if l:prevline =~ '^\s*$'
|
||||||
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 =~ '\Wm\=do\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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
let dataEquals = match(prevl, '\(data.*\)\@<==')
|
|
||||||
if dataEquals != -1
|
|
||||||
return dataEquals
|
|
||||||
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 do or where with some bindings
|
|
||||||
" following it on the same line, accommodate and align with the first non-ws
|
|
||||||
" char after the where
|
|
||||||
if prevl =~ '\W\(do\|where\)\s\+\w'
|
|
||||||
let bindStart = match(prevl, '\(\W\(do\|where\)\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
|
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, '"\([^"]\|\\"\)*"', '\=repeat("s", len(submatch(0)))', '')
|
|
||||||
let noLineCom = substitute(noStrings, '--.*$', '', '')
|
|
||||||
|
|
||||||
" If there are no fancy block comments involved, skip some of this extra
|
|
||||||
" work
|
|
||||||
if noLineCom !~ '\({-\|-}\)'
|
|
||||||
return noLineCom
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" We stripped line comments, now we need to strip out any relevant multiline
|
let l:line = getline(v:lnum)
|
||||||
" 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
|
if l:line =~ '\C^\s*\<where\>'
|
||||||
" within the search range or -1 if not found. Stops searching at lines
|
let l:s = match(l:prevline, '\S')
|
||||||
" starting at column 0 with an identifier character.
|
return l:s + &shiftwidth
|
||||||
function! s:BackwardPatternSearch(lnum, pat)
|
endif
|
||||||
let lnum = s:PrevNonCommentLineNum(a:lnum)
|
|
||||||
while 1
|
if l:line =~ '\C^\s*\<deriving\>'
|
||||||
let aline = s:GetAndStripTrailingComments(lnum)
|
let l:s = match(l:prevline, '\C\<\(newtype\|data\)\>')
|
||||||
if a:lnum - lnum > g:hasksyn_indent_search_backward
|
if l:s >= 0
|
||||||
return -1
|
return l:s + &shiftwidth
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
let theMatch = match(aline, a:pat)
|
if l:line =~ '\C^\s*\<let\>'
|
||||||
if theMatch != -1
|
let l:s = match(l:prevline, '\C\<let\>')
|
||||||
return theMatch
|
if l:s != 0
|
||||||
else
|
return l:s
|
||||||
" We want to be able to consider lines starting in column 0, but we don't
|
endif
|
||||||
" want to search back past them.
|
endif
|
||||||
if aline =~ '^\w'
|
|
||||||
return -1
|
if l:line =~ '\C^\s*\<in\>'
|
||||||
|
let l:s = match(l:prevline, '\C\<let\>')
|
||||||
|
if l:s >= 0
|
||||||
|
return l:s + g:haskell_indent_in
|
||||||
|
elseif match(l:prevline, '=') > 0
|
||||||
|
let l:s = match(l:prevline, '\S')
|
||||||
|
return l:s - (4 - g:haskell_indent_in)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:line =~ '^\s*|'
|
||||||
|
if match(l:prevline, '^\s*data') < 0
|
||||||
|
if match(l:prevline, '^\s*|\s') >= 0
|
||||||
|
return match(l:prevline, '|')
|
||||||
|
else
|
||||||
|
return &shiftwidth
|
||||||
endif
|
endif
|
||||||
let lnum = s:PrevNonCommentLineNum(lnum)
|
|
||||||
endif
|
endif
|
||||||
endwhile
|
endif
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
if l:line =~ '^\s*[=-]>'
|
||||||
|
let l:s = match(l:prevline, ' :: ')
|
||||||
|
if l:s >= 0
|
||||||
|
return l:s + 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:prevline =~ '\s\+[!#$%&*+./<>?@\\^|~-]\+\s*$'
|
||||||
|
let l:s = match(l:prevline, '\S')
|
||||||
|
if l:s > 0
|
||||||
|
return l:s + &shiftwidth
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:prevline =~ '[{([][^})\]]\+$'
|
||||||
|
return match(l:prevline, '[{([]')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:prevline =~ '\C\<let\>\s\+[^=]\+=\s*$'
|
||||||
|
return match(l:prevline, '\C\<let\>') + g:haskell_indent_let + &shiftwidth
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:prevline =~ '\C\<let\>\s\+.\+\(\<in\>\)\?\s*$'
|
||||||
|
return match(l:prevline, '\C\<let\>') + g:haskell_indent_let
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:prevline !~ '\C\<else\>'
|
||||||
|
let l:s = match(l:prevline, '\C\<if\>.*\&.*\zs\<then\>')
|
||||||
|
if l:s > 0
|
||||||
|
return l:s
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:s = match(l:prevline, '\C\<if\>')
|
||||||
|
if l:s > 0
|
||||||
|
return l:s + g:haskell_indent_if
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:prevline =~ '\C\(\<where\>\|\<do\>\|=\|[{([]\)\s*$'
|
||||||
|
return match(l:prevline, '\S') + &shiftwidth
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:prevline =~ '\C\<where\>\s\+\S\+.*$'
|
||||||
|
return match(l:prevline, '\C\<where\>') + g:haskell_indent_where
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:prevline =~ '\C\<do\>\s\+\S\+.*$'
|
||||||
|
return match(l:prevline, '\C\<do\>') + g:haskell_indent_do
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:prevline =~ '\C^\s*\<data\>\s\+[^=]\+\s\+=\s\+\S\+.*$'
|
||||||
|
if l:line =~ '^\s*|'
|
||||||
|
return match(l:prevline, '=')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:prevline =~ '\C\<case\>\s\+.\+\<of\>\s*$'
|
||||||
|
return match(l:prevline, '\C\<case\>') + g:haskell_indent_case
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:prevline =~ '\C^\s*\<\data\>\s\+\S\+\s*$'
|
||||||
|
return match(l:prevline, '\C\<data\>') + &shiftwidth
|
||||||
|
endif
|
||||||
|
|
||||||
|
return match(l:prevline, '\S')
|
||||||
|
endfunction
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
182
syntax/cabal.vim
182
syntax/cabal.vim
@@ -1,151 +1,55 @@
|
|||||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
||||||
|
|
||||||
" Vim syntax file
|
" syntax highlighting for cabal
|
||||||
" Language: Cabal
|
"
|
||||||
" Author: Tristan Ravitch
|
" author: raichoo (raichoo@googlemail.com)
|
||||||
" Version: 0.0.1
|
|
||||||
|
|
||||||
if version < 600
|
if version < 600
|
||||||
syntax clear
|
syn clear
|
||||||
elseif exists('b:current_syntax')
|
elseif exists("b:current_syntax")
|
||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
|
|
||||||
syn sync minlines=50 maxlines=200
|
syn match cabalLineComment "---*\([^-!#$%&\*\+./<=>\?@\\^|~].*\)\?$" contains=@Spell
|
||||||
syn case ignore
|
syn match cabalIdentifier "[A-Za-z\-]*" contained
|
||||||
|
syn match cabalOperator "[<=>&|!]"
|
||||||
|
syn match cabalColon ":" contained
|
||||||
|
syn match cabalNumber "\<[0-9][0-9\.*]*\>"
|
||||||
|
syn match cabalDelimiter "[,()]"
|
||||||
|
syn keyword cabalBool True False
|
||||||
|
syn keyword cabalConditional if else
|
||||||
|
syn match cabalCompilerFlag "\s\+-[^ -][^ ]*"
|
||||||
|
syn match cabalDocBulletPoint "^\s\+\*"
|
||||||
|
syn match cabalDocHeadline "^\s\+=.*$"
|
||||||
|
syn match cabalDocCode "^\s\+>.*$"
|
||||||
|
syn match cabalDocNewline "^\s\+\.\s*$"
|
||||||
|
syn match cabalSection "^\c\(executable\|library\|flag\|source-repository\|test-suite\|benchmark\)"
|
||||||
|
syn match cabalEntry "^\s*[A-Za-z][a-zA-Z\-]*:" contains=cabalIdentifier,cabalColon
|
||||||
|
|
||||||
" Top-level package keywords
|
syn region cabalDescription start="^\s*[dD]escription:" end="^\<" keepend
|
||||||
syn match cabalKey '^name:'
|
\ contains=
|
||||||
syn match cabalKey '^version:'
|
\ cabalEntry,
|
||||||
syn match cabalKey '^cabal-version:'
|
\ cabalLineComment,
|
||||||
syn match cabalKey '^build-type:'
|
\ cabalDocBulletPoint,
|
||||||
syn match cabalKey '^license:'
|
\ cabalDocHeadline,
|
||||||
syn match cabalKey '^license-file:'
|
\ cabalDocNewline,
|
||||||
syn match cabalKey '^copyright:'
|
\ cabalDocCode
|
||||||
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
|
highlight def link cabalIdentifier Identifier
|
||||||
syn match cabalLit '\(:\s*\)\@<=\(true\|false\)'
|
highlight def link cabalLineComment Comment
|
||||||
|
highlight def link cabalOperator Operator
|
||||||
|
highlight def link cabalColon Operator
|
||||||
|
highlight def link cabalNumber Number
|
||||||
|
highlight def link cabalSection Structure
|
||||||
|
highlight def link cabalDelimiter Delimiter
|
||||||
|
highlight def link cabalBool Boolean
|
||||||
|
highlight def link cabalCompilerFlag Macro
|
||||||
|
highlight def link cabalConditional Conditional
|
||||||
|
highlight def link cabalDocBulletPoint Structure
|
||||||
|
highlight def link cabalDocHeadline Include
|
||||||
|
highlight def link cabalDocNewline Operator
|
||||||
|
highlight def link cabalDocCode Macro
|
||||||
|
|
||||||
" Library-specifics
|
let b:current_syntax = "cabal"
|
||||||
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 '--.*$' contains=@Spell
|
|
||||||
|
|
||||||
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'
|
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -1,162 +1,258 @@
|
|||||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1
|
||||||
|
|
||||||
" Vim syntax file
|
" syntax highlighting for haskell
|
||||||
" Language: Haskell
|
"
|
||||||
" Author: Tristan Ravitch
|
" Heavily modified version of the haskell syntax
|
||||||
" Maintainer: Tristan Ravitch
|
" highlighter to support haskell.
|
||||||
" Version: 0.0.1
|
"
|
||||||
|
" author: raichoo (raichoo@googlemail.com)
|
||||||
|
|
||||||
if version < 600
|
if version < 600
|
||||||
syntax clear
|
syn clear
|
||||||
elseif exists('b:current_syntax')
|
elseif exists("b:current_syntax")
|
||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
|
|
||||||
syn sync minlines=50 maxlines=200
|
if exists('g:haskell_enable_quantification') && g:haskell_enable_quantification == 1
|
||||||
|
syn region haskellRecordBlock matchgroup=haskellDelimiter start="{" end="}"
|
||||||
|
\ contains=
|
||||||
|
\ haskellType,
|
||||||
|
\ haskellSeparator,
|
||||||
|
\ haskellParens,
|
||||||
|
\ haskellBrackets,
|
||||||
|
\ haskellRecordField,
|
||||||
|
\ haskellOperators,
|
||||||
|
\ haskellDot,
|
||||||
|
\ haskellLineComment,
|
||||||
|
\ haskellBlockComment,
|
||||||
|
\ haskellPragma,
|
||||||
|
\ haskellForall
|
||||||
|
else
|
||||||
|
syn region haskellRecordBlock matchgroup=haskellDelimiter start="{" end="}"
|
||||||
|
\ contains=
|
||||||
|
\ haskellType,
|
||||||
|
\ haskellSeparator,
|
||||||
|
\ haskellParens,
|
||||||
|
\ haskellBrackets,
|
||||||
|
\ haskellRecordField,
|
||||||
|
\ haskellOperators,
|
||||||
|
\ haskellDot,
|
||||||
|
\ haskellLineComment,
|
||||||
|
\ haskellBlockComment,
|
||||||
|
\ haskellPragma
|
||||||
|
endif
|
||||||
|
if exists('g:haskell_enable_pattern_synonyms') && g:haskell_enable_pattern_synonyms == 1
|
||||||
|
syn region haskellImportList matchgroup=haskellDelimiter start="(" end=")"
|
||||||
|
\ contains=
|
||||||
|
\ haskellSeparator,
|
||||||
|
\ haskellType,
|
||||||
|
\ haskellLineComment,
|
||||||
|
\ haskellBlockComment,
|
||||||
|
\ haskellDot,
|
||||||
|
\ haskellParens,
|
||||||
|
\ haskellPatternKeyword
|
||||||
|
else
|
||||||
|
syn region haskellImportList matchgroup=haskellDelimiter start="(" end=")"
|
||||||
|
\ contains=
|
||||||
|
\ haskellSeparator,
|
||||||
|
\ haskellType,
|
||||||
|
\ haskellLineComment,
|
||||||
|
\ haskellBlockComment,
|
||||||
|
\ haskellDot,
|
||||||
|
\ haskellParens
|
||||||
|
end
|
||||||
|
syn match haskellRecordField "[_a-z][a-zA-Z0-9_']*\s*::" contained
|
||||||
|
\ contains=
|
||||||
|
\ haskellIdentifier,
|
||||||
|
\ haskellOperators
|
||||||
|
syn match haskellTopLevelDecl
|
||||||
|
\ "^\s*\(where\s\+\|let\s\+\|default\s\+\)\?[_a-z][a-zA-Z0-9_']*\(,\s*[_a-z][a-zA-Z0-9_']*\)*\(\s*::\|\n\s\+::\)"
|
||||||
|
\ contains=
|
||||||
|
\ haskellIdentifier,
|
||||||
|
\ haskellOperators,
|
||||||
|
\ haskellSeparator,
|
||||||
|
\ haskellParens,
|
||||||
|
\ haskellBrackets,
|
||||||
|
\ haskellWhere,
|
||||||
|
\ haskellLet,
|
||||||
|
\ haskellDefault
|
||||||
|
syn region haskellModuleBlock matchgroup=haskellBlockKeywords start="\<module\>" end="\<where\>"
|
||||||
|
\ contains=haskellType,haskellDot,haskellImportList
|
||||||
|
syn region haskellClassBlock
|
||||||
|
\ matchgroup=haskellBlockKeywords
|
||||||
|
\ start="^\<\(class\|instance\)\>"
|
||||||
|
\ end="\<where\>\|^\<"
|
||||||
|
\ contains=
|
||||||
|
\ haskellType,
|
||||||
|
\ haskellSeparator,
|
||||||
|
\ haskellParens,
|
||||||
|
\ haskellDot,
|
||||||
|
\ haskellOperators,
|
||||||
|
\ haskellLineComment,
|
||||||
|
\ haskellBlockComment,
|
||||||
|
\ haskellPragma
|
||||||
|
syn keyword haskellDeclKeyword newtype data type family instance where contained
|
||||||
|
syn region haskellDeclBlock keepend
|
||||||
|
\ start="^\<\(newtype\|data\|type\)\>\s\+\(\<\(family\|instance\)\>\)\?"
|
||||||
|
\ end="\<where\>\|=\|^\<"
|
||||||
|
\ contains=
|
||||||
|
\ haskellDeclKeyword,
|
||||||
|
\ haskellType,
|
||||||
|
\ haskellQuoted,
|
||||||
|
\ haskellParens,
|
||||||
|
\ haskellBrackets,
|
||||||
|
\ haskellDot,
|
||||||
|
\ haskellOperators,
|
||||||
|
\ haskellLineComment,
|
||||||
|
\ haskellBlockComment,
|
||||||
|
\ haskellPragma
|
||||||
|
syn match haskellAssocType "\s\+\<\(data\|type\|newtype\)\>"
|
||||||
|
syn match haskellDeriving "\(deriving\s\+instance\|deriving\)"
|
||||||
|
syn keyword haskellDefault default
|
||||||
|
syn keyword haskellImportKeywords import qualified safe as hiding contained
|
||||||
|
syn keyword haskellForeignKeywords foreign export import ccall safe unsafe interruptible capi prim contained
|
||||||
|
syn region haskellForeignImport start="\<foreign\>" end="::" keepend
|
||||||
|
\ contains=
|
||||||
|
\ haskellString,
|
||||||
|
\ haskellOperators,
|
||||||
|
\ haskellForeignKeywords,
|
||||||
|
\ haskellIdentifier
|
||||||
|
syn region haskellImport
|
||||||
|
\ start="^import"
|
||||||
|
\ end="^\<"
|
||||||
|
\ contains=
|
||||||
|
\ haskellImportKeywords,
|
||||||
|
\ haskellImportList,
|
||||||
|
\ haskellType,
|
||||||
|
\ haskellLineComment,
|
||||||
|
\ haskellBlockComment,
|
||||||
|
\ haskellDot
|
||||||
|
syn keyword haskellStatement do case of in
|
||||||
|
syn keyword haskellWhere where
|
||||||
|
syn keyword haskellLet let
|
||||||
|
if exists('g:haskell_enable_static_pointers') && g:haskell_enable_static_pointers == 1
|
||||||
|
syn keyword haskellStatic static
|
||||||
|
endif
|
||||||
|
syn keyword haskellConditional if then else
|
||||||
|
syn match haskellNumber "\<[0-9]\+\>\|\<0[xX][0-9a-fA-F]\+\>\|\<0[oO][0-7]\+\>\|\<0[bB][10]\+\>"
|
||||||
|
syn match haskellFloat "\<[0-9]\+\.[0-9]\+\([eE][-+]\=[0-9]\+\)\=\>"
|
||||||
|
syn match haskellSeparator "[,;]"
|
||||||
|
syn region haskellParens matchgroup=haskellDelimiter start="(" end=")" contains=TOP
|
||||||
|
syn region haskellBrackets matchgroup=haskellDelimiter start="\[" end="]" contains=TOP
|
||||||
|
syn region haskellBlock matchgroup=haskellDelimiter start="{" end="}" contains=TOP
|
||||||
|
syn keyword haskellInfix infix infixl infixr
|
||||||
|
syn keyword haskellBottom undefined error
|
||||||
|
syn match haskellOperators "[-!#$%&\*\+/<=>\?@\\^|~:]\+\|\<_\>"
|
||||||
|
syn match haskellQuote "\<'\+" contained
|
||||||
|
syn match haskellQuotedType "[A-Z][a-zA-Z0-9_']*\>" contained
|
||||||
|
syn region haskellQuoted start="\<'\+" end="\>"
|
||||||
|
\ contains=
|
||||||
|
\ haskellType,
|
||||||
|
\ haskellQuote,
|
||||||
|
\ haskellQuotedType,
|
||||||
|
\ haskellSeparator,
|
||||||
|
\ haskellParens,
|
||||||
|
\ haskellOperators,
|
||||||
|
\ haskellIdentifier
|
||||||
|
syn match haskellDot "\."
|
||||||
|
syn match haskellLineComment "---*\([^-!#$%&\*\+./<=>\?@\\^|~].*\)\?$"
|
||||||
|
\ contains=
|
||||||
|
\ haskellTodo,
|
||||||
|
\ @Spell
|
||||||
|
syn match haskellBacktick "`[A-Za-z_][A-Za-z0-9_\.']*`"
|
||||||
|
syn region haskellString start=+"+ skip=+\\\\\|\\"+ end=+"+
|
||||||
|
\ contains=@Spell
|
||||||
|
syn match haskellIdentifier "[_a-z][a-zA-z0-9_']*" contained
|
||||||
|
syn match haskellChar "\<'[^'\\]'\|'\\.'\|'\\u[0-9a-fA-F]\{4}'\>"
|
||||||
|
syn match haskellType "\<[A-Z][a-zA-Z0-9_']*\>\n\?\s*"
|
||||||
|
\ nextgroup=haskellBlockComment,haskellRecordBlock
|
||||||
|
syn region haskellBlockComment start="{-" end="-}"
|
||||||
|
\ contains=
|
||||||
|
\ haskellBlockComment,
|
||||||
|
\ haskellTodo,
|
||||||
|
\ @Spell
|
||||||
|
syn region haskellPragma start="{-#" end="#-}"
|
||||||
|
syn region haskellQuasiQuote matchgroup=haskellTH start="\[[_a-z][a-zA-z0-9_']*|" end="|\]"
|
||||||
|
syn region haskellTHBlock matchgroup=haskellTH start="\[\(d\|t\|p\)\?|" end="|]" contains=TOP
|
||||||
|
syn region haskellTHDoubleBlock matchgroup=haskellTH start="\[||" end="||]" contains=TOP
|
||||||
|
syn match haskellPreProc "^#.*$"
|
||||||
|
syn keyword haskellTodo TODO FIXME contained
|
||||||
|
if exists('g:haskell_enable_typeroles') && g:haskell_enable_typeroles == 1
|
||||||
|
syn keyword haskellTypeRoles phantom representational nominal contained
|
||||||
|
syn region haskellTypeRoleBlock matchgroup=haskellTypeRoles start="type\s\+role" end="^\<" keepend
|
||||||
|
\ contains=
|
||||||
|
\ haskellType,
|
||||||
|
\ haskellTypeRoles
|
||||||
|
endif
|
||||||
|
if exists('g:haskell_enable_quantification') && g:haskell_enable_quantification == 1
|
||||||
|
syn keyword haskellForall forall
|
||||||
|
endif
|
||||||
|
if exists('g:haskell_enable_recursivedo') && g:haskell_enable_recursivedo == 1
|
||||||
|
syn keyword haskellRecursiveDo mdo rec
|
||||||
|
endif
|
||||||
|
if exists('g:haskell_enable_arrowsyntax') && g:haskell_enable_arrowsyntax == 1
|
||||||
|
syn keyword haskellArrowSyntax proc
|
||||||
|
endif
|
||||||
|
if exists('g:haskell_enable_pattern_synonyms') && g:haskell_enable_pattern_synonyms == 1
|
||||||
|
syn region haskellPatternSynonym start="^\<pattern\>" end="=\|<-" keepend
|
||||||
|
\ contains=
|
||||||
|
\ haskellPatternKeyword,
|
||||||
|
\ haskellType,
|
||||||
|
\ haskellOperators
|
||||||
|
syn keyword haskellPatternKeyword pattern contained
|
||||||
|
endif
|
||||||
|
|
||||||
" These basic lexical definitions are taken from the orignal haskell syntax
|
highlight def link haskellBottom Macro
|
||||||
" description from vim 7.3.
|
highlight def link haskellTH Boolean
|
||||||
syn match hsSpecialChar contained "\\\([0-9]\+\|o[0-7]\+\|x[0-9a-fA-F]\+\|[\"\\'&\\abfnrtv]\|^[A-Z^_\[\\\]]\)"
|
highlight def link haskellBlockKeywords Structure
|
||||||
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\)"
|
highlight def link haskellIdentifier Identifier
|
||||||
syn match hsSpecialCharError contained "\\&\|'''\+"
|
highlight def link haskellForeignKeywords Structure
|
||||||
syn region hsString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=hsSpecialChar
|
highlight def link haskellDeriving Structure
|
||||||
syn match hsCharacter "[^a-zA-Z0-9_']'\([^\\]\|\\[^']\+\|\\'\)'"lc=1 contains=hsSpecialChar,hsSpecialCharError
|
highlight def link haskellStatement Statement
|
||||||
syn match hsCharacter "^'\([^\\]\|\\[^']\+\|\\'\)'" contains=hsSpecialChar,hsSpecialCharError
|
highlight def link haskellWhere Statement
|
||||||
syn match hsNumber "\<[0-9]\+\>\|\<0[xX][0-9a-fA-F]\+\>\|\<0[oO][0-7]\+\>"
|
highlight def link haskellLet Statement
|
||||||
syn match hsFloat "\<[0-9]\+\.[0-9]\+\([eE][-+]\=[0-9]\+\)\=\>"
|
highlight def link haskellDefault Statement
|
||||||
|
highlight def link haskellConditional Conditional
|
||||||
|
highlight def link haskellNumber Number
|
||||||
|
highlight def link haskellFloat Float
|
||||||
|
highlight def link haskellSeparator Delimiter
|
||||||
|
highlight def link haskellDelimiter Delimiter
|
||||||
|
highlight def link haskellInfix PreProc
|
||||||
|
highlight def link haskellOperators Operator
|
||||||
|
highlight def link haskellQuote Operator
|
||||||
|
highlight def link haskellQuotedType Include
|
||||||
|
highlight def link haskellDot Operator
|
||||||
|
highlight def link haskellType Include
|
||||||
|
highlight def link haskellLineComment Comment
|
||||||
|
highlight def link haskellBlockComment Comment
|
||||||
|
highlight def link haskellPragma SpecialComment
|
||||||
|
highlight def link haskellString String
|
||||||
|
highlight def link haskellChar String
|
||||||
|
highlight def link haskellBacktick Operator
|
||||||
|
highlight def link haskellPreProc Macro
|
||||||
|
highlight def link haskellTodo Todo
|
||||||
|
highlight def link haskellAssocType Structure
|
||||||
|
highlight def link haskellImportBlock Delimiter
|
||||||
|
highlight def link haskellImportKeywords Structure
|
||||||
|
highlight def link haskellDeclKeyword Structure
|
||||||
|
|
||||||
" This case matches the names of types and constructors: names beginning with
|
if exists('g:haskell_enable_quantification') && g:haskell_enable_quantification == 1
|
||||||
" a capital letter. Note that this also handles the case of @M.lookup@ where
|
highlight def link haskellForall Operator
|
||||||
" M is a qualified import. There is a big negative lookbehind assertion here
|
endif
|
||||||
" so that we don't highlight import and module statements oddly.
|
if exists('g:haskell_enable_recursivedo') && g:haskell_enable_recursivedo == 1
|
||||||
syn match hsTypeName "\(^import\s.*\|^module\s.*\)\@<!\(^\|[^a-zA-Z0-9]\)\@<=[A-Z][a-zA-Z0-9_]*"
|
highlight def link haskellRecursiveDo Operator
|
||||||
" Also make unit and the empty list easy to spot - they are constructors too.
|
endif
|
||||||
syn match hsTypeName "()"
|
if exists('g:haskell_enable_arrowsyntax') && g:haskell_enable_arrowsyntax == 1
|
||||||
syn match hsTypeName "\[\]"
|
highlight def link haskellArrowSyntax Operator
|
||||||
|
endif
|
||||||
" These are keywords that are only highlighted if they are in comments.
|
if exists('g:haskell_enable_pattern_synonyms') && g:haskell_enable_pattern_synonyms == 1
|
||||||
syn keyword hsFIXME contained FIXME TODO XXX BUG NOTE
|
highlight def link haskellPatternKeyword Structure
|
||||||
|
endif
|
||||||
" Comment stuff
|
if exists('g:haskell_enable_typeroles') && g:haskell_enable_typeroles == 1
|
||||||
syn region hsPragma start='{-#' end='#-}'
|
highlight def link haskellTypeRoles Structure
|
||||||
syn region hsBlockComment start='{-' end='-}' fold contains=hsFIXME,hsBlockComment,@Spell
|
endif
|
||||||
" FIXME: haddock block comments should be able to contain hsBlockComments, but
|
if exists('g:haskell_enable_static_pointers') && g:haskell_enable_static_pointers == 1
|
||||||
" it doesn't seem to work at the moment.
|
highlight def link haskellStatic Statement
|
||||||
syn region hsHaddockComment start='{-|' end='-}' contains=hsFIXME,@Spell
|
|
||||||
syn match hsLineComment "--.*$" contains=hsFIXME,@Spell
|
|
||||||
" 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,@Spell
|
|
||||||
syn region hsHaddockComment start='-- \$\w\+' end='^\(\s*--\)\@!' contains=hsFIXME,@Spell
|
|
||||||
syn region hsHaddockComment start='-- ^' end='^\(\s*--\)\@!' contains=hsFIXME,@Spell
|
|
||||||
" Haddock sections for import lists
|
|
||||||
syn match hsHaddockSection '-- \*.*$'
|
|
||||||
" Named documentation chunks (also for import lists)
|
|
||||||
syn match hsHaddockSection '-- \$.*$'
|
|
||||||
" Treat a shebang line at the start of the file as a comment
|
|
||||||
syn match hsLineComment "\%^\#\!.*$"
|
|
||||||
|
|
||||||
|
|
||||||
" Keywords appearing in expressions, plus a few top-level keywords
|
|
||||||
syn keyword hsKeyword do mdo 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 module
|
|
||||||
" Treat 'qualified', 'as', and 'hiding' as keywords when following 'import'
|
|
||||||
syn match hsImport '\(\<import\>.*\)\@<=\<\(qualified\|as\|hiding\)\>'
|
|
||||||
|
|
||||||
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...
|
|
||||||
|
|
||||||
" We want to let '-' participate in operators, but we can't let it match
|
|
||||||
" '--', '---', etc. because it interferes with comments. The same goes for
|
|
||||||
" '#!' at the start of a file. Also, the dot (.) is an operator character,
|
|
||||||
" but not when it comes immediately after a module name.
|
|
||||||
syn match hsOperator "\(\%^\#\!\)\@!\(\(\<[A-Z]\w*\)\@64<=\.\)\@!\(--\+\([^.%\~\&\*/\$\^|@:+<!>=#!\?]\|$\)\)\@![-.%\~\&\*/\$\^|@:+<!>=#!\?]\+"
|
|
||||||
" 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*\(\<\(where\>\|let\>\)\@![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 "\(\<\(where\|let\)\s\+\([a-z][a-zA-Z0-9']*\s*,\s*\)*\)\@<=[a-z][a-zA-Z0-9']*\(\s*\(,\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>
|
|
||||||
else
|
|
||||||
command -nargs=+ HiLink hi def link <args>
|
|
||||||
endif
|
|
||||||
|
|
||||||
" CPP
|
|
||||||
HiLink hsCPP PreProc
|
|
||||||
HiLink hsCPPCond PreCondit
|
|
||||||
HiLink hsCPPInclude Include
|
|
||||||
HiLink hsCPPDefine Define
|
|
||||||
HiLink hsCPPDefined PreProc
|
|
||||||
|
|
||||||
" Comments
|
|
||||||
HiLink hsLineComment Comment
|
|
||||||
HiLink hsBlockComment Comment
|
|
||||||
HiLink hsPragma Comment
|
|
||||||
HiLink hsHaddockComment SpecialComment
|
|
||||||
HiLink hsHaddockSection SpecialComment
|
|
||||||
|
|
||||||
HiLink hsKeyword Keyword
|
|
||||||
HiLink hsConditional Conditional
|
|
||||||
HiLink hsImport Include
|
|
||||||
HiLink hsTypeDecls Keyword
|
|
||||||
|
|
||||||
HiLink hsFIXME Todo
|
|
||||||
|
|
||||||
HiLink hsOperator Operator
|
|
||||||
|
|
||||||
HiLink hsModuleQualifier StorageClass
|
|
||||||
|
|
||||||
HiLink hsFunction Function
|
|
||||||
HiLink hsTypeName Type
|
|
||||||
|
|
||||||
" Literals
|
|
||||||
HiLink hsSpecialChar SpecialChar
|
|
||||||
HiLink hsFloat Float
|
|
||||||
HiLink hsNumber Number
|
|
||||||
HiLink hsCharacter Character
|
|
||||||
HiLink hsString String
|
|
||||||
|
|
||||||
HiLink hsScary Todo
|
|
||||||
|
|
||||||
delcommand HiLink
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let b:current_syntax = "haskell"
|
let b:current_syntax = "haskell"
|
||||||
|
|||||||
Reference in New Issue
Block a user