diff --git a/src/indexMain.ml b/src/indexMain.ml
index f15cd8e..cb30546 100644
--- a/src/indexMain.ml
+++ b/src/indexMain.ml
@@ -19,6 +19,18 @@ open Cmdliner
 
 let common_opts = IndexOptions.common_opts ()
 
+let man = [
+  `S "COPYRIGHT";
+  `P "Ocp-index is written by Louis Gesbert <louis.gesbert@ocamlpro.com>, \
+      copyright OCamlPro 2013-2014, \
+      distributed under the terms of the LGPL v3 with linking exception. \
+      Full source available at $(i,https://github.com/OCamlPro/ocp-index)";
+  `S "BUGS";
+  `P "Bugs are tracked at $(i,https://github.com/OCamlPro/ocp-index/issues).";
+  `S "SEE ALSO";
+  `P "ocp-grep, ocp-browser";
+]
+
 let default_cmd =
   let man = [
     `S "DESCRIPTION";
@@ -26,8 +38,21 @@ let default_cmd =
         OCaml, for command-line or integrated use (e.g. for completion). \
         It gathers information from .cmi (like ocamlbrowser) and \
         .cmt/cmti files, including structure, location, type, and ocamldoc \
-        comments when available."
-  ]
+        comments when available.";
+    `S "USING AN .ocp-index FILE";
+    `P "It is possible to specify some of the options for ocp-index in a file \
+        called $(b, .ocp-index) placed at the root of the project directory. \
+        Currently only the list of include directories can be specified in this way. \
+        Each line of the .ocp-index file should be of the form";
+    `P "I \"<dir>\"";
+    `P "where \"<dir>\" is the name of a directory (between double quotes) \
+        where ocp-index should look for .cmt[i] files. Typically this way \
+        of specifying include directories would \
+        be used in conjunction with the $(b,--no-recursive) options in order to \
+        speed up directory scanning in those environments where the default \
+        method is not fast enough (e.g. Cygwin).  One can generate such a file by running";
+    `P "find . -name '*.cmt*' -exec dirname {} \\\\; | sort | uniq | sed 's/.*/I \"&\"/g' > .ocp-index"
+  ] @ man
   in
   let doc = "Explore the interfaces of installed OCaml libraries." in
   Term.(ret (pure (fun _ -> `Help (`Pager, None)) $ common_opts)),
@@ -59,18 +84,6 @@ let format_man =
         interpreted:" ] @
   List.map (fun (k, s) -> `I (Printf.sprintf "$(b,%s)" k, s)) formats
 
-let man = [
-  `S "COPYRIGHT";
-  `P "Ocp-index is written by Louis Gesbert <louis.gesbert@ocamlpro.com>, \
-      copyright OCamlPro 2013-2014, \
-      distributed under the terms of the LGPL v3 with linking exception. \
-      Full source available at $(i,https://github.com/OCamlPro/ocp-index)";
-  `S "BUGS";
-  `P "Bugs are tracked at $(i,https://github.com/OCamlPro/ocp-index/issues).";
-  `S "SEE ALSO";
-  `P "ocp-grep, ocp-browser";
-]
-
 let complete_cmd =
   let man = [
     `S "DESCRIPTION";
diff --git a/src/indexMisc.ml b/src/indexMisc.ml
index eee8666..3f19ec3 100644
--- a/src/indexMisc.ml
+++ b/src/indexMisc.ml
@@ -110,12 +110,21 @@ let unique_subdirs ?(skip = fun _ -> false) dir_list =
   in
   remove_dups (List.fold_left subdirs [] dir_list)
 
+let read_all_lines path =
+  let ic = open_in path in
+  let acc = ref [] in
+  try
+    while true do
+      acc := input_line ic :: !acc
+    done;
+    assert false
+  with End_of_file -> !acc
 
 (* - Project root finding - *)
 
 let build_roots = (* by increasing order of priority *)
   [ "_darcs"; ".hg"; ".git";
-    "jengaroot.ml"; "omakeroot"; "_build"; "_obuild" ]
+    "jengaroot.ml"; "omakeroot"; "_build"; "_obuild"; ".ocp-index" ]
 
 let find_build_dir path =
   let ( / ) = Filename.concat in
