parent
1b082d0e29
commit
3e1c2ef3c6
|
@ -3,13 +3,14 @@ import curses, curses.ascii, getpass, os, re, string, sets, sys, termios, time
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
import buffer2, bufferlist, color, completer, keyinput, method, minibuffer
|
import buffer2, bufferlist, color, completer, keyinput, method, minibuffer
|
||||||
import mode2, util, window2
|
import util, window2
|
||||||
from point2 import Point
|
from point2 import Point
|
||||||
|
|
||||||
# modes
|
# modes
|
||||||
import mode, mode_c, mode_mini, mode_python, mode_nasm, mode_perl, mode_search
|
#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_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_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):
|
def run(buffers, jump_to_line=None, init_mode=None):
|
||||||
# save terminal state so we can restore it when the program exits
|
# 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")
|
self.set_error("Dynamic color not available")
|
||||||
|
|
||||||
# initialize our modes
|
# initialize our modes
|
||||||
self.modes = {'fundamental': mode2.Fundamental}
|
self.modes = {
|
||||||
|
'fundamental': mode2.Fundamental,
|
||||||
|
'mini': mode_mini2.Mini,
|
||||||
|
}
|
||||||
# self.modes = {
|
# self.modes = {
|
||||||
# 'blame': mode_blame.Blame,
|
# 'blame': mode_blame.Blame,
|
||||||
# 'c': mode_c.C,
|
# 'c': mode_c.C,
|
||||||
|
@ -169,9 +173,7 @@ class Application:
|
||||||
|
|
||||||
# see if the user has requested that we go to a particular line
|
# see if the user has requested that we go to a particular line
|
||||||
if jump_to_line:
|
if jump_to_line:
|
||||||
name = buffers[0].name()
|
w = self.bufferlist.slots[0].window
|
||||||
b = self.bufferlist.get_buffer_by_name(name)
|
|
||||||
w = b.get_window(self.active_slot)
|
|
||||||
method.GotoLine().execute(w, lineno=jump_to_line)
|
method.GotoLine().execute(w, lineno=jump_to_line)
|
||||||
|
|
||||||
# initialize our kill ring and last action
|
# initialize our kill ring and last action
|
||||||
|
@ -205,7 +207,7 @@ class Application:
|
||||||
|
|
||||||
def add_slot(self):
|
def add_slot(self):
|
||||||
# XYZ
|
# XYZ
|
||||||
b = self.bufferlist.slots[self.active_slot].buffer
|
b = self.bufferlist.slots[self.active_slot].window.buffer
|
||||||
n = self.bufferlist.add_slot()
|
n = self.bufferlist.add_slot()
|
||||||
self.bufferlist.set_slot(n, b)
|
self.bufferlist.set_slot(n, b)
|
||||||
def remove_slot(self, n):
|
def remove_slot(self, n):
|
||||||
|
@ -238,10 +240,8 @@ class Application:
|
||||||
if self.mini_buffer_is_open():
|
if self.mini_buffer_is_open():
|
||||||
self.close_mini_buffer()
|
self.close_mini_buffer()
|
||||||
self.mini_prompt = prompt
|
self.mini_prompt = prompt
|
||||||
self.mini_buffer = minibuffer.MiniBuffer(callback, method, tabber,
|
self.mini_buffer = minibuffer.MiniBuffer(callback, method, tabber, modename)
|
||||||
modename)
|
window2.Window(self.mini_buffer, self, height=1, width=self.x-1-len(self.mini_prompt)-1)
|
||||||
window2.Window(self.mini_buffer, self, height=1,
|
|
||||||
width=self.x-1-len(self.mini_prompt)-1, slot='mini')
|
|
||||||
self.mini_active = True
|
self.mini_active = True
|
||||||
def exec_mini_buffer(self):
|
def exec_mini_buffer(self):
|
||||||
self.mini_buffer.callback(self.mini_buffer.make_string())
|
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)
|
assert 0 <= self.active_slot and self.active_slot < len(self.bufferlist.slots)
|
||||||
self.active_slot = (self.active_slot + 1) % len(self.bufferlist.slots)
|
self.active_slot = (self.active_slot + 1) % len(self.bufferlist.slots)
|
||||||
def window(self):
|
def window(self):
|
||||||
slotname = self.active_slot
|
return self.bufferlist.slots[self.active_slot].window
|
||||||
return self.bufferlist.slots[slotname].buffer.get_window(slotname)
|
|
||||||
def active_window(self):
|
def active_window(self):
|
||||||
if self.mini_active:
|
if self.mini_active:
|
||||||
return self.mini_buffer.get_window('mini')
|
return self.mini_buffer.windows[0]
|
||||||
else:
|
else:
|
||||||
assert 0 <= self.active_slot and self.active_slot < len(self.bufferlist.slots), \
|
assert 0 <= self.active_slot and self.active_slot < len(self.bufferlist.slots), \
|
||||||
"0 <= %d < %d" % (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)
|
(px, py) = (None, None)
|
||||||
while count < slot.height:
|
while count < slot.height:
|
||||||
if y >= len(lines):
|
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:
|
else:
|
||||||
if cy == y and cx >= x and cx < x + slot.width:
|
if cy == y and cx >= x and cx < x + slot.width:
|
||||||
px = cx - x
|
px = cx - x
|
||||||
|
@ -617,29 +616,22 @@ class Application:
|
||||||
self.win.addnstr(self.y-1, 0, s2, l)
|
self.win.addnstr(self.y-1, 0, s2, l)
|
||||||
def draw_mini_buffer(self):
|
def draw_mini_buffer(self):
|
||||||
l = self.x - 1
|
l = self.x - 1
|
||||||
w = self.mini_buffer.get_window('mini')
|
b = self.mini_buffer
|
||||||
lines = w.visible_lines()
|
s1 = self.mini_prompt + b.lines[0]
|
||||||
s1 = self.mini_prompt + lines[0]
|
|
||||||
s2 = util.padtrunc(s1, l)
|
s2 = util.padtrunc(s1, l)
|
||||||
self.win.addnstr(self.y-1, 0, s2, l)
|
self.win.addnstr(self.y-1, 0, s2, l)
|
||||||
|
|
||||||
if self.mini_active:
|
if self.mini_active:
|
||||||
cursor = w.visible_cursor()
|
w = b.windows[0]
|
||||||
cx, cy = (cursor.x, cursor.y)
|
cursor = w.logical_cursor()
|
||||||
if cy >= len(lines):
|
(cx, cy) = cursor.xy()
|
||||||
#self.set_error('in main2: cursor error; %d >= %d' %
|
if cy >= len(b.lines):
|
||||||
# (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])))
|
|
||||||
|
|
||||||
return
|
return
|
||||||
elif cx == len(lines[cy]):
|
elif cx == len(b.lines[cy]):
|
||||||
c = ' '
|
c = ' '
|
||||||
else:
|
else:
|
||||||
c = lines[cy][cx]
|
c = b.lines[cy][cx]
|
||||||
self.win.addch(self.y-1, cx + len(self.mini_prompt), c,
|
self.win.addch(self.y-1, cx + len(self.mini_prompt), c, curses.A_REVERSE)
|
||||||
curses.A_REVERSE)
|
|
||||||
def draw_nothing(self):
|
def draw_nothing(self):
|
||||||
l = self.x - 1
|
l = self.x - 1
|
||||||
self.win.addnstr(self.y-1, 0, util.pad('', l), l)
|
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 debugging, disable error handling to produce backtraces
|
||||||
if opts.debug:
|
if opts.debug:
|
||||||
mode.DEBUG = True
|
mode2.DEBUG = True
|
||||||
|
|
||||||
# we will support using +19 as the first argument to indicate opening the
|
# 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)
|
# 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:])
|
opts.goto = int(args[0][1:])
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
|
|
||||||
|
if opts.goto is not None:
|
||||||
|
opts.goto += 1
|
||||||
|
|
||||||
# figure out which kind of line types we're using
|
# figure out which kind of line types we're using
|
||||||
if opts.linetype not in linetypes:
|
if opts.linetype not in linetypes:
|
||||||
sys.stderr.write('invalid linetype: %r' % opts.linetype)
|
sys.stderr.write('invalid linetype: %r' % opts.linetype)
|
||||||
|
|
|
@ -39,6 +39,7 @@ class Buffer(object):
|
||||||
self.stack_limit = stack_limit
|
self.stack_limit = stack_limit
|
||||||
self.nl = nl
|
self.nl = nl
|
||||||
self.modified = False
|
self.modified = False
|
||||||
|
self.modes = {}
|
||||||
|
|
||||||
# basic file operation stuff
|
# basic file operation stuff
|
||||||
def _open_file_r(self, path):
|
def _open_file_r(self, path):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import sets
|
import sets
|
||||||
|
import window2
|
||||||
|
|
||||||
class Slot:
|
class Slot:
|
||||||
def __init__(self, height, width, offset):
|
def __init__(self, height, width, offset):
|
||||||
|
@ -39,12 +40,13 @@ class BufferList:
|
||||||
for b in buffers:
|
for b in buffers:
|
||||||
self.add_buffer(b)
|
self.add_buffer(b)
|
||||||
def fit_slots(self):
|
def fit_slots(self):
|
||||||
heights = [self.height / len(self.slots)] * len(self.slots)
|
total = self.height - len(self.slots) + 1
|
||||||
for i in range(0, self.height % len(self.slots)):
|
heights = [total / len(self.slots)] * len(self.slots)
|
||||||
|
for i in range(0, total % len(self.slots)):
|
||||||
heights[i] += 1
|
heights[i] += 1
|
||||||
offsets = [0]
|
offsets = [0]
|
||||||
for i in range(1, len(self.slots)):
|
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)):
|
for i in range(0, len(self.slots)):
|
||||||
self.slots[i].resize(heights[i], self.width, offsets[i])
|
self.slots[i].resize(heights[i], self.width, offsets[i])
|
||||||
def resize(self, height, width):
|
def resize(self, height, width):
|
||||||
|
@ -84,6 +86,7 @@ class BufferList:
|
||||||
def set_slot(self, i, b):
|
def set_slot(self, i, b):
|
||||||
assert i > -1 and i < len(self.slots), "slot %d does not exist" % i
|
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())
|
assert b in self.buffers, "buffer %s does not exist" % (b.name())
|
||||||
|
slot = self.slots[i]
|
||||||
self.unset_slot(i)
|
self.unset_slot(i)
|
||||||
|
|
||||||
if b in self.hidden_buffers:
|
if b in self.hidden_buffers:
|
||||||
|
@ -93,7 +96,7 @@ class BufferList:
|
||||||
w = window2.Window(b, app, height=slot.height, width=slot.width)
|
w = window2.Window(b, app, height=slot.height, width=slot.width)
|
||||||
else:
|
else:
|
||||||
w = b.windows[0]
|
w = b.windows[0]
|
||||||
self.slots[i].set(w)
|
slot.set(w)
|
||||||
|
|
||||||
def remove_slot(self, i):
|
def remove_slot(self, i):
|
||||||
assert i > -1 and i < len(self.slots), "slot %d does not exist" % i
|
assert i > -1 and i < len(self.slots), "slot %d does not exist" % i
|
||||||
|
|
|
@ -990,8 +990,9 @@ class CvsStatus(Method):
|
||||||
assert m, "regex6 %r" % lines[7]
|
assert m, "regex6 %r" % lines[7]
|
||||||
soptions = m.group(1)
|
soptions = m.group(1)
|
||||||
|
|
||||||
w.application.set_error('%s %s %s/%s [%s|%s|%s]' % \
|
w.application.set_error('%s %s %s/%s [%s|%s|%s]' % (ffile, fstatus,
|
||||||
(ffile, fstatus, wrev, rrev, stag, sdate, soptions))
|
wrev, rrev, stag,
|
||||||
|
sdate, soptions))
|
||||||
|
|
||||||
class CvsDiff(Method):
|
class CvsDiff(Method):
|
||||||
'''diff the current file with the version in CVS'''
|
'''diff the current file with the version in CVS'''
|
||||||
|
@ -1256,8 +1257,8 @@ class SplitWindow(Method):
|
||||||
a = w.application
|
a = w.application
|
||||||
a.add_slot()
|
a.add_slot()
|
||||||
if not w.cursor_is_visible():
|
if not w.cursor_is_visible():
|
||||||
#w.center_view()
|
p = w.first
|
||||||
w.relocate_cursor()
|
w.goto(p)
|
||||||
n = len(a.bufferlist.slots)
|
n = len(a.bufferlist.slots)
|
||||||
a.set_error('Window has been split into %d windows!' % n)
|
a.set_error('Window has been split into %d windows!' % n)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import buffer
|
import buffer2
|
||||||
|
|
||||||
# minibuffer is a singleton
|
# minibuffer is a singleton
|
||||||
mini = None
|
mini = None
|
||||||
class MiniBuffer(buffer.Buffer):
|
class MiniBuffer(buffer2.Buffer):
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, **kwargs):
|
||||||
global mini
|
global mini
|
||||||
if mini is None:
|
if mini is None:
|
||||||
|
@ -10,7 +10,7 @@ class MiniBuffer(buffer.Buffer):
|
||||||
return mini
|
return mini
|
||||||
# the callback function should take one argument (window)
|
# the callback function should take one argument (window)
|
||||||
def __init__(self, func, method=None, tabber=None, modename=None):
|
def __init__(self, func, method=None, tabber=None, modename=None):
|
||||||
buffer.Buffer.__init__(self)
|
buffer2.Buffer.__init__(self)
|
||||||
self.callback = func
|
self.callback = func
|
||||||
self.method = method
|
self.method = method
|
||||||
self.tabber = tabber
|
self.tabber = tabber
|
||||||
|
|
|
@ -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)
|
|
@ -424,7 +424,7 @@ class Window(object):
|
||||||
return self.copy(p1, p2)
|
return self.copy(p1, p2)
|
||||||
def kill(self, p1, p2):
|
def kill(self, p1, p2):
|
||||||
killed = self.buffer.get_substring(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)
|
self.application.push_kill(killed)
|
||||||
return killed
|
return killed
|
||||||
def copy(self, p1, p2):
|
def copy(self, p1, p2):
|
||||||
|
|
Loading…
Reference in New Issue