-
Notifications
You must be signed in to change notification settings - Fork 70
/
erlide_scan_util.erl
55 lines (46 loc) · 2.05 KB
/
erlide_scan_util.erl
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
%% @author jakob
%% @doc @todo Add description to erlide_scan_util.
-module(erlide_scan_util).
-export([split_lines_w_lengths/1, find_line_w_offset/2]).
%% [{Length, TextIncNL}...]
split_lines_w_lengths(Text) ->
split_lines_w_lengths(Text, 0, [], []).
split_lines_w_lengths("", _Length, [], Acc) ->
lists:reverse(Acc);
split_lines_w_lengths("", Length, LineAcc, Acc) ->
lists:reverse(Acc, [{Length, lists:reverse(LineAcc)}]);
split_lines_w_lengths("\r\n" ++ Text, Length, LineAcc, Acc) ->
split_lines_w_lengths(Text, 0, [],
[{Length+2, lists:reverse(LineAcc, "\r\n")} | Acc]);
split_lines_w_lengths("\n" ++ Text, Length, LineAcc, Acc) ->
split_lines_w_lengths(Text, 0, [],
[{Length+1, lists:reverse(LineAcc, "\n")} | Acc]);
split_lines_w_lengths("\r" ++ Text, Length, LineAcc, Acc) ->
split_lines_w_lengths(Text, 0, [],
[{Length+1, lists:reverse(LineAcc, "\r")} | Acc]);
split_lines_w_lengths([C | Text], Length, LineAcc, Acc) ->
split_lines_w_lengths(Text, Length+1, [C | LineAcc], Acc).
%% Find a line from [{Length, Line
find_line_w_offset(Offset, Lines) ->
find_line_w_offset(Offset, 0, 0, Lines).
find_line_w_offset(0, _Pos, _N, []) ->
{0, 0, 0, "", on_eof};
find_line_w_offset(_Offset, _Pos, _N, []) ->
not_found;
find_line_w_offset(Offset, Pos, N, [{Length, _Line} | Lines]) when Offset >= Pos+Length, Lines =/= [] ->
find_line_w_offset(Offset, Pos+Length, N+1, Lines);
find_line_w_offset(Offset, Pos, N, [{Length, Line} |_]) when Pos =< Offset, Offset < Pos + Length ->
{N, Pos, Length, Line, false};
find_line_w_offset(Offset, Pos, N, [{Length, Line}]) ->
case ends_with_newline(Line) orelse Offset > Pos + Length of
true ->
{N+1, Pos+Length, 0, "", beyond_eof};
false ->
{N, Pos+Length, Length, Line, on_eof}
end.
ends_with_newline("") -> false;
ends_with_newline("\n") -> true;
ends_with_newline("\r") -> true;
ends_with_newline("\r\n") -> true;
ends_with_newline([_C | R]) ->
ends_with_newline(R).