search is better, other stuff is worse

--HG--
branch : pmacs2
This commit is contained in:
moculus 2007-07-05 20:18:09 +00:00
parent 124fb154d7
commit 7f5734e1f2
4 changed files with 151 additions and 73 deletions

View File

@ -428,8 +428,8 @@ class Application(object):
# highlighting # highlighting
# each highlighted_range contains three things: [window, start_p, end_p] # each highlighted_range contains three things: [window, start_p, end_p]
def add_highlighted_range(self, w, start_p, end_p): def add_highlighted_range(self, w, p1, p2, fg='default', bg='default'):
self.highlighted_ranges.append([w, start_p, end_p]) self.highlighted_ranges.append([w, p1, p2, fg, bg])
def clear_highlighted_ranges(self): def clear_highlighted_ranges(self):
self.highlighted_ranges = [] self.highlighted_ranges = []
@ -483,16 +483,15 @@ class Application(object):
self.draw_slot(i) self.draw_slot(i)
self.draw_status_bar(i) self.draw_status_bar(i)
def highlight_char(self, sy, sx): def highlight_char(self, sy, sx, fg='default', bg='default'):
junk = self.win.inch(sy, sx) junk = self.win.inch(sy, sx)
c = junk & 255 char = junk & 255
# FIXME? #attr = color.build(fg, bg, curses.A_REVERSE)
#attr = (junk & (curses.A_COLOR|curses.A_ATTRIBUTES)) | curses.A_REVERSE attr = color.build(fg, bg)
attr = curses.A_REVERSE self.win.addch(sy, sx, char, attr)
self.win.addch(sy, sx, c, attr) def highlight_chars(self, sy, sx1, sx2, fg='default', bg='default'):
def highlight_chars(self, sy, sx1, sx2):
for x in range(sx1, sx2): for x in range(sx1, sx2):
self.highlight_char(sy, x) self.highlight_char(sy, x, fg, bg)
def draw_slot(self, i): def draw_slot(self, i):
assert self.active_slot < len(self.bufferlist.slots), "only two" assert self.active_slot < len(self.bufferlist.slots), "only two"
@ -509,7 +508,7 @@ class Application(object):
self._draw_slot_raw(i) self._draw_slot_raw(i)
# highlighted regions # highlighted regions
for (high_w, p1, p2) in self.highlighted_ranges: for (high_w, p1, p2, fg, bg) in self.highlighted_ranges:
if w is high_w and p2 >= w.first and p1 <= w.last: if w is high_w and p2 >= w.first and p1 <= w.last:
count = 0 count = 0
(x, y) = w.first.xy() (x, y) = w.first.xy()
@ -517,10 +516,10 @@ class Application(object):
while count < slot.height: while count < slot.height:
if p1.y == y and px >= x and px < x + slot.width: if p1.y == y and px >= x and px < x + slot.width:
if px + slot.width > p2.x: if px + slot.width > p2.x:
self.highlight_chars(slot.offset + count, px - x, p2.x -x) self.highlight_chars(slot.offset + count, px - x, p2.x -x, fg, bg)
break break
else: else:
self.highlight_chars(slot.offset + count, px - x, px + slot.width -x-1) self.highlight_chars(slot.offset + count, px - x, px + slot.width -x-1, fg, bg)
px += slot.width px += slot.width
if x + slot.width >= len(w.buffer.lines[y]): if x + slot.width >= len(w.buffer.lines[y]):
x = 0 x = 0

24
miniparse.py Normal file
View File

@ -0,0 +1,24 @@
import parser, symbol, sys, token
from pprint import pprint
def proc(asttup):
queue = [asttup]
pairs = []
while queue:
node = queue.pop(0)
if not node:
continue
elif node[0] in token.tok_name:
pairs.append((token.tok_name[node[0]], node[1]))
else:
for i in range(0, len(node) - 1):
queue.insert(i, node[i + 1])
return pairs
for name in sys.argv[1:]:
f = open(name, 'r')
code = f.read()
f.close()
ast = parser.suite(code)
pairs = proc(ast.totuple())
pprint(pairs)

View File

