search improvements

--HG--
branch : pmacs2
This commit is contained in:
moculus 2007-07-09 21:47:15 +00:00
parent 95f63f3ca2
commit b5deaab9a8
4 changed files with 63 additions and 34 deletions

View File

@ -141,6 +141,7 @@ class Search(Method):
self.old_cursor = w.logical_cursor() self.old_cursor = w.logical_cursor()
self.old_window = w self.old_window = w
self.direction = 'next' self.direction = 'next'
self.is_literal = True
w.application.open_mini_buffer('I-Search: ', lambda x: None, self, None, 'search') w.application.open_mini_buffer('I-Search: ', lambda x: None, self, None, 'search')
class ReverseSearch(Method): class ReverseSearch(Method):
'''Interactive search; finds previous occurance of text in buffer''' '''Interactive search; finds previous occurance of text in buffer'''
@ -148,6 +149,7 @@ class ReverseSearch(Method):
self.old_cursor = w.logical_cursor() self.old_cursor = w.logical_cursor()
self.old_window = w self.old_window = w
self.direction = 'previous' self.direction = 'previous'
self.is_literal = True
w.application.open_mini_buffer('I-Search: ', lambda x: None, self, None, 'search') w.application.open_mini_buffer('I-Search: ', lambda x: None, self, None, 'search')
class Replace(Method): class Replace(Method):
'''Replace occurances of string X with string Y''' '''Replace occurances of string X with string Y'''

View File

