import sets, string import color, method, minibuffer, mode2 from point2 import Point class Search(mode2.Fundamental): '''This is the default mode''' def __init__(self, w): mode2.Fundamental.__init__(self, w) self.actions = {} self.bindings = {} default_actions = ( (SearchNext(), ('C-s',)), (SearchPrevious(), ('C-r',)), (EndSearch(), ('RETURN', 'C-n', 'C-p', 'C-a', 'C-e', 'C-f', 'C-b')), (CancelSearch(), ('C-]',)), (DeleteLeft(), ('DELETE', 'BACKSPACE',)), (DeleteLeftWord(), ('M-DELETE', 'M-BACKSPACE',)), ) # add the search actions for pair in default_actions: (action, sequences) = pair assert type(sequences) == type(()), repr(pair) self.add_action_and_bindings(action, sequences) # create all the insert actions for the character ranges we like for collection in (string.letters, string.digits, string.punctuation): for c in collection: self.add_action_and_bindings(InsertSearchString(c), (c,)) self.add_action_and_bindings(InsertSearchString(' '), ('SPACE',)) def name(self): return "Search" class SearchNext(method.Method): def execute(self, w, **vargs): w.buffer.method.direction = 'next' s = w.buffer.make_string() if not s: s = w.application.last_search w.buffer.set_data(s) else: old_w = w.buffer.method.old_window _find_next(old_w, w, move=True) class SearchPrevious(method.Method): def execute(self, w, **vargs): w.buffer.method.direction = 'previous' s = w.buffer.make_string() if not s: return else: old_w = w.buffer.method.old_window _find_previous(old_w, w, move=True) class EndSearch(method.Method): def execute(self, w, **vargs): old_w = w.buffer.method.old_window old_cursor = w.buffer.method.old_cursor _end(w) old_w.set_mark_point(old_cursor) w.set_error("Mark set to search start") class CancelSearch(method.Method): def execute(self, w, **vargs): old_w = w.buffer.method.old_window old_cursor = w.buffer.method.old_cursor old_w.goto(old_cursor) _end(w) w.set_error("Search cancelled") class DeleteLeft(method.Method): def execute(self, w, **vargs): w.left_delete() old_cursor = w.buffer.method.old_cursor old_w = w.buffer.method.old_window old_w.goto(old_cursor) _end(w) return if w.buffer.method.direction == 'next': _find_next(old_w, w, move=False) else: _find_previous(old_w, w, move=False) class DeleteLeftWord(method.Method): def execute(self, w, **vargs): w.kill_left_word() old_cursor = w.buffer.method.old_cursor old_w = w.buffer.method.old_window old_w.goto(old_cursor) if w.buffer.method.direction == 'next': _find_next(old_w, w, move=False) else: _find_previous(old_w, w, move=False) class InsertSearchString(method.Method): def __init__(self, s): self.name = 'insert-search-string-%s' % (s) self.string = s self.args = [] self.help = None def execute(self, w, **vargs): w.insert_string_at_cursor(self.string) s = w.buffer.make_string() if not s: return else: old_w = w.buffer.method.old_window if w.buffer.method.direction == 'next': _find_next(old_w, w, move=False) else: _find_previous(old_w, w, move=False) def _end(w): s = w.buffer.make_string() w.application.last_search = s w.application.close_mini_buffer() #w.application.highlighted_range = [] w.application.clear_highlighted_ranges() w.buffer.method.old_cursor = None w.buffer.method.old_window = None def _find_previous(old_w, new_w, move=False): s = new_w.buffer.make_string() old_b = old_w.buffer c = old_w.logical_cursor() (x, y) = (c.x, c.y) if move: x -= 1 l = old_b.lines[y][:x + len(s)] # for each line available while y >= 0: if s in l: # success x = l.index(s) old_w.goto(Point(x, y)) old_w.application.clear_highlighted_ranges() new_w.application.add_highlighted_range(old_w, Point(x,y), Point(x + len(s), y)) break elif y >= len(old_b.lines) - 1: # failure break else: # keep trying y -= 1 l = old_b.lines[y] x = 0 def _find_next(old_w, new_w, move=False): s = new_w.buffer.make_string() old_b = old_w.buffer c = old_w.logical_cursor() (x, y) = (c.x, c.y) if move: x += 1 l = old_b.lines[y][x:] # for each line available while y < len(old_b.lines): if s in l: # success x = l.index(s) + x old_w.goto(Point(x, y)) old_w.application.clear_highlighted_ranges() new_w.application.add_highlighted_range(old_w, Point(x,y), Point(x + len(s), y)) break elif y >= len(old_b.lines) - 1: # failure break else: # keep trying y += 1 l = old_b.lines[y] x = 0