about summary refs log tree commit diff
path: root/saneterm/search.py
blob: 98cfb343c542ef6a9cafe1a6501fe642f37f66af (plain) (blame)
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
from gi.repository import Gtk

class SearchBar(Gtk.SearchBar):
    "SearchBar implements Gtk.SearchBar on a Gtk.TextBuffer."

    BG_COLOR = "yellow"
    FG_COLOR = "black"

    def __init__(self, buffer):
        Gtk.SearchBar.__init__(self)
        self.__buffer = buffer

        self.__match = None
        self.__tag = buffer.create_tag("search-match",
                background=self.BG_COLOR,
                foreground=self.FG_COLOR)

        search_entry = Gtk.SearchEntry.new()
        search_entry.connect("search-changed", self.__search_changed)
        search_entry.connect("next-match", self.__next_match)
        search_entry.connect("previous-match", self.__prev_match)

        self.set_show_close_button(True)
        self.connect_entry(search_entry)
        self.add(search_entry)

    def __find_match(self, entry, start, forward=True):
        buf = self.__buffer
        text = entry.get_text()

        # Remove old match.
        buf.remove_tag(self.__tag,
                buf.get_start_iter(),
                buf.get_end_iter())

        if forward:
            self.__match = start.forward_search(text, 0, None)
        else:
            self.__match = start.backward_search(text, 0, None)

        if self.__match:
            mstart, mend = self.__match
            buf.apply_tag(self.__tag, mstart, mend)

    def __search_changed(self, entry):
        self.__find_match(entry, self.__buffer.get_start_iter())

    def __next_match(self, entry):
        # Wrap around if no match was found previously.
        if self.__match is None:
            start = self.__buffer.get_start_iter()
        else:
            _, start = self.__match

        self.__find_match(entry, start)

    def __prev_match(self, entry):
        # Wrap around if no match was found previously.
        if self.__match is None:
            start = self.__buffer.get_end_iter()
        else:
            start, _ = self.__match

        self.__find_match(entry, start, forward=False)