--HG--
branch : pmacs2
This commit is contained in:
moculus 2007-06-04 07:29:37 +00:00
parent d769305721
commit bb2716a532
5 changed files with 231 additions and 267 deletions

View File

@ -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__":

View File

@ -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

View File

@ -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)

View File

@ -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"

View File

@ -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