diff --git a/application.py b/application.py index ea7a74d..248b1e3 100755 --- a/application.py +++ b/application.py @@ -3,13 +3,14 @@ import curses, curses.ascii, getpass, os, re, string, sets, sys, termios, time import traceback import buffer2, bufferlist, color, completer, keyinput, method, minibuffer -import mode2, util, window2 +import util, window2 from point2 import Point # modes -import mode, mode_c, mode_mini, mode_python, mode_nasm, mode_perl, mode_search -import mode_replace, mode_xml, mode_console, mode_sh, mode_text, mode_which -import mode_mutt, mode_sql, mode_javascript, mode_diff, mode_blame, mode_tt +#import mode, mode_c, mode_mini, mode_python, mode_nasm, mode_perl, mode_search +#import mode_replace, mode_xml, mode_console, mode_sh, mode_text, mode_which +#import mode_mutt, mode_sql, mode_javascript, mode_diff, mode_blame, mode_tt +import mode2, mode_mini2 def run(buffers, jump_to_line=None, init_mode=None): # save terminal state so we can restore it when the program exits @@ -76,7 +77,10 @@ class Application: self.set_error("Dynamic color not available") # initialize our modes - self.modes = {'fundamental': mode2.Fundamental} + self.modes = { + 'fundamental': mode2.Fundamental, + 'mini': mode_mini2.Mini, + } # self.modes = { # 'blame': mode_blame.Blame, # 'c': mode_c.C, @@ -169,9 +173,7 @@ class Application: # see if the user has requested that we go to a particular line if jump_to_line: - name = buffers[0].name() - b = self.bufferlist.get_buffer_by_name(name) - w = b.get_window(self.active_slot) + w = self.bufferlist.slots[0].window method.GotoLine().execute(w, lineno=jump_to_line) # initialize our kill ring and last action @@ -205,7 +207,7 @@ class Application: def add_slot(self): # XYZ - b = self.bufferlist.slots[self.active_slot].buffer + b = self.bufferlist.slots[self.active_slot].window.buffer n = self.bufferlist.add_slot() self.bufferlist.set_slot(n, b) def remove_slot(self, n): @@ -238,10 +240,8 @@ class Application: if self.mini_buffer_is_open(): self.close_mini_buffer() self.mini_prompt = prompt - self.mini_buffer = minibuffer.MiniBuffer(callback, method, tabber, - modename) - window2.Window(self.mini_buffer, self, height=1, - width=self.x-1-len(self.mini_prompt)-1, slot='mini') + self.mini_buffer = minibuffer.MiniBuffer(callback, method, tabber, modename) + window2.Window(self.mini_buffer, self, height=1, width=self.x-1-len(self.mini_prompt)-1) self.mini_active = True def exec_mini_buffer(self): self.mini_buffer.callback(self.mini_buffer.make_string()) @@ -262,11 +262,10 @@ class Application: assert 0 <= self.active_slot and self.active_slot < len(self.bufferlist.slots) self.active_slot = (self.active_slot + 1) % len(self.bufferlist.slots) def window(self): - slotname = self.active_slot - return self.bufferlist.slots[slotname].buffer.get_window(slotname) + return self.bufferlist.slots[self.active_slot].window def active_window(self): if self.mini_active: - return self.mini_buffer.get_window('mini') + return self.mini_buffer.windows[0] else: assert 0 <= self.active_slot and self.active_slot < len(self.bufferlist.slots), \ "0 <= %d < %d" % (self.active_slot, len(self.bufferlist.slots)) @@ -498,7 +497,7 @@ class Application: (px, py) = (None, None) while count < slot.height: if y >= len(lines): - self.win.addstr(count, 0, '~' + ' ' * (slot.width - 1), redattr) + self.win.addstr(slot.offset + count, 0, '~' + ' ' * (slot.width - 1), redattr) else: if cy == y and cx >= x and cx < x + slot.width: px = cx - x @@ -617,29 +616,22 @@ class Application: self.win.addnstr(self.y-1, 0, s2, l) def draw_mini_buffer(self): l = self.x - 1 - w = self.mini_buffer.get_window('mini') - lines = w.visible_lines() - s1 = self.mini_prompt + lines[0] + b = self.mini_buffer + s1 = self.mini_prompt + b.lines[0] s2 = util.padtrunc(s1, l) self.win.addnstr(self.y-1, 0, s2, l) if self.mini_active: - cursor = w.visible_cursor() - cx, cy = (cursor.x, cursor.y) - if cy >= len(lines): - #self.set_error('in main2: cursor error; %d >= %d' % - # (cy, len(lines))) - self.set_error('in main2: %r, %r [f:%r,l:%r] {h:%r,w:%r} %r' % - (len(lines), cursor, w.first, w.last, - w.height, w.width, len(lines[0]))) - + w = b.windows[0] + cursor = w.logical_cursor() + (cx, cy) = cursor.xy() + if cy >= len(b.lines): return - elif cx == len(lines[cy]): + elif cx == len(b.lines[cy]): c = ' ' else: - c = lines[cy][cx] - self.win.addch(self.y-1, cx + len(self.mini_prompt), c, - curses.A_REVERSE) + c = b.lines[cy][cx] + self.win.addch(self.y-1, cx + len(self.mini_prompt), c, curses.A_REVERSE) def draw_nothing(self): l = self.x - 1 self.win.addnstr(self.y-1, 0, util.pad('', l), l) @@ -685,7 +677,7 @@ if __name__ == "__main__": # if debugging, disable error handling to produce backtraces if opts.debug: - mode.DEBUG = True + mode2.DEBUG = True # we will support using +19 as the first argument to indicate opening the # first file on line 19 (same as -g 19 or --goto 19) @@ -693,6 +685,9 @@ if __name__ == "__main__": opts.goto = int(args[0][1:]) args = args[1:] + if opts.goto is not None: + opts.goto += 1 + # figure out which kind of line types we're using if opts.linetype not in linetypes: sys.stderr.write('invalid linetype: %r' % opts.linetype) diff --git a/buffer2.py b/buffer2.py index 0cfc6cb..cb2a764 100644 --- a/buffer2.py +++ b/buffer2.py @@ -39,6 +39,7 @@ class Buffer(object): self.stack_limit = stack_limit self.nl = nl self.modified = False + self.modes = {} # basic file operation stuff def _open_file_r(self, path): diff --git a/bufferlist.py b/bufferlist.py index 18e9b07..ee8bcb0 100644 --- a/bufferlist.py +++ b/bufferlist.py @@ -1,4 +1,5 @@ import sets +import window2 class Slot: def __init__(self, height, width, offset): @@ -39,12 +40,13 @@ class BufferList: 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)): + total = self.height - len(self.slots) + 1 + heights = [total / len(self.slots)] * len(self.slots) + for i in range(0, total % 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]) + offsets.insert(i, offsets[i - 1] + heights[i - 1] + 1) for i in range(0, len(self.slots)): self.slots[i].resize(heights[i], self.width, offsets[i]) def resize(self, height, width): @@ -84,6 +86,7 @@ class BufferList: 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()) + slot = self.slots[i] self.unset_slot(i) if b in self.hidden_buffers: @@ -93,7 +96,7 @@ class BufferList: w = window2.Window(b, app, height=slot.height, width=slot.width) else: w = b.windows[0] - self.slots[i].set(w) + slot.set(w) def remove_slot(self, i): assert i > -1 and i < len(self.slots), "slot %d does not exist" % i diff --git a/method.py b/method.py index ebb28a4..be10a0b 100644 --- a/method.py +++ b/method.py @@ -990,8 +990,9 @@ class CvsStatus(Method): assert m, "regex6 %r" % lines[7] soptions = m.group(1) - w.application.set_error('%s %s %s/%s [%s|%s|%s]' % \ - (ffile, fstatus, wrev, rrev, stag, sdate, soptions)) + w.application.set_error('%s %s %s/%s [%s|%s|%s]' % (ffile, fstatus, + wrev, rrev, stag, + sdate, soptions)) class CvsDiff(Method): '''diff the current file with the version in CVS''' @@ -1256,8 +1257,8 @@ class SplitWindow(Method): a = w.application a.add_slot() if not w.cursor_is_visible(): - #w.center_view() - w.relocate_cursor() + p = w.first + w.goto(p) n = len(a.bufferlist.slots) a.set_error('Window has been split into %d windows!' % n) diff --git a/minibuffer.py b/minibuffer.py index 77c2064..d066ca8 100644 --- a/minibuffer.py +++ b/minibuffer.py @@ -1,8 +1,8 @@ -import buffer +import buffer2 # minibuffer is a singleton mini = None -class MiniBuffer(buffer.Buffer): +class MiniBuffer(buffer2.Buffer): def __new__(cls, *args, **kwargs): global mini if mini is None: @@ -10,7 +10,7 @@ class MiniBuffer(buffer.Buffer): return mini # the callback function should take one argument (window) def __init__(self, func, method=None, tabber=None, modename=None): - buffer.Buffer.__init__(self) + buffer2.Buffer.__init__(self) self.callback = func self.method = method self.tabber = tabber diff --git a/mode_mini2.py b/mode_mini2.py new file mode 100644 index 0000000..7bdb7ac --- /dev/null +++ b/mode_mini2.py @@ -0,0 +1,41 @@ +import method, mode2 + +class Mini(mode2.Fundamental): + '''This is the default mode''' + def __init__(self, w): + mode2.Fundamental.__init__(self, w) + + # delete actions relating to multiple lines + self.del_action('center-view') + self.del_action('next-line') + self.del_action('previous-line') + self.del_action('page-down') + self.del_action('page-up') + self.del_action('goto-beginning') + self.del_action('goto-end') + self.del_action('switch-buffer') + + # add some new actions for the minibuffer + self.add_action_and_bindings(MiniCallback(), ('RETURN',)) + self.add_action_and_bindings(MiniTabComplete(), ('TAB',)) + #self.add_action_and_bindings(MiniCancel(), ('C-]',)) + + def name(self): + return "Mini" + +class MiniCallback(method.Method): + def execute(self, window, **vargs): + window.buffer.do_callback() + +class MiniTabComplete(method.Method): + def __init__(self): + self.name = "tab-complete" + self.args = [] + def execute(self, window, **vargs): + b = window.buffer + if b.tabber is None: + window.application.set_error("No tab completion") + return + s1 = b.make_string() + s2, exists, complete = b.tabber.tab_string(s1, window) + b.set_data(s2) diff --git a/window2.py b/window2.py index 57c77b4..d95cecb 100644 --- a/window2.py +++ b/window2.py @@ -424,7 +424,7 @@ class Window(object): return self.copy(p1, p2) def kill(self, p1, p2): killed = self.buffer.get_substring(p1, p2) - self.buffer.delete_string(p1, p2) + self.buffer.delete(p1, p2) self.application.push_kill(killed) return killed def copy(self, p1, p2):