Commits

camlspotter committed 24f80b6 Merge

merge

  • Participants
  • Parent commits 9dfc2f2, 114b713

Comments (0)

Files changed (26)

 name.cmo : name.cmi
 name.cmx : name.cmi
 ocamlspot.cmo : utils.cmi typeexpand.cmi spotfile.cmi spoteval.cmi \
-    spotconfig.cmi spot.cmi ext.cmo command.cmi cmt.cmi
+    spotconfig.cmi spot.cmi filepath.cmi ext.cmo compdir.cmi command.cmi \
+    cmt.cmi
 ocamlspot.cmx : utils.cmx typeexpand.cmx spotfile.cmx spoteval.cmx \
-    spotconfig.cmx spot.cmx ext.cmx command.cmx cmt.cmx
+    spotconfig.cmx spot.cmx filepath.cmx ext.cmx compdir.cmx command.cmx \
+    cmt.cmx
 pathreparse.cmo : utils.cmi spot.cmi locident.cmi ext.cmo pathreparse.cmi
 pathreparse.cmx : utils.cmx spot.cmx locident.cmx ext.cmx pathreparse.cmi
-spot.cmo : spot.cmi
-spot.cmx : spot.cmi
+record.cmo :
+record.cmx :
+spot.cmo : utils.cmi treeset.cmi ext.cmo cmt.cmi checksum.cmo spot.cmi
+spot.cmx : utils.cmx treeset.cmx ext.cmx cmt.cmx checksum.cmx spot.cmi
 spotconfig.cmo : utils.cmi spot.cmi ext.cmo spotconfig.cmi
 spotconfig.cmx : utils.cmx spot.cmx ext.cmx spotconfig.cmi
 spotconfig_intf.cmo : spot.cmi ext.cmo
 .*~$
 ocamlspot$
 tests/ocamlbuild/_build
+tests/a\.out$
+tests/ocamlbuild/hello\.native$
 
 
+
-- this will be filled with bugs YOU find and report to jun.furuse@gmail.com.
+Please report bugs to the following:
+https://bitbucket.org/camlspotter/ocamlspot/issues?status=new&status=open
+4.01.0.2.2.0 (not yet)
+--------------
+
+- Big clean up of cmt file traversal, by removing quick hacks introduced in porting OCamlSpot from OCaml 3 to OCaml 4.
+- Bug fixes of build dir (_build and those specified by .ocamlspot) support
+
+4.01.0.2.1.3
+--------------
+
+- Quick port to OCaml 4.01.
+- Further bugfix around .ocamlspot file
+
+4.00.1.2.1.4 (not yet)
+--------------
+
+- Spot results now points to the real source files, not copied one to build directories like _build and those specified by .ocamlspot
+
+4.00.1.2.1.3
+--------------
+
+- Further bugfix around .ocamlspot file
+
+2.1.2
+--------------
+
+- Clean up
+- Some bug fixes around .ocamlspot file
+
 2.1.1
 --------------
 