@ -1,4 +1,4 @@
import sets, string import re, sets, string
import color, method, minibuffer, mode2, search import color, method, minibuffer, mode2, search
from point2 import Point from point2 import Point
@ -32,15 +32,23 @@ class Search(mode2.Fundamental):
def name(self): def name(self):
return "Search" return "Search"
def _make_regex(w, s):
if w.buffer.method.is_literal:
s = search.escape_literal(s)
return re.compile(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'
if not w.buffer.make_string(): s = w.buffer.make_string()
w.buffer.set_data(w.application.last_search) r = _make_regex(w, s)
if s:
try:
search.find_next(s, w.buffer.method.old_window, move=True)
except search.IllegalPatternError:
w.application.clear_highlighted_ranges()
else: else:
s = w.buffer.make_string() w.buffer.set_data(w.application.last_search)
w2 = w.buffer.method.old_window
search.find_next(s, w2, move=True)
class SearchPrevious(method.Method): class SearchPrevious(method.Method):
def execute(self, w, **vargs): def execute(self, w, **vargs):
@ -49,8 +57,12 @@ 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
search.find_previous(s, w2, move=True) try:
search.find_previous(s, w2, move=True)
except search.IllegalPatternError:
w.application.clear_highlighted_ranges()
class EndSearch(method.Method): class EndSearch(method.Method):
def execute(self, w, **vargs): def execute(self, w, **vargs):
@ -82,11 +94,15 @@ 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
if w.buffer.method.direction == 'next': try:
search.find_next(s, w2, move=False) if w.buffer.method.direction == 'next':
else: search.find_next(s, w2, move=False)
search.find_previous(s, w2, move=False) else:
search.find_previous(s, w2, move=False)
except search.IllegalPatternError:
w.application.clear_highlighted_ranges()
class InsertSearchString(method.Method): class InsertSearchString(method.Method):
def __init__(self, s): def __init__(self, s):
@ -101,11 +117,15 @@ 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
if w.buffer.method.direction == 'next': try:
search.find_next(s, w2, move=False) if w.buffer.method.direction == 'next':
else: search.find_next(s, w2, move=False)
search.find_previous(s, w2, move=False) else:
search.find_previous(s, w2, move=False)
except search.IllegalPatternError:
w.application.clear_highlighted_ranges()
def _end(w): def _end(w):
w.application.close_mini_buffer() w.application.close_mini_buffer()

View File

@ -1,5 +1,8 @@
import re import re
# meta regexes
meta_chars = re.compile(r'([\.\^\$\*\+\?\{\}\(\)\[\]\|\\])')
# whitespace regexes # whitespace regexes
leading_whitespace = re.compile('^ *') leading_whitespace = re.compile('^ *')
trailing_whitespace = re.compile(' *$') trailing_whitespace = re.compile(' *$')
@ -11,11 +14,11 @@ word_char = re.compile('^[A-Za-z0-9_]$')
# perl regexes # perl regexes
perl_base = re.compile("^sub ") perl_base = re.compile("^sub ")
perl_hash_cleanup = re.compile("^( *)([^ ]+|'(?:\\.|[^'\\'])*'|\"(?:\\.|[^\\\"]*)\")( *)(=>)( *)([^ ].*)$") perl_hash_cleanup = re.compile(r"^( *)([^ ]+|'(?:\.|[^'\'])*'|\"(?:\.|[^\\\"]*)\")( *)(=>)( *)([^ ].*)$")
perl_assign_cleanup = re.compile("^( *)((?:my |our )?[^ ]+)( *)(=(?!>))( *)([^ ].*)$") perl_assign_cleanup = re.compile(r"^( *)((?:my |our )?[^ ]+)( *)(=(?!>))( *)([^ ].*)$")
perl_function = re.compile("^ *sub ([A-Za-z_][A-Za-z0-9_]*)") perl_function = re.compile(r"^ *sub ([A-Za-z_][A-Za-z0-9_]*)")
# python regexes # python regexes
python_base = re.compile("^[^ ]") python_base = re.compile(r"^[^ ]")
python_dict_cleanup = re.compile("^( *)((?:[^'\":]|'(?:\\.|[^\\'])*'|\"(?:\\.|[^\\'])*)+?)( *)(:)( *)([^ ].*)$") python_dict_cleanup = re.compile(r"^( *)((?:[^'\":]|'(?:\.|[^\'])*'|\"(?:\.|[^\'])*)+?)( *)(:)( *)([^ ].*)$")
python_assign_cleanup = re.compile("^( *)([^ ]+)( *)(=)( *)([^ ].*)$") python_assign_cleanup = re.compile(r"^( *)([^ ]+)( *)(=)( *)([^ ].*)$")

View File

@ -1,9 +1,17 @@
import re
import regex
from point2 import Point from point2 import Point
bg_color = 'black' bg_color = 'black'
selected_color = 'magenta' selected_color = 'magenta'
unselected_color = 'yellow' unselected_color = 'yellow'
class IllegalPatternError(Exception):
pass
def escape_literal(s):
return regex.meta_chars.sub(r'\\\1', s)
def find_ranges(s, w, start=None, end=None): def find_ranges(s, w, start=None, end=None):
if not w.buffer.lines: if not w.buffer.lines:
return [] return []
@ -16,26 +24,22 @@ def find_ranges(s, w, start=None, end=None):
(x2, y2) = (len(w.buffer.lines[-1]) - 1, len(w.buffer.lines) - 1) (x2, y2) = (len(w.buffer.lines[-1]) - 1, len(w.buffer.lines) - 1)
else: else:
(x2, y2) = end.xy() (x2, y2) = end.xy()
#if x2 == 0:
# y2 -= 1 #s2 = escape_literal(s)
# x2 = len(w.buffer.lines[-1]) - 1 #r = re.compile(s2, re.IGNORECASE)
#else:
# x2 -= 1 r = re.compile(s, re.IGNORECASE)
ranges = [] ranges = []
#while y <= y2:
while y <= y2: while y <= y2:
if y == y2: if y == y2:
limit = x2 limit = x2
else: else:
limit = len(w.buffer.lines[y]) - 1 limit = len(w.buffer.lines[y]) - 1
while x <= limit: for m in r.finditer(w.buffer.lines[y], x, limit):
try: if len(m.group(0)) == 0:
i = w.buffer.lines[y].index(s, x) raise IllegalPatternError, "zero-width match found for: %r" % s
except ValueError: ranges.append([Point(m.start(), y), Point(m.end(), y), bg_color, unselected_color])
break
x = i + len(s)
ranges.append([Point(i, y), Point(x, y), bg_color, unselected_color])
x = 0 x = 0
y += 1 y += 1
return ranges return ranges