diff runtime/ftplugin/ocaml.vim @ 557:862863033fdd v7.0158

updated for version 7.0158
author vimboss
date Wed, 23 Nov 2005 21:25:05 +0000
parents 4ac1dce8dd5e
children d6a69271cb9a
line wrap: on
line diff
--- 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)
+" 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
 
-" 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
-
+" 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(
   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
+