+==========================================
+OCamlSpotter - OCaml source browsing
+==========================================
+
+OCamlSpotter is a tool for OCaml source code browsing. 
+
+* You can search the definitions of names of values, functions, data types and modules.
+* Emacs and Vim helpers help your browsing via editors.
+* Definition search traverses module aliases and functor applications: if module M = N, OCamlSpotter automatically seeks the definition of M.x in N. Very helpful in the modern OCaml programming with lots of modules.
+
+OCamlSpotter 2.x uses \*.cmt and \*.cmti files created by OCaml compiler 4.00.0 or newer with -bin-annot option.
+
+Unlike OCamlSpotter 1.x, OCamlSpotter 2.x is a standalone application. You NO LONGER need compiler patching. Just make, make install, and configure ocamlspot.el.
+
+Dependency
+=====================
+
+OCamlSpotter strongly depends on OCaml compiler implementation and its compiler-libs library.
+You need use the correct pairs of compiler and OCamlSpotter.
+
+https://bitbucket.org/camlspotter/ocamlspot provides OCamlSpotter branches for each OCaml versions:
+
+* ocaml-<version-name> : compilable against the given OCaml version
+    * ocaml-4.00.0 : the latest "stable" version
+    * ocaml-4.00.1 : the latest "stable" version
+* default : Development version. Sometimes not compilable. Not for you.
+
+Versions
+================
+
+OCamlSpotter is always under development and there is no clear release versions.
+If you want to use the latest stable version of OCamlSpotter, choose the tip of the branch 
+with the name of your OCaml compiler version. 
+When you report bugs, please note the revision hash with your issue description please.
+
+Installation
+============================
+
+To compile OCamlSpotter::
+
+   % make
+   % make opt           (This is optional but recommended)
+   % make install     
+ 
+Setup
+============================
+
+If you are Emacs user, see ``ocamlspot.el``. It explains how to set up
+and use it.
+
+I have also written Vim script ``ocamlspot.vim``, but it is not tested at all.
+Sorry but I do not use Vim.
+
+
+How to use
+===============================
+
+Before using, it is better to know what to do if something goes wrong
+---------------------------------------------------------------------------
+
+* Use the correct ``ocamlspot`` matching with your OCaml compiler version.
+* Compile OCaml modules with ``-bin-annot`` ocaml compiler option.
+* Keep the source code and produced cmt/cmti files.
+* Install cmt/cmti files along with cmi/cma/cmxa files.
+* Use ``ocamlspot.opt`` if you have done ``make opt``. It is much faster than ``ocamlspot``.
+* CamlP4 has lots of location issues. In many cases, OCamlSpotter cannot workaround them.
+* OCamlSpotter has its own bugs.
+
+Browsing your code
+-------------------------------------------------
+
+Compile your OCaml source code with ``-bin-annot`` option, 
+then it should create ``\*.cmt`` and ``\*.cmti`` files.
+
+Open the source code in your Emacs and move the cursor to an identifier
+usage, then type ``C-c ;``. If things are properly installed and set up,
+Emacs should display the definition of the identifier.
+
+Browsing libraries and packages
+----------------------------------------------
+
+Normally OCaml libraries and packages are not always compiled with -bin-annot option
+and do not always install the annotation files.
+Therefore, if you want to use OCamlSpotter with installed libraries and packages,
+you must rebuild them with -bin-annot compiler option.
+This requires little modifications to their build script (Makefile/OMakefile/...).
+Basically, you need:
+
+* Add -bin-annot to the compiler switch. For example OCAMLCFLAGS += -bin-annot
+* Copy cmt and cmti files at installation. For example::
+
+     install::
+        cp \*.mli \*.cmi \*.cma \*.cmt \*.cmti \*.cmxa $(INSTALLDIR)
+
+* Do not remove the original source files, otherwise browsing cannot work.
+
+Browsing OCaml stdlib and otherlibs
+---------------------------------------------------
+
+If you want to browse OCaml's standard library (stdlib and otherlibs), 
+you must recompile those modules with -bin-annot option to create cmt/cmti files. 
+It should require some Makefile changes and reinstallation of the compiler.
+
+Automation
+------------------------------------
+
+Recompilation of libraries and compiler with fixing their build scripts is very lousy. To facilitate these you may want to use SpotInstall( https://bitbucket.org/camlspotter/spotinstall ). SpotInstall provides:
+
+* A small OCaml compiler patch to automatically enable -bin-annot by the existence of OCAML_ANNOT environment variable; no need to fix build scripts.
+* An automatic cmt/cmti post installation command, spotinstall.
+
+Even with SpotInstall, you have to still recompile the compiler and the libraries. But you do no longer need to fix the build scripts.
 
 https://bitbucket.org/camlspotter/ocamlspot provides OCamlSpotter branches for each OCaml versions:
 
-* For OCaml 4.01.0, use branch 4.01.0.2.2.0
-* For OCaml 4.00.1, use branch 4.00.1.2.1.2
-* For OCaml 4.00.0, use branch 4.00.0.2.1.1
+* For OCaml 4.01.0, use branch 4.01.0.2.x.y
+* For OCaml 4.00.1, use branch 4.00.1.2.x.y
+* For OCaml 4.00.0, use branch 4.00.0.2.x.y
 * default : Development version. Sometimes not compilable. Not for you.
 
 Installation
 Setup
 ============================
 
-If you are Emacs user, see ``ocamlspot.el``. It explains how to set up
-and use it. ``M-x customiize-group`` => ``ocamlspot`` shows majour configurable
-options.
+Emacs users
+---------------
+
+Put ``ocamlspot.el`` somewhere, then edit your ``.emacs``::
+
+     ; load-path
+     (setq load-path (cons "WHERE-YOU-HAVE-INSTALLED-THIS-ELISP" load-path))
+     
+     (require 'ocamlspot)
+     
+     ; tuareg mode hook (use caml-mode-hook instead if you use caml-mode)
+     (add-hook 'tuareg-mode-hook
+       '(lambda ()
+         (local-set-key "\C-c;" 'ocamlspot-query)
+         (local-set-key "\C-c:" 'ocamlspot-query-interface)
+         (local-set-key "\C-c'" 'ocamlspot-query-uses)
+         (local-set-key "\C-c\C-t" 'ocamlspot-type)
+         (local-set-key "\C-c\C-i" 'ocamlspot-xtype)
+         (local-set-key "\C-c\C-y" 'ocamlspot-type-and-copy)
+         (local-set-key "\C-ct" 'caml-types-show-type)
+         (local-set-key "\C-cp" 'ocamlspot-pop-jump-stack)))
+     
+     ; set the path of the ocamlspot binary. If you did make opt, ocamlspot.opt is recommended.
+     (setq ocamlspot-command "WHERE-YOU-HAVE-INSTALLED-THE-BINARIES/ocamlspot")
+     
+     ; Optional: You can also change overlay colors as follows:
+     ;  (set-face-background 'ocamlspot-spot-face "#660000")
+     ;  (set-face-background 'ocamlspot-tree-face "#006600")
+
+
+``M-x customize-group`` => ``ocamlspot`` shows majour configurable options.
+
+Vim users
+-----------
 
 I have also written Vim script ``ocamlspot.vim``, but it is not tested at all.
 Sorry but I do not use Vim.
 
-
 How to use
 ===============================
 
 Compile your OCaml source code with ``-bin-annot`` option, 
 then it should create ``*.cmt`` and ``*.cmti`` files.
 
-Open the source code in your Emacs and move the cursor to an identifier
+Emacs users: Open the source code in your Emacs and move the cursor to an identifier
 usage, then type ``C-c ;``. If things are properly installed and set up,
 Emacs should display the definition of the identifier.
 
 * ``ocamlspot-use``: Display the identifier's stamps
 * ``ocamlspot-pop-jump-stack``: Go back to previous buffer layout. Useful when you are lost during browsing.
 
+Vim users...
+
 If something goes wrong
 ---------------------------------------------------------------------------
 
 * set OPAMKEEPBUILDDIR to keep your source code and ``.cmt*`` files
 * use ``spotinstall`` to install ``.cmt*`` files along with other object files.
 
+OCamlSpotter with multiple OCaml versions
+---------------------------------------------------
+
+OCamlSpotter is compiler version dependent. So, each version of OCaml compiler,
+the corresponding OCamlSpotter is required.
+
+Changing automatically from one to another OCamlSpotter, OPAM users may want to
+specify the following shell script as a wrapper. Change the OCamlSpotter location
+of your favorite editor config to this.::
+
+    #!/bin/sh
+    
+    # This is a sample shell script which tries to call the corresponding OCamlSpotter
+    # with the current OPAM switch.
+    
+    DIR=`opam config var bin`
+    
+    if [ -x $DIR/ocamlspot.opt ]; then 
+      $DIR/ocamlspot.opt $*
+    else 
+      if [ -x $DIR/ocamlspot ]; then 
+        $DIR/ocamlspot $*
+      else 
+        echo "ERROR: No ocamlspot.opt or ocamlspot found at $DIR"
+      fi
+    fi
+
 Reporting bugs
 ==============================
 
 
 module FP = Filepath
 
+let rec find_dot_ocamlspot fp = 
+  let open FP in
+  match
+    if Unix.is_dir (FP.to_string (fp ^/ "_build")) then Some (fp, "_build")
+    else
+      let dot_ocamlspot = fp ^/ ".ocamlspot" in
+      if Sys.file_exists (FP.to_string dot_ocamlspot) then
+        match (Dotfile.load (FP.to_string dot_ocamlspot)).Dotfile.build_dir with
+        | Some dir -> Some (fp, dir)
+        | None -> None
+      else None
+  with
+  | (Some _ as res) -> res
+  | None ->
+      if FP.is_root fp then None
+      else match FP.dirbase fp with
+      | dir, Some _ -> find_dot_ocamlspot dir
+      | _ -> None
+
 let comp_dir fp0 =
-  assert (FP.is_absolute fp0);
-  let rec f bases fp = 
-    let dir = FP.to_string fp in
-
-    let fix () =
-      let dot_ocamlspot = 
-        let dot_ocamlspot_path = dir ^/ ".ocamlspot" in
-        if Sys.file_exists dot_ocamlspot_path then
-          match (Dotfile.load dot_ocamlspot_path).Dotfile.build_dir with
-          | (Some _ as res) -> res
-          | None -> None
-        else None
-      in
-      match dot_ocamlspot with
-      | (Some _ as res) -> res
-      | None ->
-          let ocamlbuild_path = dir ^/ "_build" in
-          if Unix.is_dir ocamlbuild_path then Some "_build"
-          else None
-    in
-    match fix () with
-    | Some p -> Some (FP.(^/) fp (Filename.concats (p :: bases)))
-    | None -> 
-        if FP.is_root fp then Some fp0
-        else match FP.dirbase fp with
-        | dir, Some base -> f (base :: bases) dir
-        | _ -> assert false
-  in
-  Option.default (f [] fp0) (fun () -> fp0)
+  if not  (FP.is_absolute fp0) then fp0
+  else
+    match find_dot_ocamlspot fp0 with
+    | None -> fp0
+    | Some (dir, mv) ->
+        match FP.contains_abs dir fp0 with
+        | None -> fp0
+        | Some postfixes ->
+            match FP.contains_abs (FP.(^/) dir mv) fp0 with
+            | Some _ -> fp0 (* already in the comp dir *)
+            | None -> 
+                (* CR jfuruse: inefficient *)
+                FP.of_string (Filename.concats (FP.to_string dir :: mv :: postfixes))
 
 let comp_dir x =
   let y = comp_dir x in
-  Format.eprintf "comp_dir: %s => %s@." (FP.to_string x) (FP.to_string y);
+  if not (FP.equal x y) then
+    Format.eprintf "comp_dir: %s => %s@." (FP.to_string x) (FP.to_string y);
   y
 
 let comp_dir = Hashtbl.memoize (Hashtbl.create 107) comp_dir
 
-let src_dir fp0 =
-  assert (FP.is_absolute fp0);
+let src_file fp0 =
+  if not (FP.is_absolute fp0) then fp0
+  else
+    match find_dot_ocamlspot fp0 with
+    | None -> fp0
+    | Some (dir, mv) ->
+        match FP.contains_abs (FP.(^/) dir mv) fp0 with
+        | None -> fp0
+        | Some postfixes -> 
+            (* CR jfuruse: inefficient *)
+            FP.of_string (Filename.concats (FP.to_string dir :: postfixes))
 
-  Debug.format "Compdir.src_dir: %s@." (FP.to_string fp0);
+let src_file x =
+  let y = src_file x in
+  if not (FP.equal x y) then
+    Format.eprintf "src_file: %s => %s@." (FP.to_string x) (FP.to_string y);
+  y
 
-  let rec f dirs fp = 
-    match FP.dirbase fp with
-    | dir, Some "_build" -> FP.(^/) dir (Filename.concats dirs)
-    | _, None -> fp0
-    | dir, Some x -> f (x::dirs) dir
-  in
-  
-  let res = f [] fp0 in
-  Debug.format "Compdir.src_dir => %s@." (FP.to_string res); 
-  res
-
-let src_dir = Hashtbl.memoize (Hashtbl.create 107) src_dir
+(* No need of memoize
+let src_file = Hashtbl.memoize (Hashtbl.create 107) src_file
+*)
 (***********************************************************************)
 
 (** ocamlbuild compilation directory tweak *)
+
 val comp_dir : Filepath.t -> Filepath.t
-val src_dir : Filepath.t -> Filepath.t
+(** ocaml/camlp4/Camlp4 => ocaml/_build/camlp4/Camlp *)
+
+val src_file : Filepath.t -> Filepath.t
+(** ocaml/_build/camlp4/Camlp4Bin.ml => ocaml/camlp4/Camlp4Bin.ml *)
 
 let compare t1 t2 = if equal t1 t2 then 0 else compare t1 t2
 
+let contains_abs (b1,dir) (b2,f) =
+  assert (b1 && b2);
+  let dir = List.rev dir in
+  let f = List.rev f in
+  let rec loop dir f = match dir, f with
+    | [], fs -> Some fs
+    | d::ds, f::fs when d = f -> loop ds fs
+    | _::_, _ -> None
+  in
+  loop dir f
+
+let () = 
+  assert (contains_abs (true, ["c"; "b"; "a"]) (true, ["e"; "d"; "c"; "b"; "a"]) =
+      Some ["d"; "e"])
+
 let of_string path = 
   let abs, xs = split path in
   abs, rev_normalize [] abs xs
   | (true, []) -> (true, [])
   | (abs, (_::xs)) -> (abs, xs)
 
+let wrap f s = to_string (f (of_string s))

File filepath.mli

 val compare : t -> t -> int
 val equal : t -> t -> bool
 
+val contains_abs : t -> t -> string list option
+(** contains_abs /a/b/c /a/b/c/d/e = Some ["d"; "e"] 
+    Only works for absolute paths
+*)
+
 val of_string : string -> t
 val to_string : t -> string
 val is_absolute : t -> bool
 val dirbase : t -> t * string option
 val (^/) : t -> string -> t
 val parent : t -> t
+val wrap : (t -> t) -> string -> string

File ocamlspot.el

 ;      (require 'ocamlspot)
 ;     
 ;     ; tuareg mode hook (use caml-mode-hook instead if you use caml-mode)
-;        (add-hook 'tuareg-mode-hook
+;      (add-hook 'tuareg-mode-hook
 ;              '(lambda ()
 ;                 (local-set-key "\C-c;" 'ocamlspot-query)
+;      	     (local-set-key "\C-c:" 'ocamlspot-query-interface)
+;                 (local-set-key "\C-c'" 'ocamlspot-query-uses)
 ;                 (local-set-key "\C-c\C-t" 'ocamlspot-type)
 ;                 (local-set-key "\C-c\C-i" 'ocamlspot-xtype)
 ;                 (local-set-key "\C-c\C-y" 'ocamlspot-type-and-copy)
-;                 (local-set-key "\C-c\C-u" 'ocamlspot-use)
-;                 (local-set-key "\C-cx" 'ocamlspot-expand)
 ;                 (local-set-key "\C-ct" 'caml-types-show-type)
 ;                 (local-set-key "\C-cp" 'ocamlspot-pop-jump-stack)))
 ;     
 ;     ; set the path of the ocamlspot binary. If you did make opt, ocamlspot.opt is recommended.
 ;      (setq ocamlspot-command "WHERE-YOU-HAVE-INSTALLED-THE-BINARIES/ocamlspot")
 ;     
-;     ; You can also change overlay colors as follows:
-;      (set-face-background 'ocamlspot-spot-face "#660000")
-;      (set-face-background 'ocamlspot-tree-face "#006600")
+;     ; Optional: You can also change overlay colors as follows:
+;     ;  (set-face-background 'ocamlspot-spot-face "#660000")
+;     ;  (set-face-background 'ocamlspot-tree-face "#006600")
 ;
 ;
 ; # Setup
 	      (if err
 		  (ocamlspot-message-add (concat "Error: ocamlspot raised an exception!!: " err))))
 		
-	    (let ((err (ocamlspot-find-query-result "Fatal error")))
-	      (if err
-		  (ocamlspot-message-add (concat "Error: ocamlspot raised an exception!!: " err))))
-		
 	    nil))))))
 
 ;; Jump to [position] of [filename], with highlighting the spot overlay
 ; CR can be shared with ocamlspot-type
 (defun ocamlspot-query-uses ()
   (interactive)
-  (let ((dir (expand-file-name 
-	      (read-directory-name "Search directory: "
-				   (file-name-directory (buffer-file-name))))))
+  (let ((dir (read-directory-name "Search directory: "
+				  (file-name-directory (buffer-file-name)))))
     (ocamlspot-message-init (buffer-file-name))
     (ocamlspot-type-init)
     (ocamlspot-delete-overlays-now)
-    (ocamlspot-query-at-cursor (list "use") (list dir))
+    (ocamlspot-query-at-cursor (list "use" dir))
     (if (ocamlspot-find-tree)
 	(progn
 	 (ocamlspot-find-spot)

File ocamlspot.ml

   (* CR jfuruse: In the case of a.mll => a.ml => a.cmt,
      a.ml often does not exist. ocamlspot should warn you when a.ml
      does not exist and propose creation of a.ml from a.mll. *)
+  module FP = Filepath
   let print_query_result kind = function
     | None -> printf "Spot: no spot@."
-    | Some (pident, res) -> match res with
+    | Some (pident, res) -> 
+        let src_file path =
+          let path' = FP.wrap Compdir.src_file path in
+          if path = path' then path 
+          else
+            if not (Sys.file_exists path') then begin
+              Format.eprintf "Warning: this is a source file in a build directory. No original file found at %s@." path';
+              path
+            end else path' (* CR jfuruse: we must check path and path' have the same contents *)
+        in
+        match res with
 	| File.File_itself ->
-            printf "Spot: <%s:all>@." pident.PIdent.path
+            let path = src_file pident.PIdent.path in
+            printf "Spot: <%s:all>@." path
 	| File.Found_at (path, region) ->
+            let path = src_file path in
             printf "Spot: <%s:%s>@."
               path
               (Region.to_string region)
 
 	(* Tree is an older format. XTree is a newer which is the same as one for Spot *)
         printf "Tree: %s@." (Region.to_string r);
-        (* Beware, the search target and file.Unit.path may be different *)
+
+        (* Beware, the search target and file.Unit.path may be different.
+           If _build dir is used, XTree points source file copied inside _build dir. 
+           ocamlspot.el does not use XTree but Tree, so it is ok.
+        *)
         printf "XTree: <%s:%s>@." file.Unit.path (Region.to_string r);
 
 	(* Find the innermost module *)

File ocamlspot.sh

+#!/bin/sh
+
+# This is a sample shell script which tries to call the corresponding OCamlSpotter
+# with the current OPAM switch.
+
+DIR=`opam config var bin`
+
+if [ -x $DIR/ocamlspot.opt ]; then 
+  $DIR/ocamlspot.opt $*
+else 
+  if [ -x $DIR/ocamlspot ]; then 
+    $DIR/ocamlspot $*
+  else 
+    echo "ERROR: No ocamlspot.opt or ocamlspot found at $DIR"
+  fi
+fi

File opam/ocamlspot.4.00.1.2.1.4/descr

+OCamlSpotter - OCaml source browsing
+OCamlSpotter is a tool for OCaml source code browsing. 
+
+* You can search the definitions of names of values, functions, data types and modules.
+* Emacs and Vim helpers help your browsing via editors.
+* Definition search traverses module aliases and functor applications: if module M = N, OCamlSpotter automatically seeks the definition of M.x in N. Very helpful in the modern OCaml programming with lots of modules.
+
+OCamlSpotter uses \*.cmt and \*.cmti files created by OCaml compiler 4.00.0 or newer with -bin-annot option.
+
+In OPAM, ocamlspot.el and ocamlspot.vim is %{lib%}/ocamlspot .

File opam/ocamlspot.4.00.1.2.1.4/files/ocamlspot.install

+lib: ["ocamlspot.vim" "ocamlspot.el"]
+bin: []
+toplevel: []
+misc: []

File opam/ocamlspot.4.00.1.2.1.4/opam

+opam-version: "1"
+maintainer: "jun.furuse@gmail.com"
+build: [
+  [make "all" "opt" "install" "BINDIR=%{bin}%" "PREFIX=%{prefix}%"]
+]
+remove: [
+  [make "uninstall" "BINDIR=%{bin}%" "PREFIX=%{prefix}%"]
+]
+ocaml-version: [= "4.00.1"]

File opam/ocamlspot.4.00.1.2.1.4/url

+archive: "https://bitbucket.org/camlspotter/ocamlspot/get/4.00.1.2.1.4.tar.gz"

File opam/ocamlspot.4.01.0.2.2.0/descr

+OCamlSpotter - OCaml source browsing
+OCamlSpotter is a tool for OCaml source code browsing. 
+
+* You can search the definitions of names of values, functions, data types and modules.
+* Emacs and Vim helpers help your browsing via editors.
+* Definition search traverses module aliases and functor applications: if module M = N, OCamlSpotter automatically seeks the definition of M.x in N. Very helpful in the modern OCaml programming with lots of modules.
+
+OCamlSpotter uses \*.cmt and \*.cmti files created by OCaml compiler 4.00.0 or newer with -bin-annot option.
+
+In OPAM, ocamlspot.el and ocamlspot.vim is %{lib%}/ocamlspot .

File opam/ocamlspot.4.01.0.2.2.0/files/ocamlspot.install

+lib: ["ocamlspot.vim" "ocamlspot.el"]
+bin: []
+toplevel: []
+misc: []

File opam/ocamlspot.4.01.0.2.2.0/opam

+opam-version: "1"
+maintainer: "jun.furuse@gmail.com"
+build: [
+  [make "all" "opt" "install" "BINDIR=%{bin}%" "PREFIX=%{prefix}%"]
+]
+remove: [
+  [make "uninstall" "BINDIR=%{bin}%" "PREFIX=%{prefix}%"]
+]
+ocaml-version: [= "4.01.0"]

File opam/ocamlspot.4.01.0.2.2.0/url

+archive: "https://bitbucket.org/camlspotter/ocamlspot/get/4.01.0.2.2.0.tar.gz"

File opam/template/descr

 * Emacs and Vim helpers help your browsing via editors.
 * Definition search traverses module aliases and functor applications: if module M = N, OCamlSpotter automatically seeks the definition of M.x in N. Very helpful in the modern OCaml programming with lots of modules.
 
-OCamlSpotter 2.x uses \*.cmt and \*.cmti files created by OCaml compiler 4.00.0 or newer with -bin-annot option.
-
-Unlike OCamlSpotter 1.x, OCamlSpotter 2.x is a standalone application. You NO LONGER need compiler patching. Just make, make install, and configure ocamlspot.el.
+OCamlSpotter uses \*.cmt and \*.cmti files created by OCaml compiler 4.00.0 or newer with -bin-annot option.
 
 In OPAM, ocamlspot.el and ocamlspot.vim is %{lib%}/ocamlspot .

File tests/dot_ocamlspot/Makefile

-test: build/hello.cmo
+test: build/hello.cmo build/dir/dir2/bye.cmo
 	../../ocamlspot hello.ml:l5c8
 	../../ocamlspot dir/dir2/bye.ml:l2c12
+	../../ocamlspot hello.ml:l6c24
 
 build/dir/dir2/bye.cmo: dir/dir2/bye.ml
 	ocamlc -c -bin-annot -I build/dir/dir2 -o build/dir/dir2/bye.cmo $<
 
-build/hello.cmo: hello.ml build/dir/dir2/bye.cmo
+build/hello.cmo: hello.ml build/dir/dir2/bye.cmo build/dir/dir2/copied_before_build.cmo
 	ocamlc -c -bin-annot -I build/dir/dir2 -o $@ $<
 
+build/dir/dir2/copied_before_build.cmo: build/dir/dir2/copied_before_build.ml
+	ocamlc -c -bin-annot $<
+
+build/dir/dir2/copied_before_build.ml: dir/dir2/copied_before_build.ml
+	cp $< $@
+
 clean:
-	rm build/hello.* build/dir/dir2/bye.*
+	find build -iname '*.cm*' | xargs rm
 
-

File tests/dot_ocamlspot/dir/dir2/copied_before_build.ml

+let x = 42

File tests/dot_ocamlspot/hello.ml

 let _ =
-  Printf.printf "Hello, %s ! My name is %s! %s!\n"
+  Printf.printf "Hello, %s ! My name is %s! %s %d!\n"
     (if Array.length Sys.argv > 1 then Sys.argv.(1) else "stranger")
     Sys.argv.(0)
     Bye.bye
+    Copied_before_build.x
 ;;

File tests/ocamlbuild/Makefile

+test: hello.native
+	../../ocamlspot hello.ml:l5c8
+        ../../ocamlspot dir/dir2/bye.ml:l2c12
+
 hello.native: hello.ml
-	ocamlbuild -I dir/dir2 hello.native
+	ocamlbuild -cflag -bin-annot -I dir/dir2 hello.native
 
 clean:
 	ocamlbuild -clean
-
-test:
-	../../ocamlspot hello.ml:l5c8
-        ../../ocamlspot dir/dir2/bye.ml:l2c12