--HG--
branch : pmacs2
This commit is contained in:
moculus 2008-04-07 02:31:13 +00:00
parent cfac74acab
commit 406331e650
9 changed files with 131 additions and 66 deletions

4
IDEAS
View File

@ -1,3 +1,7 @@
2008/04/06:
line numbers/margin support
2008/04/02:
fix read-only warnings to seem less junky (e.g. catch the buffer.ReadOnlyError

View File

@ -522,9 +522,7 @@ class Application(object):
self.draw_slots()
self.draw_input_bar()
self.draw_cursor()
#self.win.noutrefresh()
#curses.doupdate()
curses.refresh()
self.win.refresh()
except Exception, e:
# ok, so there was a problem...
# let's see if the screen changed sizes and if so, resize our slots
@ -558,7 +556,8 @@ class Application(object):
(vy, vx) = (None, None)
while count < slot.height:
if p.y == y and p.x >= x and p.x <= x + slot.width:
(vy, vx) = (slot.offset + count, p.x - x)
#(vy, vx) = (slot.y_offset + count, p.x - x + slot.lmargin)
(vy, vx) = (slot.y_offset + count, p.x - x + w.mode.lmargin)
break
if x + slot.width >= len(w.buffer.lines[y]):
x = 0
@ -610,6 +609,7 @@ class Application(object):
self._draw_slot_lit(i)
else:
self._draw_slot_raw(i)
self.draw_slot_margins(i)
# highlighted regions
for (high_w, p1, p2, fg, bg) in self.highlighted_ranges:
@ -620,10 +620,12 @@ class Application(object):
while count < slot.height:
if p1.y == y and px >= x and px - x < slot.width:
if slot.width > p2.x - x:
self.highlight_chars(slot.offset + count, px-x, p2.x-x, fg, bg)
#self.highlight_chars(slot.y_offset + count, px-x + slot.lmargin, p2.x-x, fg, bg)
self.highlight_chars(slot.y_offset + count, px-x + w.mode.lmargin, p2.x-x, fg, bg)
break
else:
self.highlight_chars(slot.offset + count, px-x, slot.width, fg, bg)
#self.highlight_chars(slot.y_offset + count, px-x + slot.lmargin, slot.width, fg, bg)
self.highlight_chars(slot.y_offset + count, px-x + w.mode.lmargin, slot.width, fg, bg)
px += slot.width - px + x
if x + slot.width >= len(w.buffer.lines[y]):
x = 0
@ -634,12 +636,29 @@ class Application(object):
if w.margins_visible:
for (limit, shade) in w.margins:
#if limit <= self.x:
if limit < self.x:
for j in range(0, slot.height):
char = chr(self.win.inch(j + slot.offset, limit) & 255)
char = chr(self.win.inch(j + slot.y_offset, limit) & 255)
attr = color.build('default', shade, 'bold')
self.win.addstr(j + slot.offset, limit, char, attr)
#self.win.addstr(j + slot.y_offset, limit + slot.lmargin, char, attr)
self.win.addstr(j + slot.y_offset, limit + w.mode.lmargin, char, attr)
def draw_slot_margins(self, i):
slot = self.bufferlist.slots[i]
w = slot.window
b = w.buffer
#x = slot.lmargin + slot.width + 1
x = w.mode.lmargin + slot.width + 1
for i in range(0, slot.height):
y = i + slot.y_offset
#if slot.lmargin:
if w.mode.lmargin:
(lmargin, lattr) = w.mode.get_lmargin(i)
self.win.addstr(y, 0, lmargin, lattr)
#if slot.rmargin:
if w.mode.rmargin:
(rmargin, rattr) = w.mode.get_rmargin(i)
self.win.addstr(y, x, rmargin, rattr)
def _draw_slot_raw(self, i):
slot = self.bufferlist.slots[i]
@ -648,26 +667,33 @@ class Application(object):
redattr = color.build_attr(color.pairs('red', 'default'))
(x, y) = w.first.xy()
lines = w.buffer.lines
count = 0
lines = w.buffer.lines
count = 0
swidth = slot.width - w.mode.lmargin - w.mode.rmargin
while count < slot.height:
if y >= len(lines):
self.win.addstr(slot.offset + count, 0, '~', redattr)
#self.win.addstr(slot.y_offset + count, 0 + slot.lmargin, '~', redattr)
self.win.addstr(slot.y_offset + count, 0 + w.mode.lmargin, '~', redattr)
count += 1
continue
line = lines[y]
s = line[x:x + slot.width]
#s = line[x:x + slot.width]
s = line[x:x + swidth]
try:
self.win.addstr(slot.offset + count, 0, s)
#self.win.addstr(slot.y_offset + count, 0 + slot.lmargin, s)
self.win.addstr(slot.y_offset + count, 0 + w.mode.lmargin, s)
except:
self.set_error("addstr(%r + %r, %r, %r)" % (slot.offset, count, 0, s))
if x + slot.width >= len(line):
#self.set_error("addstr(%r+%r, %r+%r, %r)" % (slot.y_offset, count, 0, slot.lmargin, s))
self.set_error("addstr(%r+%r, %r+%r, %r)" % (slot.y_offset, count, 0, w.mode.lmargin, s))
#if x + slot.width >= len(line):
if x + swidth >= len(line):
x = 0
y += 1
else:
self.win.addstr(slot.offset + count, slot.width, '\\', redattr)
x += slot.width
#self.win.addstr(slot.y_offset + count, slot.width + slot.lmargin, '\\', redattr)
self.win.addstr(slot.y_offset + count, swidth + w.mode.lmargin, '\\', redattr)
x += swidth
count += 1
def _draw_slot_lit(self, i):
@ -694,21 +720,24 @@ class Application(object):
s_offset = max(x - token.x, 0)
x_offset = max(token.x - x, 0)
assert x_offset <= slot.width, '%d <= %d' % (x_offset, slot.width)
swidth = slot.width - w.mode.lmargin - w.mode.rmargin
assert x_offset <= swidth, '%d <= %d' % (x_offset, swidth)
s = tstring[s_offset:]
token_done = x_offset + len(s) <= slot.width
token_wrap = x_offset + len(s) > slot.width
token_done = x_offset + len(s) <= swidth
token_wrap = x_offset + len(s) > swidth
# for debugging things like lexing/relexing/etc.
if token._debug:
attr = color.build('blue', 'green')
else:
attr = color.build(*token.color)
self.win.addstr(slot.offset + count, x_offset, s[:slot.width - x_offset], attr)
#self.win.addstr(slot.y_offset + count, x_offset + slot.lmargin, s[:slot.width - x_offset], attr)
self.win.addstr(slot.y_offset + count, x_offset + w.mode.lmargin, s[:swidth - x_offset], attr)
if token_wrap:
self.win.addstr(slot.offset + count, slot.width, '\\', redattr)
x += slot.width
#self.win.addstr(slot.y_offset + count, slot.width + slot.lmargin, '\\', redattr)
self.win.addstr(slot.y_offset + count, swidth + w.mode.lmargin, '\\', redattr)
x += swidth
count += 1
if token_done:
j += 1
@ -717,10 +746,11 @@ class Application(object):
# we have finished this logical line of tokens
j = x = 0
y += 1
count += 1
y += 1
count += 1
else:
self.win.addstr(slot.offset + count, 0, '~', redattr)
#self.win.addstr(slot.y_offset + count, 0 + slot.lmargin, '~', redattr)
self.win.addstr(slot.y_offset + count, 0 + w.mode.lmargin, '~', redattr)
count += 1
def draw_status_bar(self, slotname):
@ -758,15 +788,12 @@ class Application(object):
else:
perc = "%2d%%" % (first.y*100 / len(b.lines))
# XYZ: we should actually use more of the 'state' variables
format = "%s %-18s (%s)--L%d--C%d--%s"
status = format % (modflag, name, w.mode.name(), cursor.y+1, cursor.x+1, perc)
#format = "%s %-18s (%s)--L%d--C%d--%s %s %s %s"
#status = format % (modflag, name, w.mode.name(), cursor.y+1, cursor.x+1, perc, w.first, cursor, w.last)
status = status.ljust(slot.total_width + 1)[:slot.total_width + 1]
status = status.ljust(slot.width + 1)[:slot.width + 1]
self.win.addstr(slot.height + slot.offset, 0, status, curses.A_REVERSE)
self.win.addstr(slot.height + slot.y_offset, 0, status, curses.A_REVERSE)
# input bar drawing
def draw_input_bar(self):
@ -874,12 +901,6 @@ if __name__ == "__main__":
# first file on line 19 (same as -g 19 or --goto 19)
if goto_line:
opts.goto = goto_line
#if len(args) > 0 and args[0].startswith('+'):
# 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:
@ -897,8 +918,7 @@ if __name__ == "__main__":
buffers = []
names = sets.Set()
paths = sets.Set()
#if not args:
# args = ['.']
for path in args:
path = os.path.abspath(os.path.realpath(util.expand_tilde(path)))
if path in paths:

View File

@ -2,6 +2,8 @@ import datetime, grp, md5, os, pwd, re, sets, shutil, stat, string
import aes, dirutil, regex, highlight, lex
from point import Point
#from point import Pointfrom point import Pointfrom point import Pointfrom point import Pointfrom point import Pointfrom point import Pointfrom point import Pointfrom point import Pointfrom point import Pointfrom point import Pointfrom point import Pointfrom point import Pointfrom point import Pointfrom point import Pointfrom point import Point
# undo/redo stack constants
ACT_NORM = 0
ACT_UNDO = 1

View File

@ -2,21 +2,26 @@ import sets
import window
class Slot(object):
def __init__(self, height, width, offset):
self.height = height
self.width = width
self.offset = offset
self.window = None
def __init__(self, height, width, y_offset=0, x_offset=0):
self.window = None
self.lmargin = 0
self.rmargin = 0
self.resize(height, width, y_offset, x_offset)
def is_empty(self):
return self.window is None
def resize(self, height, width, offset):
self.height = height
self.width = width
self.offset = offset
def resize(self, height, width, y_offset=0, x_offset=0):
self.height = height
self.total_width = width
self.width = width - self.lmargin - self.rmargin
self.y_offset = y_offset
self.x_offset = x_offset
if self.window is not None:
self.window.set_size(self.width, self.height)
def set(self, w):
self.window = w
self.window = w
self.lmargin = w.mode.lmargin
self.rmargin = w.mode.rmargin
self.resize(self.height, self.width, self.y_offset, self.x_offset)
w.set_size(self.width, self.height)
def unset(self):
if not self.is_empty():

View File

@ -8,7 +8,9 @@ sub foo {
}
#@@:heredoc:sql
#@@:heredoc.string:xml
my $s = <<EOT;
select '<foo attr="3">bar bar</foo>';
drop table foog;
insert into mytable (col1, col2, "col3") values (99, 33, 1234);
select cast(plunk as timestamp) from blarg join plarg using(id_what) where x = 3;

View File

@ -964,6 +964,15 @@ class SetConfigVariable(Method):
else:
w.set_error("previously unset param %r set to %r" % (name, value))
class ToggleLineNumbers(Method):
def _execute(self, w, **vargs):
if w.mode.show_line_numbers:
w.mode.disable_line_numbers()
w.set_error('Line numbers hidden')
else:
w.mode.enable_line_numbers()
w.set_error('Line numbers visible')
class SetTabWidth(Method):
args = [arg('width', t=type(0), p="Tab Width: ", h='New tab width for buffer')]
def _execute(self, w, **vargs):

View File

@ -88,6 +88,11 @@ class Fundamental(Handler):
colors = {}
config = {}
# margin/line numbering
show_line_numbers = False
lmargin = 0
rmargin = 0
def install(cls, app):
app.setmode(cls.modename.lower(), cls, paths=cls.paths,
basenames=cls.basenames, extensions=cls.extensions,
@ -188,6 +193,9 @@ class Fundamental(Handler):
self.add_bindings('insert-squotes', ('M-\'',))
self.add_bindings('insert-dquotes', ('M-"',))
self.add_bindings('get-token', ('C-c t',))
self.add_bindings('insert-text', ('C-c i',))
self.add_bindings('insert-text2', ('C-c M-i',))
self.add_bindings('insert-multiline-text', ('C-c m',))
# create all the insert actions for the basic text input
for c in string.letters + string.digits + string.punctuation:
@ -205,6 +213,24 @@ class Fundamental(Handler):
if self.tabbercls:
self.tabber = self.tabbercls(self)
def enable_line_numbers(self):
self.show_line_numbers = True
self.lmargin = 4
self.get_lmargin = self._line_number_margin
def disable_line_numbers(self):
self.show_line_numbers = False
self.lmargin = 0
self.get_lmargin = self._null_margin
def get_rmargin(self, i):
return ('', color.build('default', 'default'))
def _null_margin(self, i):
return ('', color.build('default', 'default'))
def _line_number_margin(self, i):
return ('% 3d ' % i, color.build('default', 'default', 'bold'))
get_lmargin = _null_margin
get_rmargin = _null_margin
# get mode name
def name(self):
return self.modename

View File

@ -41,32 +41,29 @@ class InsertMini(mode.Fundamental):
self.add_bindings('delete-right-whitespace', ('C-c d',))
self.add_bindings('insert-space', ('SPACE',))
self.add_bindings('insert-tab', ('TAB',))
self.add_action_and_bindings(InsertExec(), ('RETURN',))
self.add_action_and_bindings(InsertLine(), ('RETURN',))
self.add_action_and_bindings(InsertComplete(), ('M-RETURN',))
self.add_action_and_bindings(InsertCancel(), ('C-]',))
self.add_action_and_bindings(InsertTab(), ('TAB',))
for c in string.letters + string.digits + string.punctuation:
self.add_binding('insert-string-%s' % c, c)
def insert_line(w):
s = w.buffer.make_string()
w.mode.lines.append(s)
w.buffer.set_data('')
class InsertTab(method.Method):
def _execute(self, w, **vargs):
w.insert_string_at_cursor(' ' * w.mode.tabwidth)
class InsertExec(method.Method):
class InsertLine(method.Method):
def _execute(self, w, **vargs):
s = w.buffer.make_string()
w.mode.lines.append(s)
w.buffer.set_data('')
w.mode.history[-1] = s
w.mode.history.append('')
w.mode.hindex = len(w.mode.history) - 1
insert_line(w)
class InsertComplete(method.Method):
def execute(self, w, **vargs):
s = '\n'.join(w.mode.lines)
w.buffer.callback(s)
insert_line(w)
w.buffer.callback('\n'.join(w.mode.lines))
w.application.close_mini_buffer()
class InsertCancel(method.Method):
def execute(self, w, **vargs):
w.application.close_mini_buffer()

View File

@ -1,5 +1,5 @@
import os.path, string
import highlight, regex
import color, highlight, regex
from point import Point
WORD_LETTERS = list(string.letters + string.digits)
@ -125,7 +125,7 @@ class Window(object):
l = 0
x = min(self.cursor.x, l)
return Point(x, self.cursor.y)
# last visible point
def _calc_last(self):
(x, y) = self.first.xy()
@ -151,7 +151,7 @@ class Window(object):
def set_size(self, width, height):
assert type(width) == type(0), width
assert type(height) == type(0), height
self.width = width
self.width = width - self.mode.lmargin - self.mode.rmargin
self.height = height
self.redraw()