diff --git a/application.py b/application.py index 62bbd12..1ade56d 100755 --- a/application.py +++ b/application.py @@ -1,9 +1,10 @@ #!/usr/bin/env python -import curses, curses.ascii, getpass, os, re, string, sys, termios, time +import curses, curses.ascii, getpass, os, re, string, sets, sys, termios, time import traceback -import buffer, bufferlist, color, completer, keyinput, method, minibuffer -import mode, point, sets, util, window +import buffer2, bufferlist, color, completer, keyinput, method, minibuffer +import mode2, util, window2 +from point2 import Point # modes import mode, mode_c, mode_mini, mode_python, mode_nasm, mode_perl, mode_search @@ -75,61 +76,62 @@ class Application: self.set_error("Dynamic color not available") # initialize our modes - self.modes = { - 'blame': mode_blame.Blame, - 'c': mode_c.C, - 'console': mode_console.Console, - 'diff': mode_diff.Diff, - 'fundamental': mode.Fundamental, - 'mini': mode_mini.Mini, - 'nasm': mode_nasm.Nasm, - 'perl': mode_perl.Perl, - 'python': mode_python.Python, - 'replace': mode_replace.Replace, - 'search': mode_search.Search, - 'sh': mode_sh.Sh, - 'text': mode_text.Text, - 'which': mode_which.Which, - 'xml': mode_xml.XML, - 'mutt': mode_mutt.Mutt, - 'sql': mode_sql.Sql, - 'javascript': mode_javascript.Javascript, - 'template': mode_tt.Template, - } + self.modes = {'fundamental': mode2.Fundamental} +# self.modes = { +# 'blame': mode_blame.Blame, +# 'c': mode_c.C, +# 'console': mode_console.Console, +# 'diff': mode_diff.Diff, +# 'fundamental': mode.Fundamental, +# 'mini': mode_mini.Mini, +# 'nasm': mode_nasm.Nasm, +# 'perl': mode_perl.Perl, +# 'python': mode_python.Python, +# 'replace': mode_replace.Replace, +# 'search': mode_search.Search, +# 'sh': mode_sh.Sh, +# 'text': mode_text.Text, +# 'which': mode_which.Which, +# 'xml': mode_xml.XML, +# 'mutt': mode_mutt.Mutt, +# 'sql': mode_sql.Sql, +# 'javascript': mode_javascript.Javascript, +# 'template': mode_tt.Template, +# } # these are used in this order to determine which mode to open certain # kinds of files self.mode_paths = { - '/etc/profile': 'sh', + #'/etc/profile': 'sh', } self.mode_basenames = { - '.bashrc': 'sh', - '.bash_profile': 'sh', - '.profile': 'sh', + #'.bashrc': 'sh', + #'.bash_profile': 'sh', + #'.profile': 'sh', } self.mode_extensions = { - '.py': 'python', - '.pl': 'perl', - '.pm': 'perl', - '.t': 'perl', - '.c': 'c', - '.txt': 'text', - '.s': 'nasm', - '.sh': 'sh', - '.bash': 'sh', - '.xml': 'xml', - '.xml.in': 'xml', - '.html': 'xml', - '.htm': 'xml', - '.sql': 'sql', - '.js': 'javascript', - '.tt': 'template' +# '.py': 'python', +# '.pl': 'perl', +# '.pm': 'perl', +# '.t': 'perl', +# '.c': 'c', +# '.txt': 'text', +# '.s': 'nasm', +# '.sh': 'sh', +# '.bash': 'sh', +# '.xml': 'xml', +# '.xml.in': 'xml', +# '.html': 'xml', +# '.htm': 'xml', +# '.sql': 'sql', +# '.js': 'javascript', +# '.tt': 'template' } self.mode_detection = { - 'python': 'python', - 'perl': 'perl', - 'sh': 'sh', - 'bash': 'sh', +# 'python': 'python', +# 'perl': 'perl', +# 'sh': 'sh', +# 'bash': 'sh', } # initialize our methods @@ -153,17 +155,17 @@ class Application: # initialize our buffers # note that the first buffer in buffers will be initially visible - buffers.append(buffer.ScratchBuffer()) - buffers.append(buffer.ConsoleBuffer()) + buffers.append(buffer2.ScratchBuffer()) + buffers.append(buffer2.ConsoleBuffer()) self.bufferlist = bufferlist.BufferList(height, width) self.active_slot = 0 self.resize_slots() # build windows for our buffers for b in buffers: - window.Window(b, self, height, width, slot=self.active_slot, - mode_name=init_mode) + window2.Window(b, self, height, width, mode_name=init_mode) self.bufferlist.add_buffer(b) + self.bufferlist.set_slot(0, buffers[0]) self.resize_windows() # see if the user has requested that we go to a particular line @@ -203,21 +205,17 @@ class Application: return locals() def add_slot(self): + # XYZ b = self.bufferlist.slots[self.active_slot].buffer - n = self.bufferlist.add_slot(0, 0, 0, b) - self.resize_slots() - self.add_window_to_buffer(b, n) - self.resize_windows() - def remove_slot(self, slotname): + n = self.bufferlist.add_slot() + self.bufferlist.set_slot(n, b) + def remove_slot(self, n): assert len(self.bufferlist.slots) > 1, "oh no you didn't!" - assert slotname >= 0 and slotname < len(self.bufferlist.slots), \ - "invalid slot: %r (%r)" % (slotname, len(self.bufferlist.slots)) - b = self.bufferlist.slots[slotname].buffer - self.bufferlist.remove_slot(slotname) + assert n >= 0 and n < len(self.bufferlist.slots), \ + "invalid slot: %r (%r)" % (n, len(self.bufferlist.slots)) + self.bufferlist.remove_slot(n) if self.active_slot > slotname: self.active_slot = max(0, self.active_slot - 1) - self.resize_slots() - self.resize_windows() def single_slot(self): while len(self.bufferlist.slots) > 1: if self.active_slot == 0: @@ -225,10 +223,10 @@ class Application: else: self.remove_slot(0) - def get_window_height_width(self, slotname): - assert slotname >= 0 and slotname < len(self.bufferlist.slots), \ + def get_window_height_width(self, i): + assert i >= 0 and i < len(self.bufferlist.slots), \ "invalid slot: %r" % slotname - slot = self.bufferlist.slots[slotname] + slot = self.bufferlist.slots[i] return (slot.height, slot.width) # mini buffer handling @@ -243,7 +241,7 @@ class Application: self.mini_prompt = prompt self.mini_buffer = minibuffer.MiniBuffer(callback, method, tabber, modename) - window.Window(self.mini_buffer, self, height=1, + window2.Window(self.mini_buffer, self, height=1, width=self.x-1-len(self.mini_prompt)-1, slot='mini') self.mini_active = True def exec_mini_buffer(self): @@ -273,8 +271,8 @@ class Application: else: assert 0 <= self.active_slot and self.active_slot < len(self.bufferlist.slots), \ "0 <= %d < %d" % (self.active_slot, len(self.bufferlist.slots)) - slotname = self.active_slot - return self.bufferlist.slots[slotname].buffer.get_window(slotname) + i = self.active_slot + return self.bufferlist.slots[i].window # buffer handling def file_buffer(self, path, data, switch_to=True): @@ -283,7 +281,7 @@ class Application: f = open(path, 'w') f.write(data) f.close() - b = buffer.FileBuffer(path) + b = buffer2.FileBuffer(path) b.open() self.add_window_to_buffer(b, self.active_slot) self.add_buffer(b) @@ -293,7 +291,7 @@ class Application: if self.has_buffer_name(name): b = self.bufferlist.buffer_names[name] self.remove_buffer(b) - b = buffer.DataBuffer(name, data) + b = buffer2.DataBuffer(name, data) if modename is not None: b.modename = modename self.add_window_to_buffer(b, self.active_slot) @@ -328,7 +326,7 @@ class Application: def add_window_to_buffer(self, b, slotname): if not b.has_window(slotname): slot = self.bufferlist.slots[slotname] - window.Window(b, self, height=slot.height, width=slot.width, slot=slotname) + window2.Window(b, self, height=slot.height, width=slot.width) # error string handling def set_error(self, s): @@ -355,16 +353,16 @@ class Application: y_offset += y + 1 slot = self.bufferlist.slots[n-1].resize(y_pool, x, y_offset) def resize_windows(self): - for b in self.bufferlist.buffers: - keys = b.windows.keys() - for name in keys: - try: - (height, width) = self.get_window_height_width(name) - b.windows[name].set_size(width, height) - except: - w = b.windows[name] - del b.windows[name] - # kill w now + #for slot in + pass +# for b in self.bufferlist.buffers: +# keys = b.windows.keys() +# for w in b.windows: +# try: +# (height, width) = self.get_window_height_width(name) +# b.windows[name].set_size(width, height) +# except: +# b.windows.remove(w) # hide the curses cursor def hide_cursor(self): @@ -398,12 +396,12 @@ class Application: # undo/redo def undo(self): try: - self.window().buffer.undo() + self.window().undo() except Exception, e: self.set_error("%s" % (e)) def redo(self): try: - self.window().buffer.redo() + self.window().redo() except Exception, e: self.set_error("%s" % (e)) @@ -503,101 +501,38 @@ class Application: self.draw_slot(i) self.draw_status_bar(i) - def draw_slot(self, slotname): - slot = self.bufferlist.slots[slotname] - if not slot.buffer.has_window(slotname): + def draw_slot(self, i): + #return + slot = self.bufferlist.slots[i] + if slot.window is None: return - w = slot.buffer.get_window(slotname) - lines = w.visible_lines() - regions = w.mode.visible_regions() - ## FIXME: why isn't this always the same???? - assert (len(lines) == len(regions) or - len(lines) == len(regions) - 1), "%d,%d" % (len(lines), - len(regions)-1) - assert len(lines) > 0, "no lines... why?" - m = min(len(lines), slot.height) - assert m > 0 - x = slot.width - y = slot.height - y_offset = slot.offset + w = slot.window - assert x > 0 - assert y > 0 - red_attr = color.build_attr(color.pairs('red', 'default')) - for i in range(0, m): - j = 0 - line = lines[i] - for r in regions[i]: - try: - # start, end, attr, value, ttype = r - assert 0 <= r.start, "0 <= %d" % (r.start) - assert r.start <= r.end, "%d <= %d" % (r.start, r.end) - assert r.end <= len(line), "%d <= %d" % (r.end, len(line)) - except Exception, e: - s = "\n".join([repr(x) for x in regions]) - raise Exception, "%s\n%s\n\n%s\n\n%s\n\n%s\n\n%d" % \ - (e, s, regions[i], r, repr(line), len(line)) - assert line[r.start:r.end] == r.value, \ - "%r != %r" % (line[r.start:r.end], r.value) - try: - if DARK_BACKGROUND: - attr = r.attr | curses.A_BOLD - else: - attr = r.attr - self.win.addnstr(i + y_offset, r.start, r.value, r.end - r.start, attr) - except Exception, e: - raise Exception, "%s\n%s %s %s %s" % \ - (e, repr(i), repr(r.start), repr(r.value), repr(r.end - r.start)) - j = r.end - if j < len(line): - # this is cheating... FIXME - self.win.addnstr(i + y_offset, j, line[j:], len(line) - j) - j += len(line) - j - if j < x: - self.win.addnstr(i + y_offset, j, ' ' * (x-j), (x-j)) - if w.continued_visible_line(i): - self.win.addch(i + y_offset, x, '\\', red_attr) + lines = w.buffer.lines + count = 0 + (x, y) = w.first.xy() + cursor = w.logical_cursor() + (cx, cy) = cursor.xy() + (px, py) = (None, None) + while count < slot.height: + if y >= len(lines): + self.win.addstr(count, 0, '~' + ' ' * (slot.width - 1)) else: - self.win.addch(i + y_offset, x, ' ') - - for i in range(m, y): - self.win.addnstr(i + y_offset, 0, '~' + ' ' * (x), x + 1, red_attr) + if cy == y and cx >= x and cx < x + slot.width: + px = cx - x + py = count + line = lines[y] + subline = line[x:x + slot.width] + if len(subline) < slot.width: + subline += ' ' * (slot.width - len(subline)) + self.win.addstr(slot.offset + count, 0, line[x:x + slot.width]) - for (high_w, lp1, lp2) in self.highlighted_ranges: - if lp1.y != lp2.y: - # this region is incoherent, so skip it, or die, whatever - #raise Exception, "haddock %d != %d" % (lp1.y, lp2.y) - pass - elif w is not high_w: - # this region isn't in the current window so skip it - pass - else: - (pp1, pp2) = (w.physical_point(lp1), w.physical_point(lp2)) - vo = w.visible_offset() - (vp1, vp2) = (pp1.offset(0, -vo), pp2.offset(0, -vo)) - if vp2.y < 0 or vp1.y > w.height: - # this region is not visible, so skip it - pass + if x + slot.width >= len(line): + x = 0 + y += 1 else: - # first let's fix our points so we're sure they're visible - if vp1.y < 0: - vp1 = point.Point(0,0) - if vp2.y > w.height: - vp2 = point.Point(len(lines[-1]), w.height-1) - - if vp1.y == vp2.y: - # our region physically fits on one line; this is easy - b = lines[vp1.y][vp1.x:vp2.x] - self.win.addstr(vp1.y + y_offset, vp1.x, b, curses.A_REVERSE) - else: - # our region spans multiple physical lines, so deal - b1 = lines[vp1.y][vp1.x:] - self.win.addstr(vp1.y + y_offset, vp1.x, b1, curses.A_REVERSE) - for i in range(vp1.y + 1, vp2.y): - b = lines[i] - self.wind.addstr(i + y_offset, 0, b, curses.A_REVERSE) - b2 = lines[vp2.y][:vp2.x] - self.win.addstr(vp2.y + y_offset, 0, b2, curses.A_REVERSE) + x += slot.width + count += 1 if self.margins_visible: for (limit, shade) in self.margins: @@ -606,44 +541,42 @@ class Application: # the actual character is the lower 8 bits, and the # attribute is the upper 8 bits; we will ignore the # attribute and just get the character - char = self.win.inch(i + y_offset, limit) & 255 + char = self.win.inch(i + slot.offset, limit) & 255 attr = color.build('default', shade, 'bold') - self.win.addch(i + y_offset, limit, char, attr) + self.win.addch(i + slot.offset, limit, char, attr) - if self.mini_active is False and self.active_slot == slotname: - if w.active_point is not None and w.point_is_visible(w.active_point): + if self.mini_active is False and self.active_slot == i: + if False and w.active_point is not None and w.point_is_visible(w.active_point): pa = w.physical_point(w.active_point) va = pa.offset(0, -w.visible_offset()) if len(lines[va.y]): a = lines[va.y][va.x] else: a = ' ' - self.win.addch(va.y + y_offset, va.x, a, curses.A_REVERSE) + self.win.addch(va.y + slot.offset, va.x, a, curses.A_REVERSE) else: - cursor = w.visible_cursor() - cx, cy = (cursor.x, cursor.y) + assert px is not None and py is not None + if cy >= len(lines): - self.set_error('in main1: cursor error; %d >= %d' % - (cy, len(lines))) + self.set_error('in main1: cursor error; %d >= %d' % (cy, len(lines))) return elif cx == len(lines[cy]): c = ' ' - elif cx > len(lines[cy]): - self.set_error('why? %r %r' % (cursor, len(lines[cy]))) + elif px > len(lines[cy]): + self.set_error('why? %r %r' % (cx, len(lines[cy]))) return else: c = lines[cy][cx] - self.win.addch(cy + y_offset, cx, c, curses.A_REVERSE) + self.win.addch(slot.offset + py , px, c, curses.A_REVERSE) def draw_status_bar(self, slotname): slot = self.bufferlist.slots[slotname] - if not slot.buffer.has_window(slotname): + if slot.window is None: return - w = slot.buffer.get_window(slotname) + w = slot.window b = w.buffer cursor = w.logical_cursor() - pcursor = w.physical_cursor() first = w.first last = w.last @@ -661,7 +594,7 @@ class Application: if w.mark: mark = w.mark else: - mark = point.Point(-1, -1) + mark = Point(-1, -1) name = b.name() if w.first_is_visible(): @@ -673,8 +606,10 @@ class Application: # XYZ: we should actually use more of the 'state' variables - format = "----:%s-Fl %-18s (%s)--L%d--C%d--%s" - status = format % (modflag, name, w.mode.name(), cursor.y+1, cursor.x+1, perc) + #format = "----:%s-Fl %-18s (%s)--L%d--C%d--%s" + #status = format % (modflag, name, w.mode.name(), cursor.y+1, cursor.x+1, perc) + format = "----:%s-Fl %-18s (%s)--L%d--C%d--%s--%s--%s" + status = format % (modflag, name, w.mode.name(), cursor.y+1, cursor.x+1, w.first, w.last, perc) status = status[:slot.width + 1] status += "-" * (slot.width - len(status) + 1) self.win.addnstr(slot.height + slot.offset, 0, status, slot.width + 1, @@ -729,11 +664,11 @@ class Application: def open_aes_file(path, nl, name=None): p = getpass.getpass("Please enter the AES password: ") - b = buffer.AesBuffer(path, p, nl, name) + b = buffer2.AesBuffer(path, p, nl, name) return b def open_plain_file(path, nl, name=None): - b = buffer.FileBuffer(path, nl, name) + b = buffer2.FileBuffer(path, nl, name) return b if __name__ == "__main__": diff --git a/bufferlist.py b/bufferlist.py index ae4f027..18e9b07 100644 --- a/bufferlist.py +++ b/bufferlist.py @@ -1,66 +1,105 @@ import sets class Slot: - def __init__(self, height, width, offset, buffer=None): + def __init__(self, height, width, offset): self.height = height self.width = width self.offset = offset - self.buffer = buffer - self.resize(height, width, offset) + self.window = None def is_empty(self): - return self.buffer is None + return self.window is None def resize(self, height, width, offset): self.height = height self.width = width self.offset = offset - # possible callbacks - def remove(self): - # possible callbacks - pass + if self.window is not None: + self.window.set_size(self.width, self.height) + def set(self, w): + self.window = w + w.set_size(self.width, self.height) + def unset(self): + if not self.is_empty(): + old_w = self.window + self.window = None + return old_w + else: + return None class BufferList: def __init__(self, height, width, buffers=()): - self.slots = [] - self.add_slot(height, width, 0) - - self.buffers = sets.Set() - self.buffer_names = {} + self.height = height + self.width = width + self.buffers = sets.Set() + self.buffer_names = {} self.hidden_buffers = [] + self.slots = [] + + self.add_slot() + self.fit_slots() for b in buffers: self.add_buffer(b) + def fit_slots(self): + heights = [self.height / len(self.slots)] * len(self.slots) + for i in range(0, self.height % len(self.slots)): + heights[i] += 1 + offsets = [0] + for i in range(1, len(self.slots)): + offsets.insert(i, offsets[i - 1] + heights[i - 1]) + for i in range(0, len(self.slots)): + self.slots[i].resize(heights[i], self.width, offsets[i]) + def resize(self, height, width): + self.height = height + self.width = width + self.fit_slots() + + def is_window_visible(self, w): + for slot in self.slots: + if w is slot.window: + return True + return False + def is_buffer_visible(self, b): + for slot in self.slots: + if slot.window is not None and b is slot.window.buffer: + return True + return False # manipulate slots - def add_slot(self, height, width, offset=0, buffer=None): - self.slots.append(Slot(height, width, offset, buffer)) + def add_slot(self): + self.slots.append(Slot(self.height, self.width, 0)) + self.fit_slots() return len(self.slots) - 1 def empty_slot(self, i): assert i > -1 and i < len(self.slots), "slot %d does not exist" % i return self.slots[i].is_empty() + def unset_slot(self, i): + assert i > -1 and i < len(self.slots), "slot %d does not exist" % i + old_w = self.slots[i].unset() + if old_w is not None: + old_b = old_w.buffer + if not self.is_buffer_visible(old_b): + self.hidden_buffers.insert(0, old_b) + if len(old_b.windows) > 1: + old_b.remove_window(old_w) + def set_slot(self, i, b): assert i > -1 and i < len(self.slots), "slot %d does not exist" % i assert b in self.buffers, "buffer %s does not exist" % (b.name()) + self.unset_slot(i) + if b in self.hidden_buffers: self.hidden_buffers.remove(b) - if not self.slots[i].is_empty(): - b2 = self.slots[i].buffer - self.hidden_buffers.insert(0, b2) - self.slots[i].buffer = b + if self.is_window_visible(b.windows[0]): + app = b.windows[0].application + w = window2.Window(b, app, height=slot.height, width=slot.width) + else: + w = b.windows[0] + self.slots[i].set(w) + def remove_slot(self, i): assert i > -1 and i < len(self.slots), "slot %d does not exist" % i - if not self.slots[i].is_empty(): - b = self.slots[i].buffer - self.hidden_buffers.insert(0, b) - self.slots[i].remove() + self.unset_slot(i) del self.slots[i] - - # now fix the stored slot numbers for all the - for b in self.buffers: - for j in range(i, len(self.slots)): - if b.has_window(j+1): - w = b.get_window(j+1) - del b.windows[j+1] - w.slot = j - b.windows[j] = w + self.fit_slots() # add/remove buffers def add_buffer(self, b): @@ -68,9 +107,6 @@ class BufferList: self.buffers.add(b) self.buffer_names[b.name()] = b self.hidden_buffers.append(b) - for i in range(0, len(self.slots)): - if self.empty_slot(i): - self.set_slot(i, b) def has_buffer(self, b): return b in self.buffers def has_buffer_name(self, name): @@ -84,9 +120,10 @@ class BufferList: return None def remove_buffer(self, b): assert b in self.buffers, "buffer %s does not exist" % (b.name()) - for slot in self.slots: - if slot.buffer is b: - slot.buffer = None + for i in range(0, len(self.slots)): + slot = self.slots[i] + if self.slots[i].window is not None and self.slots[i].window.buffer is b: + self.unset_slot(i) self.buffers.remove(b) del self.buffer_names[b.name()] if b in self.hidden_buffers: @@ -96,9 +133,9 @@ class BufferList: def is_buffer_hidden(self, b): assert b in self.buffers, "buffer %s does not exist" % (b.name()) return b in self.hidden_buffers - def is_buffer_visible(self, b): - assert b in self.buffers, "buffer %s does not exist" % (b.name()) - for slot in self.slots: - if slot.buffer is b: - return True - return False +# def is_buffer_visible(self, b): +# assert b in self.buffers, "buffer %s does not exist" % (b.name()) +# for slot in self.slots: +# if slot.buffer is b: +# return True +# return False diff --git a/highlight2.py b/highlight2.py index 7073d73..695730b 100644 --- a/highlight2.py +++ b/highlight2.py @@ -4,7 +4,7 @@ import lex2 color_list = [] color_list.extend(['\033[3%dm' % x for x in range(0, 8)]) color_list.extend(['\033[3%d;1m' % x for x in range(0, 8)]) -color_list.append('\033[0m') +color_list.extend(['\033[0m']) color_names = [ 'black', 'dred', 'dgreen', 'brown', 'dblue', 'dpurple', 'dcyan', 'lgrey', @@ -158,7 +158,7 @@ class Highlighter: tx2 = token.x + len(token.string) # the notation "*|*| " refers to what the text spans, i.e.: - # before|during|after + # before|during|after the deletion if (y, tx2) <= (y1, x1): # *| | newtokens[y].append(token) diff --git a/method.py b/method.py index aff7eea..ebb28a4 100644 --- a/method.py +++ b/method.py @@ -336,7 +336,7 @@ class InsertString(Method): self.help = "Insert %r into the current buffer." % s self.string = s def _execute(self, window, **vargs): - window.insert_string(self.string) + window.insert_string_at_cursor(self.string) # killing/copying/etc. class Kill(Method): @@ -487,18 +487,18 @@ class SwitchMark(Method): class InsertNewline(Method): '''Insert newline into buffer at the cursor''' def _execute(self, window, **vargs): - window.insert_string('\n') + window.insert_string_at_cursor('\n') class InsertSpace(Method): '''Insert space into buffer at the cursor''' def _execute(self, window, **vargs): - window.insert_string(' ') + window.insert_string_at_cursor(' ') class InsertTab(Method): '''Insert tab into buffer, or tabbify line, depending on mode''' def _execute(self, window, **vargs): cursor = window.logical_cursor() i = window.mode.get_indentation_level(cursor.y) if i is None: - window.insert_string(' ') + window.insert_string_at_cursor(' ') else: j = window.buffer.count_leading_whitespace(cursor.y) if i != j: @@ -541,7 +541,7 @@ class CommentRegion(Method): window.input_line = "Empty kill region" return for y in range(p1.y, p2.y): - window.buffer.insert_string(point.Point(0, y), "#") + window.buffer.insert_string_at_cursor(point.Point(0, y), "#") class UncommentRegion(Method): '''Remove a comment from every line in the current buffer''' def _execute(self, w, **vargs): @@ -582,7 +582,7 @@ class WrapLine(Method): old_cursor.y += 1 window.goto(point.Point(j, i)) window.right_delete() - window.insert_string('\n') + window.insert_string_at_cursor('\n') i += 1 l = len(window.buffer.lines[old_cursor.y]) @@ -627,7 +627,7 @@ class JustifyRight(Method): if i >= len(prev_line): return s = ' ' * (i - cursor.x) - window.insert_string(s) + window.insert_string_at_cursor(s) class JustifyLeft(Method): '''Justify text with the previous line left from the cursor by whitespace''' def _execute(self, window, **vargs): @@ -767,7 +767,7 @@ class UnindentBlock(Method): if lines[i].startswith(' '): lines[i] = lines[i][4:] w.buffer.delete_string(point.Point(0, p1.y), point.Point(0, p2.y)) - w.buffer.insert_string(point.Point(0, p1.y), '\n'.join(lines) + '\n') + w.buffer.insert_string_at_cursor(point.Point(0, p1.y), '\n'.join(lines) + '\n') class IndentBlock(Method): '''Add 4 spaces to each line in region''' def _execute(self, w, **vargs): @@ -785,7 +785,7 @@ class IndentBlock(Method): for i in range(0, len(lines)): lines[i] = ' ' + lines[i] w.buffer.delete_string(point.Point(0, p1.y), point.Point(0, p2.y)) - w.buffer.insert_string(point.Point(0, p1.y), '\n'.join(lines) + '\n') + w.buffer.insert_string_at_cursor(point.Point(0, p1.y), '\n'.join(lines) + '\n') class CodeComplete(Method): '''Complete based on tokenized strings''' @@ -830,7 +830,7 @@ class CodeComplete(Method): pass elif sofar: w.buffer.delete_string(p1, p2) - w.buffer.insert_string(p1, sofar) + w.buffer.insert_string_at_cursor(p1, sofar) if num_seen == 1: w.application.set_error('Unique!') else: @@ -1279,7 +1279,7 @@ class CloseTag(Method): def _execute(self, w, **vargs): # if w.mode doesn't do tag matching, just insert the character return if not w.mode.tag_matching: - w.insert_string(self.mytag) + w.insert_string_at_cursor(self.mytag) return # first, de-reference some variables and actually do the insertion @@ -1289,7 +1289,7 @@ class CloseTag(Method): buffer = w.buffer #cursor = w.physical_cursor() tag_stack = [] - w.insert_string(self.mytag) + w.insert_string_at_cursor(self.mytag) cursor = w.physical_cursor() assert cursor.x > 0, "my assumptions made an ass out of u and me" diff --git a/mode2.py b/mode2.py index b00f4be..78ad0ae 100644 --- a/mode2.py +++ b/mode2.py @@ -3,7 +3,8 @@ import sets, string import color, default, highlight, method, point -DEBUG = False +#DEBUG = False +DEBUG = True class Handler: def __init__(self): @@ -191,8 +192,6 @@ class Fundamental(Handler): self.window.application.set_error(err) def invalidate(self): - if self.tabber is not None: - self.tabber.invalidate() if self.lexer is not None: self.highlighter.invalidate_regions() @@ -212,20 +211,13 @@ class Fundamental(Handler): regions = self.get_regions() return regions[i:i+self.window.height] - def region_added(self, p, xdiff, ydiff, s): + def region_added(self, p, newlines): if self.lexer is not None: - if self.tabber is not None and s != ' ' and s != ' ': - self.tabber.invalidate() - self.highlighter.region_added(p, xdiff, ydiff, s) + self.highlighter.relex_add(lines, p.y, p.x, newlines) - def region_removed(self, p1, p2, s): + def region_removed(self, p1, p2): if self.lexer is not None: - if self.tabber is not None: - self.tabber.invalidate() - self.highlighter.region_removed(p1, p2, s) + self.highlighter.relex_del(lines, p1, p2) def get_indentation_level(self, y): - if self.tabber is None: - return None - else: - return self.tabber.get_indentation_level(y) + return None