regex searching is complete

--HG--
branch : pmacs2
This commit is contained in:
moculus 2007-07-09 22:31:59 +00:00
parent b5deaab9a8
commit 1e3a417fb9
5 changed files with 46 additions and 44 deletions

View File

@ -113,14 +113,10 @@ class Handler:
def __init__(self): def __init__(self):
self.tokens = [] self.tokens = []
self.unset_meta() self.unset_meta()
def unset_meta(self): def unset_meta(self):
self.meta = MAP self.meta = MAP
self.has_meta = False
def set_meta(self, d): def set_meta(self, d):
self.meta = d self.meta = d
self.has_meta = True
def parse(self, i): def parse(self, i):
if i == -1: if i == -1:
@ -142,8 +138,6 @@ class Handler:
else: else:
# we got a regular character # we got a regular character
# we may have interrupted a meta sequence... so unset it # we may have interrupted a meta sequence... so unset it
#if self.has_meta:
# self.tokens.append("ESC")
self.unset_meta() self.unset_meta()
if(32 < i and i < 127): if(32 < i and i < 127):

View File

@ -137,20 +137,24 @@ class ForwardLines(Method):
# search and replace # search and replace
class Search(Method): class Search(Method):
'''Interactive search; finds next occurance of text in buffer''' '''Interactive search; finds next occurance of text in buffer'''
direction = 'next'
is_literal = True
prompt = 'I-Search: '
def execute(self, w, **vargs): def execute(self, w, **vargs):
self.old_cursor = w.logical_cursor() self.old_cursor = w.logical_cursor()
self.old_window = w self.old_window = w
self.direction = 'next' w.application.open_mini_buffer(self.prompt, lambda x: None, self, None, 'search')
self.is_literal = True class ReverseSearch(Search):
w.application.open_mini_buffer('I-Search: ', lambda x: None, self, None, 'search')
class ReverseSearch(Method):
'''Interactive search; finds previous occurance of text in buffer''' '''Interactive search; finds previous occurance of text in buffer'''
def execute(self, w, **vargs): direction = 'previous'
self.old_cursor = w.logical_cursor() class RegexSearch(Search):
self.old_window = w '''Interactive search; finds next occurance of regex in buffer'''
self.direction = 'previous' is_literal = False
self.is_literal = True prompt = 'I-RegexSearch: '
w.application.open_mini_buffer('I-Search: ', lambda x: None, self, None, 'search') class RegexReverseSearch(RegexSearch):
'''Interactive search; finds prevoius occurance of regex in buffer'''
direction = 'previous'
class Replace(Method): class Replace(Method):
'''Replace occurances of string X with string Y''' '''Replace occurances of string X with string Y'''
args = [Argument('before', prompt="Replace: ", args = [Argument('before', prompt="Replace: ",

View File

@ -107,6 +107,8 @@ class Fundamental(Handler):
self.add_bindings('forward-lines', ('C-x M-n',)) self.add_bindings('forward-lines', ('C-x M-n',))
self.add_bindings('search', ('C-s',)) self.add_bindings('search', ('C-s',))
self.add_bindings('reverse-search', ('C-r',)) 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('toggle-margins', ('M-m',))
self.add_bindings('replace', ('M-%',)) self.add_bindings('replace', ('M-%',))
self.add_bindings('open-file', ('C-x C-f',)) self.add_bindings('open-file', ('C-x C-f',))

View File

@ -33,18 +33,21 @@ class Search(mode2.Fundamental):
return "Search" return "Search"
def _make_regex(w, s): def _make_regex(w, s):
if w.buffer.method.is_literal: try:
s = search.escape_literal(s) if w.buffer.method.is_literal:
return re.compile(s) s = search.escape_literal(s)
return re.compile(s)
except:
raise search.IllegalPatternError, "failed to compile: %r" % s
class SearchNext(method.Method): class SearchNext(method.Method):
def execute(self, w, **vargs): def execute(self, w, **vargs):
w.buffer.method.direction = 'next' w.buffer.method.direction = 'next'
s = w.buffer.make_string() s = w.buffer.make_string()
r = _make_regex(w, s)
if s: if s:
try: 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: except search.IllegalPatternError:
w.application.clear_highlighted_ranges() w.application.clear_highlighted_ranges()
else: else:
@ -57,10 +60,10 @@ class SearchPrevious(method.Method):
return return
else: else:
s = w.buffer.make_string() s = w.buffer.make_string()
r = _make_regex(w, s)
w2 = w.buffer.method.old_window w2 = w.buffer.method.old_window
try: try:
search.find_previous(s, w2, move=True) r = _make_regex(w, s)
search.find_previous(r, w2, move=True)
except search.IllegalPatternError: except search.IllegalPatternError:
w.application.clear_highlighted_ranges() w.application.clear_highlighted_ranges()
@ -94,13 +97,13 @@ def _post_delete(w):
w.application.clear_highlighted_ranges() w.application.clear_highlighted_ranges()
return return
s = w.buffer.make_string() s = w.buffer.make_string()
r = _make_regex(w, s)
w2 = w.buffer.method.old_window w2 = w.buffer.method.old_window
try: try:
r = _make_regex(w, s)
if w.buffer.method.direction == 'next': if w.buffer.method.direction == 'next':
search.find_next(s, w2, move=False) search.find_next(r, w2, move=False)
else: else:
search.find_previous(s, w2, move=False) search.find_previous(r, w2, move=False)
except search.IllegalPatternError: except search.IllegalPatternError:
w.application.clear_highlighted_ranges() w.application.clear_highlighted_ranges()
@ -117,13 +120,13 @@ class InsertSearchString(method.Method):
return return
else: else:
s = w.buffer.make_string() s = w.buffer.make_string()
r = _make_regex(w, s)
w2 = w.buffer.method.old_window w2 = w.buffer.method.old_window
try: try:
r = _make_regex(w, s)
if w.buffer.method.direction == 'next': if w.buffer.method.direction == 'next':
search.find_next(s, w2, move=False) search.find_next(r, w2, move=False)
else: else:
search.find_previous(s, w2, move=False) search.find_previous(r, w2, move=False)
except search.IllegalPatternError: except search.IllegalPatternError:
w.application.clear_highlighted_ranges() w.application.clear_highlighted_ranges()

View File

@ -12,7 +12,7 @@ class IllegalPatternError(Exception):
def escape_literal(s): def escape_literal(s):
return regex.meta_chars.sub(r'\\\1', 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: if not w.buffer.lines:
return [] return []
@ -25,11 +25,6 @@ def find_ranges(s, w, start=None, end=None):
else: else:
(x2, y2) = end.xy() (x2, y2) = end.xy()
#s2 = escape_literal(s)
#r = re.compile(s2, re.IGNORECASE)
r = re.compile(s, re.IGNORECASE)
ranges = [] ranges = []
while y <= y2: while y <= y2:
if 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 limit = len(w.buffer.lines[y]) - 1
for m in r.finditer(w.buffer.lines[y], x, limit): for m in r.finditer(w.buffer.lines[y], x, limit):
if len(m.group(0)) == 0: 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]) ranges.append([Point(m.start(), y), Point(m.end(), y), bg_color, unselected_color])
x = 0 x = 0
y += 1 y += 1
return ranges 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 app = w.application
c = w.logical_cursor() c = w.logical_cursor()
newc = None newc = None
ranges = find_ranges(s, w, start, end) ranges = find_ranges(r, w, start, end)
indices = range(0, len(ranges)) indices = range(0, len(ranges))
(x, y) = c.xy() (x, y) = c.xy()
if move: if move:
@ -58,7 +53,12 @@ def find(s, w, move=False, direction='next', start=None, end=None):
if direction == 'next': if direction == 'next':
limit = Point(x - 1 + offset, y) limit = Point(x - 1 + offset, y)
else: 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() indices.reverse()
for i in indices: for i in indices:
if ((direction == 'next' and ranges[i][0] > limit) or 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) app.add_highlighted_range(w, p1, p2, fg, bg)
return newc return newc
def find_previous(s, w, move=False, start=None, end=None): def find_previous(r, w, move=False, start=None, end=None):
return find(s, w, move, 'previous', start, end) return find(r, w, move, 'previous', start, end)
def find_next(r, w, move=False, start=None, end=None):
def find_next(s, w, move=False, start=None, end=None): return find(r, w, move, 'next', start, end)
return find(s, w, move, 'next', start, end)