1 -- helpers for the search bar (C-f)
3 function Text
.draw_search_bar(State
)
4 local h
= State
.line_height
+2
5 local y
= App
.screen
.height
-h
6 love
.graphics
.setColor(0.9,0.9,0.9)
7 love
.graphics
.rectangle('fill', 0, y
-10, App
.screen
.width
-1, h
+8)
8 love
.graphics
.setColor(0.6,0.6,0.6)
9 love
.graphics
.line(0, y
-10, App
.screen
.width
-1, y
-10)
10 love
.graphics
.setColor(1,1,1)
11 love
.graphics
.rectangle('fill', 20, y
-6, App
.screen
.width
-40, h
+2, 2,2)
12 love
.graphics
.setColor(0.6,0.6,0.6)
13 love
.graphics
.rectangle('line', 20, y
-6, App
.screen
.width
-40, h
+2, 2,2)
15 App
.screen
.print(State
.search_term
, 25,y
-5)
16 if State
.search_text
== nil then
17 State
.search_text
= App
.newText(love
.graphics
.getFont(), State
.search_term
)
19 Text
.draw_cursor(State
, 25+App
.width(State
.search_text
),y
-5)
22 function Text
.search_next(State
)
23 -- search current line from cursor
24 local pos
= find(State
.lines
[State
.cursor1
.line
].data
, State
.search_term
, State
.cursor1
.pos
)
26 State
.cursor1
.pos
= pos
29 -- search lines below cursor
30 for i
=State
.cursor1
.line
+1,#State
.lines
do
31 pos
= find(State
.lines
[i
].data
, State
.search_term
)
33 State
.cursor1
.line
= i
34 State
.cursor1
.pos
= pos
41 for i
=1,State
.cursor1
.line
-1 do
42 pos
= find(State
.lines
[i
].data
, State
.search_term
)
44 State
.cursor1
.line
= i
45 State
.cursor1
.pos
= pos
51 -- search current line until cursor
52 pos
= find(State
.lines
[State
.cursor1
.line
].data
, State
.search_term
)
53 if pos
and pos
< State
.cursor1
.pos
then
54 State
.cursor1
.pos
= pos
58 State
.cursor1
.line
= State
.search_backup
.cursor
.line
59 State
.cursor1
.pos
= State
.search_backup
.cursor
.pos
60 State
.screen_top1
.line
= State
.search_backup
.screen_top
.line
61 State
.screen_top1
.pos
= State
.search_backup
.screen_top
.pos
63 if Text
.lt1(State
.cursor1
, State
.screen_top1
) or Text
.lt1(State
.screen_bottom1
, State
.cursor1
) then
64 State
.screen_top1
.line
= State
.cursor1
.line
65 local pos
= Text
.pos_at_start_of_screen_line(State
, State
.cursor1
)
66 State
.screen_top1
.pos
= pos
70 function Text
.search_previous(State
)
71 -- search current line before cursor
72 local pos
= rfind(State
.lines
[State
.cursor1
.line
].data
, State
.search_term
, State
.cursor1
.pos
-1)
74 State
.cursor1
.pos
= pos
77 -- search lines above cursor
78 for i
=State
.cursor1
.line
-1,1,-1 do
79 pos
= rfind(State
.lines
[i
].data
, State
.search_term
)
81 State
.cursor1
.line
= i
82 State
.cursor1
.pos
= pos
89 for i
=#State
.lines
,State
.cursor1
.line
+1,-1 do
90 pos
= rfind(State
.lines
[i
].data
, State
.search_term
)
92 State
.cursor1
.line
= i
93 State
.cursor1
.pos
= pos
99 -- search current line after cursor
100 pos
= rfind(State
.lines
[State
.cursor1
.line
].data
, State
.search_term
)
101 if pos
and pos
> State
.cursor1
.pos
then
102 State
.cursor1
.pos
= pos
106 State
.cursor1
.line
= State
.search_backup
.cursor
.line
107 State
.cursor1
.pos
= State
.search_backup
.cursor
.pos
108 State
.screen_top1
.line
= State
.search_backup
.screen_top
.line
109 State
.screen_top1
.pos
= State
.search_backup
.screen_top
.pos
111 if Text
.lt1(State
.cursor1
, State
.screen_top1
) or Text
.lt1(State
.screen_bottom1
, State
.cursor1
) then
112 State
.screen_top1
.line
= State
.cursor1
.line
113 local pos
= Text
.pos_at_start_of_screen_line(State
, State
.cursor1
)
114 State
.screen_top1
.pos
= pos
118 function find(s
, pat
, i
)
119 if s
== nil then return end
120 return s
:find(pat
, i
)
123 function rfind(s
, pat
, i
)
124 if s
== nil then return end
125 local rs
= s
:reverse()
126 local rpat
= pat
:reverse()
127 if i
== nil then i
= #s
end
128 local ri
= #s
- i
+ 1
129 local rendpos
= rs
:find(rpat
, ri
)
130 if rendpos
== nil then return nil end
131 local endpos
= #s
- rendpos
+ 1
132 assert (endpos
>= #pat
)