New release.
[rox-edit.git] / search.py
blob64a107dd1d707ba66425c94b4b26f3f705353fe5
1 import rox
2 from rox import g
3 from EditWindow import Minibuffer
5 class Search(Minibuffer):
6 "A minibuffer used to search for text."
8 def setup(self, window):
9 self.window = window
10 buffer = window.buffer
11 cursor = buffer.get_iter_at_mark(window.insert_mark)
12 buffer.move_mark_by_name('search_base', cursor)
13 self.dir = 1
14 self.set_label()
16 info = 'Type a string to search for. The display will scroll to show the ' \
17 'next match as you type. Use the Up and Down cursor keys to move ' \
18 'to the next or previous match. Press Escape or Return to finish.'
20 def set_label(self):
21 if self.dir == 1:
22 self.window.set_mini_label('Forward search:')
23 else:
24 self.window.set_mini_label('Backward search:')
26 def set_dir(self, dir):
27 assert dir == 1 or dir == -1
29 buffer = self.window.buffer
30 cursor = buffer.get_iter_at_mark(self.window.insert_mark)
31 buffer.move_mark_by_name('search_base', cursor)
33 if dir == self.dir:
34 if dir == 1:
35 cursor.forward_char()
36 else:
37 cursor.backward_char()
38 if self.search(cursor):
39 buffer.move_mark_by_name('search_base', cursor)
40 else:
41 g.gdk.beep()
42 else:
43 self.dir = dir
44 self.set_label()
45 self.changed()
47 def activate(self):
48 self.window.set_minibuffer(None)
50 def key_press(self, kev):
51 k = kev.keyval
52 if k == g.keysyms.Up:
53 self.set_dir(-1)
54 elif k == g.keysyms.Down:
55 self.set_dir(1)
56 else:
57 return 0
58 return 1
60 def search(self, start):
61 "Search forwards or backwards for the pattern. Matches at 'start'"
62 "are allowed in both directions. Returns (match_start, match_end) if"
63 "found."
64 iter = start.copy()
65 pattern = self.window.mini_entry.get_text()
66 if not pattern:
67 return (iter, iter)
68 if self.dir == 1:
69 found = iter.forward_search(pattern, 0, None)
70 else:
71 iter.forward_chars(len(pattern))
72 found = iter.backward_search(pattern, 0, None)
73 return found
75 def changed(self):
76 buffer = self.window.buffer
77 pos = buffer.get_iter_at_mark(self.window.search_base)
79 found = self.search(pos)
80 if found:
81 buffer.move_mark_by_name('insert', found[0])
82 buffer.move_mark_by_name('selection_bound', found[1])
83 self.window.text.scroll_to_iter(found[0], 0.05, g.FALSE)
84 else:
85 g.gdk.beep()