2007-03-06 10:05:38 -05:00
|
|
|
import sets, string
|
|
|
|
|
2007-06-14 06:10:20 -04:00
|
|
|
import color, method, minibuffer, mode2
|
|
|
|
from point2 import Point
|
2007-03-06 10:05:38 -05:00
|
|
|
|
2007-06-14 06:10:20 -04:00
|
|
|
class Search(mode2.Fundamental):
|
2007-03-06 10:05:38 -05:00
|
|
|
'''This is the default mode'''
|
|
|
|
def __init__(self, w):
|
2007-06-14 06:10:20 -04:00
|
|
|
mode2.Fundamental.__init__(self, w)
|
2007-03-06 10:05:38 -05:00
|
|
|
|
|
|
|
self.actions = {}
|
|
|
|
self.bindings = {}
|
|
|
|
|
|
|
|
default_actions = (
|
|
|
|
(SearchNext(), ('C-s',)),
|
|
|
|
(SearchPrevious(), ('C-r',)),
|
|
|
|
(EndSearch(), ('RETURN', 'C-n', 'C-p', 'C-a', 'C-e', 'C-f', 'C-b')),
|
|
|
|
(CancelSearch(), ('C-]',)),
|
|
|
|
(DeleteLeft(), ('DELETE', 'BACKSPACE',)),
|
2007-05-06 00:32:20 -04:00
|
|
|
(DeleteLeftWord(), ('M-DELETE', 'M-BACKSPACE',)),
|
2007-03-06 10:05:38 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
# add the search actions
|
|
|
|
for pair in default_actions:
|
|
|
|
(action, sequences) = pair
|
|
|
|
assert type(sequences) == type(()), repr(pair)
|
|
|
|
self.add_action_and_bindings(action, sequences)
|
|
|
|
|
|
|
|
# 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',))
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return "Search"
|
|
|
|
|
|
|
|
class SearchNext(method.Method):
|
2007-07-03 12:53:14 -04:00
|
|
|
def execute(self, w, **vargs):
|
|
|
|
w.buffer.method.direction = 'next'
|
|
|
|
s = w.buffer.make_string()
|
2007-03-06 10:05:38 -05:00
|
|
|
if not s:
|
2007-07-03 12:53:14 -04:00
|
|
|
s = w.application.last_search
|
|
|
|
w.buffer.set_data(s)
|
2007-03-06 10:05:38 -05:00
|
|
|
else:
|
2007-07-03 12:53:14 -04:00
|
|
|
old_w = w.buffer.method.old_window
|
|
|
|
_find_next(old_w, w, move=True)
|
2007-03-06 10:05:38 -05:00
|
|
|
|
|
|
|
class SearchPrevious(method.Method):
|
2007-07-03 12:53:14 -04:00
|
|
|
def execute(self, w, **vargs):
|
|
|
|
w.buffer.method.direction = 'previous'
|
|
|
|
s = w.buffer.make_string()
|
2007-03-06 10:05:38 -05:00
|
|
|
if not s:
|
|
|
|
return
|
|
|
|
else:
|
2007-07-03 12:53:14 -04:00
|
|
|
old_w = w.buffer.method.old_window
|
|
|
|
_find_previous(old_w, w, move=True)
|
2007-03-06 10:05:38 -05:00
|
|
|
|
|
|
|
class EndSearch(method.Method):
|
2007-07-03 12:53:14 -04:00
|
|
|
def execute(self, w, **vargs):
|
|
|
|
old_w = w.buffer.method.old_window
|
|
|
|
old_cursor = w.buffer.method.old_cursor
|
|
|
|
_end(w)
|
|
|
|
old_w.set_mark_point(old_cursor)
|
|
|
|
w.set_error("Mark set to search start")
|
2007-03-06 10:05:38 -05:00
|
|
|
|
|
|
|
class CancelSearch(method.Method):
|
2007-07-03 12:53:14 -04:00
|
|
|
def execute(self, w, **vargs):
|
|
|
|
old_w = w.buffer.method.old_window
|
|
|
|
old_cursor = w.buffer.method.old_cursor
|
|
|
|
old_w.goto(old_cursor)
|
|
|
|
_end(w)
|
|
|
|
w.set_error("Search cancelled")
|
2007-03-06 10:05:38 -05:00
|
|
|
|
|
|
|
class DeleteLeft(method.Method):
|
2007-07-03 12:53:14 -04:00
|
|
|
def execute(self, w, **vargs):
|
|
|
|
w.left_delete()
|
|
|
|
old_cursor = w.buffer.method.old_cursor
|
|
|
|
old_w = w.buffer.method.old_window
|
|
|
|
old_w.goto(old_cursor)
|
|
|
|
_end(w)
|
|
|
|
return
|
|
|
|
if w.buffer.method.direction == 'next':
|
|
|
|
_find_next(old_w, w, move=False)
|
2007-03-06 10:05:38 -05:00
|
|
|
else:
|
2007-07-03 12:53:14 -04:00
|
|
|
_find_previous(old_w, w, move=False)
|
2007-03-06 10:05:38 -05:00
|
|
|
|
2007-05-06 00:32:20 -04:00
|
|
|
class DeleteLeftWord(method.Method):
|
2007-07-03 12:53:14 -04:00
|
|
|
def execute(self, w, **vargs):
|
|
|
|
w.kill_left_word()
|
|
|
|
old_cursor = w.buffer.method.old_cursor
|
|
|
|
old_w = w.buffer.method.old_window
|
|
|
|
old_w.goto(old_cursor)
|
|
|
|
if w.buffer.method.direction == 'next':
|
|
|
|
_find_next(old_w, w, move=False)
|
2007-05-06 00:32:20 -04:00
|
|
|
else:
|
2007-07-03 12:53:14 -04:00
|
|
|
_find_previous(old_w, w, move=False)
|
2007-05-06 00:32:20 -04:00
|
|
|
|
2007-03-06 10:05:38 -05:00
|
|
|
class InsertSearchString(method.Method):
|
|
|
|
def __init__(self, s):
|
|
|
|
self.name = 'insert-search-string-%s' % (s)
|
|
|
|
self.string = s
|
|
|
|
self.args = []
|
|
|
|
self.help = None
|
2007-07-03 12:53:14 -04:00
|
|
|
def execute(self, w, **vargs):
|
|
|
|
w.insert_string_at_cursor(self.string)
|
|
|
|
s = w.buffer.make_string()
|
2007-03-06 10:05:38 -05:00
|
|
|
if not s:
|
|
|
|
return
|
|
|
|
else:
|
2007-07-03 12:53:14 -04:00
|
|
|
old_w = w.buffer.method.old_window
|
|
|
|
if w.buffer.method.direction == 'next':
|
|
|
|
_find_next(old_w, w, move=False)
|
2007-03-06 10:05:38 -05:00
|
|
|
else:
|
2007-07-03 12:53:14 -04:00
|
|
|
_find_previous(old_w, w, move=False)
|
|
|
|
|
|
|
|
def _end(w):
|
|
|
|
s = w.buffer.make_string()
|
|
|
|
w.application.last_search = s
|
|
|
|
w.application.close_mini_buffer()
|
|
|
|
#w.application.highlighted_range = []
|
|
|
|
w.application.clear_highlighted_ranges()
|
|
|
|
w.buffer.method.old_cursor = None
|
|
|
|
w.buffer.method.old_window = None
|
|
|
|
|
|
|
|
def _find_previous(old_w, new_w, move=False):
|
|
|
|
s = new_w.buffer.make_string()
|
|
|
|
old_b = old_w.buffer
|
|
|
|
c = old_w.logical_cursor()
|
2007-03-06 10:05:38 -05:00
|
|
|
(x, y) = (c.x, c.y)
|
|
|
|
if move:
|
|
|
|
x -= 1
|
2007-07-03 12:53:14 -04:00
|
|
|
l = old_b.lines[y][:x + len(s)]
|
2007-03-06 10:05:38 -05:00
|
|
|
# for each line available
|
|
|
|
while y >= 0:
|
|
|
|
if s in l:
|
|
|
|
# success
|
|
|
|
x = l.index(s)
|
2007-07-03 12:53:14 -04:00
|
|
|
old_w.goto(Point(x, y))
|
|
|
|
old_w.application.clear_highlighted_ranges()
|
|
|
|
new_w.application.add_highlighted_range(old_w,
|
2007-06-14 06:10:20 -04:00
|
|
|
Point(x,y),
|
|
|
|
Point(x + len(s), y))
|
2007-03-06 10:05:38 -05:00
|
|
|
break
|
2007-07-03 12:53:14 -04:00
|
|
|
elif y >= len(old_b.lines) - 1:
|
2007-03-06 10:05:38 -05:00
|
|
|
# failure
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
# keep trying
|
|
|
|
y -= 1
|
2007-07-03 12:53:14 -04:00
|
|
|
l = old_b.lines[y]
|
2007-03-06 10:05:38 -05:00
|
|
|
x = 0
|
|
|
|
|
2007-07-03 12:53:14 -04:00
|
|
|
def _find_next(old_w, new_w, move=False):
|
|
|
|
s = new_w.buffer.make_string()
|
|
|
|
old_b = old_w.buffer
|
|
|
|
c = old_w.logical_cursor()
|
2007-03-06 10:05:38 -05:00
|
|
|
(x, y) = (c.x, c.y)
|
|
|
|
if move:
|
|
|
|
x += 1
|
2007-07-03 12:53:14 -04:00
|
|
|
l = old_b.lines[y][x:]
|
2007-03-06 10:05:38 -05:00
|
|
|
# for each line available
|
2007-07-03 12:53:14 -04:00
|
|
|
while y < len(old_b.lines):
|
2007-03-06 10:05:38 -05:00
|
|
|
if s in l:
|
|
|
|
# success
|
|
|
|
x = l.index(s) + x
|
2007-07-03 12:53:14 -04:00
|
|
|
old_w.goto(Point(x, y))
|
|
|
|
old_w.application.clear_highlighted_ranges()
|
|
|
|
new_w.application.add_highlighted_range(old_w,
|
2007-06-14 06:10:20 -04:00
|
|
|
Point(x,y),
|
|
|
|
Point(x + len(s), y))
|
2007-03-06 10:05:38 -05:00
|
|
|
break
|
2007-07-03 12:53:14 -04:00
|
|
|
elif y >= len(old_b.lines) - 1:
|
2007-03-06 10:05:38 -05:00
|
|
|
# failure
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
# keep trying
|
|
|
|
y += 1
|
2007-07-03 12:53:14 -04:00
|
|
|
l = old_b.lines[y]
|
2007-03-06 10:05:38 -05:00
|
|
|
x = 0
|