@ -37,7 +37,6 @@ class PythonGrammar(Grammar):
] ]
class PythonTabber(tab2.StackTabber): class PythonTabber(tab2.StackTabber):
unanchored_names = ('null', 'string', 'comment')
endlevel_names = ('pass', 'return', 'yield', 'raise', 'break', 'continue') endlevel_names = ('pass', 'return', 'yield', 'raise', 'break', 'continue')
startlevel_names = ('if', 'try', 'class', 'def', 'for', 'while', 'try') startlevel_names = ('if', 'try', 'class', 'def', 'for', 'while', 'try')
def __init__(self, m): def __init__(self, m):
@ -52,7 +51,7 @@ class PythonTabber(tab2.StackTabber):
if not tokens: if not tokens:
# if a line has no tokens, we don't know much about its indentation # if a line has no tokens, we don't know much about its indentation
return False return False
elif tokens[0].name not in self.unanchored_names: elif tokens[0].name in self.startlevel_names:
# if a line has no whitespace and beings with something like # if a line has no whitespace and beings with something like
# 'while','class','def','if',etc. then we can start at it # 'while','class','def','if',etc. then we can start at it
return True return True
@ -82,6 +81,7 @@ class PythonTabber(tab2.StackTabber):
# if we were continuing, let's pop that previous continuation token # if we were continuing, let's pop that previous continuation token
# and note that we're continuing # and note that we're continuing
if self.markers and self.markers[-1].name == 'cont': if self.markers and self.markers[-1].name == 'cont':
raise Exception, repr(self.markers)
self.continued = True self.continued = True
self._pop() self._pop()
# if we haven't reached the target-line yet, we can detect how many # if we haven't reached the target-line yet, we can detect how many

View File

