Commits

camlspotter  committed 36fac6b

cursor move (ongoing)

  • Participants
  • Parent commits 5ea486b

Comments (0)

Files changed (4)

 let function_read_ahead = lbrace_read_ahead
 
 let token state str at_the_head region (t : Parser.token) : State.t * State.t =
+
+  (** Which line the token is in *)
   let line = Region.lnum region in
+
+  (** Which column the token is at *)
   let cols = Region.columns region in
+
+  (** The indent of the current line.
+      If the token is at the head of the line, it may be the original indent
+  *)
   let indent = state.last_indent in
+
+  (** The original indent stack. You must update this. *)
   let bases0 = state.bases in
 
+  (** Just change the indentation to [cols]. Useful at the line heads *)
   let fix cols = [{ k = KNone; indent = cols }] in
 
   (* A basic rule.
         if at_the_head then
           { k = KMatch cols; indent = cols + 2; } :: bases0
         else
-          { k = KMatch indent; indent = cols + 2; } :: bases0
+          (* bit special handling *)
+          let rec compute bases = match bases with
+            | [] -> indent
+            | { k = KLet (_, cols) } :: _ -> max (cols + 2) indent
+            | _ :: bs -> compute bs
+          in
+          { k = KMatch (compute bases0); indent = cols + 2; } :: bases0
 
     | TRY ->
         bases0,
 open Pos
 open Machine
 
-let paths, debug, lines, showstate =
+let paths, debug, lines, showstate, cursor =
   let rev_paths = ref [] in
   let debug = ref false in
   let lines = ref None in
   let showstate = ref false in
+  let cursor = ref None in
   Arg.parse [
     ("-debug", Arg.Set debug, "debugging");
     ("-lines", Arg.String (fun s ->
       with
       | _ -> failwith (Printf.sprintf "Wrong -lines specification: %s" s)),
      "lines, ex. 10-12") ;
+    ("-cursor", Arg.String (fun s ->
+      try
+        let pos = String.index s ':' in
+        let (rows,cols) = (int_of_string (String.sub s 0 pos),
+                           int_of_string (String.sub s (pos+1) (String.length s - pos - 1))) in
+        if rows <= 0 || cols < 0 then
+          failwith (Printf.sprintf "Wrong -cursor specification: %s" s);
+        cursor := Some (rows, cols)
+      with
+      | _ -> failwith (Printf.sprintf "Wrong -cursor specification: %s" s)),
+     "cursor position, ex. 10:12") ;
     ("-show-state", Arg.Set showstate, "show state at the last");
   ] (fun s -> rev_paths := s :: !rev_paths) "indent paths";
   let paths = List.rev !rev_paths in
   | _, Some _ -> failwith "Region can be specified with at most one file"
   | _ -> ()
   end;
-  paths, !debug, !lines, !showstate
+  paths, !debug, !lines, !showstate, !cursor
 
 let check_lines l = function
   | None -> `Inside
         let current_line = Region.lnum orig_region in
         let new_line = last_line <>  current_line in
 
+        (* Where the cursor move *)
+         let _cursor_info = 
+          match cursor with
+          | None -> None
+          | Some lines_cols ->
+              match
+                Pos.Region.contain_lines_cols last_orig_region lines_cols,
+                Pos.Region.contain_lines_cols orig_region lines_cols
+              with
+              | (`In | `Right), _ -> None (* far past *)
+              | `Left, `Right -> None (* far future *)
+              | `Left, `Left -> (* cursor in the space_between *)
+                  Some `In_space_between 
+              | `Left, `In -> (* cursor on the token *)
+                  Some `In_the_token
+              | _ -> assert false (* It must be more tolerant, but for now... *)
+        in
+
         match check_lines (Region.lnum orig_region) lines with
         | `Over -> 
             Printer.add_string printer last_line space_between;
                pos_cnum = 0 }
 
   let columns p = p.pos_cnum - p.pos_bol
+
+  (* ignore filename *)
+  let compare p1 p2 = compare p1.pos_cnum p2.pos_cnum
+
+  let compare_lines_cols p (lines, cols) =
+    match Pervasives.compare p.pos_lnum lines with
+    | -1 -> -1
+    | 1 -> 1
+    | 0 ->
+        let p_cols = p.pos_cnum - p.pos_bol in
+        Pervasives.compare p_cols cols
+    | _ -> assert false
 end
 
 module Region = struct
   let move_chars diff (p,p') = 
     { p  with pos_cnum = p .pos_cnum + diff },
     { p' with pos_cnum = p'.pos_cnum + diff } 
+
+  let contain (start, end_) pos = 
+    match Position.compare start pos, Position.compare pos end_ with
+    | (-1 | 0), (-1 | 0) -> `In
+    | _, 1 -> `Out_right
+    | -1, _ -> `Out_left
+    | _ -> assert false
+
+  let contain_lines_cols (start, end_) l_c = 
+    match Position.compare_lines_cols start l_c, Position.compare_lines_cols end_ l_c with
+    | (-1 | 0), (1 | 0) -> `In
+    | _, -1 -> `Out_right
+    | -1, _ -> `Out_left
+    | _ -> assert false
 end

File tests/begin_match.ml

   else
     0
 
+let _ =
+  let x = match true with
+    | true -> 1
+    | false -> 2
+  in
+  x
+
+let _ =
+  prerr_endline 1; let x = match true with
+    | true -> 1
+    | false -> 2
+  in
+  x