142 lines
4.9 KiB
Python
142 lines
4.9 KiB
Python
import re, sets, string
|
|
|
|
import color, method, minibuffer, mode, searchutil
|
|
from point import Point
|
|
|
|
selected_color = 'magenta'
|
|
unselected_color = 'yellow'
|
|
|
|
def _make_regex(w, s):
|
|
try:
|
|
if w.buffer.method.is_literal:
|
|
s = searchutil.escape_literal(s)
|
|
if s.islower():
|
|
return re.compile(s, re.IGNORECASE)
|
|
else:
|
|
return re.compile(s)
|
|
else:
|
|
return re.compile(s)
|
|
except:
|
|
raise searchutil.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()
|
|
if s:
|
|
try:
|
|
r = _make_regex(w, s)
|
|
searchutil.find_next(r, w.buffer.method.old_window, move=True)
|
|
except searchutil.IllegalPatternError:
|
|
w.application.clear_highlighted_ranges()
|
|
else:
|
|
action = InsertSearchString(w.application.last_search)
|
|
action.execute(w)
|
|
|
|
class SearchPrevious(method.Method):
|
|
def execute(self, w, **vargs):
|
|
w.buffer.method.direction = 'previous'
|
|
if not w.buffer.make_string():
|
|
return
|
|
else:
|
|
s = w.buffer.make_string()
|
|
w2 = w.buffer.method.old_window
|
|
try:
|
|
r = _make_regex(w, s)
|
|
searchutil.find_previous(r, w2, move=True)
|
|
except searchutil.IllegalPatternError:
|
|
w.application.clear_highlighted_ranges()
|
|
|
|
class EndSearch(method.Method):
|
|
def execute(self, w, **vargs):
|
|
old_w = w.buffer.method.old_window
|
|
old_c = w.buffer.method.old_cursor
|
|
_end(w)
|
|
old_w.set_mark_point(old_c)
|
|
w.set_error("Mark set to search start")
|
|
|
|
class CancelSearch(method.Method):
|
|
def execute(self, w, **vargs):
|
|
w.buffer.method.old_window.goto(w.buffer.method.old_cursor)
|
|
_end(w)
|
|
w.set_error("Search cancelled")
|
|
|
|
class SearchDeleteLeft(method.Method):
|
|
def execute(self, w, **vargs):
|
|
w.left_delete()
|
|
_post_delete(w)
|
|
class SearchDeleteLeftWord(method.Method):
|
|
def execute(self, w, **vargs):
|
|
w.kill_left_word()
|
|
_post_delete(w)
|
|
def _post_delete(w):
|
|
old_cursor = w.buffer.method.old_cursor
|
|
old_w = w.buffer.method.old_window
|
|
old_w.goto(old_cursor)
|
|
if not w.buffer.make_string():
|
|
w.application.clear_highlighted_ranges()
|
|
return
|
|
s = w.buffer.make_string()
|
|
w2 = w.buffer.method.old_window
|
|
try:
|
|
r = _make_regex(w, s)
|
|
if w.buffer.method.direction == 'next':
|
|
searchutil.find_next(r, w2, move=False)
|
|
else:
|
|
searchutil.find_previous(r, w2, move=False)
|
|
except searchutil.IllegalPatternError:
|
|
w.application.clear_highlighted_ranges()
|
|
|
|
class InsertSearchString(method.Method):
|
|
def __init__(self, s):
|
|
self.name = 'insert-search-string-%s' % (s)
|
|
self.string = s
|
|
self.args = []
|
|
self.help = ''
|
|
def execute(self, w, **vargs):
|
|
w.insert_string_at_cursor(self.string)
|
|
s = w.buffer.make_string()
|
|
if not s:
|
|
w.application.clear_highlighted_ranges()
|
|
return
|
|
else:
|
|
try:
|
|
r = _make_regex(w, s)
|
|
w2 = w.buffer.method.old_window
|
|
if w.buffer.method.direction == 'next':
|
|
searchutil.find_next(r, w2, move=False)
|
|
else:
|
|
searchutil.find_previous(r, w2, move=False)
|
|
except searchutil.IllegalPatternError:
|
|
w.application.clear_highlighted_ranges()
|
|
|
|
def _end(w):
|
|
w.application.close_mini_buffer()
|
|
w.application.clear_highlighted_ranges()
|
|
w.application.last_search = w.buffer.make_string()
|
|
|
|
class Search(mode.Fundamental):
|
|
modename = 'Search'
|
|
actions = [SearchNext, SearchPrevious, EndSearch, CancelSearch,
|
|
SearchDeleteLeft, SearchDeleteLeftWord]
|
|
def __init__(self, w):
|
|
mode.Fundamental.__init__(self, w)
|
|
|
|
# clear out all the defaults that we don't want/need, and add ours
|
|
self.actions = {}
|
|
self.bindings = {}
|
|
self.add_bindings('search-next', ('C-s',))
|
|
self.add_bindings('search-previous', ('C-r',))
|
|
self.add_bindings('end-search', ('RETURN', 'C-n', 'C-p', 'C-a', 'C-e', 'C-f', 'C-b',))
|
|
self.add_bindings('cancel-search', ('C-]',))
|
|
self.add_bindings('search-delete-left', ('DELETE', 'BACKSPACE',))
|
|
self.add_bindings('search-delete-left-word', ('M-DELETE', 'M-BACKSPACE',))
|
|
|
|
# create all the insert actions for the character ranges we like
|
|
for collection in (string.letters, string.digits, string.punctuation):
|
|
for c in collection:
|
|
self.add_action_and_bindings(InsertSearchString(c), (c,))
|
|
self.add_action_and_bindings(InsertSearchString(' '), ('SPACE',))
|
|
|
|
install = Search.install
|