@ -9,13 +9,13 @@ class Search(mode2.Fundamental):
mode2.Fundamental.__init__(self, w) mode2.Fundamental.__init__(self, w)
# clear out all the defaults that we don't want/need # clear out all the defaults that we don't want/need
self.actions = {} self.actions = {}
self.bindings = {} self.bindings = {}
# add some useful bindings # add some useful bindings
self.add_action_and_bindings(SearchNext(), ('C-s',)) self.add_action_and_bindings(SearchNext(), ('C-s',))
self.add_action_and_bindings(SearchPrevious(), ('C-r',)) self.add_action_and_bindings(SearchPrevious(), ('C-r',))
self.add_action_and_bindings(EndSearch(), ('RETURN', 'C-n', 'C-p', 'C-a', 'C-e', 'C-f', 'C-b')) self.add_action_and_bindings(EndSearch(), ('RETURN', 'C-n', 'C-p', 'C-a', 'C-e', 'C-f', 'C-b',))
self.add_action_and_bindings(CancelSearch(), ('C-]',)) self.add_action_and_bindings(CancelSearch(), ('C-]',))
self.add_action_and_bindings(SearchDeleteLeft(), ('DELETE', 'BACKSPACE',)) self.add_action_and_bindings(SearchDeleteLeft(), ('DELETE', 'BACKSPACE',))
self.add_action_and_bindings(SearchDeleteLeftWord(), ('M-DELETE', 'M-BACKSPACE',)) self.add_action_and_bindings(SearchDeleteLeftWord(), ('M-DELETE', 'M-BACKSPACE',))
@ -49,8 +49,10 @@ class SearchPrevious(method.Method):
class EndSearch(method.Method): class EndSearch(method.Method):
def execute(self, w, **vargs): def execute(self, w, **vargs):
old_w = w.buffer.method.old_window
old_c = w.buffer.method.old_cursor
_end(w) _end(w)
w.buffer.method.old_window.set_mark_point(w.buffer.method.old_cursor) old_w.set_mark_point(old_c)
w.set_error("Mark set to search start") w.set_error("Mark set to search start")
class CancelSearch(method.Method): class CancelSearch(method.Method):
@ -62,24 +64,21 @@ class CancelSearch(method.Method):
class SearchDeleteLeft(method.Method): class SearchDeleteLeft(method.Method):
def execute(self, w, **vargs): def execute(self, w, **vargs):
w.left_delete() w.left_delete()
old_cursor = w.buffer.method.old_cursor _post_delete(w)
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)
else:
_find_previous(old_w, w, move=False)
class SearchDeleteLeftWord(method.Method): class SearchDeleteLeftWord(method.Method):
def execute(self, w, **vargs): def execute(self, w, **vargs):
w.kill_left_word() w.kill_left_word()
old_cursor = w.buffer.method.old_cursor _post_delete(w)
old_w = w.buffer.method.old_window def _post_delete(w):
old_w.goto(old_cursor) old_cursor = w.buffer.method.old_cursor
if w.buffer.method.direction == 'next': old_w = w.buffer.method.old_window
_find_next(old_w, w, move=False) old_w.goto(old_cursor)
else: if not w.buffer.make_string():
_find_previous(old_w, w, move=False) w.application.clear_highlighted_ranges()
elif w.buffer.method.direction == 'next':
_find_next(old_w, w, move=False)
else:
_find_previous(old_w, w, move=False)
class InsertSearchString(method.Method): class InsertSearchString(method.Method):
def __init__(self, s): def __init__(self, s):
@ -106,56 +105,112 @@ def _end(w):
w.buffer.method.old_cursor = None w.buffer.method.old_cursor = None
w.buffer.method.old_window = None w.buffer.method.old_window = None
def _find_ranges(w, s):
(x, y) = (0, 0)
ranges = []
while y < len(w.buffer.lines):
while x < len(w.buffer.lines[y]):
try:
i = w.buffer.lines[y].index(s, x)
x = i + len(s)
ranges.append([Point(i, y), Point(x, y), 'black', 'white'])
except ValueError:
break
x = 0
y += 1
return ranges
def _find(old_w, new_w, move=False, direction='next'):
# DOESN'T WORK WELL FOR NEXT
app = old_w.application
s = new_w.buffer.make_string()
c = old_w.logical_cursor()
(x, y) = c.xy()
newc = None
ranges = _find_ranges(old_w, s)
indices = range(0, len(ranges))
if direction == 'next':
if move:
limit = Point(x, y)
else:
limit = Point(x - 1, y)
else:
if move:
limit = Point(x + len(s), y)
else:
limit = Point(x + len(s) + 1, y)
indices.reverse()
for i in indices:
if (direction == 'next' and ranges[i][0] > limit) or ranges[i][1] < limit:
ranges[i][3] = 'magenta'
newc = ranges[i][0]
break
if ranges and not newc:
return
app.clear_highlighted_ranges()
if newc:
old_w.goto(newc)
for (p1, p2, fg, bg) in ranges:
if p1 < old_w.first:
continue
elif p2 > old_w.last:
break
app.add_highlighted_range(old_w, p1, p2, fg, bg)
def _find_previous(old_w, new_w, move=False): def _find_previous(old_w, new_w, move=False):
s = new_w.buffer.make_string() return _find(old_w, new_w, move, 'previous')
old_b = old_w.buffer app = old_w.application
c = old_w.logical_cursor() s = new_w.buffer.make_string()
(x, y) = (c.x, c.y) c = old_w.logical_cursor()
(x, y) = c.xy()
if move: if move:
x -= 1 x -= 1
l = old_b.lines[y][:x + len(s)] limit = Point(x + len(s) + 1, y)
# for each line available newc = None
while y >= 0: ranges = _find_ranges(old_w, s)
if s in l: l = len(ranges) - 1
# success for i in range(0, len(ranges)):
x = l.rindex(s) if ranges[l - i][1] < limit:
(p1, p2) = (Point(x,y), Point(x + len(s), y)) ranges[l - i][3] = 'magenta'
old_w.goto(p1) newc = ranges[l - i][0]
old_w.application.clear_highlighted_ranges()
new_w.application.add_highlighted_range(old_w, p1, p2)
break break
elif y >= len(old_b.lines) - 1: if ranges and not newc:
# failure return
app.clear_highlighted_ranges()
if newc:
old_w.goto(newc)
for (p1, p2, fg, bg) in ranges:
if p1 < old_w.first:
continue
elif p2 > old_w.last:
break break
else: app.add_highlighted_range(old_w, p1, p2, fg, bg)
# keep trying
y -= 1
l = old_b.lines[y]
x = 0
def _find_next(old_w, new_w, move=False): def _find_next(old_w, new_w, move=False):
#return _find(old_w, new_w, move, 'next') # in time
app = old_w.application
s = new_w.buffer.make_string() s = new_w.buffer.make_string()
old_b = old_w.buffer
c = old_w.logical_cursor() c = old_w.logical_cursor()
(x, y) = (c.x, c.y) (x, y) = c.xy()
if move: if move:
x += 1 x += 1
l = old_b.lines[y][x:] limit = Point(x - 1, y)
# for each line available newc = None
while y < len(old_b.lines): ranges = _find_ranges(old_w, s)
if s in l: l = len(ranges) - 1
# success for i in range(0, len(ranges)):
x = l.index(s) + x if ranges[i][0] > limit:
(p1, p2) = (Point(x,y), Point(x + len(s), y)) ranges[i][3] = 'magenta'
old_w.goto(p1) newc = ranges[i][0]
old_w.application.clear_highlighted_ranges()
new_w.application.add_highlighted_range(old_w, p1, p2)
break break
elif y >= len(old_b.lines) - 1: if ranges and not newc:
# failure return
app.clear_highlighted_ranges()
if newc:
old_w.goto(newc)
for (p1, p2, fg, bg) in ranges:
if p1 < old_w.first:
continue
elif p2 > old_w.last:
break break
else: app.add_highlighted_range(old_w, p1, p2, fg, bg)
# keep trying
y += 1
l = old_b.lines[y]
x = 0