diff --git a/application.py b/application.py index 1ce1b2f..4d26c1f 100755 --- a/application.py +++ b/application.py @@ -19,6 +19,7 @@ class Application(object): # initialize some basic stuff self.config = {} self.highlighted_ranges = [] + self.highlight_mark = False self.mini_active = False self.mini_buffer = None self.mini_prompt = "" @@ -100,6 +101,8 @@ class Application(object): exec("import %s" % name) mod = eval(name) for mname in dir(mod): + if mname.startswith('_'): + continue cls = eval("%s.%s" % (name, mname)) if hasattr(cls, '_is_method') and cls._is_method: self.methods[cls._name()] = cls() @@ -580,12 +583,20 @@ class Application(object): if os.path.exists(path): try: f = open(path, 'r') - #execfile(path) exec(f) f.close() except Exception, e: s = traceback.format_exc() self.rcerror = 'There was an error during startup:\n\n%s' % s + + # after actions get handled, do some stuff + def post_action_hook(self, act): + self.last_action = act.name + if self.highlight_mark: + if act.name == 'set-mark' or act.metadata.get('is_move'): + pass + else: + self.highlight_mark = False # the mighty run-loop! def run(self): @@ -619,7 +630,7 @@ class Application(object): self.draw() self.need_draw = False - # gjeiwgjeiw + # clean up, clean up for b in self.bufferlist.buffers: b.close() @@ -780,6 +791,71 @@ class Application(object): x += slot.width count += 1 + def highlight_simple_range(self, slot, y1, x1, x2, fg, bg): + count = slot.window.mode.header + tx1, tx2 = slot.window.mode.lmargin, slot.width - 1 + x, y = slot.window.first.xy() + while count < slot.height: + if y1 == y and x1 < slot.width + x: + sy = slot.y_offset + count + sx1 = x1 - x + slot.window.mode.lmargin + sx2 = x2 - x + slot.window.mode.lmargin + if x1 <= x: + if x2 < slot.width + x: + self.highlight_chars(sy, tx1, sx2, fg, bg) + break + else: + self.highlight_chars(sy, tx1, tx2, fg, bg) + else: + if x2 < slot.width + x: + self.highlight_chars(sy, sx1, sx2, fg, bg) + break + else: + self.highlight_chars(sy, sx1, tx2, fg, bg) + + if x + slot.width > len(slot.window.buffer.lines[y]): + x = 0 + y += 1 + else: + x += slot.width - 1 + count += 1 + + def highlight_complex_range(self, slot, p1, p2, fg, bg): + count = slot.window.mode.header + tx1, tx2 = slot.window.mode.lmargin, slot.width - 1 + x, y = slot.window.first.xy() + while count < slot.height: + if p1.y <= y: + sy = slot.y_offset + count + if p1.y == y: + if p1.x > slot.width + x: + pass + elif p1.x > x: + self.highlight_chars(sy, p1.x - x + tx1, tx2, fg, bg) + else: + self.highlight_chars(sy, tx1, tx2, fg, bg) + elif p2.y > y: + self.highlight_chars(sy, tx1, tx2, fg, bg) + elif p2.y == y and p2.x >= x and p2.x < slot.width + x: + if slot.width > p2.x - x: + self.highlight_chars(sy, tx1, p2.x - x + tx1, fg, bg) + break + else: + self.highlight_chars(sy, tx1, tx2, fg, bg) + + if x + slot.width > len(slot.window.buffer.lines[y]): + x = 0 + y += 1 + else: + x += slot.width - 1 + count += 1 + + def highlight_range(self, slot, p1, p2, fg, bg): + if p1.y == p2.y: + return self.highlight_simple_range(slot, p1.y, p1.x, p2.x, fg, bg) + else: + return self.highlight_complex_range(slot, p1, p2, fg, bg) + def draw_slot(self, i): assert self.active_slot < len(self.bufferlist.slots), \ "strange: %d < %d" % (self.active_slot, len(self.bufferlist.slots)) @@ -807,24 +883,27 @@ class Application(object): for hr in self.highlighted_ranges: (high_w, p1, p2, fg, bg) = hr if w is high_w and p2 >= w.first and p1 <= w.last: - count = w.mode.header - x, y = w.first.xy() - px = p1.x - while count < slot.height: - if p1.y == y and px >= x and px - x < slot.width: - sy, sx = slot.y_offset + count, px - x + w.mode.lmargin - if slot.width > p2.x - x: - self.highlight_chars(sy, sx, p2.x-x, fg, bg) - break - else: - self.highlight_chars(sy, sx, slot.width - 1, fg, bg) - px += slot.width - px + x - 1 - if x + slot.width > len(w.buffer.lines[y]): - x = 0 - y += 1 - else: - x += slot.width - 1 - count += 1 + #raise Exception(repr((slot, p1, p2, fg, bg))) + self.highlight_range(slot, p1, p2, fg, bg) + + #self.highlight_range(slot, Point(13, 8), Point(29, 8), 'black', 'magenta') + if not self.highlighted_ranges and self.highlight_mark: + fg, bg = 'black', 'cyan' + cursor = w.logical_cursor() + mark = w.mark + if mark is None: + return + + if mark <= cursor: + p1, p2 = mark, cursor + else: + p1, p2 = cursor, mark + + if p1 < w.first: p1 = w.first + if p2 > w.last: p2 = w.last + #raise Exception("blargh") + self.highlight_range(slot, p1, p2, fg, bg) + #raise Exception("p1=%r p2=%r fg=%r bg=%r" % (p1, p2, fg, bg)) if w.margins_visible: shade = util.get_margin_color(w, 'blue') @@ -956,10 +1035,7 @@ def run_app(stdscr, buffers, **kwargs): a = Application(stdscr, buffers, **kwargs) metax = a.methods['meta-x'] for cmd in kwargs.get('init_cmds', []): - #act = a.methods[name] - #act.execute(a.active_window()) metax.execute(a.active_window(), method=cmd) - #a.last_action = act.name a.run() return 0 diff --git a/method/__init__.py b/method/__init__.py index 7db5272..52d739f 100644 --- a/method/__init__.py +++ b/method/__init__.py @@ -64,6 +64,7 @@ class Method(object): _is_method = True args = [] help = "" + metadata = {} def __init__(self): self.name = self._name() if self.__doc__: @@ -497,7 +498,11 @@ class CenterView(Method): class SetMark(Method): '''Set the mark to the current cursor location''' def _execute(self, w, **vargs): - w.set_mark() + if w.application.last_action == self.name: + w.application.highlight_mark = True + w.set_error("Highlighting enabled: %r" % w.application.highlight_mark) + else: + w.set_mark() class SwitchMark(Method): '''Switch the mark and the cursor locations''' def _execute(self, w, **vargs): diff --git a/method/move.py b/method/move.py index c064958..b88464a 100644 --- a/method/move.py +++ b/method/move.py @@ -6,63 +6,67 @@ from point import Point from method import Method, Argument -class StartOfLine(Method): +class _Move(Method): + '''Abstract base move action''' + metadata = {'is_move': True} + +class StartOfLine(_Move): '''Move the cursor to the start of the current line''' def _execute(self, w, **vargs): w.start_of_line() -class EndOfLine(Method): +class EndOfLine(_Move): '''Move the cursor to the end of the current line''' def _execute(self, w, **vargs): w.end_of_line() -class Forward(Method): +class Forward(_Move): '''Move the cursor right one character''' def _execute(self, w, **vargs): w.forward() -class Backward(Method): +class Backward(_Move): '''Move the cursor left one character''' def _execute(self, w, **vargs): w.backward() -class NextLine(Method): +class NextLine(_Move): '''Move the cursor down one line''' def _execute(self, w, **vargs): w.next_line() -class PreviousLine(Method): +class PreviousLine(_Move): '''Move the cursor up one line''' def _execute(self, w, **vargs): w.previous_line() -class PageUp(Method): +class PageUp(_Move): '''Move the cursor up one page''' def _execute(self, w, **vargs): w.page_up() -class PageDown(Method): +class PageDown(_Move): '''Move the cursor down one page''' def _execute(self, w, **vargs): w.page_down() -class GotoBeginning(Method): +class GotoBeginning(_Move): '''Move the cursor to the beginning of the buffer''' def _execute(self, w, **vargs): w.set_mark() w.goto_beginning() -class GotoEnd(Method): +class GotoEnd(_Move): '''Move the cursor to the end of the buffer''' def _execute(self, w, **vargs): w.set_mark() w.goto_end() -class RightWord(Method): +class RightWord(_Move): '''Move the cursor to the start of the word to the right''' def _execute(self, w, **vargs): w.right_word() -class LeftWord(Method): +class LeftWord(_Move): '''Move the cursor to the start of the word to the left''' def _execute(self, w, **vargs): w.left_word() -class NextSection(Method): +class NextSection(_Move): '''Move the cursor to the next section''' def _execute(self, w, **vargs): cursor = w.logical_cursor() @@ -74,7 +78,7 @@ class NextSection(Method): break seen_null_line = regex.whitespace.match(w.buffer.lines[i]) i += 1 -class PreviousSection(Method): +class PreviousSection(_Move): '''Move the cursor to the previous section''' def _execute(self, w, **vargs): cursor = w.logical_cursor() @@ -87,19 +91,19 @@ class PreviousSection(Method): seen_null_line = regex.whitespace.match(w.buffer.lines[i]) i -= 1 -class GotoChar(Method): +class GotoChar(_Move): '''Jump to the specified character''' args = [Argument("charno", type=type(0), prompt="Goto char: ")] def _execute(self, w, **vargs): w.goto_char(vargs["charno"]) -class ForwardChars(Method): +class ForwardChars(_Move): '''Move forward the specified number of characters''' args = [Argument("charno", type=type(0), prompt="Forward chars: ")] def _execute(self, w, **vargs): w.forward_chars(vargs["charno"]) -class GotoLine(Method): +class GotoLine(_Move): '''Jump to the specified line number''' args = [Argument("lineno", type=type(0), prompt="Goto line: ")] def _execute(self, w, **vargs): @@ -112,7 +116,7 @@ class GotoLine(Method): n = 1 w.goto_line(n) -class ForwardLines(Method): +class ForwardLines(_Move): '''Move forward the specified number of lines''' args = [Argument("lineno", type=type(0), prompt="Forward lines: ")] def _execute(self, w, **vargs): diff --git a/mode/__init__.py b/mode/__init__.py index bb4d5ad..458ac25 100644 --- a/mode/__init__.py +++ b/mode/__init__.py @@ -449,7 +449,8 @@ class Fundamental(Handler): return else: act.execute(self.window) - self.window.application.last_action = act.name + self.window.application.post_action_hook(act) + #self.window.application.last_action = act.name except ActionError, e: #XYZ: HACK--should fix if t in ('C-]', 'C-g'):