summaryrefslogtreecommitdiff
path: root/runtime/ftplugin/ocaml.vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/ftplugin/ocaml.vim')
-rw-r--r--runtime/ftplugin/ocaml.vim227
1 files changed, 153 insertions, 74 deletions
diff --git a/runtime/ftplugin/ocaml.vim b/runtime/ftplugin/ocaml.vim
index c2bc20edc..322be55f8 100644
--- a/runtime/ftplugin/ocaml.vim
+++ b/runtime/ftplugin/ocaml.vim
@@ -1,38 +1,36 @@
-" Vim settings file
-" Language: OCaml
-" Maintainers: Mike Leary <leary@nwlink.com>
-" Markus Mottl <markus@oefai.at>
-" Stefano Zacchiroli <zack@bononia.it>
-" URL: http://www.oefai.at/~markus/vim/ftplugin/ocaml.vim
-" Last Change: 2004 Apr 12 - better .ml/.mli-switching without Python (SZ)
-" 2003 Nov 21 - match_words-patterns and .ml/.mli-switching (MM)
-" 2003 Oct 16 - re-entered variable 'did_ocaml_dtypes' (MM)
-" 2003 Oct 15 - added Stefano Zacchirolis (SZ) Python-code for
-" displaying type annotations (MM)
-
-" Only do these settings when not done yet for this buffer
-if exists("b:did_ftplugin")
- finish
-endif
-
-" Don't do other file type settings for this buffer
-let b:did_ftplugin = 1
+" Language: OCaml
+" Maintainer: David Baelde <firstname.name@ens-lyon.org>
+" Mike Leary <leary@nwlink.com>
+" Markus Mottl <markus.mottl@gmail.com>
+" Stefano Zacchiroli <zack@bononia.it>
+" URL: http://www.ocaml.info/vim/ftplugin/ocaml.vim
+" Last Change: 2005 Oct 13 - removed GPL; better matchit support (MM, SZ)
+"
+" if exists("b:did_ftplugin")
+" finish
+" endif
+let b:did_ftplugin=1
+" Error handling -- helps moving where the compiler wants you to go
+let s:cposet=&cpoptions
set cpo-=C
-
-" Error formats
setlocal efm=
- \%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
+ \%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',
+ \%DMaking\ %*\\a\ in\ %f
" Add mappings, unless the user didn't want this.
if !exists("no_plugin_maps") && !exists("no_ocaml_maps")
- " Uncommenting
+ " (un)commenting
if !hasmapto('<Plug>Comment')
nmap <buffer> <LocalLeader>c <Plug>LUncomOn
vmap <buffer> <LocalLeader>c <Plug>BUncomOn
@@ -41,46 +39,141 @@ if !exists("no_plugin_maps") && !exists("no_ocaml_maps")
endif
nnoremap <buffer> <Plug>LUncomOn mz0i(* <ESC>$A *)<ESC>`z
- nnoremap <buffer> <Plug>LUncomOff <ESC>:s/^(\* \(.*\) \*)/\1/<CR>
+ nnoremap <buffer> <Plug>LUncomOff :s/^(\* \(.*\) \*)/\1/<CR>:noh<CR>
vnoremap <buffer> <Plug>BUncomOn <ESC>:'<,'><CR>`<O<ESC>0i(*<ESC>`>o<ESC>0i*)<ESC>`<
vnoremap <buffer> <Plug>BUncomOff <ESC>:'<,'><CR>`<dd`>dd`<
if !hasmapto('<Plug>Abbrev')
- iabbrev <buffer> ASS (assert false)
+ iabbrev <buffer> ASS (assert false (* XXX *))
endif
endif
" Let % jump between structure elements (due to Issac Trotts)
-let b:mw='\<let\>:\<and\>:\(\<in\>\|;;\),'
-let b:mw=b:mw . '\<if\>:\<then\>:\<else\>,\<do\>:\<done\>,'
-let b:mw=b:mw . '\<\(object\|sig\|struct\|begin\)\>:\<end\>'
-let b:match_words=b:mw
+let b:mw = ''
+let b:mw = b:mw . ',\<let\>:\<and\>:\(\<in\>\|;;\)'
+let b:mw = b:mw . ',\<if\>:\<then\>:\<else\>'
+let b:mw = b:mw . ',\<\(for\|while\)\>:\<do\>:\<done\>,'
+let b:mw = b:mw . ',\<\(object\|sig\|struct\|begin\)\>:\<end\>'
+let b:mw = b:mw . ',\<\(match\|try\)\>:\<with\>'
+let b:match_words = b:mw
+
+let b:match_ignorecase=0
" switching between interfaces (.mli) and implementations (.ml)
if !exists("g:did_ocaml_switch")
let g:did_ocaml_switch = 1
- map ,s :call OCaml_switch(0)<CR>
- map ,S :call OCaml_switch(1)<CR>
+ map <LocalLeader>s :call OCaml_switch(0)<CR>
+ map <LocalLeader>S :call OCaml_switch(1)<CR>
fun OCaml_switch(newwin)
if (match(bufname(""), "\\.mli$") >= 0)
let fname = substitute(bufname(""), "\\.mli$", ".ml", "")
if (a:newwin == 1)
- exec "new " . fname
+ exec "new " . fname
else
- exec "arge " . fname
+ exec "arge " . fname
endif
elseif (match(bufname(""), "\\.ml$") >= 0)
let fname = bufname("") . "i"
if (a:newwin == 1)
- exec "new " . fname
+ exec "new " . fname
else
- exec "arge " . fname
+ exec "arge " . fname
endif
endif
endfun
endif
-" Vim support for OCaml 3.07 .annot files (requires Vim with python support)
+" Folding support
+
+" Get the modeline because folding depends on indentation
+let s:s = line2byte(line('.'))+col('.')-1
+if search('^\s*(\*:o\?caml:')
+ let s:modeline = getline(".")
+else
+ let s:modeline = ""
+endif
+if s:s > 0
+ exe 'goto' s:s
+endif
+
+" Get the indentation params
+let s:m = matchstr(s:modeline,'default\s*=\s*\d\+')
+if s:m != ""
+ let s:idef = matchstr(s:m,'\d\+')
+elseif exists("g:omlet_indent")
+ let s:idef = g:omlet_indent
+else
+ let s:idef = 2
+endif
+let s:m = matchstr(s:modeline,'struct\s*=\s*\d\+')
+if s:m != ""
+ let s:i = matchstr(s:m,'\d\+')
+elseif exists("g:omlet_indent_struct")
+ let s:i = g:omlet_indent_struct
+else
+ let s:i = s:idef
+endif
+
+" Set the folding method
+if exists("g:ocaml_folding")
+ setlocal foldmethod=expr
+ setlocal foldexpr=OMLetFoldLevel(v:lnum)
+endif
+
+" - Only definitions below, executed once -------------------------------------
+
+if exists("*OMLetFoldLevel")
+ finish
+endif
+
+function s:topindent(lnum)
+ let l = a:lnum
+ while l > 0
+ if getline(l) =~ '\s*\%(\<struct\>\|\<sig\>\|\<object\>\)'
+ return indent(l)
+ endif
+ let l = l-1
+ endwhile
+ return -s:i
+endfunction
+
+function OMLetFoldLevel(l)
+
+ " This is for not merging blank lines around folds to them
+ if getline(a:l) !~ '\S'
+ return -1
+ endif
+
+ " We start folds for modules, classes, and every toplevel definition
+ if getline(a:l) =~ '^\s*\%(\<val\>\|\<module\>\|\<class\>\|\<type\>\|\<method\>\|\<initializer\>\|\<inherit\>\|\<exception\>\|\<external\>\)'
+ exe 'return ">' (indent(a:l)/s:i)+1 '"'
+ endif
+
+ " Toplevel let are detected thanks to the indentation
+ if getline(a:l) =~ '^\s*let\>' && indent(a:l) == s:i+s:topindent(a:l)
+ exe 'return ">' (indent(a:l)/s:i)+1 '"'
+ endif
+
+ " We close fold on end which are associated to struct, sig or object.
+ " We use syntax information to do that.
+ if getline(a:l) =~ '^\s*end\>' && synIDattr(synID(a:l, indent(a:l)+1, 0), "name") != "ocamlKeyword"
+ return (indent(a:l)/s:i)+1
+ endif
+
+ " Folds end on ;;
+ if getline(a:l) =~ '^\s*;;'
+ exe 'return "<' (indent(a:l)/s:i)+1 '"'
+ endif
+
+ " Comments around folds aren't merged to them.
+ if synIDattr(synID(a:l, indent(a:l)+1, 0), "name") == "ocamlComment"
+ return -1
+ endif
+
+ return '='
+endfunction
+
+" Vim support for OCaml .annot files (requires Vim with python support)
"
" Executing OCamlPrintType(<mode>) function will display in the Vim bottom
" line(s) the type of an ocaml value getting it from the corresponding .annot
@@ -92,37 +185,15 @@ endif
" .annot files are parsed lazily the first time OCamlPrintType is invoked; is
" also possible to force the parsing using the OCamlParseAnnot() function.
"
-" Hitting the <F3> key will cause OCamlPrintType function to be invoked with
+" Typing ',3' will cause OCamlPrintType function to be invoked with
" the right argument depending on the current mode (visual or not).
"
-" Copyright (C) <2003> Stefano Zacchiroli <zack@bononia.it>
+" Copyright (C) <2003-2004> Stefano Zacchiroli <zack@bononia.it>
"
" Created: Wed, 01 Oct 2003 18:16:22 +0200 zack
-" LastModified: Mon, 06 Oct 2003 11:05:39 +0200 zack
-"
-" This program is free software; you can redistribute it and/or modify
-" it under the terms of the GNU General Public License as published by
-" the Free Software Foundation; either version 2 of the License, or
-" (at your option) any later version.
-"
-" This program is distributed in the hope that it will be useful,
-" but WITHOUT ANY WARRANTY; without even the implied warranty of
-" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-" GNU General Public License for more details.
-"
-" You should have received a copy of the GNU General Public License
-" along with this program; if not, write to the Free Software
-" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"
+" LastModified: Wed, 25 Aug 2004 18:28:39 +0200 zack
if !has("python")
- echo "Python support not found: OCaml .annot support disabled"
- finish
-endif
-
-if !exists("g:did_ocaml_dtypes")
- let g:did_ocaml_dtypes = 1
-else
finish
endif
@@ -166,7 +237,7 @@ class Annotations:
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.
+ 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.
@@ -182,7 +253,7 @@ class Annotations:
self.__timestamp = None # last parse action timestamp
self.__annot = {}
self.__re = re.compile(
- '^"[^"]+"\s+(\d+)\s+(\d+)\s+(\d+)\s+"[^"]+"\s+(\d+)\s+(\d+)\s+(\d+)$')
+ '^"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)\s+"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)$')
def __parse(self, fname):
try:
@@ -210,7 +281,9 @@ class Annotations:
lineno += 1
if (line == ""): raise malformed_annotations(lineno)
type = string.join(type, "\n")
- self.__annot[(line1, col1), (line2, col2)] = type
+ key = ((line1, col1), (line2, col2))
+ if not self.__annot.has_key(key):
+ self.__annot[key] = type
line = f.readline() # position line
f.close()
self.__filename = fname
@@ -285,7 +358,7 @@ def parseOCamlAnnot():
EOF
-fun OCamlPrintType(current_mode)
+fun! OCamlPrintType(current_mode)
if (a:current_mode == "visual")
python printOCamlType("visual")
else
@@ -293,9 +366,15 @@ fun OCamlPrintType(current_mode)
endif
endfun
-fun OCamlParseAnnot()
+fun! OCamlParseAnnot()
python parseOCamlAnnot()
endfun
-map <F3> :call OCamlPrintType("normal")<RETURN>
-vmap <F3> :call OCamlPrintType("visual")<RETURN>
+map <LocalLeader>t :call OCamlPrintType("normal")<RETURN>
+vmap <LocalLeader>t :call OCamlPrintType("visual")<RETURN>
+
+let &cpoptions=s:cposet
+unlet s:cposet
+
+" vim:sw=2
+