import sets, string import color, method, minibuffer, mode2 from point2 import Point class Replace(mode2.Fundamental): '''This is the default mode''' def __init__(self, w): mode2.Fundamental.__init__(self, w) self.actions = {} self.bindings = {} default_actions = ( (ReplaceAll(), ('a', '!',)), (ReplaceOne(), ('y', 'SPACE',)), (SkipReplace(), ('n', 'DELETE',)), (CancelReplace(), ('q', 'RETURN', 'C-]', 'C-n', 'C-p', 'C-a', 'C-e', 'C-f', 'C-b')), ) # add the replace actions for pair in default_actions: (action, sequences) = pair assert type(sequences) == type(()), repr(pair) self.add_action_and_bindings(action, sequences) _find_next(w, False) _set_prompt(w.buffer.method, w.buffer.method.old_window) def name(self): return "Replace" class ReplaceOne(method.Method): def execute(self, w, **vargs): m = w.buffer.method old_window = m.old_window _replace(m, old_window) _find_next(w, True) _finish(m, w, old_window) class SkipReplace(method.Method): def execute(self, w, **vargs): m = w.buffer.method old_window = m.old_window _find_next(w, True) _finish(m, w, old_window) class ReplaceAll(method.Method): def execute(self, w, **vargs): m = w.buffer.method old_window = m.old_window while m.p1 is not None: _replace(m, old_window) _find_next(w, True) _end(w) w.application.set_error("Replace ended") class CancelReplace(method.Method): def execute(self, w, **vargs): _end(w) w.application.set_error("Replace cancelled") def _set_prompt(m, w): (x, y) = m.p1.xy() count = 0 while y < len(w.buffer.lines): count += w.buffer.lines[y][x:].count(m.before) y += 1 x = 0 if count > 1: p = 'Replace %r with %r [ynaq] (%d occurances)?' % (m.before, m.after, count) else: p = 'Replace %r with %r [ynaq] (1 occurance)?' % (m.before, m.after) w.application.mini_prompt = p def _replace(m, old_window): old_window.buffer.delete(m.p1, m.p2) if m.after: old_window.buffer.insert_string(m.p1, m.after) def _find_next(w, move=False): m = w.buffer.method old_window = m.old_window b = old_window.buffer s = m.before c = old_window.logical_cursor() (x, y) = (c.x, c.y) if move: x += 1 l = b.lines[y][x:] # for each line available while y < len(b.lines): if s in l: # success x = x + l.index(s) x2 = x + len(s) m.p1 = Point(x, y) m.p2 = Point(x2, y) old_window.goto(m.p1) old_window.application.clear_highlighted_ranges() old_window.application.add_highlighted_range(old_window, m.p1, m.p2) #old_window.application.highlighted_range = [old_window, m.p1, m.p2] _set_prompt(m, old_window) return elif y >= len(b.lines) - 1: # failure break else: # keep trying y += 1 l = b.lines[y] x = 0 m.p1 = None m.p2 = None def _finish(m, w, old_window): if m.p1 is None: _end(w) w.application.set_error("Replace ended") else: _set_prompt(m, old_window) def _end(w): w.application.close_mini_buffer() w.application.clear_highlighted_ranges() w.buffer.method.old_cursor = None w.buffer.method.old_window = None