spurious args
[lines.love.git] / search.lua
blobbd28d5834cda700273a743f2aab593a35f71eaa8
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)
14 App.color(Text_color)
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)
18 end
19 Text.draw_cursor(State, 25+App.width(State.search_text),y-5)
20 end
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)
25 if pos then
26 State.cursor1.pos = pos
27 end
28 if pos == nil then
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)
32 if pos then
33 State.cursor1.line = i
34 State.cursor1.pos = pos
35 break
36 end
37 end
38 end
39 if pos == nil then
40 -- wrap around
41 for i=1,State.cursor1.line-1 do
42 pos = find(State.lines[i].data, State.search_term)
43 if pos then
44 State.cursor1.line = i
45 State.cursor1.pos = pos
46 break
47 end
48 end
49 end
50 if pos == nil then
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
55 end
56 end
57 if pos == nil then
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
62 end
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
67 end
68 end
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)
73 if pos then
74 State.cursor1.pos = pos
75 end
76 if pos == nil then
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)
80 if pos then
81 State.cursor1.line = i
82 State.cursor1.pos = pos
83 break
84 end
85 end
86 end
87 if pos == nil then
88 -- wrap around
89 for i=#State.lines,State.cursor1.line+1,-1 do
90 pos = rfind(State.lines[i].data, State.search_term)
91 if pos then
92 State.cursor1.line = i
93 State.cursor1.pos = pos
94 break
95 end
96 end
97 end
98 if pos == nil then
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
105 if pos == nil then
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)
133 return endpos-#pat+1