/
tree_cursor.rb
87 lines (70 loc) · 1.36 KB
/
tree_cursor.rb
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
class TreeCursor
@i = 0
@txt = ""
def initialize txt, i=0
raise "1st parameter to TreeCursor.initialize must be a string" unless txt.is_a? String
@i = i
@txt = txt
end
def to_s
"[#{@i}, #{@txt.inspect}]"
end
def inspect
to_s
end
def i; @i; end
def i= num; @i = num; end
def txt; @txt; end
def to_a
@txt.strip.split("\n", -1)
end
def length
@txt.strip.count("\n") + 1
end
def line
to_a[@i]
end
def each &block
@i = 0
while @i < length
# while @i < @txt.split("\n").length
block.call
@i += 1
end
end
def at_leaf?
a = to_a
next_line = a[@i+1]
return true if next_line.nil?
indent = Line.indent a[@i]
next_indent = Line.indent a[@i+1]
indent.length >= next_indent.length
end
def [] index
to_a[index]
end
def select line
line = line.sub /^( *)\+ /, "\\1- "
index = to_a.index{|o| o.sub(/^( *)\+ /, "\\1- ") == line}
@i = index if index
end
def under
result = ""
a = to_a
target_indent = Line.indent(a[@i]).length
i = @i + 1
while i < length
indent = Line.indent(a[i]).length
break if indent <= target_indent
result << "#{a[i]}\n"
i += 1
end
result
end
def index_after
to_a[0..@i].join("\n").length
end
def << lines
@txt.insert index_after+1, lines
end
end