import re, sets, string import color, method, minibuffer, mode2, searchutil from point2 import Point class Replace(mode2.Fundamental): modename = 'Replace' def __init__(self, w): mode2.Fundamental.__init__(self, w) self.actions = {} self.bindings = {} self.add_action_and_bindings(ReplaceAll(), ('a', '!',)) self.add_action_and_bindings(ReplaceOne(), ('y', 'SPACE',)) self.add_action_and_bindings(SkipReplace(), ('n', 'DELETE',)) self.add_action_and_bindings(CancelReplace(), ('q', 'RETURN', 'C-]', 'C-n', 'C-p', 'C-a', 'C-e', 'C-f', 'C-b')) m = w.buffer.method found = _find_next(m, False) if not found: w.set_error('%r was not found' % m.before) raise minibuffer.MiniBufferError _set_prompt(m) class ReplaceOne(method.Method): def execute(self, w, **vargs): m = w.buffer.method _replace(m) _find_next(m, False) _finish(m, w) class SkipReplace(method.Method): def execute(self, w, **vargs): m = w.buffer.method _find_next(m, True) _finish(m, w) class ReplaceAll(method.Method): def execute(self, w, **vargs): m = w.buffer.method while m.p1 is not None: _replace(m) _find_next(m, False) _end(w) w.set_error("Replace ended") class CancelReplace(method.Method): def execute(self, w, **vargs): _end(w) w.set_error("Replace cancelled") def _find_next(m, move=False): s = m.before w = m.old_window c = w.logical_cursor() try: if m.is_literal: r = re.compile(searchutil.escape_literal(s)) else: r = re.compile(s) except: (m.p1, m.p2) = (None, None) return False newc = searchutil.find_next(r, w, move, start=c.add(0, 0)) if newc: (m.p1, m.p2) = newc return True else: (m.p1, m.p2) = (None, None) return False def _set_prompt(m): w = m.old_window if m.p1 is None: w.application.mini_prompt = '%r was not found' % m.before return (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): m.old_window.buffer.delete(m.p1, m.p2) if m.after: m.old_window.buffer.insert_string(m.p1, m.after) def _finish(m, w): if m.p1 is None: _end(w) w.set_error("Replace ended") else: _set_prompt(m) 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 assert not w.application.mini_active