Source

ocaml-indent / pos.ml

open Spotlib.Spot

module Position = struct
  open Sexplib.Conv

  type t = Lexing.position =  {
    pos_fname : string;
    pos_lnum : int;
    pos_bol : int;
    pos_cnum : int;
  } with sexp

  let show t = 
    Printf.sprintf "%s%d:%d" 
      (if t.pos_fname = "" then "" else t.pos_fname ^ ":")
      t.pos_lnum 
      (t.pos_cnum - t.pos_bol)

  let format ppf t = Format.fprintf ppf "%s" & show t

  let top fname = { pos_fname = fname;
                    pos_lnum = 1;
                    pos_bol = 0;
                    pos_cnum = 0 }

  let none = Lexing.dummy_pos

(*
  let zero = { pos_fname = "";
               pos_lnum = 1;
               pos_bol = 0;
               pos_cnum = 0 }

  let zero = { pos_fname = "";
               pos_lnum = 0;
               pos_bol = 0;
               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
  open Position
  type t = Position.t * Position.t with sexp
  let lnum (p,_) = p.pos_lnum
  let columns (p,_) = columns p
(*  let zero = (Position.zero, Position.zero) *) (* CR jfuruse: to be removed *)
  let none = (Position.none, Position.none)
  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

module Lines = struct
  type t = WholeFile | Lines of int * int

  (** [l] is in the interested area or not? *)
  let is_between : int -> t -> [> `Before | `Inside | `Over ] = 
    fun l -> function
      | WholeFile -> `Inside
      | Lines (start, end_) ->
          if l < start then `Before
          else if l <= end_ then `Inside
          else `Over
end
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.