diff --git a/application.py b/application.py index d2034e7..97e8574 100755 --- a/application.py +++ b/application.py @@ -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 diff --git a/miniparse.py b/miniparse.py new file mode 100644 index 0000000..3bc624d --- /dev/null +++ b/miniparse.py @@ -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) diff --git a/mode_python.py b/mode_python.py index 849cbee..a338fa2 100644 --- a/mode_python.py +++ b/mode_python.py @@ -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 diff --git a/mode_search.py b/mode_search.py index dcba11a..4f170d0 100644 --- a/mode_search.py +++ b/mode_search.py @@ -9,13 +9,13 @@ class Search(mode2.Fundamental): mode2.Fundamental.__init__(self, w) # clear out all the defaults that we don't want/need - self.actions = {} + self.actions = {} self.bindings = {} # 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,24 +64,21 @@ 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() - 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) +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() + 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): def __init__(self, s): @@ -106,56 +105,112 @@ def _end(w): w.buffer.method.old_cursor = 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): - s = new_w.buffer.make_string() - old_b = old_w.buffer - c = old_w.logical_cursor() - (x, y) = (c.x, c.y) + 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)