parent
ba7cc48dfb
commit
f69c3b1995
169
application.py
169
application.py
|
@ -581,6 +581,9 @@ class Application(object):
|
||||||
if y >= len(w.buffer.lines) or x + swidth >= len(w.buffer.lines[y]):
|
if y >= len(w.buffer.lines) or x + swidth >= len(w.buffer.lines[y]):
|
||||||
x = 0
|
x = 0
|
||||||
y += 1
|
y += 1
|
||||||
|
#XYZ
|
||||||
|
while w.ishidden(y) and y < len(w.buffer.lines):
|
||||||
|
y += 1
|
||||||
else:
|
else:
|
||||||
x += swidth
|
x += swidth
|
||||||
count += 1
|
count += 1
|
||||||
|
@ -615,25 +618,40 @@ class Application(object):
|
||||||
for x in range(sx1, sx2):
|
for x in range(sx1, sx2):
|
||||||
self.highlight_char(sy, x, fg, bg)
|
self.highlight_char(sy, x, fg, bg)
|
||||||
|
|
||||||
|
def map_point(self, p):
|
||||||
|
count = 0
|
||||||
|
x, y = w.first.xy()
|
||||||
|
while count < slot.height:
|
||||||
|
if p1.y == y and p1.x >= x and p1.x - x < slot.width:
|
||||||
|
return (count, x)
|
||||||
|
if x + slot.width > len(w.buffer.lines[y]):
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
#XYZ
|
||||||
|
while w.ishidden(y) and y < len(w.buffer.lines):
|
||||||
|
y += 1
|
||||||
|
else:
|
||||||
|
x += slot.width
|
||||||
|
count += 1
|
||||||
|
|
||||||
def draw_slot(self, i):
|
def draw_slot(self, i):
|
||||||
assert self.active_slot < len(self.bufferlist.slots), "only two"
|
assert self.active_slot < len(self.bufferlist.slots), \
|
||||||
assert i < len(self.bufferlist.slots), "only three"
|
"strange: %d < %d" % (self.active_slot, len(self.bufferlist.slots))
|
||||||
|
assert i < len(self.bufferlist.slots), \
|
||||||
|
"puzzling: %d < %d" % (i, len(self.bufferlist.slots))
|
||||||
slot = self.bufferlist.slots[i]
|
slot = self.bufferlist.slots[i]
|
||||||
if slot.window is None:
|
if slot.window is None:
|
||||||
return
|
return
|
||||||
w = slot.window
|
w = slot.window
|
||||||
modename = w.mode.name()
|
modename = w.mode.name()
|
||||||
|
|
||||||
if modename in w.buffer.highlights:
|
self._draw_slot(i)
|
||||||
self._draw_slot_lit(i)
|
|
||||||
else:
|
|
||||||
self._draw_slot_raw(i)
|
|
||||||
|
|
||||||
# highlighted regions
|
# highlighted regions
|
||||||
for (high_w, p1, p2, fg, bg) in self.highlighted_ranges:
|
for (high_w, p1, p2, fg, bg) in self.highlighted_ranges:
|
||||||
if w is high_w and p2 >= w.first and p1 <= w.last:
|
if w is high_w and p2 >= w.first and p1 <= w.last:
|
||||||
count = 0
|
count = 0
|
||||||
(x, y) = w.first.xy()
|
x, y = w.first.xy()
|
||||||
px = p1.x
|
px = p1.x
|
||||||
while count < slot.height:
|
while count < slot.height:
|
||||||
if p1.y == y and px >= x and px - x < slot.width:
|
if p1.y == y and px >= x and px - x < slot.width:
|
||||||
|
@ -646,6 +664,9 @@ class Application(object):
|
||||||
if x + slot.width > len(w.buffer.lines[y]):
|
if x + slot.width > len(w.buffer.lines[y]):
|
||||||
x = 0
|
x = 0
|
||||||
y += 1
|
y += 1
|
||||||
|
#XYZ
|
||||||
|
while w.ishidden(y) and y < len(w.buffer.lines):
|
||||||
|
y += 1
|
||||||
else:
|
else:
|
||||||
x += slot.width
|
x += slot.width
|
||||||
count += 1
|
count += 1
|
||||||
|
@ -657,123 +678,37 @@ class Application(object):
|
||||||
char = chr(self.win.inch(j + slot.y_offset, limit) & 255)
|
char = chr(self.win.inch(j + slot.y_offset, limit) & 255)
|
||||||
attr = color.build('default', shade, 'bold')
|
attr = color.build('default', shade, 'bold')
|
||||||
self.win.addstr(j + slot.y_offset, limit + w.mode.lmargin, char, attr)
|
self.win.addstr(j + slot.y_offset, limit + w.mode.lmargin, char, attr)
|
||||||
|
|
||||||
def _draw_line_margins(self, slot, count, w, y, x):
|
|
||||||
lm, rm = w.mode.lmargin, w.mode.rmargin
|
|
||||||
if y >= len(w.buffer.lines):
|
|
||||||
ended = True
|
|
||||||
cont = False
|
|
||||||
else:
|
|
||||||
ended = False
|
|
||||||
cont = x + slot.width - lm - rm < len(w.buffer.lines[y])
|
|
||||||
|
|
||||||
i = slot.y_offset + count
|
|
||||||
if lm:
|
|
||||||
groups = w.mode.get_lmargin(y, x, ended, cont)
|
|
||||||
for (x, lmargin, lattr) in groups:
|
|
||||||
self.win.addstr(i, x, lmargin, lattr)
|
|
||||||
if rm:
|
|
||||||
groups = w.mode.get_rmargin(y, x, ended, cont)
|
|
||||||
for (x, rmargin, rattr) in groups:
|
|
||||||
self.win.addstr(i, slot.width - rm + x, rmargin, rattr)
|
|
||||||
|
|
||||||
def _draw_slot_raw(self, i):
|
def _draw_slot(self, i):
|
||||||
slot = self.bufferlist.slots[i]
|
slot = self.bufferlist.slots[i]
|
||||||
w = slot.window
|
w = slot.window
|
||||||
modename = w.mode.name()
|
|
||||||
redattr = color.build_attr(color.pairs('red', 'default'))
|
redattr = color.build_attr(color.pairs('red', 'default'))
|
||||||
|
x, y = w.first.xy()
|
||||||
(x, y) = w.first.xy()
|
lines = w.buffer.lines
|
||||||
lines = w.buffer.lines
|
count = 0
|
||||||
count = 0
|
lm, rm = w.mode.lmargin, w.mode.rmargin
|
||||||
lm, rm = w.mode.lmargin, w.mode.rmargin
|
modename = w.mode.name()
|
||||||
swidth = slot.width - lm - rm
|
lit = w.mode.name() in w.buffer.highlights
|
||||||
|
ended = False
|
||||||
while count < slot.height:
|
while count < slot.height:
|
||||||
#draw some margins
|
if lit:
|
||||||
self._draw_line_margins(slot, count, w, y, x)
|
rlines = w.render_line_lit(y, slot.width - lm - rm)
|
||||||
|
|
||||||
# if the window has no more lines, display the "empty" symbol
|
|
||||||
if y >= len(lines):
|
|
||||||
self.win.addstr(slot.y_offset + count, 0 + lm, '~', redattr)
|
|
||||||
count += 1
|
|
||||||
continue
|
|
||||||
|
|
||||||
# get the line to draw and draw it
|
|
||||||
line = lines[y]
|
|
||||||
s = line[x:x + swidth]
|
|
||||||
self.win.addstr(slot.y_offset + count, 0 + lm, s)
|
|
||||||
|
|
||||||
# see if we need to draw a line-continuation symbol or not
|
|
||||||
if x + swidth >= len(line):
|
|
||||||
x = 0
|
|
||||||
y += 1
|
|
||||||
else:
|
else:
|
||||||
x += swidth
|
rlines = w.render_line_raw(y, slot.width - lm - rm)
|
||||||
|
for j in range(0, len(rlines)):
|
||||||
# move on to the next physical line
|
if lm:
|
||||||
count += 1
|
lcont = j > 0
|
||||||
|
for rstr in slot.window.mode.get_lmargin(w, y, x, ended, lcont):
|
||||||
def _draw_slot_lit(self, i):
|
rstr.draw(self.win, slot.y_offset + count, 0)
|
||||||
slot = self.bufferlist.slots[i]
|
for rstr in rlines[j]:
|
||||||
w = slot.window
|
rstr.draw(self.win, slot.y_offset + count, 0 + lm)
|
||||||
modename = w.mode.name()
|
if rm:
|
||||||
redattr = color.build_attr(color.pairs('red', 'default'))
|
rcont = j < len(rlines) - 1
|
||||||
highlighter = w.buffer.highlights[modename]
|
for rstr in slot.window.mode.get_rmargin(w, y, x, ended, rcont):
|
||||||
|
rstr.draw(self.win, slot.y_offset + count, slot.width - rm)
|
||||||
(x, y) = w.first.xy()
|
|
||||||
j = 0
|
|
||||||
count = 0
|
|
||||||
(lm, rm) = (w.mode.lmargin, w.mode.rmargin)
|
|
||||||
swidth = slot.width - lm - rm
|
|
||||||
assert len(w.buffer.lines) == len(highlighter.tokens)
|
|
||||||
while count < slot.height:
|
|
||||||
if y < len(w.buffer.lines):
|
|
||||||
while j < len(highlighter.tokens[y]):
|
|
||||||
token = highlighter.tokens[y][j]
|
|
||||||
if token.string.endswith('\n'):
|
|
||||||
tstring = token.string[:-1]
|
|
||||||
else:
|
|
||||||
tstring = token.string
|
|
||||||
|
|
||||||
assert token.y == y, '%d == %d' % (token.y, y)
|
|
||||||
|
|
||||||
s_offset = max(x - token.x, 0)
|
|
||||||
x_offset = max(token.x - x, 0)
|
|
||||||
assert x_offset <= swidth, '%d <= %d' % (x_offset, swidth)
|
|
||||||
|
|
||||||
s = tstring[s_offset:]
|
|
||||||
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')
|
|
||||||
elif token.color:
|
|
||||||
attr = color.build(*token.color)
|
|
||||||
else:
|
|
||||||
attr = color.build("default", "default")
|
|
||||||
|
|
||||||
k = slot.y_offset + count
|
|
||||||
self.win.addstr(k, x_offset + lm, s[:swidth - x_offset], attr)
|
|
||||||
|
|
||||||
if token_wrap:
|
|
||||||
self._draw_line_margins(slot, count, w, y, x)
|
|
||||||
x += swidth
|
|
||||||
count += 1
|
|
||||||
if token_done:
|
|
||||||
j += 1
|
|
||||||
if count >= slot.height:
|
|
||||||
break
|
|
||||||
|
|
||||||
# we have finished this logical line of tokens
|
|
||||||
self._draw_line_margins(slot, count, w, y, x)
|
|
||||||
j = x = 0
|
|
||||||
y += 1
|
|
||||||
count += 1
|
|
||||||
else:
|
|
||||||
self._draw_line_margins(slot, count, w, y, x)
|
|
||||||
self.win.addstr(slot.y_offset + count, 0 + lm, '~', redattr)
|
|
||||||
count += 1
|
count += 1
|
||||||
|
y += 1
|
||||||
|
ended = ended or y >= len(w.buffer.lines)
|
||||||
|
|
||||||
def draw_status_bar(self, slotname):
|
def draw_status_bar(self, slotname):
|
||||||
slot = self.bufferlist.slots[slotname]
|
slot = self.bufferlist.slots[slotname]
|
||||||
|
|
|
@ -989,3 +989,23 @@ class SetModeTabWidth(Method):
|
||||||
return
|
return
|
||||||
app.modes[mode].tabwidth = vargs['width']
|
app.modes[mode].tabwidth = vargs['width']
|
||||||
w.set_error('Default tab width set to %d' % app.modes[mode].tabwidth)
|
w.set_error('Default tab width set to %d' % app.modes[mode].tabwidth)
|
||||||
|
|
||||||
|
class HideRange(Method):
|
||||||
|
def _execute(self, w, **vargs):
|
||||||
|
cursor = w.logical_cursor()
|
||||||
|
if cursor.y < w.mark.y:
|
||||||
|
y1, y2 = cursor.y, w.mark.y
|
||||||
|
elif w.mark.y < cursor.y:
|
||||||
|
y1, y2 = w.mark.y, cursor.y
|
||||||
|
else:
|
||||||
|
w.set_error("No line range selected")
|
||||||
|
w.hide(y1, y2)
|
||||||
|
w.set_error("Lines %d through %d hidden" % (y1, y2))
|
||||||
|
class UnhideLine(Method):
|
||||||
|
def _execute(self, w, **vargs):
|
||||||
|
cursor = w.logical_cursor()
|
||||||
|
if w.ishidden(cursor.y):
|
||||||
|
w.unhide(cursor.y)
|
||||||
|
w.set_error("Line %d is no longer hidden" % cursor.y)
|
||||||
|
else:
|
||||||
|
w.set_error("Line %d is not hidden" % cursor.y)
|
||||||
|
|
|
@ -2,6 +2,7 @@ import math, os, sets, string
|
||||||
import color, method
|
import color, method
|
||||||
from lex import Lexer
|
from lex import Lexer
|
||||||
from point import Point
|
from point import Point
|
||||||
|
from render import RenderString
|
||||||
|
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
|
|
||||||
|
@ -224,27 +225,27 @@ class Fundamental(Handler):
|
||||||
self.show_line_numbers = True
|
self.show_line_numbers = True
|
||||||
l = len(self.window.buffer.lines)
|
l = len(self.window.buffer.lines)
|
||||||
self.lmargin = int(math.log(l, 10)) + 3
|
self.lmargin = int(math.log(l, 10)) + 3
|
||||||
self.rmargin = 0
|
|
||||||
def disable_line_numbers(self):
|
def disable_line_numbers(self):
|
||||||
self.show_line_numbers = False
|
self.show_line_numbers = False
|
||||||
self.lmargin = 0
|
self.lmargin = 0
|
||||||
self.rmargin = 1
|
|
||||||
|
|
||||||
def get_rmargin(self, y, x, ended=False, cont=False):
|
def get_rmargin(self, w, y, x, ended=False, cont=False):
|
||||||
|
c, fg, bg = " ", "red", "default"
|
||||||
if cont:
|
if cont:
|
||||||
return ((0, '\\', color.build('red', 'default')),)
|
c = "\\"
|
||||||
else:
|
if w.hiddenindicator(y):
|
||||||
return ((0, ' ', color.build('red', 'default')),)
|
bg = "green"
|
||||||
def get_lmargin(self, y, x=0, ended=False, cont=False):
|
return [RenderString(c, 0, color.build(fg, bg))]
|
||||||
|
def get_lmargin(self, w, y, x, ended=False, cont=False):
|
||||||
lm = self.lmargin
|
lm = self.lmargin
|
||||||
if ended:
|
if ended:
|
||||||
i = int(math.log(y, 10)) + 1
|
i = int(math.log(y, 10)) + 1
|
||||||
s = ('% *s' % (lm - 1, '-' * i))[-lm:] + ' '
|
s = ('% *s' % (lm - 1, '-' * i))[-lm:] + ' '
|
||||||
elif x == 0:
|
elif not cont:
|
||||||
s = ('% *d' % (lm - 1, y + 1))[-lm:] + ' '
|
s = ('% *d' % (lm - 1, y + 1))[-lm:] + ' '
|
||||||
else:
|
else:
|
||||||
s = ' ' * lm
|
s = ' ' * lm
|
||||||
return ((0, s, color.build('default', 'default', 'bold')),)
|
return [RenderString(s, 0, color.build('default', 'default', 'bold'))]
|
||||||
|
|
||||||
# get mode name
|
# get mode name
|
||||||
def name(self):
|
def name(self):
|
||||||
|
|
21
mode/hex.py
21
mode/hex.py
|
@ -4,6 +4,7 @@ import color, mode
|
||||||
from lex import Grammar, PatternRule, RegionRule
|
from lex import Grammar, PatternRule, RegionRule
|
||||||
from method import Method, Argument
|
from method import Method, Argument
|
||||||
from point import Point
|
from point import Point
|
||||||
|
from render import RenderString
|
||||||
|
|
||||||
class HexSetByteOrder(Method):
|
class HexSetByteOrder(Method):
|
||||||
'''Sets the byte-order to use to 'little', 'big', or 'native' order'''
|
'''Sets the byte-order to use to 'little', 'big', or 'native' order'''
|
||||||
|
@ -310,16 +311,16 @@ class Hex(mode.Fundamental):
|
||||||
def get_address(self, y, x):
|
def get_address(self, y, x):
|
||||||
return (y * 16) + x
|
return (y * 16) + x
|
||||||
|
|
||||||
def get_lmargin(self, y, x=0, ended=False, cont=False):
|
def get_lmargin(self, w, y, x, ended=False, cont=False):
|
||||||
lm = self.lmargin
|
lm = self.lmargin
|
||||||
if ended:
|
if ended:
|
||||||
s = ' -------- '
|
s = ' -------- '
|
||||||
else:
|
else:
|
||||||
addr = self.get_address(y, x)
|
addr = self.get_address(y, x)
|
||||||
s = '0x%08x ' % addr
|
s = '0x%08x ' % addr
|
||||||
return ((0, s, self.ccyan),)
|
return (RenderString(s, 0, self.ccyan),)
|
||||||
|
|
||||||
def get_rmargin(self, y, x=0, ended=False, cont=False):
|
def get_rmargin(self, w, y, x, ended=False, cont=False):
|
||||||
if ended:
|
if ended:
|
||||||
return ((0, '', 0),)
|
return ((0, '', 0),)
|
||||||
else:
|
else:
|
||||||
|
@ -329,17 +330,17 @@ class Hex(mode.Fundamental):
|
||||||
i = self.window.buffer.cursorx_to_datax(cy, cx)
|
i = self.window.buffer.cursorx_to_datax(cy, cx)
|
||||||
|
|
||||||
if i is None:
|
if i is None:
|
||||||
rmargins = ((0, s, self.cgreen),)
|
rmargins = (RenderString(s, 0, self.cgreen),)
|
||||||
elif i < len(s):
|
elif i < len(s):
|
||||||
rmargins = ((0, s[0:i], self.cgreen),
|
rmargins = (RenderString(s[0:i], 0, self.cgreen),
|
||||||
(i, s[i], self.ccursor),
|
RenderString(s[i], i, self.ccursor),
|
||||||
(i + 1, s[i+1:], self.cgreen))
|
RenderString(s[i+1:], i + 1, self.cgreen))
|
||||||
else:
|
else:
|
||||||
rmargins= ((0, s[0:i], self.cgreen),
|
rmargins= (RenderString(s[0:i], 0, self.cgreen),
|
||||||
(i, s[i], self.cgreen),)
|
RenderString(s[i], i, self.cgreen))
|
||||||
return rmargins
|
return rmargins
|
||||||
else:
|
else:
|
||||||
return ((0, s, self.cgreen),)
|
return (RenderString(s, 0, self.cgreen),)
|
||||||
|
|
||||||
def read_data(self, cy, ix, size):
|
def read_data(self, cy, ix, size):
|
||||||
b = self.window.buffer
|
b = self.window.buffer
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
import color
|
||||||
|
from point import Point
|
||||||
|
|
||||||
|
class RenderString(object):
|
||||||
|
def __init__(self, s, x=0, attrs=None):
|
||||||
|
if attrs is None:
|
||||||
|
attrs = color.build('default', 'default')
|
||||||
|
self.string = s
|
||||||
|
self.x = x
|
||||||
|
self.attrs = attrs
|
||||||
|
def draw(self, cwin, y, x):
|
||||||
|
cwin.addstr(y, self.x + x, self.string, self.attrs)
|
119
window.py
119
window.py
|
@ -1,6 +1,7 @@
|
||||||
import os.path, string
|
import os.path, string
|
||||||
import color, highlight, regex
|
import color, highlight, regex
|
||||||
from point import Point
|
from point import Point
|
||||||
|
from render import RenderString
|
||||||
|
|
||||||
WORD_LETTERS = list(string.letters + string.digits)
|
WORD_LETTERS = list(string.letters + string.digits)
|
||||||
|
|
||||||
|
@ -11,23 +12,22 @@ WORD_LETTERS = list(string.letters + string.digits)
|
||||||
# error. both buffer and window need to be aware of this possibility for points.
|
# error. both buffer and window need to be aware of this possibility for points.
|
||||||
|
|
||||||
class Window(object):
|
class Window(object):
|
||||||
boxtype = 'window'
|
|
||||||
margins = ((80, 'blue'),)
|
margins = ((80, 'blue'),)
|
||||||
margins_visible = False
|
margins_visible = False
|
||||||
def __init__(self, b, a, height=24, width=80, mode_name=None):
|
def __init__(self, b, a, height=24, width=80, mode_name=None):
|
||||||
self.buffer = b
|
self.buffer = b
|
||||||
self.application = a
|
self.application = a
|
||||||
|
self.height = height
|
||||||
|
self.width = width
|
||||||
|
|
||||||
self.first = Point(0, 0)
|
self.first = Point(0, 0)
|
||||||
self.last = None
|
self.last = None
|
||||||
self.cursor = Point(0, 0)
|
self.cursor = Point(0, 0)
|
||||||
self.mark = None
|
self.mark = None
|
||||||
self.active_point = None
|
self.active_point = None
|
||||||
|
self.input_line = ""
|
||||||
self.height = height
|
self.hidden_ranges = {}
|
||||||
self.width = width
|
self.hidden_lines = {}
|
||||||
|
|
||||||
self.input_line = ""
|
|
||||||
|
|
||||||
if mode_name is not None:
|
if mode_name is not None:
|
||||||
pass
|
pass
|
||||||
|
@ -585,6 +585,31 @@ class Window(object):
|
||||||
else:
|
else:
|
||||||
return self.buffer.lines[y][x]
|
return self.buffer.lines[y][x]
|
||||||
|
|
||||||
|
# hiding stuff
|
||||||
|
def hide(self, y1, y2):
|
||||||
|
if y2 == 0:
|
||||||
|
return
|
||||||
|
for (py1, py2) in self.hidden_ranges.itervalues():
|
||||||
|
if ((y1 >= py1 and y1 < py2) or
|
||||||
|
(y2 >= py1 and y2 < py2) or
|
||||||
|
(y1 <= py1 and y2 >= py2)):
|
||||||
|
return
|
||||||
|
for i in range(y1, y2):
|
||||||
|
self.hidden_lines[i] = y2
|
||||||
|
self.hidden_ranges[y2] = (y1, y2)
|
||||||
|
def ishidden(self, y):
|
||||||
|
return self.hidden_lines.setdefault(y, False)
|
||||||
|
def hiddenindicator(self, y):
|
||||||
|
return y in self.hidden_ranges
|
||||||
|
def unhide(self, y):
|
||||||
|
py2 = self.ishidden(y)
|
||||||
|
if not py2:
|
||||||
|
return
|
||||||
|
py1 = self.hidden_ranges[py2][0]
|
||||||
|
del self.hidden_ranges[py2]
|
||||||
|
for i in range(py1, py2):
|
||||||
|
self.hidden_lines[i] = False
|
||||||
|
|
||||||
# undo/redo
|
# undo/redo
|
||||||
def undo(self):
|
def undo(self):
|
||||||
p = self.buffer.undo()
|
p = self.buffer.undo()
|
||||||
|
@ -629,8 +654,78 @@ class Window(object):
|
||||||
def get_next_token_except_type_regex(self, p, name, regex):
|
def get_next_token_except_type_regex(self, p, name, regex):
|
||||||
l = lambda t: t.name != name or regex.match(t.string)
|
l = lambda t: t.name != name or regex.match(t.string)
|
||||||
return self.get_next_token_by_lambda(p, l)
|
return self.get_next_token_by_lambda(p, l)
|
||||||
|
|
||||||
def get_next_token_by_types(self, p, *names):
|
def get_next_token_by_types(self, p, *names):
|
||||||
return self.get_next_token_by_lambda(p, lambda t: t.name in names)
|
return self.get_next_token_by_lambda(p, lambda t: t.name in names)
|
||||||
def get_next_token_except_types(self, p, *names):
|
def get_next_token_except_types(self, p, *names):
|
||||||
return self.get_next_token_by_lambda(p, lambda t: t.name not in names)
|
return self.get_next_token_by_lambda(p, lambda t: t.name not in names)
|
||||||
|
|
||||||
|
# application drawing
|
||||||
|
#
|
||||||
|
# render methods return a list of lists of RenderString objects
|
||||||
|
# (i.e. multiple physical lines, each containing multiple areas to be drawn)
|
||||||
|
def render_line(self, y, width):
|
||||||
|
modename = self.mode.name()
|
||||||
|
if modename in self.buffer.highlights:
|
||||||
|
return self.render_line_lit(y, width)
|
||||||
|
else:
|
||||||
|
return self.render_line_raw(y, width)
|
||||||
|
|
||||||
|
def render_line_raw(self, y, width):
|
||||||
|
if y >= len(self.buffer.lines):
|
||||||
|
return [[RenderString('~', 0, color.build('red', 'default'))]]
|
||||||
|
x = 0
|
||||||
|
line = self.buffer.lines[y]
|
||||||
|
lines = []
|
||||||
|
if line:
|
||||||
|
while x < len(line):
|
||||||
|
lines.append(tuple([RenderString(line[x:x + width], 0)]))
|
||||||
|
x += width
|
||||||
|
else:
|
||||||
|
lines.append(tuple([RenderString('', 0)]))
|
||||||
|
return lines
|
||||||
|
|
||||||
|
def render_line_lit(self, y, width):
|
||||||
|
if y >= len(self.buffer.lines):
|
||||||
|
return [[RenderString('~', 0, color.build('red', 'default'))]]
|
||||||
|
|
||||||
|
modename = self.mode.name()
|
||||||
|
highlighter = self.buffer.highlights[modename]
|
||||||
|
|
||||||
|
line = []
|
||||||
|
lines = []
|
||||||
|
|
||||||
|
j = x = 0
|
||||||
|
while j < len(highlighter.tokens[y]):
|
||||||
|
# get our token, and do some basic checking/bleaching
|
||||||
|
token = highlighter.tokens[y][j]
|
||||||
|
if token.string.endswith('\n'):
|
||||||
|
tstring = token.string[:-1]
|
||||||
|
else:
|
||||||
|
tstring = token.string
|
||||||
|
assert token.y == y, '%d == %d' % (token.y, y)
|
||||||
|
|
||||||
|
# figure out what portion of the string to use
|
||||||
|
s_offset = max(x - token.x, 0)
|
||||||
|
s = tstring[s_offset:]
|
||||||
|
|
||||||
|
# for debugging things like lexing/relexing/etc.
|
||||||
|
if token._debug:
|
||||||
|
attr = color.build('blue', 'green')
|
||||||
|
elif token.color:
|
||||||
|
attr = color.build(*token.color)
|
||||||
|
else:
|
||||||
|
attr = color.build("default", "default")
|
||||||
|
|
||||||
|
# ok, so add a region with data, position, and color info
|
||||||
|
x_offset = max(token.x - x, 0)
|
||||||
|
line.append(RenderString(s[:width - x_offset], x_offset, attr))
|
||||||
|
|
||||||
|
# see if the token is wrapping, or if we move on to the next one
|
||||||
|
if x_offset + len(s) > width:
|
||||||
|
lines.append(line)
|
||||||
|
line = []
|
||||||
|
x += width
|
||||||
|
else:
|
||||||
|
j += 1
|
||||||
|
lines.append(line)
|
||||||
|
return lines
|
||||||
|
|
Loading…
Reference in New Issue