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
# each highlighted_range contains three things: [window, start_p, end_p]
def add_highlighted_range(self, w, start_p, end_p):
self.highlighted_ranges.append([w, start_p, end_p])
def add_highlighted_range(self, w, p1, p2, fg='default', bg='default'):
self.highlighted_ranges.append([w, p1, p2, fg, bg])
def clear_highlighted_ranges(self):
self.highlighted_ranges = []
@ -483,16 +483,15 @@ class Application(object):
self.draw_slot(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)
c = junk & 255
# FIXME?
#attr = (junk & (curses.A_COLOR|curses.A_ATTRIBUTES)) | curses.A_REVERSE
attr = curses.A_REVERSE
self.win.addch(sy, sx, c, attr)
def highlight_chars(self, sy, sx1, sx2):
char = junk & 255
#attr = color.build(fg, bg, curses.A_REVERSE)
attr = color.build(fg, bg)
self.win.addch(sy, sx, char, attr)
def highlight_chars(self, sy, sx1, sx2, fg='default', bg='default'):
for x in range(sx1, sx2):
self.highlight_char(sy, x)
self.highlight_char(sy, x, fg, bg)
def draw_slot(self, i):
assert self.active_slot < len(self.bufferlist.slots), "only two"
@ -509,7 +508,7 @@ class Application(object):
self._draw_slot_raw(i)
# 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:
count = 0
(x, y) = w.first.xy()
@ -517,10 +516,10 @@ class Application(object):
while count < slot.height:
if p1.y == y and px >= x and px < x + slot.width:
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
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
if x + slot.width >= len(w.buffer.lines[y]):
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):
unanchored_names = ('null', 'string', 'comment')
endlevel_names = ('pass', 'return', 'yield', 'raise', 'break', 'continue')
startlevel_names = ('if', 'try', 'class', 'def', 'for', 'while', 'try')
def __init__(self, m):
@ -52,7 +51,7 @@ class PythonTabber(tab2.StackTabber):
if not tokens:
# if a line has no tokens, we don't know much about its indentation
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
# 'while','class','def','if',etc. then we can start at it
return True
@ -82,6 +81,7 @@ class PythonTabber(tab2.StackTabber):
# if we were continuing, let's pop that previous continuation token
# and note that we're continuing
if self.markers and self.markers[-1].name == 'cont':
raise Exception, repr(self.markers)
self.continued = True
self._pop()
# if we haven't reached the target-line yet, we can detect how many

View File

@ -15,7 +15,7 @@ class Search(mode2.Fundamental):
# add some useful bindings
self.add_action_and_bindings(SearchNext(), ('C-s',))
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(SearchDeleteLeft(), ('DELETE', 'BACKSPACE',))
self.add_action_and_bindings(SearchDeleteLeftWord(), ('M-DELETE', 'M-BACKSPACE',))
@ -49,8 +49,10 @@ class SearchPrevious(method.Method):
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)
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")
class CancelSearch(method.Method):
@ -62,21 +64,18 @@ class CancelSearch(method.Method):
class SearchDeleteLeft(method.Method):
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)
if w.buffer.method.direction == 'next':
_find_next(old_w, w, move=False)
else:
_find_previous(old_w, w, move=False)
_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 w.buffer.method.direction == 'next':
if not w.buffer.make_string():
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)
@ -106,56 +105,112 @@ def _end(w):
w.buffer.method.old_cursor = None
w.buffer.method.old_window = None
def _find_previous(old_w, new_w, move=False):
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()
old_b = old_w.buffer
c = old_w.logical_cursor()
(x, y) = (c.x, c.y)
(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):
return _find(old_w, new_w, move, 'previous')
app = old_w.application
s = new_w.buffer.make_string()
c = old_w.logical_cursor()
(x, y) = c.xy()
if move:
x -= 1
l = old_b.lines[y][:x + len(s)]
# for each line available
while y >= 0:
if s in l:
# success
x = l.rindex(s)
(p1, p2) = (Point(x,y), Point(x + len(s), y))
old_w.goto(p1)
old_w.application.clear_highlighted_ranges()
new_w.application.add_highlighted_range(old_w, p1, p2)
limit = Point(x + len(s) + 1, y)
newc = None
ranges = _find_ranges(old_w, s)
l = len(ranges) - 1
for i in range(0, len(ranges)):
if ranges[l - i][1] < limit:
ranges[l - i][3] = 'magenta'
newc = ranges[l - i][0]
break
elif y >= len(old_b.lines) - 1:
# failure
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
else:
# keep trying
y -= 1
l = old_b.lines[y]
x = 0
app.add_highlighted_range(old_w, p1, p2, fg, bg)
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()
old_b = old_w.buffer
c = old_w.logical_cursor()
(x, y) = (c.x, c.y)
(x, y) = c.xy()
if move:
x += 1
l = old_b.lines[y][x:]
# for each line available
while y < len(old_b.lines):
if s in l:
# success
x = l.index(s) + x
(p1, p2) = (Point(x,y), Point(x + len(s), y))
old_w.goto(p1)
old_w.application.clear_highlighted_ranges()
new_w.application.add_highlighted_range(old_w, p1, p2)
limit = Point(x - 1, y)
newc = None
ranges = _find_ranges(old_w, s)
l = len(ranges) - 1
for i in range(0, len(ranges)):
if ranges[i][0] > limit:
ranges[i][3] = 'magenta'
newc = ranges[i][0]
break
elif y >= len(old_b.lines) - 1:
# failure
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
else:
# keep trying
y += 1
l = old_b.lines[y]
x = 0
app.add_highlighted_range(old_w, p1, p2, fg, bg)