From 1e3a417fb93d2529002d54a48c42db93114abf85 Mon Sep 17 00:00:00 2001 From: moculus Date: Mon, 9 Jul 2007 22:31:59 +0000 Subject: [PATCH] regex searching is complete --HG-- branch : pmacs2 --- keyinput.py | 6 ------ method.py | 24 ++++++++++++++---------- mode2.py | 2 ++ mode_search.py | 29 ++++++++++++++++------------- search.py | 29 ++++++++++++++--------------- 5 files changed, 46 insertions(+), 44 deletions(-) diff --git a/keyinput.py b/keyinput.py index 8ffe549..e95eb97 100644 --- a/keyinput.py +++ b/keyinput.py @@ -113,14 +113,10 @@ class Handler: def __init__(self): self.tokens = [] self.unset_meta() - def unset_meta(self): self.meta = MAP - self.has_meta = False - def set_meta(self, d): self.meta = d - self.has_meta = True def parse(self, i): if i == -1: @@ -142,8 +138,6 @@ class Handler: else: # we got a regular character # we may have interrupted a meta sequence... so unset it - #if self.has_meta: - # self.tokens.append("ESC") self.unset_meta() if(32 < i and i < 127): diff --git a/method.py b/method.py index 59564c4..d6cfe4d 100644 --- a/method.py +++ b/method.py @@ -137,20 +137,24 @@ class ForwardLines(Method): # search and replace class Search(Method): '''Interactive search; finds next occurance of text in buffer''' + direction = 'next' + is_literal = True + prompt = 'I-Search: ' def execute(self, w, **vargs): self.old_cursor = w.logical_cursor() self.old_window = w - self.direction = 'next' - self.is_literal = True - w.application.open_mini_buffer('I-Search: ', lambda x: None, self, None, 'search') -class ReverseSearch(Method): + w.application.open_mini_buffer(self.prompt, lambda x: None, self, None, 'search') +class ReverseSearch(Search): '''Interactive search; finds previous occurance of text in buffer''' - def execute(self, w, **vargs): - self.old_cursor = w.logical_cursor() - self.old_window = w - self.direction = 'previous' - self.is_literal = True - w.application.open_mini_buffer('I-Search: ', lambda x: None, self, None, 'search') + direction = 'previous' +class RegexSearch(Search): + '''Interactive search; finds next occurance of regex in buffer''' + is_literal = False + prompt = 'I-RegexSearch: ' +class RegexReverseSearch(RegexSearch): + '''Interactive search; finds prevoius occurance of regex in buffer''' + direction = 'previous' + class Replace(Method): '''Replace occurances of string X with string Y''' args = [Argument('before', prompt="Replace: ", diff --git a/mode2.py b/mode2.py index cced555..f16eb9c 100644 --- a/mode2.py +++ b/mode2.py @@ -107,6 +107,8 @@ class Fundamental(Handler): self.add_bindings('forward-lines', ('C-x M-n',)) self.add_bindings('search', ('C-s',)) self.add_bindings('reverse-search', ('C-r',)) + self.add_bindings('regex-search', ('M-C-s',)) + self.add_bindings('regex-reverse-search', ('M-C-r',)) self.add_bindings('toggle-margins', ('M-m',)) self.add_bindings('replace', ('M-%',)) self.add_bindings('open-file', ('C-x C-f',)) diff --git a/mode_search.py b/mode_search.py index 0d63315..155cc8e 100644 --- a/mode_search.py +++ b/mode_search.py @@ -33,18 +33,21 @@ class Search(mode2.Fundamental): return "Search" def _make_regex(w, s): - if w.buffer.method.is_literal: - s = search.escape_literal(s) - return re.compile(s) + try: + if w.buffer.method.is_literal: + s = search.escape_literal(s) + return re.compile(s) + except: + raise search.IllegalPatternError, "failed to compile: %r" % s class SearchNext(method.Method): def execute(self, w, **vargs): w.buffer.method.direction = 'next' s = w.buffer.make_string() - r = _make_regex(w, s) if s: try: - search.find_next(s, w.buffer.method.old_window, move=True) + r = _make_regex(w, s) + search.find_next(r, w.buffer.method.old_window, move=True) except search.IllegalPatternError: w.application.clear_highlighted_ranges() else: @@ -57,10 +60,10 @@ class SearchPrevious(method.Method): return else: s = w.buffer.make_string() - r = _make_regex(w, s) w2 = w.buffer.method.old_window try: - search.find_previous(s, w2, move=True) + r = _make_regex(w, s) + search.find_previous(r, w2, move=True) except search.IllegalPatternError: w.application.clear_highlighted_ranges() @@ -94,13 +97,13 @@ def _post_delete(w): w.application.clear_highlighted_ranges() return s = w.buffer.make_string() - r = _make_regex(w, s) w2 = w.buffer.method.old_window try: + r = _make_regex(w, s) if w.buffer.method.direction == 'next': - search.find_next(s, w2, move=False) + search.find_next(r, w2, move=False) else: - search.find_previous(s, w2, move=False) + search.find_previous(r, w2, move=False) except search.IllegalPatternError: w.application.clear_highlighted_ranges() @@ -117,13 +120,13 @@ class InsertSearchString(method.Method): return else: s = w.buffer.make_string() - r = _make_regex(w, s) w2 = w.buffer.method.old_window try: + r = _make_regex(w, s) if w.buffer.method.direction == 'next': - search.find_next(s, w2, move=False) + search.find_next(r, w2, move=False) else: - search.find_previous(s, w2, move=False) + search.find_previous(r, w2, move=False) except search.IllegalPatternError: w.application.clear_highlighted_ranges() diff --git a/search.py b/search.py index b29bca2..68dc6b0 100644 --- a/search.py +++ b/search.py @@ -12,7 +12,7 @@ class IllegalPatternError(Exception): def escape_literal(s): return regex.meta_chars.sub(r'\\\1', s) -def find_ranges(s, w, start=None, end=None): +def find_ranges(r, w, start=None, end=None): if not w.buffer.lines: return [] @@ -25,11 +25,6 @@ def find_ranges(s, w, start=None, end=None): else: (x2, y2) = end.xy() - #s2 = escape_literal(s) - #r = re.compile(s2, re.IGNORECASE) - - r = re.compile(s, re.IGNORECASE) - ranges = [] while y <= y2: if y == y2: @@ -38,17 +33,17 @@ def find_ranges(s, w, start=None, end=None): limit = len(w.buffer.lines[y]) - 1 for m in r.finditer(w.buffer.lines[y], x, limit): if len(m.group(0)) == 0: - raise IllegalPatternError, "zero-width match found for: %r" % s + raise IllegalPatternError, "zero-width match found" ranges.append([Point(m.start(), y), Point(m.end(), y), bg_color, unselected_color]) x = 0 y += 1 return ranges -def find(s, w, move=False, direction='next', start=None, end=None): +def find(r, w, move=False, direction='next', start=None, end=None): app = w.application c = w.logical_cursor() newc = None - ranges = find_ranges(s, w, start, end) + ranges = find_ranges(r, w, start, end) indices = range(0, len(ranges)) (x, y) = c.xy() if move: @@ -58,7 +53,12 @@ def find(s, w, move=False, direction='next', start=None, end=None): if direction == 'next': limit = Point(x - 1 + offset, y) else: - limit = Point(x + len(s) + 1 - offset, y) + limit = Point(x + 1 - offset, y) + for stuff in app.highlighted_ranges: + (wz, p1, p2, fg, bg) = stuff + if p1.y == c.y and p1.x == c.x: + limit = Point(x + 1 + p2.x - p1.x - offset, y) + break indices.reverse() for i in indices: if ((direction == 'next' and ranges[i][0] > limit) or @@ -79,8 +79,7 @@ def find(s, w, move=False, direction='next', start=None, end=None): app.add_highlighted_range(w, p1, p2, fg, bg) return newc -def find_previous(s, w, move=False, start=None, end=None): - return find(s, w, move, 'previous', start, end) - -def find_next(s, w, move=False, start=None, end=None): - return find(s, w, move, 'next', start, end) +def find_previous(r, w, move=False, start=None, end=None): + return find(r, w, move, 'previous', start, end) +def find_next(r, w, move=False, start=None, end=None): + return find(r, w, move, 'next', start, end)