Source file rawDocument.ml
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
open Lsp.Types
type text_edit = Range.t * string
type t = {
text : string;
lines : int array;
}
let compute_lines text =
let lines = String.split_on_char '\n' text in
let _,lines_locs = CList.fold_left_map (fun acc s -> let n = String.length s in n + acc + 1, acc) 0 lines in
Array.of_list lines_locs
let create text = { text; lines = compute_lines text }
let text t = t.text
let position_of_loc raw loc =
let i = ref 0 in
while (!i < Array.length raw.lines && raw.lines.(!i) <= loc) do incr(i) done;
Position.{ line = !i - 1; character = loc - raw.lines.(!i - 1) }
let loc_of_position raw Position.{ line; character } =
raw.lines.(line) + character
let end_loc raw =
String.length raw.text
let range_of_loc raw loc =
let open Range in
{ start = position_of_loc raw loc.Loc.bp;
end_ = position_of_loc raw loc.Loc.ep;
}
let word_at_position raw pos : string option =
let r = Str.regexp {|\([a-zA-Z_][a-zA-Z_0-9]*\)|} in
let start = ref (loc_of_position raw pos) in
let word = ref None in
while (Str.string_match r raw.text start.contents) do
start := start.contents - 1;
word := Some (Str.matched_string raw.text);
done;
word.contents
let apply_text_edit raw (Range.{start; end_}, editText) =
let start = loc_of_position raw start in
let stop = loc_of_position raw end_ in
let before = String.sub raw.text 0 start in
let after = String.sub raw.text stop (String.length raw.text - stop) in
let new_text = before ^ editText ^ after in
let new_lines = compute_lines new_text in
{ text = new_text; lines = new_lines }, start
let only_whitespace_between raw loc1 loc2 =
let res = ref true in
for i = loc1 to loc2 do
let code = Char.code raw.text.[i] in
if code <> 0x20 && code <> 0xD && code <> 0xA && code <> 0x9
then res := false
done;
!res