Skip to content

Commit

Permalink
History: split seek into seek_forward and seek_backward
Browse files Browse the repository at this point in the history
  • Loading branch information
let-def committed Feb 17, 2013
1 parent 9d51165 commit f38c856
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 37 deletions.
2 changes: 1 addition & 1 deletion command.ml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ let command_seek = {
failwith "TODO" failwith "TODO"


| [`String "end"] -> | [`String "end"] ->
let outlines = History.seek (fun _ -> 1) state.outlines in let outlines = History.seek_forward (fun _ -> true) state.outlines in
let chunks = History.Sync.right fst outlines state.chunks in let chunks = History.Sync.right fst outlines state.chunks in
let types = History.Sync.right fst chunks state.types in let types = History.Sync.right fst chunks state.types in
let pos = let pos =
Expand Down
65 changes: 41 additions & 24 deletions history.ml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ let prev = function
| _ -> None | _ -> None


let prevs { prev } = prev let prevs { prev } = prev

let next = function let next = function
| { next = n :: _ } -> Some n | { next = n :: _ } -> Some n
| _ -> None | _ -> None
Expand All @@ -26,7 +26,7 @@ let nexts { next } = next


type offset = int type offset = int
let offset { pos } = pos let offset { pos } = pos

let move amount h = let move amount h =
let rec shift count lx ly = let rec shift count lx ly =
match count, lx, ly with match count, lx, ly with
Expand All @@ -37,10 +37,10 @@ let move amount h =
let diff, prev, next = shift amount h.prev h.next in let diff, prev, next = shift amount h.prev h.next in
let moved = amount - diff in let moved = amount - diff in
{ prev ; next ; pos = h.pos + moved } { prev ; next ; pos = h.pos + moved }

let seek_offset offset h = let seek_offset offset h =
move (offset - h.pos) h move (offset - h.pos) h



let forward = function let forward = function
| { prev ; next = n :: ns ; pos } -> | { prev ; next = n :: ns ; pos } ->
Expand All @@ -65,25 +65,37 @@ let modify f = function
{ prev = (f p) :: ps ; next ; pos } { prev = (f p) :: ps ; next ; pos }
| x -> x | x -> x


let seek_forward cmp = let wrap_seek f { prev ; next ; pos } =
let prev, next, pos = f prev next pos in
{ prev ; next ; pos }

let seek_forward p =
let rec aux prev next pos = let rec aux prev next pos =
match next with match next with
| t :: next' when cmp t > 0 -> | t :: next' when p t ->
aux (t :: prev) next' (succ pos) aux (t :: prev) next' (succ pos)
| _ -> prev, next, pos | _ -> prev, next, pos
in in
aux wrap_seek aux


let seek_backward cmp = let seek_backward p =
let rec aux prev next pos = let rec aux prev next pos =
match prev with match prev with
| t :: prev' when cmp t < 0 -> | t :: prev' when p t ->
aux prev' (t :: next) (pred pos) aux prev' (t :: next) (pred pos)
| _ -> prev, next, pos | _ -> prev, next, pos
in in
aux wrap_seek aux


let seek cmp { prev ; next ; pos } = (** [seek cmp hist] returns a history such that, if [p] and [n] are
* the previous and next element of history, then both [cmp p >= 0] and
* [cmp n <= 0] hold.
*
* For example, [seek (fun p -> Pervasives.compare p0 p) hist] will
* move the history to the position [p0], if it exists.
*)
(* val seek : ('a -> int) -> 'a t -> 'a t *)
(*let seek cmp { prev ; next ; pos } =
let prev', next', pos' = let prev', next', pos' =
match prev, next with match prev, next with
| (t :: prev'), next when cmp t < 0 -> | (t :: prev'), next when cmp t < 0 ->
Expand All @@ -92,9 +104,8 @@ let seek cmp { prev ; next ; pos } =
seek_forward cmp (t :: prev) next (succ pos) seek_forward cmp (t :: prev) next (succ pos)
| _ -> prev, next, pos | _ -> prev, next, pos
in in
{ prev = prev' ; next = next' ; pos = pos' } { prev = prev' ; next = next' ; pos = pos' }*)


(* val wrap : ('a * pos * pos) t ref -> (Lexing.lexbuf -> 'a) -> (Lexing.lexbuf -> 'a) *)
type 'a loc = 'a * pos * pos type 'a loc = 'a * pos * pos


let wrap_lexer ?(filter=fun _-> true) ?bufpos r f buf = let wrap_lexer ?(filter=fun _-> true) ?bufpos r f buf =
Expand All @@ -109,7 +120,7 @@ let wrap_lexer ?(filter=fun _-> true) ?bufpos r f buf =
| Some p -> buf.Lexing.lex_curr_p <- !p | Some p -> buf.Lexing.lex_curr_p <- !p
| None -> ()); | None -> ());
let t = f buf in let t = f buf in
if filter t then if filter t then
r := insert (t,buf.Lexing.lex_start_p,buf.Lexing.lex_curr_p) !r; r := insert (t,buf.Lexing.lex_start_p,buf.Lexing.lex_curr_p) !r;
(match bufpos with (match bufpos with
| Some p -> p := buf.Lexing.lex_curr_p; | Some p -> p := buf.Lexing.lex_curr_p;
Expand All @@ -123,26 +134,32 @@ let current_pos ?(default=Lexing.dummy_pos) hist =
| Some (_,_,p) -> p | Some (_,_,p) -> p
| _ -> default | _ -> default


let seek_pos pos = let seek_pos pos h =
seek (fun (_,_,p) -> compare pos.Lexing.pos_cnum p.Lexing.pos_cnum) let cmp (_,_,p) = compare pos.Lexing.pos_cnum p.Lexing.pos_cnum in
let go_backward item = cmp item < 0 in
let go_forward item = cmp item > 0 in
match backward h with
| Some (item,h') when go_backward item ->
seek_backward go_backward h'
| _ -> seek_forward go_forward h


type 'a sync = (int * 'a) option type 'a sync = (int * 'a) option


module Sync = module Sync =
struct struct
let origin = None let origin = None

let (>>=) = function let (>>=) = function
| None -> fun _ -> None | None -> fun _ -> None
| Some a -> fun f -> f a | Some a -> fun f -> f a

let at h = let at h =
prev h >>= fun a -> Some (offset h, a) prev h >>= fun a -> Some (offset h, a)

let item = function let item = function
| None -> None | None -> None
| Some (_,a) -> Some a | Some (_,a) -> Some a

let rec nearest f ah bh = let rec nearest f ah bh =
let point = prev bh >>= f in let point = prev bh >>= f in
let found = point >>= let found = point >>=
Expand All @@ -155,7 +172,7 @@ struct
match found with match found with
| Some a -> a | Some a -> a
| None -> seek_offset 0 ah, seek_offset 0 bh | None -> seek_offset 0 ah, seek_offset 0 bh

let rec rewind f ah bh = let rec rewind f ah bh =
let point = prev bh >>= f in let point = prev bh >>= f in
let found = point >>= let found = point >>=
Expand All @@ -171,7 +188,7 @@ struct
match found with match found with
| Some a -> a | Some a -> a
| None -> seek_offset 0 ah, seek_offset 0 bh | None -> seek_offset 0 ah, seek_offset 0 bh

let right f ah bh = let right f ah bh =
let off = offset ah in let off = offset ah in
let rec loop bh = let rec loop bh =
Expand All @@ -189,7 +206,7 @@ struct
match backward bh with match backward bh with
| Some (_,bh') -> loop bh' | Some (_,bh') -> loop bh'
| None -> loop bh | None -> loop bh

let left f ah bh = let left f ah bh =
let off = let off =
match prev bh >>= f with match prev bh >>= f with
Expand Down
18 changes: 7 additions & 11 deletions history.mli
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -39,36 +39,32 @@ type offset = int
val offset : 'a t -> offset val offset : 'a t -> offset
val seek_offset : offset -> 'a t -> 'a t val seek_offset : offset -> 'a t -> 'a t


(** Move forward while item under cursor satisfy predicate *)
val seek_forward : ('a -> bool) -> 'a t -> 'a t
(** Move backward while item under cursor satisfy predicate *)
val seek_backward : ('a -> bool) -> 'a t -> 'a t

(** Moves one step in the future, returning the next element (** Moves one step in the future, returning the next element
* and shifted history (if they exist). * and shifted history (if they exist).
* *
* If [forward t = Some (e, t')], then [next t = Some e = prev t']. * If [forward t = Some (e, t')], then [next t = Some e = prev t'].
*) *)


val forward : 'a t -> ('a * 'a t) option val forward : 'a t -> ('a * 'a t) option


(** Moves one step in the past, returning the previous element (** Moves one step in the past, returning the previous element
* and shifted history (if they exist). * and shifted history (if they exist).
* *
* If [backward t = Some (e, t')] then [prev t = Some e = next t']. * If [backward t = Some (e, t')] then [prev t = Some e = next t'].
*) *)
val backward : 'a t -> ('a * 'a t) option val backward : 'a t -> ('a * 'a t) option


(** Moves an arbitrary number of steps. (** Moves an arbitrary number of steps.
* *
* May stop early if it reaches an end of history. * May stop early if it reaches an end of history.
*) *)
val move : int -> 'a t -> 'a t val move : int -> 'a t -> 'a t


(** [seek cmp hist] returns a history such that, if [p] and [n] are
* the previous and next element of history, then both [cmp p >= 0] and
* [cmp n <= 0] hold.
*
* For example, [seek (fun p -> Pervasives.compare p0 p) hist] will
* move the history to the position [p0], if it exists.
*)
val seek : ('a -> int) -> 'a t -> 'a t

(** Adds an element to the left of the cursor: (** Adds an element to the left of the cursor:
* insert w [..zyx|abc..] = [..zyxw|abc..] *) * insert w [..zyx|abc..] = [..zyxw|abc..] *)
val insert : 'a -> 'a t -> 'a t val insert : 'a -> 'a t -> 'a t
Expand Down
4 changes: 3 additions & 1 deletion outline.ml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ let seek cmp t =
| [] -> failwith "Outline.seek: Invalid t" | [] -> failwith "Outline.seek: Invalid t"
| _ -> 1 | _ -> 1
in in
History.seek seek_func (History.seek seek_func t) let go_forward t = seek_func t > 0 in
let go_backward t = seek_func t < 0 in
History.seek_backward go_backward (History.seek_forward go_forward t)


let seek_before pos t = let seek_before pos t =
let cmp = Misc.compare_pos pos in let cmp = Misc.compare_pos pos in
Expand Down

0 comments on commit f38c856

Please sign in to comment.