diff --git a/src/indexMisc.mli b/src/indexMisc.mli
index df74234..fe777d1 100644
--- a/src/indexMisc.mli
+++ b/src/indexMisc.mli
@@ -43,6 +43,8 @@ val parent_type: IndexTypes.info -> IndexTypes.info option
     If directory basename verifies [skip], it is not descended nor returned. *)
 val unique_subdirs: ?skip:(string -> bool) -> string list -> string list
 
+val read_all_lines: string -> string list
+
 (** An heuristic to guess where the root directory of the current project.
     Returns (project_root, build_dir) *)
 val project_root: ?path:string -> unit -> string option * string option
diff --git a/src/indexOptions.ml b/src/indexOptions.ml
index d5b5d18..3237dad 100644
--- a/src/indexOptions.ml
+++ b/src/indexOptions.ml
@@ -65,7 +65,7 @@ let default_filter = [ `V ; `E ; `C ; `M ; `K ]
 
 let filter_to_string l =
   let pp = function
-    | `V -> "v" | `E -> "b" | `C -> "c"
+    | `V -> "v" | `E -> "e" | `C -> "c"
     | `M -> "m" | `K -> "k" | `S -> "s"
     | `T -> "t"
   in
@@ -84,7 +84,9 @@ let common_opts ?(default_filter = default_filter) () : t Term.t =
       Arg.(value & flag & info ["no-opamlib"] ~doc);
     in
     let arg =
-      let doc = "OCaml directories to (recursively) load the libraries from." in
+      let doc = "OCaml directories to load the libraries from. \
+                 By default, the directories are traversed recursively. \
+                 This can be changed by passing the $(b,--no-recursive) option." in
       Arg.(value & opt_all (list string) [] & info ["I"] ~docv:"DIRS" ~doc)
     in
     let set_default no_stdlib no_opamlib includes =
@@ -99,6 +101,10 @@ let common_opts ?(default_filter = default_filter) () : t Term.t =
     in
     Term.(pure set_default $ no_stdlib $ no_opamlib $ arg)
   in
+  let no_recursive : bool Term.t =
+    let doc = "Do not traverse include directories recursively." in
+    Arg.(value & flag & info ["no-recursive"] ~doc)
+  in
   let color : bool Term.t =
     let arg =
       let choices = Arg.enum [ "always", `Always;
@@ -245,14 +251,32 @@ let common_opts ?(default_filter = default_filter) () : t Term.t =
     Arg.(value & opt (some filepos_converter) None
          & info ["context"] ~docv:"FILEPOS" ~doc)
   in
-  let lib_info ocamllib (_root,build) (opens,full_opens) context =
+  let lib_info ocamllib no_recursive (root,build) (opens,full_opens) context =
     let dirs = match build with
       | None -> ocamllib
       | Some d -> d :: ocamllib
     in
+    let dirs =
+      let extra_dirs = match root with
+        | Some root ->
+            let make_absolute path = if Filename.is_relative path then Filename.concat root path else path in
+            let dot_ocp_index = Filename.concat root ".ocp-index" in
+            if Sys.file_exists dot_ocp_index then begin
+              let l = IndexMisc.read_all_lines dot_ocp_index in
+              List.map (fun s -> Scanf.sscanf s "I %S" make_absolute) l
+            end
+            else
+              []
+        | None -> []
+      in
+      dirs @ extra_dirs
+    in
     if dirs = [] then
       failwith "Failed to guess OCaml / opam lib dirs. Please use `-I'";
-    let dirs = LibIndex.Misc.unique_subdirs dirs in
+    IndexMisc.debug "Scanning directories... ";
+    let chrono = IndexMisc.timer () in
+    let dirs = if no_recursive then dirs else LibIndex.Misc.unique_subdirs dirs in
+    IndexMisc.debug "%.3fs\n%!" (chrono ());
     let info = LibIndex.load dirs in
     let info =
       List.fold_left (LibIndex.open_module ~cleanup_path:true) info opens
@@ -281,8 +305,8 @@ let common_opts ?(default_filter = default_filter) () : t Term.t =
   in
   Term.(
     pure
-      (fun ocamllib project_dirs opens color filter context ->
-         { lib_info = lib_info ocamllib project_dirs opens context;
+      (fun ocamllib no_recursive project_dirs opens color filter context ->
+         { lib_info = lib_info ocamllib no_recursive project_dirs opens context;
            color; filter; project_root = fst project_dirs })
-    $ ocamllib $ project_dirs $ open_modules $ color $ filter $ context
+    $ ocamllib $ no_recursive $ project_dirs $ open_modules $ color $ filter $ context
   )