camlspotter avatar camlspotter committed bca5ee3

coverage is now 29%

Comments (0)

Files changed (6)

   end
 
   let aliases_of_include mexp ids =
-    let sg = match (mexp.mod_type : Types.module_type) with Mty_signature sg -> sg | _ -> assert false in (* CR jfuruse: I hope so... *)
+    let sg = match mexp.mod_type with Mty_signature sg -> sg | _ -> assert false in
     let kids = List.concat_map T.kident_of_sigitem sg in
     (* [ids] only contain things with values, i.e. values, modules and classes *)
     List.map (fun (k,id) -> match k with
     | AMod_ident _ -> []
     | AMod_packed _ -> []
     | AMod_structure str -> flatten str
-    | AMod_functor _ -> []
+    | AMod_functor (_, _, mexp) -> flatten_module_expr mexp
     | AMod_apply (_, m) -> flatten_module_expr m
     | AMod_constraint (m, _) -> flatten_module_expr m
     | AMod_unpack m -> flatten_module_expr m
         | Texp_letmodule (id, {loc}, mexp, _) -> 
             record loc (Str (AStr_module (id, module_expr mexp)))
         | Texp_newtype (_string, _expr) (* CR jfuruse: ? *) -> ()
-        | Texp_constant _
-        | Texp_let _
-        | Texp_function _
-        | Texp_apply _
-        | Texp_match _
-        | Texp_try _
-        | Texp_tuple _
-        | Texp_variant _
-        | Texp_array _
-        | Texp_ifthenelse _
-        | Texp_sequence _
-        | Texp_while _
-        | Texp_when _
-        | Texp_send _
-        | Texp_assert _
-        | Texp_assertfalse
-        | Texp_lazy _
-        | Texp_poly _
-        | Texp_object _
-        | Texp_pack _ -> ()
+        | Texp_constant _ | Texp_let _ | Texp_function _
+        | Texp_apply _ | Texp_match _ | Texp_try _
+        | Texp_tuple _ | Texp_variant _ | Texp_array _
+        | Texp_ifthenelse _ | Texp_sequence _ | Texp_while _
+        | Texp_when _ | Texp_send _ | Texp_assert _ | Texp_assertfalse
+        | Texp_lazy _ | Texp_poly _ | Texp_object _ | Texp_pack _ -> ()
         end;
         super#expression_desc ed
 (*          
 and meth =
     Tmeth_name of string
   | Tmeth_val of Ident.t
+*)
 
-(* Value expressions for the class language *)
+(* CR jfuruse: Class_type
+      method! class_expr ce =
+        record ce.cl_loc (Class_type (ce.cl_type, ce.cl_env));
+        super#class_expr ce
+*)
 
-and class_expr =
-  { cl_desc: class_expr_desc;
-    cl_loc: Location.t;
-    cl_type: Types.class_type;
-    cl_env: Env.t }
-
+(*
 and class_expr_desc =
     Tcl_ident of Path.t * Longident.t loc * core_type list (* Pcl_constr *)
   | Tcl_structure of class_structure
   | Tcf_init of expression
 
 (* Value expressions for the module language *)
+*)
+      method! module_expr me = (* CR jfuruse: me.mod_env *)
+        record me.mod_loc (Mod_type me.mod_type);
+        super#module_expr me
 
-and module_expr =
-  { mod_desc: module_expr_desc;
-    mod_loc: Location.t;
-    mod_type: Types.module_type;
-    mod_env: Env.t }
-
+(*
 and module_type_constraint =
   Tmodtype_implicit
 | Tmodtype_explicit of module_type
+*)
 
-and module_expr_desc =
-    Tmod_ident of Path.t * Longident.t loc
-  | Tmod_structure of structure
-  | Tmod_functor of Ident.t * string loc * module_type * module_expr
-  | Tmod_apply of module_expr * module_expr * module_coercion
-  | Tmod_constraint of
-      module_expr * Types.module_type * module_type_constraint * module_coercion
-  | Tmod_unpack of expression * Types.module_type
+      method! module_expr_desc med = 
+        begin match med with
+        | Tmod_ident (path, {loc}) -> 
+            record loc (Use (Kind.Module, path))
+        | Tmod_functor (id, {loc}, _, _) ->
+            (* CR jfuruse: must rethink *)
+            (* record loc (Str (AStr_module (id, ???))) *)
+            record loc (Functor_parameter id);
+        | Tmod_structure _
+        | Tmod_apply _
+        | Tmod_constraint _
+        | Tmod_unpack _ -> ()
+        end;
+        super#module_expr_desc med
 
+(* CR jfuruse: I want to put the sig
 and structure = {
   str_items : structure_item list;
   str_type : Types.signature;
   str_final_env : Env.t;
 }
+*)
 
+(* add env 
 and structure_item =
   { str_desc : structure_item_desc;
     str_loc : Location.t;
     str_env : Env.t
   }
+*)
+      method! structure_item_desc sid =
+        begin match sid with
+        | Tstr_primitive (id, {loc}, _) -> 
+            record loc (Str (AStr_value id))
+        | Tstr_type lst ->
+            List.iter (fun (id, {loc}, _) ->
+              record loc (Str (AStr_type id))) lst
+        | Tstr_exception (id, {loc}, _) -> 
+            record loc (Str (AStr_exception id))
+        | Tstr_exn_rebind (id, {loc}, path, {loc=loc'}) ->
+            record loc (Str (AStr_exception id));
+            record loc (Use (Kind.Exception, path))
+        | Tstr_module (id, {loc}, mexp) -> 
+            record loc (Str (AStr_module (id, module_expr mexp)))
+        | Tstr_recmodule lst ->
+            List.iter (fun (id, {loc}, _mty, mexp) ->
+              record loc (Str (AStr_module (id, module_expr mexp)))) lst
+        | Tstr_modtype (id, {loc}, mty) -> 
+            record loc (Str (AStr_modtype (id, module_type mty)))
+        | Tstr_open (path, {loc}) -> 
+            record loc (Use (Kind.Module, path))
+        | Tstr_class_type lst ->
+            List.iter (fun (id, {loc}, _) -> 
+              record loc (Str (AStr_cltype id))) lst
+        | Tstr_include (_mexp, _idents) -> () (* CR jfuruse: TODO *)
+        | Tstr_eval _ 
+        | Tstr_value _ 
+        | Tstr_class _  
+          -> ()
+        end;
+        super#structure_item_desc sid
 
-and structure_item_desc =
-    Tstr_eval of expression
-  | Tstr_value of rec_flag * (pattern * expression) list
-  | Tstr_primitive of Ident.t * string loc * value_description
-  | Tstr_type of (Ident.t * string loc * type_declaration) list
-  | Tstr_exception of Ident.t * string loc * exception_declaration
-  | Tstr_exn_rebind of Ident.t * string loc * Path.t * Longident.t loc
-  | Tstr_module of Ident.t * string loc * module_expr
-  | Tstr_recmodule of (Ident.t * string loc * module_type * module_expr) list
-  | Tstr_modtype of Ident.t * string loc * module_type
-  | Tstr_open of Path.t * Longident.t loc
-  | Tstr_class of (class_declaration * string list * virtual_flag) list
-  | Tstr_class_type of (Ident.t * string loc * class_type_declaration) list
-  | Tstr_include of module_expr * Ident.t list
-
+(*
 and module_coercion =
     Tcoerce_none
   | Tcoerce_structure of (int * module_coercion) list
   | Tcoerce_functor of module_coercion * module_coercion
   | Tcoerce_primitive of Primitive.description
+*)
 
+(* add env?
 and module_type =
   { mty_desc: module_type_desc;
     mty_type : Types.module_type;
     mty_env : Env.t; (* BINANNOT ADDED *)
     mty_loc: Location.t }
+*)
 
-and module_type_desc =
-    Tmty_ident of Path.t * Longident.t loc
-  | Tmty_signature of signature
-  | Tmty_functor of Ident.t * string loc * module_type * module_type
-  | Tmty_with of module_type * (Path.t * Longident.t loc * with_constraint) list
-  | Tmty_typeof of module_expr
+      method! module_type_desc mtd =
+        begin match mtd with
+        | Tmty_ident (path, {loc}) -> 
+            record loc (Use (Kind.Module_type, path))
+        | Tmty_functor (id, {loc}, mty, _mty) -> 
+            record loc (Str (AStr_module (id, module_type mty)))
+        | Tmty_with (_mty, lst) -> 
+            List.iter (fun (path, {loc}, with_constraint) -> 
+              record loc (Use ( (match with_constraint with
+                                 | Twith_type _ -> Kind.Type
+                                 | Twith_module _ -> Kind.Module
+                                 | Twith_typesubst _ -> Kind.Type
+                                 | Twith_modsubst _ -> Kind.Module),
+                                path ))) lst
+        | Tmty_typeof _
+        | Tmty_signature _ -> ()
+        end;
+        super#module_type_desc mtd
 
+(* add env
 and signature = {
   sig_items : signature_item list;
   sig_type : Types.signature;
   sig_final_env : Env.t;
 }
 
+add env
 and signature_item =
   { sig_desc: signature_item_desc;
     sig_env : Env.t; (* BINANNOT ADDED *)
     sig_loc: Location.t }
+*)
 
-and signature_item_desc =
-    Tsig_value of Ident.t * string loc * value_description
-  | Tsig_type of (Ident.t * string loc * type_declaration) list
-  | Tsig_exception of Ident.t * string loc * exception_declaration
-  | Tsig_module of Ident.t * string loc * module_type
-  | Tsig_recmodule of (Ident.t * string loc * module_type) list
-  | Tsig_modtype of Ident.t * string loc * modtype_declaration
-  | Tsig_open of Path.t * Longident.t loc
-  | Tsig_include of module_type * Types.signature
-  | Tsig_class of class_description list
-  | Tsig_class_type of class_type_declaration list
+      method! signature_item_desc sid =
+        begin match sid with
+        | Tsig_value (id, {loc}, _) -> record loc (Str (AStr_value id))
+        | Tsig_type lst -> 
+            List.iter (fun (id, {loc}, _) -> 
+              record loc (Str (AStr_type id))) lst
+        | Tsig_exception (id, {loc}, _) -> record loc (Str (AStr_exception id))
+        | Tsig_module (id, {loc}, mty) -> record loc (Str (AStr_module (id, module_type mty)))
+        | Tsig_recmodule lst -> 
+            List.iter (fun (id, {loc}, mty) -> 
+              record loc (Str (AStr_module (id, module_type mty)))) lst
+        | Tsig_modtype (id, {loc}, mtd) -> 
+            record loc (Str (AStr_modtype (id, modtype_declaration mtd)))
+        | Tsig_open (path, {loc}) -> record loc (Use (Kind.Module, path))
+        | Tsig_include _ -> ()
+        | Tsig_class _ -> ()
+        | Tsig_class_type _ -> ()
+        end;
+        super#signature_item_desc sid
+        
 
-and modtype_declaration =
-    Tmodtype_abstract
-  | Tmodtype_manifest of module_type
-
+(*
 and with_constraint =
     Twith_type of type_declaration
   | Twith_module of Path.t * Longident.t loc
   | Twith_typesubst of type_declaration
   | Twith_modsubst of Path.t * Longident.t loc
+*)
 
+(* add env?
 and core_type =
 (* mutable because of [Typeclass.declare_method] *)
   { mutable ctyp_desc : core_type_desc;
     mutable ctyp_type : type_expr;
     ctyp_env : Env.t; (* BINANNOT ADDED *)
     ctyp_loc : Location.t }
+*)
 
-and core_type_desc =
-    Ttyp_any
-  | Ttyp_var of string
-  | Ttyp_arrow of label * core_type * core_type
-  | Ttyp_tuple of core_type list
-  | Ttyp_constr of Path.t * Longident.t loc * core_type list
-  | Ttyp_object of core_field_type list
-  | Ttyp_class of Path.t * Longident.t loc * core_type list * label list
-  | Ttyp_alias of core_type * string
-  | Ttyp_variant of row_field list * bool * label list option
-  | Ttyp_poly of string list * core_type
-  | Ttyp_package of package_type
+      method! core_type_desc ctd =
+        begin match ctd with
+        | Ttyp_var _var -> () (* CR jfuruse: todo *)
+        | Ttyp_constr (path, {loc}, _) -> record loc (Use (Kind.Type, path))
+        | Ttyp_class (path, {loc}, _, _) -> record loc (Use (Kind.Class, path))
+            (* CR jfuruse: or class type? *)
+        | Ttyp_alias (_core_type, _var) -> () (* CR jfuruse: todo *)
+        | Ttyp_poly (_vars, _core_type) -> () (* CR jfuruse; todo *)
+        | Ttyp_any 
+        | Ttyp_arrow _
+        | Ttyp_tuple _
+        | Ttyp_object _
+        | Ttyp_variant _
+        | Ttyp_package _
+            -> ()
+        end;
+        super#core_type_desc ctd
 
+(*
 and package_type = {
   pack_name : Path.t;
   pack_fields : (Longident.t loc * core_type) list;
 
 open Format
 open Utils
+open Ext
 
 (* To avoid name collisions *)
 module OCaml = struct
   module Format = Format
 end
 
-(* Keep the original modules *)
-module Ident0 = Ident
-
 open Spot
 
 module PIdent = struct
   module Binding : sig
     type t = binding
     val domain : t -> Ident.t list
-    val find : t -> Ident.t -> Kind.t * z
+    val find : t -> Ident.t -> (Kind.t * z) option
     val override : t -> structure_item -> t
     val overrides : t -> structure -> t
     val set : t -> structure -> unit
 end = struct
 
   type t = 
-    | Ident of PIdent.t
+    | Ident     of PIdent.t
     | Structure of PIdent.t * structure * structure option (* sig part *)
-    | Closure of PIdent.t * env * Ident.t * Types.module_type * Abstraction.module_expr
+    | Closure   of PIdent.t * env * Ident.t * Types.module_type * Abstraction.module_expr
     | Parameter of PIdent.t
-    | Error of exn 
+    | Error     of exn 
 
   and structure = structure_item list
 
       | None -> error ()
       | Some str -> f str
     let domain = with_check (List.map fst) 
-    let find t id = with_check (List.assoc id) t
+    let find t id = try Some (with_check (List.assoc id) t) with Not_found -> None
     let override t v = ref (Some (with_check (fun t -> v :: t) t))
     let overrides t vs = ref (Some (with_check (fun t -> vs @ t) t))
     let invalid = ref None 
         (fun id _ _ -> add_predefined Kind.Type id)
         (fun id _ _ -> add_predefined Kind.Exception id) 
         ();
-      List.iter (fun (_, id) -> add_predefined Kind.Value id) 
-        Predef.builtin_values;
+      List.iter (fun (_, id) -> add_predefined Kind.Value id) Predef.builtin_values;
       ref (Some !items)
     let set b str = b := Some str
   end
   let rec find_path env (kind, p) : Value.z = 
     match p with
     | Path.Papply (p1, p2) -> 
-	let v1 = find_path env (kind, p1) in
+	let v1 = find_path env (kind, p1) in (* CR jfuruse: Kind.Module ? *)
 	let v2 = find_path env (kind, p2) in
 	apply v1 v2
     | Path.Pident id -> 
         (* predef check first (testing) *)
-        begin try snd (Env.find Env.predef id) with Not_found ->
-        
-        if Ident.global id then
-          lazy begin try
-            let path, str = 
-              !str_of_global_ident ~load_paths:env.load_paths id
-            in
-            let str = Structure ( { PIdent.path = path; ident = None }, 
-                                  str,
-                                  None (* CR jfuruse: todo (read .mli *))
-            in
-            Debug.format "@[<2>LOAD SUCCESS %s =@ %a@]@."
-              (Ident.name id)
-              Value.Format.t str;
-            str
-          with
-          | e -> 
-              eprintf "LOAD FAILIURE %s: %s@." (Ident.name id) (Printexc.to_string e);
-              Error e
-          end
-        else begin 
-          lazy begin
-            Debug.format "find_path %s in { %s }@." 
-              (Path.name p)
-              (String.concat "; " 
-                (List.map Ident.name (Env.domain env)));
-            try !!(snd (Env.find env id)) with Not_found -> 
-(*
-              (* it may be a predefed thing *)
-              try !!(snd (Env.find Env.predef id)) with Not_found ->
-*)
-              Error (Failure (Printf.sprintf "%s not found in { %s }" 
-                                (Ident.name id)
-                                (String.concat "; " 
-                                   (List.map Ident.name (Env.domain env)))))
-          end
-        end
-        end
+        begin match Env.find Env.predef id with
+        | Some (_, v) -> v
+        | None -> 
+            if Ident.global id then
+              lazy begin try
+                let path, str = 
+                  !str_of_global_ident ~load_paths:env.load_paths id
+                in
+                let str = Structure ( { PIdent.path = path; ident = None }, 
+                                      str,
+                                      None (* CR jfuruse: todo (read .mli *))
+                in
+                Debug.format "@[<2>LOAD SUCCESS %s =@ %a@]@."
+                  (Ident.name id)
+                  Value.Format.t str;
+                str
+              with
+              | e -> 
+                  eprintf "LOAD FAILIURE %s: %s@." (Ident.name id) (Printexc.to_string e);
+                  Error e
+              end
+            else begin 
+              lazy begin
+                Debug.format "find_path %s in { %s }@." 
+                  (Path.name p)
+                  (String.concat "; " 
+                    (List.map Ident.name (Env.domain env)));
+                match Env.find env id with
+                | Some (_, lazy v) -> v
+                | None -> 
+    (*
+                  (* it may be a predefed thing *)
+                  try !!(snd (Env.find Env.predef id)) with Not_found ->
+    *)
+                  Error (Failure (Printf.sprintf "%s not found in { %s }" 
+                                    (Ident.name id)
+                                    (String.concat "; " 
+                                       (List.map Ident.name (Env.domain env)))))
+              end
+            end
+            end
     | Path.Pdot (p, name, pos) ->
         lazy begin
           match !!(find_path env (Kind.Module, p)) with
         end
 
   and find_ident (str : Value.structure) (kind, name, pos) : Value.z =
-    let name_filter = fun (id, (k,_)) -> k = kind && Ident0.name id = name in
+    let name_filter = fun (id, (k,_)) -> 
+      Format.eprintf "DEBUG: %s %s ? %s %s@."
+        (Kind.to_string kind)
+        name 
+        (Kind.to_string k)
+        (Ident0.name id);
+      k = kind && Ident0.name id = name in
     (* CR jfuruse: double check by pos! *)
     lazy begin
       try
           (* pos_filter id_value && *) name_filter id_value) str)))
       with
       | Not_found ->
-          Debug.format "Error: Not found %s(%s) @[%a@]@."
+          Debug.format "Error: Not found %s %s in { @[%a@] }@."
             (String.capitalize (Kind.to_string kind))
             name
             Value.Format.structure str;
 
   and module_expr env idopt : module_expr -> Value.z = function
     | AMod_abstract -> eager (Error (Failure "abstract"))
-    | AMod_ident p -> 
-        find_path env (Kind.Module, p)
+    | AMod_ident p -> find_path env (Kind.Module, p)
     | AMod_packed s -> lazy (!packed env s)
     | AMod_structure str -> 
         lazy begin
           Structure ({ PIdent.path= env.path; ident = idopt }, str, None)
         end
     | AMod_functor (id, mty, mexp) -> 
-        Debug.format "evaluating functor (arg %s) under %s@."
+        Debug.format "creating a closure of a functor (fun %s -> ...) under %s@."
           (Ident.name id)
           (String.concat "; " (List.map Ident.name (Env.domain env)));
         eager (Closure ({ PIdent.path = env.path; ident = idopt }, 
-                       env, id, mty, mexp))
+                        env, id, mty, mexp))
     | AMod_constraint (mexp, _mty) -> 
         (* [mty] may not be a simple signature but an ident which is
            hard to get its definition at this point. 
             | Structure (_, str, _ (* CR jfuruse *) ) -> 
                 List.map (fun (id, (k, v)) -> (k, id), v) str
             | Parameter pid -> 
-                List.map (fun (_, (k,id)) -> 
-                  (k, id), eager (Parameter pid)) aliases
+                List.map (fun (_, (k,id)) -> (k, id), eager (Parameter pid)) aliases
             | Ident _ -> assert false
             | Closure _ -> assert false
             | Error _ -> [] (* error *)
             end
           in
-          let str' =
-            List.map (fun (id', (k, id)) ->
-              let v = 
-                lazy begin
-                  try
-                    !!(List.assoc (k, id) !!kid_ztbl)
-                  with
-                  | Not_found -> Error Not_found
-                end
-              in
-              id', (k, v)) aliases
+          let str' = List.map (fun (id', (k, id)) ->
+            let v = lazy begin
+              let kid_tbl = !!kid_ztbl in
+              (* include does not preserve id stamp, so we must ignore them *)
+              match 
+                List.find_map_opt (fun ((k', id'), v) -> 
+                  if k = k' && Ident0.name id = Ident0.name id' then Some v else None) kid_tbl
+              with
+              | Some vz -> !!vz
+              | None -> 
+                Format.eprintf "INCLUDE ERROR: %s %a in @[%a@]@."
+                  (Kind.name k)
+                  Ident.format id
+                  (Format.list ";@ " (fun ppf ((k,id), _) -> 
+                    Format.fprintf ppf "%s %a" (Kind.name k) Ident.format id))
+                  kid_tbl;
+                Error (Failure "not found in include")
+            end in
+            id', (k, v)) aliases
           in
           str' @ str
 (*
   and apply v1 v2 =
     lazy begin match !!v1 with
     | Ident _ -> assert false
-    | Parameter pid -> Parameter pid
+    | Parameter pid -> Parameter pid (* CR jfuruse: ??? *)
     | Structure _ -> assert false
     | Error exn -> Error exn
     | Closure (_, env, id, _mty, mexp) -> 
-        !!(module_expr (Env.override env (id, (Kind.Module, v2)))
-          None(*?*) mexp)
+        let v = 
+          !!(module_expr (Env.override env (id, (Kind.Module, v2)))
+               None(*?*) mexp)
+        in
+        Format.eprintf "closure app: %a@." Value.Format.t v;
+        v
     end
 end
   type t = Value.binding
       
   val domain : t -> Ident.t list
-  val find : t -> Ident.t -> Kind.t * Value.z
+  val find : t -> Ident.t -> (Kind.t * Value.z) option
   val override : t -> Value.structure_item -> t
   val overrides : t -> Value.structure -> t
   val set : t -> Value.structure -> unit
   }
   val format : Format.formatter -> Value.env -> unit
   val domain : t -> Ident.t list
-  val find : t -> Ident.t -> Kind.t * Value.z
+  val find : t -> Ident.t -> (Kind.t * Value.z) option
   val override : t -> Value.structure_item -> t
   val overrides : t -> Value.structure -> t
   val predef : t

tests/Makefile.targets

 fstclassmodule.cmo \
 fstclassmodule2.cmo \
 functor.cmo \
+functor_app.cmo \
+functor_call.cmo \
+functor_expansion.cmo \
 functor_parameter.cmo \
 immediate_include.cmo \
 include.cmo \
 
 (* from internal module *)
 
-(* M => *)
-module M = struct
+module (* M => *) M (* <= M *) = struct
   let (* M.bar => *) bar (* <= M.bar *) = foo
 end
-(* <= M *)
 
 (* to internal module *)
 let _ = M.bar (* ? M.bar *)
 
-(* F => *)
-module F (S : sig val bar : int end) = struct
+module (* F => *) F (* <= F *) (S : sig val bar : int end) = struct
   include S
   let (* F.bar2 => *) bar2 (* <= F.bar2 *) = 
     S.bar (* CR jfuruse: functor abstracted module? *)
   let _ = bar2 (* ? F.bar2 *)
   let _ = bar (* CR jfuruse: functor abstracted module? *)
 end
-(* <= F *)
 
 module N = F (* ? F *)(M (* ? M *))
 
 let ttt = 1
 class type ttt = object val x : float end
 
-(* ext => *)
-external ext : int -> int = "hoge"
-(* <= ext *)
+external (* ext => *)ext(* <= ext *) : int -> int = "hoge"
 let _ = ext (* ? ext *)
  
 module KM : sig
 (* extend the original module *)
 open Path
+module Ident = struct
+  include Ident
+  include Xident
+end
 
 let rec name = function
   | Pident id -> Ident.name id
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.