Change ocaml provider, closes #320

This commit is contained in:
Adam Stankiewicz 2019-03-04 12:09:44 +01:00
parent b4cb58661e
commit 521220f389
19 changed files with 1329 additions and 387 deletions

View File

@ -116,7 +116,7 @@ If you need full functionality of any plugin, please use it directly with your p
- [nim](https://github.com/zah/nim.vim) (syntax, compiler, indent) - [nim](https://github.com/zah/nim.vim) (syntax, compiler, indent)
- [nix](https://github.com/LnL7/vim-nix) (syntax, indent, compiler, ftplugin) - [nix](https://github.com/LnL7/vim-nix) (syntax, indent, compiler, ftplugin)
- [objc](https://github.com/b4winckler/vim-objc) (ftplugin, syntax, indent) - [objc](https://github.com/b4winckler/vim-objc) (ftplugin, syntax, indent)
- [ocaml](https://github.com/jrk/vim-ocaml) (syntax, indent, ftplugin) - [ocaml](https://github.com/rgrinberg/vim-ocaml) (syntax, indent, compiler, ftplugin)
- [octave](https://github.com/vim-scripts/octave.vim--) (syntax) - [octave](https://github.com/vim-scripts/octave.vim--) (syntax)
- [opencl](https://github.com/petRUShka/vim-opencl) (syntax, indent, ftplugin) - [opencl](https://github.com/petRUShka/vim-opencl) (syntax, indent, ftplugin)
- [perl](https://github.com/vim-perl/vim-perl) (syntax, indent, ftplugin) - [perl](https://github.com/vim-perl/vim-perl) (syntax, indent, ftplugin)

2
build
View File

@ -224,7 +224,7 @@ PACKS="
nim:zah/nim.vim:_BASIC nim:zah/nim.vim:_BASIC
nix:LnL7/vim-nix nix:LnL7/vim-nix
objc:b4winckler/vim-objc objc:b4winckler/vim-objc
ocaml:jrk/vim-ocaml ocaml:rgrinberg/vim-ocaml
octave:vim-scripts/octave.vim-- octave:vim-scripts/octave.vim--
opencl:petRUShka/vim-opencl opencl:petRUShka/vim-opencl
perl:vim-perl/vim-perl perl:vim-perl/vim-perl

59
compiler/ocaml.vim Normal file
View File

@ -0,0 +1,59 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
" Vim Compiler File
" Compiler: ocaml
" Maintainer: Markus Mottl <markus.mottl@gmail.com>
" URL: http://www.ocaml.info/vim/compiler/ocaml.vim
" Last Change:
" 2017 Nov 26 - Improved error format (Markus Mottl)
" 2013 Aug 27 - Added a new OCaml error format (Markus Mottl)
" 2013 Jun 30 - Initial version (Marc Weber)
"
" Marc Weber's comments:
" Setting makeprg doesn't make sense, because there is ocamlc, ocamlopt,
" ocamake and whatnot. So which one to use?
"
" This error format was moved from ftplugin/ocaml.vim to this file,
" because ftplugin is the wrong file to set an error format
" and the error format itself is annoying because it joins many lines in this
" error case:
"
" Error: The implementation foo.ml does not match the interface foo.cmi:
" Modules do not match case.
"
" So having it here makes people opt-in
if exists("current_compiler")
finish
endif
let current_compiler = "ocaml"
let s:cpo_save = &cpo
set cpo&vim
CompilerSet errorformat =
\%EFile\ \"%f\"\\,\ line\ %l\\,\ characters\ %c-%*\\d:,
\%EFile\ \"%f\"\\,\ line\ %l\\,\ characters\ %c-%*\\d\ %.%#,
\%EFile\ \"%f\"\\,\ line\ %l\\,\ character\ %c:%m,
\%+EReference\ to\ unbound\ regexp\ name\ %m,
\%Eocamlyacc:\ e\ -\ line\ %l\ of\ \"%f\"\\,\ %m,
\%Wocamlyacc:\ w\ -\ %m,
\%-Zmake%.%#,
\%C%m,
\%D%*\\a[%*\\d]:\ Entering\ directory\ `%f',
\%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f',
\%D%*\\a:\ Entering\ directory\ `%f',
\%X%*\\a:\ Leaving\ directory\ `%f',
\%D%*\\a[%*\\d]:\ Entering\ directory\ '%f',
\%X%*\\a[%*\\d]:\ Leaving\ directory\ '%f',
\%D%*\\a:\ Entering\ directory\ '%f',
\%X%*\\a:\ Leaving\ directory\ '%f',
\%DEntering\ directory\ '%f',
\%XLeaving\ directory\ '%f',
\%DMaking\ %*\\a\ in\ %f
let &cpo = s:cpo_save
unlet s:cpo_save

View File

@ -771,6 +771,55 @@ au BufRead,BufNewFile *.nix set filetype=nix
augroup end augroup end
endif endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ocaml') == -1
augroup filetypedetect
" ocaml, from jbuild.vim in rgrinberg/vim-ocaml
au BufRead,BufNewFile jbuild,dune,dune-project set ft=jbuild
augroup end
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ocaml') == -1
augroup filetypedetect
" ocaml, from oasis.vim in rgrinberg/vim-ocaml
au BufNewFile,BufRead _oasis set filetype=oasis
augroup end
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ocaml') == -1
augroup filetypedetect
" ocaml, from ocaml.vim in rgrinberg/vim-ocaml
au BufRead,BufNewFile *.ml,*.mli,*.mll,*.mly,.ocamlinit,*.mlt,*.mlp,*.mlip,*.mli.cppo,*.ml.cppo set ft=ocaml
augroup end
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ocaml') == -1
augroup filetypedetect
" ocaml, from ocamlbuild_tags.vim in rgrinberg/vim-ocaml
au BufNewFile,BufRead _tags set filetype=ocamlbuild_tags
augroup end
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ocaml') == -1
augroup filetypedetect
" ocaml, from omake.vim in rgrinberg/vim-ocaml
au! BufRead,BufNewFile OMakefile,OMakeroot,*.om,OMakeroot.in set ft=omake
augroup end
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ocaml') == -1
augroup filetypedetect
" ocaml, from opam.vim in rgrinberg/vim-ocaml
au BufNewFile,BufRead opam,*.opam set filetype=opam
augroup end
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ocaml') == -1
augroup filetypedetect
" ocaml, from sexplib.vim in rgrinberg/vim-ocaml
au BufRead,BufNewFile *.sexp set ft=sexplib
augroup end
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'opencl') == -1 if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'opencl') == -1
augroup filetypedetect augroup filetypedetect
" opencl, from opencl.vim in petRUShka/vim-opencl " opencl, from opencl.vim in petRUShka/vim-opencl

16
ftplugin/jbuild.vim Normal file
View File

@ -0,0 +1,16 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin=1
set lisp
" Comment string
setl commentstring=;\ %s
setl comments=:;
setl iskeyword+=#,?,.,/

7
ftplugin/oasis.vim Normal file
View File

@ -0,0 +1,7 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
setlocal comments=:#
setlocal commentstring=#\ %s

View File

@ -6,82 +6,116 @@ endif
" Maintainer: David Baelde <firstname.name@ens-lyon.org> " Maintainer: David Baelde <firstname.name@ens-lyon.org>
" Mike Leary <leary@nwlink.com> " Mike Leary <leary@nwlink.com>
" Markus Mottl <markus.mottl@gmail.com> " Markus Mottl <markus.mottl@gmail.com>
" Pierre Vittet <pierre-vittet@pvittet.com>
" Stefano Zacchiroli <zack@bononia.it> " Stefano Zacchiroli <zack@bononia.it>
" Vincent Aravantinos <firstname.name@imag.fr>
" URL: http://www.ocaml.info/vim/ftplugin/ocaml.vim " URL: http://www.ocaml.info/vim/ftplugin/ocaml.vim
" Last Change: 2009 Nov 10 - Improved .annot support " Last Change:
" (MM for <radugrigore@gmail.com>) " 2013 Oct 27 - Added commentstring (MM)
" 2009 Nov 10 - Added support for looking up definitions " 2013 Jul 26 - load default compiler settings (MM)
" (MM for <ygrek@autistici.org>) " 2013 Jul 24 - removed superfluous efm-setting (MM)
" " 2013 Jul 22 - applied fixes supplied by Hirotaka Hamada (MM)
if exists("b:did_ftplugin") if exists("b:did_ftplugin")
finish finish
endif endif
let b:did_ftplugin=1 let b:did_ftplugin=1
" Use standard compiler settings unless user wants otherwise
if !exists("current_compiler")
:compiler ocaml
endif
" some macro
if exists('*fnameescape')
function! s:Fnameescape(s)
return fnameescape(a:s)
endfun
else
function! s:Fnameescape(s)
return escape(a:s," \t\n*?[{`$\\%#'\"|!<")
endfun
endif
" Error handling -- helps moving where the compiler wants you to go " Error handling -- helps moving where the compiler wants you to go
let s:cposet=&cpoptions let s:cposet=&cpoptions
set cpo-=C set cpo&vim
setlocal efm=
\%EFile\ \"%f\"\\,\ line\ %l\\,\ characters\ %c-%*\\d:, " Comment string
\%EFile\ \"%f\"\\,\ line\ %l\\,\ character\ %c:%m, setlocal comments=
\%+EReference\ to\ unbound\ regexp\ name\ %m, setlocal commentstring=(*%s*)
\%Eocamlyacc:\ e\ -\ line\ %l\ of\ \"%f\"\\,\ %m,
\%Wocamlyacc:\ w\ -\ %m,
\%-Zmake%.%#,
\%C%m,
\%D%*\\a[%*\\d]:\ Entering\ directory\ `%f',
\%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f',
\%D%*\\a:\ Entering\ directory\ `%f',
\%X%*\\a:\ Leaving\ directory\ `%f',
\%DMaking\ %*\\a\ in\ %f
" Add mappings, unless the user didn't want this. " Add mappings, unless the user didn't want this.
if !exists("no_plugin_maps") && !exists("no_ocaml_maps") if !exists("no_plugin_maps") && !exists("no_ocaml_maps")
" (un)commenting " (un)commenting
if !hasmapto('<Plug>Comment') if !hasmapto('<Plug>Comment')
nmap <buffer> <LocalLeader>c <Plug>LUncomOn nmap <buffer> <LocalLeader>c <Plug>LUncomOn
vmap <buffer> <LocalLeader>c <Plug>BUncomOn xmap <buffer> <LocalLeader>c <Plug>BUncomOn
nmap <buffer> <LocalLeader>C <Plug>LUncomOff nmap <buffer> <LocalLeader>C <Plug>LUncomOff
vmap <buffer> <LocalLeader>C <Plug>BUncomOff xmap <buffer> <LocalLeader>C <Plug>BUncomOff
endif endif
nnoremap <buffer> <Plug>LUncomOn mz0i(* <ESC>$A *)<ESC>`z nnoremap <buffer> <Plug>LUncomOn gI(* <End> *)<ESC>
nnoremap <buffer> <Plug>LUncomOff :s/^(\* \(.*\) \*)/\1/<CR>:noh<CR> nnoremap <buffer> <Plug>LUncomOff :s/^(\* \(.*\) \*)/\1/<CR>:noh<CR>
vnoremap <buffer> <Plug>BUncomOn <ESC>:'<,'><CR>`<O<ESC>0i(*<ESC>`>o<ESC>0i*)<ESC>`< xnoremap <buffer> <Plug>BUncomOn <ESC>:'<,'><CR>`<O<ESC>0i(*<ESC>`>o<ESC>0i*)<ESC>`<
vnoremap <buffer> <Plug>BUncomOff <ESC>:'<,'><CR>`<dd`>dd`< xnoremap <buffer> <Plug>BUncomOff <ESC>:'<,'><CR>`<dd`>dd`<
if !hasmapto('<Plug>Abbrev') nmap <buffer> <LocalLeader>s <Plug>OCamlSwitchEdit
iabbrev <buffer> ASF (assert false (* XXX *)) nmap <buffer> <LocalLeader>S <Plug>OCamlSwitchNewWin
iabbrev <buffer> ASS (assert (0=1) (* XXX *))
endif nmap <buffer> <LocalLeader>t <Plug>OCamlPrintType
xmap <buffer> <LocalLeader>t <Plug>OCamlPrintType
endif endif
" Let % jump between structure elements (due to Issac Trotts) " Let % jump between structure elements (due to Issac Trotts)
let b:mw = '' let b:mw = '\<let\>:\<and\>:\(\<in\>\|;;\)'
let b:mw = b:mw . ',\<let\>:\<and\>:\(\<in\>\|;;\)'
let b:mw = b:mw . ',\<if\>:\<then\>:\<else\>' let b:mw = b:mw . ',\<if\>:\<then\>:\<else\>'
let b:mw = b:mw . ',\<\(for\|while\)\>:\<do\>:\<done\>,' let b:mw = b:mw . ',\<\(for\|while\)\>:\<do\>:\<done\>'
let b:mw = b:mw . ',\<\(object\|sig\|struct\|begin\)\>:\<end\>' let b:mw = b:mw . ',\<\(object\|sig\|struct\|begin\)\>:\<end\>'
let b:mw = b:mw . ',\<\(match\|try\)\>:\<with\>' let b:mw = b:mw . ',\<\(match\|try\)\>:\<with\>'
let b:match_words = b:mw let b:match_words = b:mw
let b:match_ignorecase=0 let b:match_ignorecase=0
function! s:OcpGrep(bang,args) abort
let grepprg = &l:grepprg
let grepformat = &l:grepformat
let shellpipe = &shellpipe
try
let &l:grepprg = "ocp-grep -c never"
setlocal grepformat=%f:%l:%m
if &shellpipe ==# '2>&1| tee' || &shellpipe ==# '|& tee'
let &shellpipe = "| tee"
endif
execute 'grep! '.a:args
if empty(a:bang) && !empty(getqflist())
return 'cfirst'
else
return ''
endif
finally
let &l:grepprg = grepprg
let &l:grepformat = grepformat
let &shellpipe = shellpipe
endtry
endfunction
command! -bar -bang -complete=file -nargs=+ Ocpgrep exe s:OcpGrep(<q-bang>, <q-args>)
" switching between interfaces (.mli) and implementations (.ml) " switching between interfaces (.mli) and implementations (.ml)
if !exists("g:did_ocaml_switch") if !exists("g:did_ocaml_switch")
let g:did_ocaml_switch = 1 let g:did_ocaml_switch = 1
map <LocalLeader>s :call OCaml_switch(0)<CR> nnoremap <Plug>OCamlSwitchEdit :<C-u>call OCaml_switch(0)<CR>
map <LocalLeader>S :call OCaml_switch(1)<CR> nnoremap <Plug>OCamlSwitchNewWin :<C-u>call OCaml_switch(1)<CR>
fun OCaml_switch(newwin) fun OCaml_switch(newwin)
if (match(bufname(""), "\\.mli$") >= 0) if (match(bufname(""), "\\.mli$") >= 0)
let fname = substitute(bufname(""), "\\.mli$", ".ml", "") let fname = s:Fnameescape(substitute(bufname(""), "\\.mli$", ".ml", ""))
if (a:newwin == 1) if (a:newwin == 1)
exec "new " . fname exec "new " . fname
else else
exec "arge " . fname exec "arge " . fname
endif endif
elseif (match(bufname(""), "\\.ml$") >= 0) elseif (match(bufname(""), "\\.ml$") >= 0)
let fname = bufname("") . "i" let fname = s:Fnameescape(bufname("")) . "i"
if (a:newwin == 1) if (a:newwin == 1)
exec "new " . fname exec "new " . fname
else else
@ -94,15 +128,8 @@ endif
" Folding support " Folding support
" Get the modeline because folding depends on indentation " Get the modeline because folding depends on indentation
let s:s = line2byte(line('.'))+col('.')-1 let lnum = search('^\s*(\*:o\?caml:', 'n')
if search('^\s*(\*:o\?caml:') let s:modeline = lnum? getline(lnum): ""
let s:modeline = getline(".")
else
let s:modeline = ""
endif
if s:s > 0
exe 'goto' s:s
endif
" Get the indentation params " Get the indentation params
let s:m = matchstr(s:modeline,'default\s*=\s*\d\+') let s:m = matchstr(s:modeline,'default\s*=\s*\d\+')
@ -128,6 +155,10 @@ if exists("g:ocaml_folding")
setlocal foldexpr=OMLetFoldLevel(v:lnum) setlocal foldexpr=OMLetFoldLevel(v:lnum)
endif endif
let b:undo_ftplugin = "setlocal efm< foldmethod< foldexpr<"
\ . "| unlet! b:mw b:match_words b:match_ignorecase"
" - Only definitions below, executed once ------------------------------------- " - Only definitions below, executed once -------------------------------------
if exists("*OMLetFoldLevel") if exists("*OMLetFoldLevel")
@ -181,329 +212,433 @@ function OMLetFoldLevel(l)
return '=' return '='
endfunction endfunction
" Vim support for OCaml .annot files (requires Vim with python support) " Vim support for OCaml .annot files
" "
" Executing OCamlPrintType(<mode>) function will display in the Vim bottom " Last Change: 2007 Jul 17
" Maintainer: Vincent Aravantinos <vincent.aravantinos@gmail.com>
" License: public domain
"
" Originally inspired by 'ocaml-dtypes.vim' by Stefano Zacchiroli.
" The source code is quite radically different for we not use python anymore.
" However this plugin should have the exact same behaviour, that's why the
" following lines are the quite exact copy of Stefano's original plugin :
"
" <<
" Executing Ocaml_print_type(<mode>) function will display in the Vim bottom
" line(s) the type of an ocaml value getting it from the corresponding .annot " line(s) the type of an ocaml value getting it from the corresponding .annot
" file (if any). If Vim is in visual mode, <mode> should be "visual" and the " file (if any). If Vim is in visual mode, <mode> should be "visual" and the
" selected ocaml value correspond to the highlighted text, otherwise (<mode> " selected ocaml value correspond to the highlighted text, otherwise (<mode>
" can be anything else) it corresponds to the literal found at the current " can be anything else) it corresponds to the literal found at the current
" cursor position. " cursor position.
" "
" .annot files are parsed lazily the first time OCamlPrintType is invoked; is " Typing '<LocalLeader>t' (LocalLeader defaults to '\', see :h LocalLeader)
" also possible to force the parsing using the OCamlParseAnnot() function. " will cause " Ocaml_print_type function to be invoked with the right
" argument depending on the current mode (visual or not).
" >>
" "
" Typing '<LocalLeader>t' (usually ',t') will cause OCamlPrintType function " If you find something not matching this behaviour, please signal it.
" to be invoked with the right argument depending on the current mode (visual
" or not).
" "
" Copyright (C) <2003-2004> Stefano Zacchiroli <zack@bononia.it> " Differences are:
" - no need for python support
" + plus : more portable
" + minus: no more lazy parsing, it looks very fast however
" "
" Created: Wed, 01 Oct 2003 18:16:22 +0200 zack " - ocamlbuild support, ie.
" LastModified: Wed, 25 Aug 2004 18:28:39 +0200 zack " + the plugin finds the _build directory and looks for the
" corresponding file inside;
" '<LocalLeader>d' will find the definition of the name under the cursor " + if the user decides to change the name of the _build directory thanks
" and position cursor on it (only for current file) or print fully qualified name " to the '-build-dir' option of ocamlbuild, the plugin will manage in
" (for external definitions). (ocaml >= 3.11) " most cases to find it out (most cases = if the source file has a unique
" name among your whole project);
" + if ocamlbuild is not used, the usual behaviour holds; ie. the .annot
" file should be in the same directory as the source file;
" + for vim plugin programmers:
" the variable 'b:_build_dir' contains the inferred path to the build
" directory, even if this one is not named '_build'.
" "
" Additionally '<LocalLeader>t' will show whether function call is tail call " Bonus :
" or not. Current implementation requires selecting the whole function call " - latin1 accents are handled
" expression (in visual mode) to work. (ocaml >= 3.11) " - lists are handled, even on multiple lines, you don't need the visual mode
" " (the cursor must be on the first bracket)
" Copyright (C) 2009 <ygrek@autistici.org> " - parenthesized expressions, arrays, and structures (ie. '(...)', '[|...|]',
" and '{...}') are handled the same way
if !has("python") " Copied from Stefano's original plugin :
finish " <<
endif " .annot ocaml file representation
"
" File format (copied verbatim from caml-types.el)
"
" file ::= block *
" block ::= position <SP> position <LF> annotation *
" position ::= filename <SP> num <SP> num <SP> num
" annotation ::= keyword open-paren <LF> <SP> <SP> data <LF> close-paren
"
" <SP> is a space character (ASCII 0x20)
" <LF> is a line-feed character (ASCII 0x0A)
" num is a sequence of decimal digits
" filename is a string with the lexical conventions of O'Caml
" open-paren is an open parenthesis (ASCII 0x28)
" close-paren is a closed parenthesis (ASCII 0x29)
" data is any sequence of characters where <LF> is always followed by
" at least two space characters.
"
" - in each block, the two positions are respectively the start and the
" end of the range described by the block.
" - in a position, the filename is the name of the file, the first num
" is the line number, the second num is the offset of the beginning
" of the line, the third num is the offset of the position itself.
" - the char number within the line is the difference between the third
" and second nums.
"
" For the moment, the only possible keyword is \"type\"."
" >>
python << EOF
import re " 1. Finding the annotation file even if we use ocamlbuild
import os
import os.path
import string
import time
import vim
debug = False " In: two strings representing paths
" Out: one string representing the common prefix between the two paths
function! s:Find_common_path (p1,p2)
let temp = a:p2
while matchstr(a:p1,temp) == ''
let temp = substitute(temp,'/[^/]*$','','')
endwhile
return temp
endfun
class AnnExc(Exception): " After call:
def __init__(self, reason): "
self.reason = reason " Following information have been put in s:annot_file_list, using
" annot_file_name name as key:
" - annot_file_path :
" path to the .annot file corresponding to the
" source file (dealing with ocamlbuild stuff)
" - _build_path:
" path to the build directory even if this one is
" not named '_build'
" - date_of_last annot:
" Set to 0 until we load the file. It contains the
" date at which the file has been loaded.
function! s:Locate_annotation()
let annot_file_name = s:Fnameescape(expand('%:t:r')).'.annot'
if !exists ("s:annot_file_list[annot_file_name]")
silent exe 'cd' s:Fnameescape(expand('%:p:h'))
" 1st case : the annot file is in the same directory as the buffer (no ocamlbuild)
let annot_file_path = findfile(annot_file_name,'.')
if annot_file_path != ''
let annot_file_path = getcwd().'/'.annot_file_path
let _build_path = ''
else
" 2nd case : the buffer and the _build directory are in the same directory
" ..
" / \
" / \
" _build .ml
"
let _build_path = finddir('_build','.')
if _build_path != ''
let _build_path = getcwd().'/'._build_path
let annot_file_path = findfile(annot_file_name,'_build')
if annot_file_path != ''
let annot_file_path = getcwd().'/'.annot_file_path
endif
else
" 3rd case : the _build directory is in a directory higher in the file hierarchy
" (it can't be deeper by ocamlbuild requirements)
" ..
" / \
" / \
" _build ...
" \
" \
" .ml
"
let _build_path = finddir('_build',';')
if _build_path != ''
let project_path = substitute(_build_path,'/_build$','','')
let path_relative_to_project = s:Fnameescape(substitute(expand('%:p:h'),project_path.'/','',''))
let annot_file_path = findfile(annot_file_name,project_path.'/_build/'.path_relative_to_project)
else
let annot_file_path = findfile(annot_file_name,'**')
"4th case : what if the user decided to change the name of the _build directory ?
" -> we relax the constraints, it should work in most cases
if annot_file_path != ''
" 4a. we suppose the renamed _build directory is in the current directory
let _build_path = matchstr(annot_file_path,'^[^/]*')
if annot_file_path != ''
let annot_file_path = getcwd().'/'.annot_file_path
let _build_path = getcwd().'/'._build_path
endif
else
let annot_file_name = ''
"(Pierre Vittet: I have commented 4b because this was chrashing
"my vim (it produced infinite loop))
"
" 4b. anarchy : the renamed _build directory may be higher in the hierarchy
" this will work if the file for which we are looking annotations has a unique name in the whole project
" if this is not the case, it may still work, but no warranty here
"let annot_file_path = findfile(annot_file_name,'**;')
"let project_path = s:Find_common_path(annot_file_path,expand('%:p:h'))
"let _build_path = matchstr(annot_file_path,project_path.'/[^/]*')
endif
endif
endif
endif
no_annotations = AnnExc("No annotations (.annot) file found") if annot_file_path == ''
annotation_not_found = AnnExc("No type annotation found for the given text") throw 'E484: no annotation file found'
definition_not_found = AnnExc("No definition found for the given text") endif
def malformed_annotations(lineno, reason):
return AnnExc("Malformed .annot file (line = %d, reason = %s)" % (lineno,reason))
class Annotations: silent exe 'cd' '-'
""" let s:annot_file_list[annot_file_name]= [annot_file_path, _build_path, 0]
.annot ocaml file representation endif
endfun
File format (copied verbatim from caml-types.el) " This variable contain a dictionnary of list. Each element of the dictionnary
" represent an annotation system. An annotation system is a list with :
" - annotation file name as it's key
" - annotation file path as first element of the contained list
" - build path as second element of the contained list
" - annot_file_last_mod (contain the date of .annot file) as third element
let s:annot_file_list = {}
file ::= block * " 2. Finding the type information in the annotation file
block ::= position <SP> position <LF> annotation *
position ::= filename <SP> num <SP> num <SP> num
annotation ::= keyword open-paren <LF> <SP> <SP> data <LF> close-paren
<SP> is a space character (ASCII 0x20) " a. The annotation file is opened in vim as a buffer that
<LF> is a line-feed character (ASCII 0x0A) " should be (almost) invisible to the user.
num is a sequence of decimal digits
filename is a string with the lexical conventions of O'Caml
open-paren is an open parenthesis (ASCII 0x28)
close-paren is a closed parenthesis (ASCII 0x29)
data is any sequence of characters where <LF> is always followed by
at least two space characters.
- in each block, the two positions are respectively the start and the " After call:
end of the range described by the block. " The current buffer is now the one containing the .annot file.
- in a position, the filename is the name of the file, the first num " We manage to keep all this hidden to the user's eye.
is the line number, the second num is the offset of the beginning function! s:Enter_annotation_buffer(annot_file_path)
of the line, the third num is the offset of the position itself. let s:current_pos = getpos('.')
- the char number within the line is the difference between the third let s:current_hidden = &l:hidden
and second nums. set hidden
let s:current_buf = bufname('%')
if bufloaded(a:annot_file_path)
silent exe 'keepj keepalt' 'buffer' s:Fnameescape(a:annot_file_path)
else
silent exe 'keepj keepalt' 'view' s:Fnameescape(a:annot_file_path)
endif
call setpos(".", [0, 0 , 0 , 0])
endfun
Possible keywords are \"type\", \"ident\" and \"call\". " After call:
""" " The original buffer has been restored in the exact same state as before.
function! s:Exit_annotation_buffer()
silent exe 'keepj keepalt' 'buffer' s:Fnameescape(s:current_buf)
let &l:hidden = s:current_hidden
call setpos('.',s:current_pos)
endfun
def __init__(self): " After call:
self.__filename = None # last .annot parsed file " The annot file is loaded and assigned to a buffer.
self.__ml_filename = None # as above but s/.annot/.ml/ " This also handles the modification date of the .annot file, eg. after a
self.__timestamp = None # last parse action timestamp " compilation (return an updated annot_file_list).
self.__annot = {} function! s:Load_annotation(annot_file_name)
self.__refs = {} let annot = s:annot_file_list[a:annot_file_name]
self.__calls = {} let annot_file_path = annot[0]
self.__re = re.compile( let annot_file_last_mod = 0
'^"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)\s+"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)$') if exists("annot[2]")
self.__re_int_ref = re.compile('^int_ref\s+(\w+)\s"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)') let annot_file_last_mod = annot[2]
self.__re_def_full = re.compile( endif
'^def\s+(\w+)\s+"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)\s+"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)$') if bufloaded(annot_file_path) && annot_file_last_mod < getftime(annot_file_path)
self.__re_def = re.compile('^def\s+(\w+)\s"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)\s+') " if there is a more recent file
self.__re_ext_ref = re.compile('^ext_ref\s+(\S+)') let nr = bufnr(annot_file_path)
self.__re_kw = re.compile('^(\w+)\($') silent exe 'keepj keepalt' 'bunload' nr
endif
if !bufloaded(annot_file_path)
call s:Enter_annotation_buffer(annot_file_path)
setlocal nobuflisted
setlocal bufhidden=hide
setlocal noswapfile
setlocal buftype=nowrite
call s:Exit_annotation_buffer()
let annot[2] = getftime(annot_file_path)
" List updated with the new date
let s:annot_file_list[a:annot_file_name] = annot
endif
endfun
def __parse(self, fname): "b. 'search' and 'match' work to find the type information
try:
f = open(fname)
self.__annot = {} # erase internal mappings when file is reparsed
self.__refs = {}
self.__calls = {}
line = f.readline() # position line
lineno = 1
while (line != ""):
m = self.__re.search(line)
if (not m):
raise malformed_annotations(lineno,"re doesn't match")
line1 = int(m.group(1))
col1 = int(m.group(3)) - int(m.group(2))
line2 = int(m.group(4))
col2 = int(m.group(6)) - int(m.group(5))
while 1:
line = f.readline() # keyword or position line
lineno += 1
m = self.__re_kw.search(line)
if (not m):
break
desc = []
line = f.readline() # description
lineno += 1
if (line == ""): raise malformed_annotations(lineno,"no content")
while line != ")\n":
desc.append(string.strip(line))
line = f.readline()
lineno += 1
if (line == ""): raise malformed_annotations(lineno,"bad content")
desc = string.join(desc, "\n")
key = ((line1, col1), (line2, col2))
if (m.group(1) == "type"):
if not self.__annot.has_key(key):
self.__annot[key] = desc
if (m.group(1) == "call"): # region, accessible only in visual mode
if not self.__calls.has_key(key):
self.__calls[key] = desc
if (m.group(1) == "ident"):
m = self.__re_int_ref.search(desc)
if m:
line = int(m.group(2))
col = int(m.group(4)) - int(m.group(3))
name = m.group(1)
else:
line = -1
col = -1
m = self.__re_ext_ref.search(desc)
if m:
name = m.group(1)
else:
line = -2
col = -2
name = desc
if not self.__refs.has_key(key):
self.__refs[key] = (line,col,name)
f.close()
self.__filename = fname
self.__ml_filename = vim.current.buffer.name
self.__timestamp = int(time.time())
except IOError:
raise no_annotations
def parse(self): "In: - lin1,col1: postion of expression first char
annot_file = os.path.splitext(vim.current.buffer.name)[0] + ".annot" " - lin2,col2: postion of expression last char
previous_head, head, tail = '***', annot_file, '' "Out: - the pattern to be looked for to find the block
while not os.path.isfile(annot_file) and head != previous_head: " Must be called in the source buffer (use of line2byte)
previous_head = head function! s:Block_pattern(lin1,lin2,col1,col2)
head, x = os.path.split(head) let start_num1 = a:lin1
if tail == '': let start_num2 = line2byte(a:lin1) - 1
tail = x let start_num3 = start_num2 + a:col1
else: let path = '"\(\\"\|[^"]\)\+"'
os.path.join(x, tail) let start_pos = path.' '.start_num1.' '.start_num2.' '.start_num3
annot_file = os.path.join(head, '_build', tail) let end_num1 = a:lin2
self.__parse(annot_file) let end_num2 = line2byte(a:lin2) - 1
let end_num3 = end_num2 + a:col2
let end_pos = path.' '.end_num1.' '.end_num2.' '.end_num3
return '^'.start_pos.' '.end_pos."$"
" rq: the '^' here is not totally correct regarding the annot file "grammar"
" but currently the annotation file respects this, and it's a little bit faster with the '^';
" can be removed safely.
endfun
def check_file(self): "In: (the cursor position should be at the start of an annotation)
if vim.current.buffer.name == None: "Out: the type information
raise no_annotations " Must be called in the annotation buffer (use of search)
if vim.current.buffer.name != self.__ml_filename or \ function! s:Match_data()
os.stat(self.__filename).st_mtime > self.__timestamp: " rq: idem as previously, in the following, the '^' at start of patterns is not necessary
self.parse() keepj while search('^type($','ce',line(".")) == 0
keepj if search('^.\{-}($','e') == 0
throw "no_annotation"
endif
keepj if searchpair('(','',')') == 0
throw "malformed_annot_file"
endif
endwhile
let begin = line(".") + 1
keepj if searchpair('(','',')') == 0
throw "malformed_annot_file"
endif
let end = line(".") - 1
return join(getline(begin,end),"\n")
endfun
def get_type(self, (line1, col1), (line2, col2)): "In: the pattern to look for in order to match the block
if debug: "Out: the type information (calls s:Match_data)
print line1, col1, line2, col2 " Should be called in the annotation buffer
self.check_file() function! s:Extract_type_data(block_pattern, annot_file_name)
try: let annot_file_path = s:annot_file_list[a:annot_file_name][0]
try: call s:Enter_annotation_buffer(annot_file_path)
extra = self.__calls[(line1, col1), (line2, col2)] try
if extra == "tail": if search(a:block_pattern,'e') == 0
extra = " (* tail call *)" throw "no_annotation"
else: endif
extra = " (* function call *)" call cursor(line(".") + 1,1)
except KeyError: let annotation = s:Match_data()
extra = "" finally
return self.__annot[(line1, col1), (line2, col2)] + extra call s:Exit_annotation_buffer()
except KeyError: endtry
raise annotation_not_found return annotation
endfun
def get_ident(self, (line1, col1), (line2, col2)): "c. link this stuff with what the user wants
if debug: " ie. get the expression selected/under the cursor
print line1, col1, line2, col2
self.check_file()
try:
(line,col,name) = self.__refs[(line1, col1), (line2, col2)]
if line >= 0 and col >= 0:
vim.command("normal "+str(line)+"gg"+str(col+1)+"|")
#current.window.cursor = (line,col)
if line == -2:
m = self.__re_def_full.search(name)
if m:
l2 = int(m.group(5))
c2 = int(m.group(7)) - int(m.group(6))
name = m.group(1)
else:
m = self.__re_def.search(name)
if m:
l2 = int(m.group(2))
c2 = int(m.group(4)) - int(m.group(3))
name = m.group(1)
else:
l2 = -1
if False and l2 >= 0:
# select region
if c2 == 0 and l2 > 0:
vim.command("normal v"+str(l2-1)+"gg"+"$")
else:
vim.command("normal v"+str(l2)+"gg"+str(c2)+"|")
return name
except KeyError:
raise definition_not_found
word_char_RE = re.compile("^[\w.]$") let s:ocaml_word_char = '\w|[À-ÿ]|'''
# TODO this function should recognize ocaml literals, actually it's just an "In: the current mode (eg. "visual", "normal", etc.)
# hack that recognize continuous sequences of word_char_RE above "Out: the borders of the expression we are looking for the type
def findBoundaries(line, col): function! s:Match_borders(mode)
""" given a cursor position (as returned by vim.current.window.cursor) if a:mode == "visual"
return two integers identify the beggining and end column of the word at let cur = getpos(".")
cursor position, if any. If no word is at the cursor position return the normal `<
column cursor position twice """ let col1 = col(".")
left, right = col, col let lin1 = line(".")
line = line - 1 # mismatch vim/python line indexes normal `>
(begin_col, end_col) = (0, len(vim.current.buffer[line]) - 1) let col2 = col(".")
try: let lin2 = line(".")
while word_char_RE.search(vim.current.buffer[line][left - 1]): call cursor(cur[1],cur[2])
left = left - 1 return [lin1,lin2,col1-1,col2]
except IndexError: else
pass let cursor_line = line(".")
try: let cursor_col = col(".")
while word_char_RE.search(vim.current.buffer[line][right + 1]): let line = getline('.')
right = right + 1 if line[cursor_col-1:cursor_col] == '[|'
except IndexError: let [lin2,col2] = searchpairpos('\[|','','|\]','n')
pass return [cursor_line,lin2,cursor_col-1,col2+1]
return (left, right) elseif line[cursor_col-1] == '['
let [lin2,col2] = searchpairpos('\[','','\]','n')
return [cursor_line,lin2,cursor_col-1,col2]
elseif line[cursor_col-1] == '('
let [lin2,col2] = searchpairpos('(','',')','n')
return [cursor_line,lin2,cursor_col-1,col2]
elseif line[cursor_col-1] == '{'
let [lin2,col2] = searchpairpos('{','','}','n')
return [cursor_line,lin2,cursor_col-1,col2]
else
let [lin1,col1] = searchpos('\v%('.s:ocaml_word_char.'|\.)*','ncb')
let [lin2,col2] = searchpos('\v%('.s:ocaml_word_char.'|\.)*','nce')
if col1 == 0 || col2 == 0
throw "no_expression"
endif
return [cursor_line,cursor_line,col1-1,col2]
endif
endif
endfun
annot = Annotations() # global annotation object "In: the current mode (eg. "visual", "normal", etc.)
"Out: the type information (calls s:Extract_type_data)
function! s:Get_type(mode, annot_file_name)
let [lin1,lin2,col1,col2] = s:Match_borders(a:mode)
return s:Extract_type_data(s:Block_pattern(lin1,lin2,col1,col2), a:annot_file_name)
endfun
def get_marks(mode): "In: A string destined to be printed in the 'echo buffer'. It has line
if mode == "visual": # visual mode: lookup highlighted text "break and 2 space at each line beginning.
(line1, col1) = vim.current.buffer.mark("<") "Out: A string destined to be yanked, without space and double space.
(line2, col2) = vim.current.buffer.mark(">") function s:unformat_ocaml_type(res)
else: # any other mode: lookup word at cursor position "Remove end of line.
(line, col) = vim.current.window.cursor let res = substitute (a:res, "\n", "", "g" )
(col1, col2) = findBoundaries(line, col) "remove double space
(line1, line2) = (line, line) let res =substitute(res , " ", " ", "g")
begin_mark = (line1, col1) "remove space at begining of string.
end_mark = (line2, col2 + 1) let res = substitute(res, "^ *", "", "g")
return (begin_mark,end_mark) return res
endfunction
def printOCamlType(mode): "d. main
try: "In: the current mode (eg. "visual", "normal", etc.)
(begin_mark,end_mark) = get_marks(mode) "After call: the type information is displayed
print annot.get_type(begin_mark, end_mark) if !exists("*Ocaml_get_type")
except AnnExc, exc: function Ocaml_get_type(mode)
print exc.reason let annot_file_name = s:Fnameescape(expand('%:t:r')).'.annot'
call s:Locate_annotation()
call s:Load_annotation(annot_file_name)
let res = s:Get_type(a:mode, annot_file_name)
" Copy result in the unnamed buffer
let @" = s:unformat_ocaml_type(res)
return res
endfun
endif
def gotoOCamlDefinition(mode): if !exists("*Ocaml_get_type_or_not")
try: function Ocaml_get_type_or_not(mode)
(begin_mark,end_mark) = get_marks(mode) let t=reltime()
print annot.get_ident(begin_mark, end_mark) try
except AnnExc, exc: let res = Ocaml_get_type(a:mode)
print exc.reason return res
catch
return ""
endtry
endfun
endif
def parseOCamlAnnot(): if !exists("*Ocaml_print_type")
try: function Ocaml_print_type(mode)
annot.parse() if expand("%:e") == "mli"
except AnnExc, exc: echohl ErrorMsg | echo "No annotations for interface (.mli) files" | echohl None
print exc.reason return
endif
try
echo Ocaml_get_type(a:mode)
catch /E484:/
echohl ErrorMsg | echo "No type annotations (.annot) file found" | echohl None
catch /no_expression/
echohl ErrorMsg | echo "No expression found under the cursor" | echohl None
catch /no_annotation/
echohl ErrorMsg | echo "No type annotation found for the given text" | echohl None
catch /malformed_annot_file/
echohl ErrorMsg | echo "Malformed .annot file" | echohl None
endtry
endfun
endif
EOF " Maps
nnoremap <silent> <Plug>OCamlPrintType :<C-U>call Ocaml_print_type("normal")<CR>
fun! OCamlPrintType(current_mode) xnoremap <silent> <Plug>OCamlPrintType :<C-U>call Ocaml_print_type("visual")<CR>`<
if (a:current_mode == "visual")
python printOCamlType("visual")
else
python printOCamlType("normal")
endif
endfun
fun! OCamlGotoDefinition(current_mode)
if (a:current_mode == "visual")
python gotoOCamlDefinition("visual")
else
python gotoOCamlDefinition("normal")
endif
endfun
fun! OCamlParseAnnot()
python parseOCamlAnnot()
endfun
map <LocalLeader>t :call OCamlPrintType("normal")<RETURN>
vmap <LocalLeader>t :call OCamlPrintType("visual")<RETURN>
map <LocalLeader>d :call OCamlGotoDefinition("normal")<RETURN>
vmap <LocalLeader>d :call OCamlGotoDefinition("visual")<RETURN>
let &cpoptions=s:cposet let &cpoptions=s:cposet
unlet s:cposet unlet s:cposet
" vim:sw=2 " vim:sw=2 fdm=indent

View File

@ -0,0 +1,7 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
setlocal comments=:#
setlocal commentstring=#\ %s

28
ftplugin/omake.vim Normal file
View File

@ -0,0 +1,28 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
" Vim filetype plugin file
" Language: OMake
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
" Set 'formatoptions' to break comment lines but not other lines,
" and insert the comment leader when hitting <CR> or using "o".
setlocal fo-=t fo+=croql
" Set 'comments' to format dashed lists in comments
setlocal com=sO:#\ -,mO:#\ \ ,b:#
" Set 'commentstring' to put the marker after a #.
setlocal commentstring=#\ %s
" always use spaces and not tabs
setlocal expandtab
" Including files.
let &l:include = '^\s*include'

18
ftplugin/sexplib.vim Normal file
View File

@ -0,0 +1,18 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
" Language: Sexplib
" Maintainer: Markus Mottl <markus.mottl@gmail.com>
" URL: http://www.ocaml.info/vim/ftplugin/sexplib.vim
" Last Change:
" 2017 Apr 12 - First version (MM)
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin=1
" Comment string
setl commentstring=;\ %s
setl comments=:;

View File

@ -8,9 +8,13 @@ endif
" Mike Leary <leary@nwlink.com> " Mike Leary <leary@nwlink.com>
" Markus Mottl <markus.mottl@gmail.com> " Markus Mottl <markus.mottl@gmail.com>
" URL: http://www.ocaml.info/vim/indent/ocaml.vim " URL: http://www.ocaml.info/vim/indent/ocaml.vim
" Last Change: 2010 Sep 04 - Added an indentation improvement by Mark Weber " Last Change: 2013 Jun 29
" 2005 Jun 25 - Fixed multiple bugs due to 'else\nreturn ind' working " 2005 Jun 25 - Fixed multiple bugs due to 'else\nreturn ind' working
" 2005 May 09 - Added an option to not indent OCaml-indents specially (MM) " 2005 May 09 - Added an option to not indent OCaml-indents specially (MM)
" 2013 June - commented textwidth (Marc Weber)
"
" Marc Weber's comment: This file may contain a lot of (very custom) stuff
" which eventually should be moved somewhere else ..
" Only load this indent file when no other was loaded. " Only load this indent file when no other was loaded.
if exists("b:did_indent") if exists("b:did_indent")
@ -23,7 +27,9 @@ setlocal indentexpr=GetOCamlIndent()
setlocal indentkeys+=0=and,0=class,0=constraint,0=done,0=else,0=end,0=exception,0=external,0=if,0=in,0=include,0=inherit,0=initializer,0=let,0=method,0=open,0=then,0=type,0=val,0=with,0;;,0>\],0\|\],0>},0\|,0},0\],0) setlocal indentkeys+=0=and,0=class,0=constraint,0=done,0=else,0=end,0=exception,0=external,0=if,0=in,0=include,0=inherit,0=initializer,0=let,0=method,0=open,0=then,0=type,0=val,0=with,0;;,0>\],0\|\],0>},0\|,0},0\],0)
setlocal nolisp setlocal nolisp
setlocal nosmartindent setlocal nosmartindent
setlocal textwidth=80
" At least Marc Weber and Markus Mottl do not like this:
" setlocal textwidth=80
" Comment formatting " Comment formatting
if !exists("no_ocaml_comments") if !exists("no_ocaml_comments")

118
indent/omake.vim Normal file
View File

@ -0,0 +1,118 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
" Vim indent file
" Language: OMakefile
if exists("b:did_indent")
finish
endif
let b:did_indent = 1
setlocal indentexpr=GetMakeIndent()
setlocal indentkeys=!^F,o,O,<:>,=else,=endif
setlocal nosmartindent
if exists("*GetMakeIndent")
finish
endif
let s:comment_rx = '^\s*#'
let s:rule_rx = '^[^ \t#:][^#:]*:\{1,2}\%([^=:]\|$\)'
let s:continued_rule_rx = '^[^#:]*:\{1,2}\%([^=:]\|$\)'
let s:continuation_rx = '\\$'
let s:assignment_rx = '^\s*\h\w*\s*[+?]\==\s*\zs.*\\$'
let s:folded_assignment_rx = '^\s*\h\w*\s*[+?]\=='
" TODO: This needs to be a lot more restrictive in what it matches.
let s:just_inserted_rule_rx = '^\s*[^#:]\+:\{1,2}$'
let s:conditional_directive_rx = '^ *\%(ifn\=\%(eq\|def\)\|else\)\>'
let s:end_conditional_directive_rx = '^\s*\%(else\|endif\)\>'
function s:remove_continuation(line)
return substitute(a:line, s:continuation_rx, "", "")
endfunction
function GetMakeIndent()
" TODO: Should this perhaps be v:lnum -1?
" let prev_lnum = prevnonblank(v:lnum - 1)
let prev_lnum = v:lnum - 1
if prev_lnum == 0
return 0
endif
let prev_line = getline(prev_lnum)
let prev_prev_lnum = prev_lnum - 1
let prev_prev_line = prev_prev_lnum != 0 ? getline(prev_prev_lnum) : ""
" TODO: Deal with comments. In comments, continuations aren't interesting.
if prev_line =~ s:continuation_rx
if prev_prev_line =~ s:continuation_rx
return indent(prev_lnum)
elseif prev_line =~ s:rule_rx
return &sw
elseif prev_line =~ s:assignment_rx
call cursor(prev_lnum, 1)
if search(s:assignment_rx, 'W') != 0
return virtcol('.') - 1
else
" TODO: ?
return &sw
endif
else
" TODO: OK, this might be a continued shell command, so perhaps indent
" properly here? Leave this out for now, but in the next release this
" should be using indent/sh.vim somehow.
"if prev_line =~ '^\t' " s:rule_command_rx
" if prev_line =~ '^\s\+[@-]\%(if\)\>'
" return indent(prev_lnum) + 2
" endif
"endif
return indent(prev_lnum) + &sw
endif
elseif prev_prev_line =~ s:continuation_rx
let folded_line = s:remove_continuation(prev_prev_line) . ' ' . s:remove_continuation(prev_line)
let lnum = prev_prev_lnum - 1
let line = getline(lnum)
while line =~ s:continuation_rx
let folded_line = s:remove_continuation(line) . ' ' . folded_line
let lnum -= 1
let line = getline(lnum)
endwhile
let folded_lnum = lnum + 1
if folded_line =~ s:rule_rx
if getline(v:lnum) =~ s:rule_rx
return 0
else
return &ts
endif
else
" elseif folded_line =~ s:folded_assignment_rx
if getline(v:lnum) =~ s:rule_rx
return 0
else
return indent(folded_lnum)
endif
" else
" " TODO: ?
" return indent(prev_lnum)
endif
elseif prev_line =~ s:rule_rx
if getline(v:lnum) =~ s:rule_rx
return 0
else
return &ts
endif
elseif prev_line =~ s:conditional_directive_rx
return &sw
else
let line = getline(v:lnum)
if line =~ s:just_inserted_rule_rx
return 0
elseif line =~ s:end_conditional_directive_rx
return v:lnum - 1 == 0 ? 0 : indent(v:lnum - 1) - &sw
else
return v:lnum - 1 == 0 ? 0 : indent(v:lnum - 1)
endif
endif
endfunction

40
syntax/jbuild.vim Normal file
View File

@ -0,0 +1,40 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
if exists("b:current_syntax")
finish
endif
set syntax=lisp
syn case match
" The syn-iskeyword setting lacks #,? from the iskeyword setting here.
" Clearing it avoids maintaining keyword characters in multiple places.
syn iskeyword clear
syn keyword lispDecl jbuild_version library executable executables rule ocamllex ocamlyacc menhir alias install
syn keyword lispKey name public_name synopsis modules libraries wrapped
syn keyword lispKey preprocess preprocessor_deps optional c_names cxx_names
syn keyword lispKey install_c_headers modes no_dynlink self_build_stubs_archive
syn keyword lispKey ppx_runtime_libraries virtual_deps js_of_ocaml link_flags
syn keyword lispKey javascript_files flags ocamlc_flags ocamlopt_flags pps staged_pps
syn keyword lispKey library_flags c_flags c_library_flags kind package action
syn keyword lispKey deps targets locks fallback
syn keyword lispKey inline_tests tests names
syn keyword lispAtom true false
syn keyword lispFunc cat chdir copy# diff? echo run setenv
syn keyword lispFunc ignore-stdout ignore-stderr ignore-outputs
syn keyword lispFunc with-stdout-to with-stderr-to with-outputs-to
syn keyword lispFunc write-file system bash
syn cluster lispBaseListCluster add=jbuildVar
syn match jbuildVar '\${[@<^]}' containedin=lispSymbol
syn match jbuildVar '\${\k\+\(:\k\+\)\?}' containedin=lispSymbol
hi def link jbuildVar Identifier
let b:current_syntax = "jbuild"

99
syntax/oasis.vim Normal file
View File

@ -0,0 +1,99 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
if exists("b:current_syntax")
finish
endif
syn keyword oasisSpecialFeatures ocamlbuild_more_args compiled_setup_ml pure_interface stdfiles_markdown
syn keyword oasisTodo FIXME NOTE NOTES TODO XXX contained
syn match oasisComment "#.*$" contains=oasisTodo,@Spell
syn keyword oasisPlugin META DevFiles StdFiles
syn match oasisOperator "(\|)\|>=\|,\|&&"
syn match oasisVariable "$\w\+"
syn match oasisVersion "\<\d\+\(.\(\d\)\+\)\+\>"
syn region oasisString start=/"/ end=/"/
syntax keyword oasisSection Document Executable Flag Library Document Test SourceRepository
syntax match oasisKey "OASISFormat:"
syntax match oasisKey "OCamlVersion:"
syntax match oasisKey "Copyrights:"
syntax match oasisKey "Maintainers:"
syntax match oasisKey "XStdFilesAUTHORS:"
syntax match oasisKey "XStdFilesREADME:"
syntax match oasisKey "FindlibVersion:"
syntax match oasisKey "Name:"
syntax match oasisKey "Version:"
syntax match oasisKey "Synopsis:"
syntax match oasisKey "Authors:"
syntax match oasisKey "Homepage:"
syntax match oasisKey "License:"
syntax match oasisKey "LicenseFile:"
syntax match oasisKey "BuildTools:"
syntax match oasisKey "Plugins:"
syntax match oasisKey "Description:"
syntax match oasisKey "AlphaFeatures:"
syntax match oasisKey "BetaFeatures:"
syntax match oasisKey "PostConfCommand:"
syntax match oasisKey "FilesAB:"
syntax match oasisKey2 "\c\s\+Index\$\=:"
syntax match oasisKey2 "\c\s\+Format\$\=:"
syntax match oasisKey2 "\c\s\+TestTools\$\=:"
syntax match oasisKey2 "\c\s\+Description\$\=:"
syntax match oasisKey2 "\c\s\+Pack\$\=:"
syntax match oasisKey2 "\c\s\+Default\$\=:"
syntax match oasisKey2 "\c\s\+Path\$\=:"
syntax match oasisKey2 "\c\s\+Findlibname\$\=:"
syntax match oasisKey2 "\c\s\+Modules\$\=:"
syntax match oasisKey2 "\c\s\+BuildDepends\$\=:"
syntax match oasisKey2 "\c\s\+MainIs\$\=:"
syntax match oasisKey2 "\c\s\+Install\$\=:"
syntax match oasisKey2 "\c\s\+Custom\$\=:"
syntax match oasisKey2 "\c\s\+InternalModules\$\=:"
syntax match oasisKey2 "\c\s\+Build\$\=:"
syntax match oasisKey2 "\c\s\+CompiledObject\$\=:"
syntax match oasisKey2 "\c\s\+Title\$\=:"
syntax match oasisKey2 "\c\s\+Type\$\=:"
syntax match oasisKey2 "\c\s\+FindlibParent\$\=:"
syntax match oasisKey2 "\c\s\+Command\$\=:"
syntax match oasisKey2 "\c\s\+Run\$\=:"
syntax match oasisKey2 "\c\s\+WorkingDirectory\$\=:"
syntax match oasisKey2 "\c\s\+BuildTools+:"
syntax match oasisKey2 "\c\s\+XMETARequires\$\=:"
syntax match oasisKey2 "\c\s\+XMETADescription\$\=:"
syntax match oasisKey2 "\c\s\+XMETAType\$\=:"
syntax match oasisKey2 "\c\s\+XMETAExtraLines\$\=:"
syntax match oasisKey2 "\c\s\+XMETAEnable\$\=:"
syntax match oasisKey2 "\c\s\+InstallDir\$\=:"
syntax match oasisKey2 "\c\s\+XOCamlbuildLibraries\$\=:"
syntax match oasisKey2 "\c\s\+XOCamlbuildPath\$\=:"
syntax match oasisKey2 "\c\s\+XOCamlbuildExtraArgs\$\=:"
syntax match oasisKey2 "\c\s\+XOCamlbuildModules\$\=:"
syntax match oasisKey2 "\c\s\+Type\$\=:"
syntax match oasisKey2 "\c\s\+Location\$\=:"
syntax match oasisKey2 "\c\s\+Branch\$\=:"
syntax match oasisKey2 "\c\s\+Browser\$\=:"
syntax match oasisKey2 "\c\s\+CSources\$\=:"
syntax match oasisKey2 "\c\s\+CCLib\$\=:"
syntax match oasisKey2 "\c\s\+CCOpt\$\=:"
syntax match oasisKey2 "\c\s\+ByteOpt\$\=:"
syntax match oasisKey2 "\c\s\+NativeOpt\$\=:"
syntax match oasisKey2 "\c\s\+Tag\$\=:"
highlight link oasisSection Keyword
highlight link oasisKey Identifier
highlight link oasisKey2 Function
highlight link oasisTodo Todo
highlight link oasisComment Comment
highlight link oasisPlugin Type
highlight link oasisSpecialFeatures Exception
highlight link oasisOperator Operator
highlight link oasisVariable Statement
highlight link oasisString String
highlight link oasisVersion Number
let b:current_syntax = "oasis"

View File

@ -9,9 +9,14 @@ endif
" Karl-Heinz Sylla <Karl-Heinz.Sylla@gmd.de> " Karl-Heinz Sylla <Karl-Heinz.Sylla@gmd.de>
" Issac Trotts <ijtrotts@ucdavis.edu> " Issac Trotts <ijtrotts@ucdavis.edu>
" URL: http://www.ocaml.info/vim/syntax/ocaml.vim " URL: http://www.ocaml.info/vim/syntax/ocaml.vim
" Last Change: 2010 Oct 11 - Added highlighting of lnot (MM, thanks to Erick Matsen) " Last Change:
" 2010 Sep 03 - Fixed escaping bug (MM, thanks to Florent Monnier) " 2018 Nov 08 - Improved highlighting of operators (Maëlan)
" 2010 Aug 07 - Fixed module type bug (MM) " 2018 Apr 22 - Improved support for PPX (Andrey Popp)
" 2018 Mar 16 - Remove raise, lnot and not from keywords (Étienne Millon, "copy")
" 2017 Apr 11 - Improved matching of negative numbers (MM)
" 2016 Mar 11 - Improved support for quoted strings (Glen Mével)
" 2015 Aug 13 - Allow apostrophes in identifiers (Jonathan Chan, Einar Lielmanis)
" 2015 Jun 17 - Added new "nonrec" keyword (MM)
" A minor patch was applied to the official version so that object/end " A minor patch was applied to the official version so that object/end
" can be distinguished from begin/end, which is used for indentation, " can be distinguished from begin/end, which is used for indentation,
@ -25,6 +30,9 @@ elseif exists("b:current_syntax") && b:current_syntax == "ocaml"
finish finish
endif endif
" ' can be used in OCaml identifiers
setlocal iskeyword+='
" OCaml is case sensitive. " OCaml is case sensitive.
syn case match syn case match
@ -32,10 +40,10 @@ syn case match
syn match ocamlMethod "#" syn match ocamlMethod "#"
" Script headers highlighted like comments " Script headers highlighted like comments
syn match ocamlComment "^#!.*" syn match ocamlComment "^#!.*" contains=@Spell
" Scripting directives " Scripting directives
syn match ocamlScript "^#\<\(quit\|labels\|warnings\|directory\|cd\|load\|use\|install_printer\|remove_printer\|require\|thread\|trace\|untrace\|untrace_all\|print_depth\|print_length\|camlp4o\)\>" syn match ocamlScript "^#\<\(quit\|labels\|warnings\|warn_error\|directory\|remove_directory\|cd\|load\|load_rec\|use\|mod_use\|install_printer\|remove_printer\|require\|list\|ppx\|principal\|predicates\|rectypes\|thread\|trace\|untrace\|untrace_all\|print_depth\|print_length\|camlp4o\|camlp4r\|topfind_log\|topfind_verbose\)\>"
" lowercase identifier - the standard way to match " lowercase identifier - the standard way to match
syn match ocamlLCIdentifier /\<\(\l\|_\)\(\w\|'\)*\>/ syn match ocamlLCIdentifier /\<\(\l\|_\)\(\w\|'\)*\>/
@ -73,7 +81,7 @@ syn cluster ocamlAllErrs contains=ocamlBraceErr,ocamlBrackErr,ocamlParenErr,oca
syn cluster ocamlAENoParen contains=ocamlBraceErr,ocamlBrackErr,ocamlCommentErr,ocamlCountErr,ocamlDoErr,ocamlDoneErr,ocamlEndErr,ocamlThenErr syn cluster ocamlAENoParen contains=ocamlBraceErr,ocamlBrackErr,ocamlCommentErr,ocamlCountErr,ocamlDoErr,ocamlDoneErr,ocamlEndErr,ocamlThenErr
syn cluster ocamlContained contains=ocamlTodo,ocamlPreDef,ocamlModParam,ocamlModParam1,ocamlPreMPRestr,ocamlMPRestr,ocamlMPRestr1,ocamlMPRestr2,ocamlMPRestr3,ocamlModRHS,ocamlFuncWith,ocamlFuncStruct,ocamlModTypeRestr,ocamlModTRWith,ocamlWith,ocamlWithRest,ocamlModType,ocamlFullMod,ocamlVal syn cluster ocamlContained contains=ocamlTodo,ocamlPreDef,ocamlModParam,ocamlModParam1,ocamlMPRestr,ocamlMPRestr1,ocamlMPRestr2,ocamlMPRestr3,ocamlModRHS,ocamlFuncWith,ocamlFuncStruct,ocamlModTypeRestr,ocamlModTRWith,ocamlWith,ocamlWithRest,ocamlModType,ocamlFullMod,ocamlVal
" Enclosing delimiters " Enclosing delimiters
@ -84,7 +92,7 @@ syn region ocamlEncl transparent matchgroup=ocamlKeyword start="\[|" matchgrou
" Comments " Comments
syn region ocamlComment start="(\*" end="\*)" contains=ocamlComment,ocamlTodo syn region ocamlComment start="(\*" end="\*)" contains=@Spell,ocamlComment,ocamlTodo
syn keyword ocamlTodo contained TODO FIXME XXX NOTE syn keyword ocamlTodo contained TODO FIXME XXX NOTE
@ -110,60 +118,66 @@ endif
" "if" " "if"
syn region ocamlNone matchgroup=ocamlKeyword start="\<if\>" matchgroup=ocamlKeyword end="\<then\>" contains=ALLBUT,@ocamlContained,ocamlThenErr syn region ocamlNone matchgroup=ocamlKeyword start="\<if\>" matchgroup=ocamlKeyword end="\<then\>" contains=ALLBUT,@ocamlContained,ocamlThenErr
"" PPX nodes
syn match ocamlPpxIdentifier /\(\[@\{1,3\}\)\@<=\w\+\(\.\w\+\)*/
syn region ocamlPpx matchgroup=ocamlPpxEncl start="\[@\{1,3\}" contains=TOP end="\]"
"" Modules "" Modules
" "sig" " "sig"
syn region ocamlSig matchgroup=ocamlModule start="\<sig\>" matchgroup=ocamlModule end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr,ocamlModule syn region ocamlSig matchgroup=ocamlSigEncl start="\<sig\>" matchgroup=ocamlSigEncl end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr,ocamlModule
syn region ocamlModSpec matchgroup=ocamlKeyword start="\<module\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\>" contained contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlModTRWith,ocamlMPRestr syn region ocamlModSpec matchgroup=ocamlKeyword start="\<module\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\>" contained contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlModTRWith,ocamlMPRestr
" "open" " "open"
syn region ocamlNone matchgroup=ocamlKeyword start="\<open\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\(\.\u\(\w\|'\)*\)*\>" contains=@ocamlAllErrs,ocamlComment syn region ocamlNone matchgroup=ocamlKeyword start="\<open\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\( *\. *\u\(\w\|'\)*\)*\>" contains=@ocamlAllErrs,ocamlComment
" "include" " "include"
syn match ocamlKeyword "\<include\>" skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod syn match ocamlKeyword "\<include\>" skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod
" "module" - somewhat complicated stuff ;-) " "module" - somewhat complicated stuff ;-)
syn region ocamlModule matchgroup=ocamlKeyword start="\<module\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\>" contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlPreDef syn region ocamlModule matchgroup=ocamlKeyword start="\<module\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\>" contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlPreDef
syn region ocamlPreDef start="."me=e-1 matchgroup=ocamlKeyword end="\l\|=\|)"me=e-1 contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam,ocamlModTypeRestr,ocamlModTRWith nextgroup=ocamlModPreRHS syn region ocamlPreDef start="."me=e-1 matchgroup=ocamlKeyword end="\l\|=\|)"me=e-1 contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam,ocamlGenMod,ocamlModTypeRestr,ocamlModTRWith nextgroup=ocamlModPreRHS
syn region ocamlModParam start="([^*]" end=")" contained contains=@ocamlAENoParen,ocamlModParam1,ocamlVal syn region ocamlModParam start="([^*]" end=")" contained contains=ocamlGenMod,ocamlModParam1,ocamlSig,ocamlVal
syn match ocamlModParam1 "\<\u\(\w\|'\)*\>" contained skipwhite skipempty nextgroup=ocamlPreMPRestr syn match ocamlModParam1 "\<\u\(\w\|'\)*\>" contained skipwhite skipempty
syn match ocamlGenMod "()" contained skipwhite skipempty
syn region ocamlPreMPRestr start="."me=e-1 end=")"me=e-1 contained contains=@ocamlAllErrs,ocamlComment,ocamlMPRestr,ocamlModTypeRestr
syn region ocamlMPRestr start=":" end="."me=e-1 contained contains=@ocamlComment skipwhite skipempty nextgroup=ocamlMPRestr1,ocamlMPRestr2,ocamlMPRestr3 syn region ocamlMPRestr start=":" end="."me=e-1 contained contains=@ocamlComment skipwhite skipempty nextgroup=ocamlMPRestr1,ocamlMPRestr2,ocamlMPRestr3
syn region ocamlMPRestr1 matchgroup=ocamlModule start="\ssig\s\=" matchgroup=ocamlModule end="\<end\>" contained contains=ALLBUT,@ocamlContained,ocamlEndErr,ocamlModule syn region ocamlMPRestr1 matchgroup=ocamlSigEncl start="\ssig\s\=" matchgroup=ocamlSigEncl end="\<end\>" contained contains=ALLBUT,@ocamlContained,ocamlEndErr,ocamlModule
syn region ocamlMPRestr2 start="\sfunctor\(\s\|(\)\="me=e-1 matchgroup=ocamlKeyword end="->" contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam skipwhite skipempty nextgroup=ocamlFuncWith,ocamlMPRestr2 syn region ocamlMPRestr2 start="\sfunctor\(\s\|(\)\="me=e-1 matchgroup=ocamlKeyword end="->" contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam,ocamlGenMod skipwhite skipempty nextgroup=ocamlFuncWith,ocamlMPRestr2
syn match ocamlMPRestr3 "\w\(\w\|'\)*\(\.\w\(\w\|'\)*\)*" contained syn match ocamlMPRestr3 "\w\(\w\|'\)*\( *\. *\w\(\w\|'\)*\)*" contained
syn match ocamlModPreRHS "=" contained skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod syn match ocamlModPreRHS "=" contained skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod
syn keyword ocamlKeyword val syn keyword ocamlKeyword val
syn region ocamlVal matchgroup=ocamlKeyword start="\<val\>" matchgroup=ocamlLCIdentifier end="\<\l\(\w\|'\)*\>" contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlMPRestr syn region ocamlVal matchgroup=ocamlKeyword start="\<val\>" matchgroup=ocamlLCIdentifier end="\<\l\(\w\|'\)*\>" contains=@ocamlAllErrs,ocamlComment,ocamlFullMod skipwhite skipempty nextgroup=ocamlMPRestr
syn region ocamlModRHS start="." end=".\w\|([^*]"me=e-2 contained contains=ocamlComment skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod syn region ocamlModRHS start="." end=". *\w\|([^*]"me=e-2 contained contains=ocamlComment skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod
syn match ocamlFullMod "\<\u\(\w\|'\)*\(\.\u\(\w\|'\)*\)*" contained skipwhite skipempty nextgroup=ocamlFuncWith syn match ocamlFullMod "\<\u\(\w\|'\)*\( *\. *\u\(\w\|'\)*\)*" contained skipwhite skipempty nextgroup=ocamlFuncWith
syn region ocamlFuncWith start="([^*]"me=e-1 end=")" contained contains=ocamlComment,ocamlWith,ocamlFuncStruct skipwhite skipempty nextgroup=ocamlFuncWith syn region ocamlFuncWith start="([^*)]"me=e-1 end=")" contained contains=ocamlComment,ocamlWith,ocamlFuncStruct skipwhite skipempty nextgroup=ocamlFuncWith
syn region ocamlFuncStruct matchgroup=ocamlModule start="[^a-zA-Z]struct\>"hs=s+1 matchgroup=ocamlModule end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr syn region ocamlFuncStruct matchgroup=ocamlStructEncl start="[^a-zA-Z]struct\>"hs=s+1 matchgroup=ocamlStructEncl end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
syn match ocamlModTypeRestr "\<\w\(\w\|'\)*\(\.\w\(\w\|'\)*\)*\>" contained syn match ocamlModTypeRestr "\<\w\(\w\|'\)*\( *\. *\w\(\w\|'\)*\)*\>" contained
syn region ocamlModTRWith start=":\s*("hs=s+1 end=")" contained contains=@ocamlAENoParen,ocamlWith syn region ocamlModTRWith start=":\s*("hs=s+1 end=")" contained contains=@ocamlAENoParen,ocamlWith
syn match ocamlWith "\<\(\u\(\w\|'\)*\.\)*\w\(\w\|'\)*\>" contained skipwhite skipempty nextgroup=ocamlWithRest syn match ocamlWith "\<\(\u\(\w\|'\)* *\. *\)*\w\(\w\|'\)*\>" contained skipwhite skipempty nextgroup=ocamlWithRest
syn region ocamlWithRest start="[^)]" end=")"me=e-1 contained contains=ALLBUT,@ocamlContained syn region ocamlWithRest start="[^)]" end=")"me=e-1 contained contains=ALLBUT,@ocamlContained
" "struct" " "struct"
syn region ocamlStruct matchgroup=ocamlModule start="\<\(module\s\+\)\=struct\>" matchgroup=ocamlModule end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr syn region ocamlStruct matchgroup=ocamlStructEncl start="\<\(module\s\+\)\=struct\>" matchgroup=ocamlStructEncl end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
" "module type" " "module type"
syn region ocamlKeyword start="\<module\>\s*\<type\>\(\s*\<of\>\)\=" matchgroup=ocamlModule end="\<\w\(\w\|'\)*\>" contains=ocamlComment skipwhite skipempty nextgroup=ocamlMTDef syn region ocamlKeyword start="\<module\>\s*\<type\>\(\s*\<of\>\)\=" matchgroup=ocamlModule end="\<\w\(\w\|'\)*\>" contains=ocamlComment skipwhite skipempty nextgroup=ocamlMTDef
syn match ocamlMTDef "=\s*\w\(\w\|'\)*\>"hs=s+1,me=s syn match ocamlMTDef "=\s*\w\(\w\|'\)*\>"hs=s+1,me=s+1 skipwhite skipempty nextgroup=ocamlFullMod
" Quoted strings
syn region ocamlString matchgroup=ocamlQuotedStringDelim start="{\z\([a-z_]*\)|" end="|\z1}" contains=@Spell
syn keyword ocamlKeyword and as assert class syn keyword ocamlKeyword and as assert class
syn keyword ocamlKeyword constraint else syn keyword ocamlKeyword constraint else
syn keyword ocamlKeyword exception external fun syn keyword ocamlKeyword exception external fun
syn keyword ocamlKeyword in inherit initializer syn keyword ocamlKeyword in inherit initializer
syn keyword ocamlKeyword land lazy let match syn keyword ocamlKeyword lazy let match
syn keyword ocamlKeyword method mutable new of syn keyword ocamlKeyword method mutable new nonrec of
syn keyword ocamlKeyword parser private raise rec syn keyword ocamlKeyword parser private rec
syn keyword ocamlKeyword try type syn keyword ocamlKeyword try type
syn keyword ocamlKeyword virtual when while with syn keyword ocamlKeyword virtual when while with
@ -173,15 +187,12 @@ if exists("ocaml_revised")
else else
syn keyword ocamlKeyword function syn keyword ocamlKeyword function
syn keyword ocamlBoolean true false syn keyword ocamlBoolean true false
syn match ocamlKeyChar "!"
endif endif
syn keyword ocamlType array bool char exn float format format4 syn keyword ocamlType array bool char exn float format format4
syn keyword ocamlType int int32 int64 lazy_t list nativeint option syn keyword ocamlType int int32 int64 lazy_t list nativeint option
syn keyword ocamlType string unit syn keyword ocamlType string unit
syn keyword ocamlOperator asr lnot lor lsl lsr lxor mod not
syn match ocamlConstructor "(\s*)" syn match ocamlConstructor "(\s*)"
syn match ocamlConstructor "\[\s*\]" syn match ocamlConstructor "\[\s*\]"
syn match ocamlConstructor "\[|\s*>|]" syn match ocamlConstructor "\[|\s*>|]"
@ -192,47 +203,69 @@ syn match ocamlConstructor "\u\(\w\|'\)*\>"
syn match ocamlConstructor "`\w\(\w\|'\)*\>" syn match ocamlConstructor "`\w\(\w\|'\)*\>"
" Module prefix " Module prefix
syn match ocamlModPath "\u\(\w\|'\)*\."he=e-1 syn match ocamlModPath "\u\(\w\|'\)* *\."he=e-1
syn match ocamlCharacter "'\\\d\d\d'\|'\\[\'ntbr]'\|'.'" syn match ocamlCharacter "'\\\d\d\d'\|'\\[\'ntbr]'\|'.'"
syn match ocamlCharacter "'\\x\x\x'" syn match ocamlCharacter "'\\x\x\x'"
syn match ocamlCharErr "'\\\d\d'\|'\\\d'" syn match ocamlCharErr "'\\\d\d'\|'\\\d'"
syn match ocamlCharErr "'\\[^\'ntbr]'" syn match ocamlCharErr "'\\[^\'ntbr]'"
syn region ocamlString start=+"+ skip=+\\\\\|\\"+ end=+"+ syn region ocamlString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@Spell
syn match ocamlFunDef "->"
syn match ocamlRefAssign ":="
syn match ocamlTopStop ";;" syn match ocamlTopStop ";;"
syn match ocamlOperator "\^"
syn match ocamlOperator "::"
syn match ocamlOperator "&&"
syn match ocamlOperator "<"
syn match ocamlOperator ">"
syn match ocamlAnyVar "\<_\>" syn match ocamlAnyVar "\<_\>"
syn match ocamlKeyChar "|[^\]]"me=e-1 syn match ocamlKeyChar "|[^\]]"me=e-1
syn match ocamlKeyChar ";" syn match ocamlKeyChar ";"
syn match ocamlKeyChar "\~" syn match ocamlKeyChar "\~"
syn match ocamlKeyChar "?" syn match ocamlKeyChar "?"
syn match ocamlKeyChar "\*"
syn match ocamlKeyChar "="
"" Operators
" The grammar of operators is found there:
" https://caml.inria.fr/pub/docs/manual-ocaml/names.html#operator-name
" https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#s:ext-ops
" https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#s:index-operators
" =, *, < and > are both operator names and keywords, we let the user choose how
" to display them (has to be declared before regular infix operators):
syn match ocamlEqual "="
syn match ocamlStar "*"
syn match ocamlAngle "<"
syn match ocamlAngle ">"
" Custom indexing operators:
syn match ocamlIndexingOp "\.[~?!:|&$%=>@^/*+-][~?!.:|&$%<=>@^*/+-]*\(()\|\[]\|{}\)\(<-\)\?"
" Extension operators (has to be declared before regular infix operators):
syn match ocamlExtensionOp "#[#~?!.:|&$%<=>@^*/+-]\+"
" Infix and prefix operators:
syn match ocamlPrefixOp "![~?!.:|&$%<=>@^*/+-]*"
syn match ocamlPrefixOp "[~?][~?!.:|&$%<=>@^*/+-]\+"
syn match ocamlInfixOp "[&$%@^/+-][~?!.:|&$%<=>@^*/+-]*"
syn match ocamlInfixOp "[|<=>*][~?!.:|&$%<=>@^*/+-]\+"
syn match ocamlInfixOp "#[~?!.:|&$%<=>@^*/+-]\+#\@!"
syn match ocamlInfixOp "!=[~?!.:|&$%<=>@^*/+-]\@!"
syn keyword ocamlInfixOpKeyword asr land lor lsl lsr lxor mod or
" := is technically an infix operator, but we may want to show it as a keyword
" (somewhat analogously to = for letbindings and <- for assignations):
syn match ocamlRefAssign ":="
" :: is technically not an operator, but we may want to show it as such:
syn match ocamlCons "::"
" -> and <- are keywords, not operators (but can appear in longer operators):
syn match ocamlArrow "->[~?!.:|&$%<=>@^*/+-]\@!"
if exists("ocaml_revised") if exists("ocaml_revised")
syn match ocamlErr "<-" syn match ocamlErr "<-[~?!.:|&$%<=>@^*/+-]\@!"
else else
syn match ocamlOperator "<-" syn match ocamlKeyChar "<-[~?!.:|&$%<=>@^*/+-]\@!"
endif endif
syn match ocamlNumber "\<-\=\d\(_\|\d\)*[l|L|n]\?\>" syn match ocamlNumber "-\=\<\d\(_\|\d\)*[l|L|n]\?\>"
syn match ocamlNumber "\<-\=0[x|X]\(\x\|_\)\+[l|L|n]\?\>" syn match ocamlNumber "-\=\<0[x|X]\(\x\|_\)\+[l|L|n]\?\>"
syn match ocamlNumber "\<-\=0[o|O]\(\o\|_\)\+[l|L|n]\?\>" syn match ocamlNumber "-\=\<0[o|O]\(\o\|_\)\+[l|L|n]\?\>"
syn match ocamlNumber "\<-\=0[b|B]\([01]\|_\)\+[l|L|n]\?\>" syn match ocamlNumber "-\=\<0[b|B]\([01]\|_\)\+[l|L|n]\?\>"
syn match ocamlFloat "\<-\=\d\(_\|\d\)*\.\?\(_\|\d\)*\([eE][-+]\=\d\(_\|\d\)*\)\=\>" syn match ocamlFloat "-\=\<\d\(_\|\d\)*\.\?\(_\|\d\)*\([eE][-+]\=\d\(_\|\d\)*\)\=\>"
" Labels " Labels
syn match ocamlLabel "\~\(\l\|_\)\(\w\|'\)*"lc=1 syn match ocamlLabel "\~\(\l\|_\)\(\w\|'\)*"lc=1
syn match ocamlLabel "?\(\l\|_\)\(\w\|'\)*"lc=1 syn match ocamlLabel "?\(\l\|_\)\(\w\|'\)*"lc=1
syn region ocamlLabel transparent matchgroup=ocamlLabel start="?(\(\l\|_\)\(\w\|'\)*"lc=2 end=")"me=e-1 contains=ALLBUT,@ocamlContained,ocamlParenErr syn region ocamlLabel transparent matchgroup=ocamlLabel start="[~?](\(\l\|_\)\(\w\|'\)*"lc=2 end=")"me=e-1 contains=ALLBUT,@ocamlContained,ocamlParenErr
" Synchronization " Synchronization
@ -290,12 +323,17 @@ if version >= 508 || !exists("did_ocaml_syntax_inits")
HiLink ocamlObject Include HiLink ocamlObject Include
HiLink ocamlModule Include HiLink ocamlModule Include
HiLink ocamlModParam1 Include HiLink ocamlModParam1 Include
HiLink ocamlGenMod Include
HiLink ocamlModType Include HiLink ocamlModType Include
HiLink ocamlMPRestr3 Include HiLink ocamlMPRestr3 Include
HiLink ocamlFullMod Include HiLink ocamlFullMod Include
HiLink ocamlFuncWith Include
HiLink ocamlModParam Include
HiLink ocamlModTypeRestr Include HiLink ocamlModTypeRestr Include
HiLink ocamlWith Include HiLink ocamlWith Include
HiLink ocamlMTDef Include HiLink ocamlMTDef Include
HiLink ocamlSigEncl ocamlModule
HiLink ocamlStructEncl ocamlModule
HiLink ocamlScript Include HiLink ocamlScript Include
@ -306,18 +344,35 @@ if version >= 508 || !exists("did_ocaml_syntax_inits")
HiLink ocamlMPRestr2 Keyword HiLink ocamlMPRestr2 Keyword
HiLink ocamlKeyword Keyword HiLink ocamlKeyword Keyword
HiLink ocamlMethod Include HiLink ocamlMethod Include
HiLink ocamlFunDef Keyword HiLink ocamlArrow Keyword
HiLink ocamlRefAssign Keyword
HiLink ocamlKeyChar Keyword HiLink ocamlKeyChar Keyword
HiLink ocamlAnyVar Keyword HiLink ocamlAnyVar Keyword
HiLink ocamlTopStop Keyword HiLink ocamlTopStop Keyword
HiLink ocamlOperator Keyword
HiLink ocamlRefAssign ocamlKeyChar
HiLink ocamlEqual ocamlKeyChar
HiLink ocamlStar ocamlInfixOp
HiLink ocamlAngle ocamlInfixOp
HiLink ocamlCons ocamlInfixOp
HiLink ocamlPrefixOp ocamlOperator
HiLink ocamlInfixOp ocamlOperator
HiLink ocamlExtensionOp ocamlOperator
HiLink ocamlIndexingOp ocamlOperator
if exists("ocaml_highlight_operators")
HiLink ocamlInfixOpKeyword ocamlOperator
HiLink ocamlOperator Operator
else
HiLink ocamlInfixOpKeyword Keyword
endif
HiLink ocamlBoolean Boolean HiLink ocamlBoolean Boolean
HiLink ocamlCharacter Character HiLink ocamlCharacter Character
HiLink ocamlNumber Number HiLink ocamlNumber Number
HiLink ocamlFloat Float HiLink ocamlFloat Float
HiLink ocamlString String HiLink ocamlString String
HiLink ocamlQuotedStringDelim Identifier
HiLink ocamlLabel Identifier HiLink ocamlLabel Identifier
@ -327,6 +382,8 @@ if version >= 508 || !exists("did_ocaml_syntax_inits")
HiLink ocamlEncl Keyword HiLink ocamlEncl Keyword
HiLink ocamlPpxEncl ocamlEncl
delcommand HiLink delcommand HiLink
endif endif

View File

@ -0,0 +1,44 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
if exists("b:current_syntax")
finish
endif
syn keyword ocamlbuild_tagsOperator ",\|:\|-\|(\|)"
syn keyword ocamlbuild_tagsTodo FIXME NOTE NOTES TODO XXX contained
syn keyword ocamlbuild_tagsKeyword1 true annot bin_annot traverse not_hygienic custom package include debug principal strict_sequence strict_formats short_paths or no_alias_deps safe_string warn syntax thread
syn match ocamlbuild_tagsKeyword2 "for-pack"
syn match ocamlbuild_tagsOr "or" contained
syn region ocamlbuild_tagsString start=/"/ end=/"/
syn region ocamlbuild_tagsPattern start=/</ end=/>/ contains=ocamlbuild_tagsGlob,ocamlbuild_tagsAlt,ocamlbuild_tagsOr
syn match ocamlbuild_tagsComment "#.*$" contains=ocamlbuild_tagsTodo,@Spell
syn match ocamlbuild_tagsGlob "\*\|\*\*\|\/" contained
syn match ocamlbuild_tagsComma ","
syn region ocamlbuild_tagsAlt start=/{/ end=/}/ contains=ocamlbuild_tagsComma contained
syn match ocamlbuild_tagsFindlibPkg "\vpkg_[a-zA-Z_.]+"
hi! link ocamlbuild_tagsKeyword1 Keyword
hi! link ocamlbuild_tagsKeyword2 Keyword
hi! link ocamlbuild_tagsOr Keyword
hi! link ocamlbuild_tagsString String
hi! link ocamlbuild_tagsPattern Statement
hi! link ocamlbuild_tagsGlob Operator
hi! link ocamlbuild_tagsOperator Operator
hi! link ocamlbuild_tagsComma Operator
hi! link ocamlbuild_tagsComment Comment
hi link ocamlbuild_tagsFindlibPkg Identifier
let b:current_syntax = "ocamlbuild_tags"

132
syntax/omake.vim Normal file
View File

@ -0,0 +1,132 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
" Vim syntax file
" Language: OMakefile
" For version 5.x: Clear all syntax items
" For version 6.x: Quit when a syntax file was already loaded
if exists("b:current_syntax")
finish
endif
syn match omakeRuleOption +:\(optional\|exists\|effects\|scanner\|value\):+
syn match omakeKeyword "^\s*\(case\|catch\|class\|declare\|default\|do\|elseif\|else\|export\|extends\|finally\|if\|import\|include\|match\|open\|raise\|return\|section\|switch\|try\|value\|when\|while\)\s*"
syn match omakeOperator "\[\]\|=\|+="
" some special characters
syn match makeSpecial "^\s*[@+-]\+"
syn match makeNextLine "\\\n\s*"
" some directives
syn match makeInclude "^ *[-s]\=include"
syn match makeStatement "^ *vpath"
syn match makeExport "^ *\(export\|unexport\)\>"
syn match makeSection "^\s*section\s*$"
syn match makeOverride "^ *override"
hi link makeOverride makeStatement
hi link makeExport makeStatement
hi link makeSection makeStatement
" Koehler: catch unmatched define/endef keywords. endef only matches it is by itself on a line
syn region makeDefine start="^\s*define\s" end="^\s*endef\s*$" contains=makeStatement,makeIdent,makeDefine
" Microsoft Makefile specials
syn case ignore
syn match makeInclude "^! *include"
syn case match
" identifiers
syn region makeIdent start="\$(" skip="\\)\|\\\\" end=")" contains=makeStatement,makeIdent,makeSString,makeDString,omakeDoubleQuoteString,omakeSingleQuoteString
syn region makeIdent start="\${" skip="\\}\|\\\\" end="}" contains=makeStatement,makeIdent,makeSString,makeDString,omakeDoubleQuoteString,omakeSingleQuoteString
syn match makeIdent "\$\$\w*"
syn match makeIdent "\$[^({]"
syn match makeIdent "^ *\a\w*\s*[:+?!*]="me=e-2
syn match makeIdent "^ *\a\w*\s*="me=e-1
syn match makeIdent "%"
" Makefile.in variables
syn match makeConfig "@[A-Za-z0-9_]\+@"
" make targets
" syn match makeSpecTarget "^\.\(STATIC\|PHONY\|DEFAULT\|MEMO\|INCLUDE\|ORDER\|SCANNER\|SUBDIRS\|BUILD_BEGIN\|BUILD_FAILURE\|BUILD_SUCCESS\|BUILDORDER\)\>"
syn match makeImplicit "^\.[A-Za-z0-9_./\t -]\+\s*:[^=]"me=e-2 nextgroup=makeSource
syn match makeImplicit "^\.[A-Za-z0-9_./\t -]\+\s*:$"me=e-1 nextgroup=makeSource
syn region makeTarget transparent matchgroup=makeTarget start="^[A-Za-z0-9_./$()%-][A-Za-z0-9_./\t $()%-]*:\{1,2}[^:=]"rs=e-1 end=";"re=e-1,me=e-1 end="[^\\]$" keepend contains=makeIdent,makeSpecTarget,makeNextLine skipnl nextGroup=makeCommands
syn match makeTarget "^[A-Za-z0-9_./$()%*@-][A-Za-z0-9_./\t $()%*@-]*::\=\s*$" contains=makeIdent,makeSpecTarget skipnl nextgroup=makeCommands
syn region makeSpecTarget transparent matchgroup=makeSpecTarget start="^\s*\.\(STATIC\|PHONY\|DEFAULT\|MEMO\|INCLUDE\|ORDER\|SCANNER\|SUBDIRS\|BUILD_BEGIN\|BUILD_FAILURE\|BUILD_SUCCESS\|BUILDORDER\)\>\s*:\{1,2}[^:=]"rs=e-1 end="[^\\]$" keepend contains=makeIdent,makeSpecTarget,makeNextLine skipnl nextGroup=makeCommands
syn match makeSpecTarget "^\s*\.\(STATIC\|PHONY\|DEFAULT\|MEMO\|INCLUDE\|ORDER\|SCANNER\|SUBDIRS\|BUILD_BEGIN\|BUILD_FAILURE\|BUILD_SUCCESS\|BUILDORDER\)\>\s*::\=\s*$" contains=makeIdent skipnl nextgroup=makeCommands
syn region makeCommands start=";"hs=s+1 start="^\t" end="^[^\t#]"me=e-1,re=e-1 end="^$" contained contains=makeCmdNextLine,makeSpecial,makeComment,makeIdent,makeDefine,makeDString,makeSString
syn match makeCmdNextLine "\\\n."he=e-1 contained
" Statements / Functions (GNU make)
syn match makeStatement contained "(\(subst\|abspath\|addprefix\|addsuffix\|and\|basename\|call\|dir\|error\|eval\|filter-out\|filter\|findstring\|firstword\|flavor\|foreach\|if\|info\|join\|lastword\|notdir\|or\|origin\|patsubst\|realpath\|shell\|sort\|strip\|suffix\|value\|warning\|wildcard\|word\|wordlist\|words\)\>"ms=s+1
" Comment
syn region makeComment start="#" end="^$" end="[^\\]$" keepend contains=@Spell,makeTodo
syn match makeComment "#$" contains=@Spell
syn keyword makeTodo TODO FIXME XXX contained
" match escaped quotes and any other escaped character
" except for $, as a backslash in front of a $ does
" not make it a standard character, but instead it will
" still act as the beginning of a variable
" The escaped char is not highlighted currently
syn match makeEscapedChar "\\[^$]"
syn match omakeCallExpr "\$(\h[a-zA-Z0-9_-]*\s\+[^(]\+)" contains=@omakeExpr
syn match omakeVar "\$(\h[a-zA-Z0-9_-]*)"
syn cluster omakeExpr contains=omakeVar,omakeCallExpr
syn region omakeSingleQuoteString start=+\$'+ skip=+[^']+ end=+'+
syn region omakeDoubleQuoteString start=+\$"+ skip=+\\.+ end=+"+
syn region omakeDoubleQuoteString start=+\$"""+ skip=+\\.+ end=+"""+
syn region makeDString start=+\(\\\)\@<!"+ skip=+\\.+ end=+"+ contains=makeIdent
syn region makeSString start=+\(\\\)\@<!'+ skip=+\\.+ end=+'+ contains=makeIdent
syn region makeBString start=+\(\\\)\@<!`+ skip=+\\.+ end=+`+ contains=makeIdent,makeSString,makeDString,makeNextLine
" Syncing
syn sync minlines=20 maxlines=200
" Sync on Make command block region: When searching backwards hits a line that
" can't be a command or a comment, use makeCommands if it looks like a target,
" NONE otherwise.
syn sync match makeCommandSync groupthere NONE "^[^\t#]"
syn sync match makeCommandSync groupthere makeCommands "^[A-Za-z0-9_./$()%-][A-Za-z0-9_./\t $()%-]*:\{1,2}[^:=]"
syn sync match makeCommandSync groupthere makeCommands "^[A-Za-z0-9_./$()%-][A-Za-z0-9_./\t $()%-]*:\{1,2}\s*$"
hi def link makeNextLine makeSpecial
hi def link makeCmdNextLine makeSpecial
hi def link makeSpecTarget Statement
hi def link makeCommands Number
hi def link makeImplicit Function
hi def link makeTarget Function
hi def link makeInclude Include
hi def link makeStatement Statement
hi def link makeIdent Identifier
hi def link makeSpecial Special
hi def link makeComment Comment
hi def link makeDString String
hi def link makeSString String
hi def link makeBString Function
hi def link makeError Error
hi def link makeTodo Todo
hi def link makeDefine Define
hi def link makeConfig PreCondit
hi def link omakeOperator Operator
hi def link omakeDoubleQuoteString String
hi def link omakeSingleQuoteString String
hi def link omakeVar Identifier
hi def link omakeCallExpr Statement
hi def link omakeKeyword Keyword
hi def link omakeRuleOption Type
let b:current_syntax = "omake"
" vim: ts=8

35
syntax/opam.vim Normal file
View File

@ -0,0 +1,35 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
if exists("b:current_syntax")
finish
endif
" need %{vars}%
" env: [[CAML_LD_LIBRARY_PATH = "%{lib}%/stublibs"]]
syn keyword opamKeyword1 remove depends depopts conflicts env packages patches version maintainer tags license homepage authors doc install author available name depexts substs synopsis description
syn match opamKeyword2 "\v(bug-reports|post-messages|ocaml-version|opam-version|dev-repo|build-test|build-doc|build)"
syn keyword opamTodo FIXME NOTE NOTES TODO XXX contained
syn match opamComment "#.*$" contains=opamTodo,@Spell
syn match opamOperator ">\|<\|=\|<=\|>="
syn region opamInterpolate start=/%{/ end=/}%/ contained
syn region opamString start=/"/ end=/"/ contains=opamInterpolate
syn region opamSeq start=/\[/ end=/\]/ contains=ALLBUT,opamKeyword1,opamKeyword2
syn region opamExp start=/{/ end=/}/ contains=ALLBUT,opamKeyword1,opamKeyword2
hi link opamKeyword1 Keyword
hi link opamKeyword2 Keyword
hi link opamString String
hi link opamExp Function
hi link opamSeq Statement
hi link opamOperator Operator
hi link opamComment Comment
hi link opamInterpolate Identifier
let b:current_syntax = "opam"
" vim: ts=2 sw=2

92
syntax/sexplib.vim Normal file
View File

@ -0,0 +1,92 @@
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'ocaml') != -1
finish
endif
" Vim syntax file
" Language: S-expressions as used in Sexplib
" Filenames: *.sexp
" Maintainers: Markus Mottl <markus.mottl@gmail.com>
" URL: http://www.ocaml.info/vim/syntax/sexplib.vim
" Last Change: 2017 Apr 11 - Improved matching of negative numbers (MM)
" 2012 Jun 20 - Fixed a block comment highlighting bug (MM)
" 2012 Apr 24 - Added support for new comment styles (MM)
" For version 5.x: Clear all syntax items
" For version 6.x: Quit when a syntax file was already loaded
if version < 600
syntax clear
elseif exists("b:current_syntax") && b:current_syntax == "sexplib"
finish
endif
" Sexplib is case sensitive.
syn case match
" Comments
syn keyword sexplibTodo contained TODO FIXME XXX NOTE
syn region sexplibBlockComment matchgroup=sexplibComment start="#|" matchgroup=sexplibComment end="|#" contains=ALLBUT,sexplibQuotedAtom,sexplibUnquotedAtom,sexplibEncl,sexplibComment
syn match sexplibSexpComment "#;" skipwhite skipempty nextgroup=sexplibQuotedAtomComment,sexplibUnquotedAtomComment,sexplibListComment,sexplibComment
syn region sexplibQuotedAtomComment start=+"+ skip=+\\\\\|\\"+ end=+"+ contained
syn match sexplibUnquotedAtomComment /\([^;()" \t#|]\|#[^;()" \t|]\||[^;()" \t#]\)[^;()" \t]*/ contained
syn region sexplibListComment matchgroup=sexplibComment start="(" matchgroup=sexplibComment end=")" contained contains=ALLBUT,sexplibEncl,sexplibString,sexplibQuotedAtom,sexplibUnquotedAtom,sexplibTodo,sexplibNumber,sexplibFloat
syn match sexplibComment ";.*" contains=sexplibTodo
" Atoms
syn match sexplibUnquotedAtom /\([^;()" \t#|]\|#[^;()" \t|]\||[^;()" \t#]\)[^;()" \t]*/
syn region sexplibQuotedAtom start=+"+ skip=+\\\\\|\\"+ end=+"+
syn match sexplibNumber "-\=\<\d\(_\|\d\)*[l|L|n]\?\>"
syn match sexplibNumber "-\=\<0[x|X]\(\x\|_\)\+[l|L|n]\?\>"
syn match sexplibNumber "-\=\<0[o|O]\(\o\|_\)\+[l|L|n]\?\>"
syn match sexplibNumber "-\=\<0[b|B]\([01]\|_\)\+[l|L|n]\?\>"
syn match sexplibFloat "-\=\<\d\(_\|\d\)*\.\?\(_\|\d\)*\([eE][-+]\=\d\(_\|\d\)*\)\=\>"
" Lists
syn region sexplibEncl transparent matchgroup=sexplibEncl start="(" matchgroup=sexplibEncl end=")" contains=ALLBUT,sexplibParenErr
" Errors
syn match sexplibUnquotedAtomErr /\([^;()" \t#|]\|#[^;()" \t|]\||[^;()" \t#]\)[^;()" \t]*\(#|\||#\)[^;()" \t]*/
syn match sexplibParenErr ")"
" Synchronization
syn sync minlines=50
syn sync maxlines=500
" Define the default highlighting.
" For version 5.7 and earlier: only when not done already
" For version 5.8 and later: only when an item doesn't have highlighting yet
if version >= 508 || !exists("did_sexplib_syntax_inits")
if version < 508
let did_sexplib_syntax_inits = 1
command -nargs=+ HiLink hi link <args>
else
command -nargs=+ HiLink hi def link <args>
endif
HiLink sexplibParenErr Error
HiLink sexplibUnquotedAtomErr Error
HiLink sexplibComment Comment
HiLink sexplibSexpComment Comment
HiLink sexplibQuotedAtomComment Include
HiLink sexplibUnquotedAtomComment Comment
HiLink sexplibBlockComment Comment
HiLink sexplibListComment Comment
HiLink sexplibBoolean Boolean
HiLink sexplibCharacter Character
HiLink sexplibNumber Number
HiLink sexplibFloat Float
HiLink sexplibUnquotedAtom Identifier
HiLink sexplibEncl Identifier
HiLink sexplibQuotedAtom Keyword
HiLink sexplibTodo Todo
HiLink sexplibEncl Keyword
delcommand HiLink
endif
let b:current_syntax = "sexplib"
" vim: ts=8