-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcursor.ml
More file actions
96 lines (82 loc) · 2.33 KB
/
cursor.ml
File metadata and controls
96 lines (82 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
(***********************************************************************)
(* *)
(* Ledit *)
(* *)
(* Daniel de Rauglaudre, INRIA Rocquencourt *)
(* *)
(* Copyright 2001-2006 Institut National de Recherche en Informatique *)
(* et Automatique. Distributed only by permission. *)
(* *)
(***********************************************************************)
(* $Id$ *)
type t 'a =
{ before : mutable list 'a;
current : mutable option 'a;
after : mutable list 'a }
;
exception Failure;
value create () = {before = []; current = None; after = []};
value before c =
match c.before with
[ [] -> raise Failure
| [x :: l] -> do {
match c.current with
[ Some y -> c.after := [y :: c.after]
| _ -> () ];
c.current := Some x;
c.before := l
} ]
;
value after c =
match c.current with
[ None -> raise Failure
| Some y -> do {
c.before := [y :: c.before];
match c.after with
[ [] -> c.current := None
| [x :: l] -> do { c.current := Some x; c.after := l } ]
} ]
;
value is_last_line c = c.current = None;
value insert c x = do {
match c.current with
[ Some y -> c.before := [y :: c.before]
| None -> () ];
c.current := Some x
};
value insert_last c x =
match c.current with
[ Some _ -> c.after := c.after @ [x]
| None -> c.current := Some x ]
;
value peek c =
match c.current with
[ Some y -> y
| None -> raise Failure ]
;
value peek_last c =
let rec peek_rec =
fun
[ [] -> raise Failure
| [x] -> x
| [_ :: l] -> peek_rec l ]
in
match (c.before, c.current, c.after) with
[ (_, Some x, []) -> x
| ([x :: _], None, []) -> x
| (_, _, l) -> peek_rec l ]
;
value rec goto_first c =
try while True do { before c } with [ Failure -> () ]
;
value rec goto_last c =
try while True do { after c } with [ Failure -> () ]
;
value get_all c =
let end_list =
match c.current with
[ Some y -> [y :: c.after]
| None -> c.after ]
in
List.rev_append c.before end_list
;