lay groundwork for variable-width characters; document problems

--HG--
branch : pmacs2
This commit is contained in:
Erik Osheim 2010-04-27 01:14:41 -04:00
parent fee24fd1f4
commit 49c372a2d5
3 changed files with 50 additions and 22 deletions

19
IDEAS
View File

@ -1,3 +1,22 @@
2010/4/27:
It would be awesome to actually handle tabs correctly (e.g. how emacs or vim
does); that is, instead of substituting N whitespace characters for each tab
it would just handle seeing tabs correctly. There are some problems doing this:
1. render objects store the X coordinate to write to; this needs to be
calculated if characters are variable-width (easy to fix)
2. buffer needs to stop munging/de-munging lines (easy to fix)
3. draw_slot() needs to keep track of the X offset when drawing (easy)
4. map_point() needs to be fixed so that logical cursor position gets
translated correctly (e.g. for x=1, line="\tfoo\n", vx=4) (medium)
5. fix all the navigation and cursor positioning code in window.py (hard)
6. find all the other places where len(line) gets used for drawing (ugh)
Each time I embark on this I get a little farther before giving up. At this
point it's a race to see whether I fix indenting for "munged" lines (so that
"\t \tfoo" and " foo" indent the same) or actually fix all these problems.
2009/10/21: 2009/10/21:
More reasonable: More reasonable:

View File

@ -782,21 +782,25 @@ class Application(object):
# NOTE: this is taken from the cursor code # NOTE: this is taken from the cursor code
def map_point(self, slot, p): def map_point(self, slot, p):
w = slot.window w = slot.window
swidth = slot.width - w.mode.lmargin - w.mode.rmargin swidth = slot.width - w.mode.lmargin - w.mode.rmargin
blen = len(w.buffer.lines) blen = len(w.buffer.lines)
count = w.mode.header count = w.mode.header
(x, y) = w.first.xy() x, y = w.first.xy()
(vy, vx) = (None, None) vy, vx = None, None
while count < slot.height: while count < slot.height:
line = w.buffer.lines[y]
l = len(line) + line.count('\t') * (w.mode.tabwidth - 1)
if p.y == y and p.x >= x and p.x <= x + swidth: if p.y == y and p.x >= x and p.x <= x + swidth:
vy, vx = slot.y_offset + count, p.x - x + w.mode.lmargin vy, vx = slot.y_offset + count, p.x - x + w.mode.lmargin
if vx == swidth and p.x < len(w.buffer.lines[y]): if vx == swidth and p.x < l:
vx = 0 vx = 0
vy += 1 vy += 1
break break
if y >= blen or x + swidth >= len(w.buffer.lines[y]): if y >= blen or x + swidth >= l:
x = 0 x = 0
y += 1 y += 1
else: else:
@ -942,7 +946,8 @@ class Application(object):
k = 0 k = 0
for rstr in rstrs[j]: for rstr in rstrs[j]:
rstr.draw(self.win, slot.y_offset + j, slot.x_offset + k, slot.width) rstr.draw(self.win, slot.y_offset + j, slot.x_offset + k, slot.width)
k += len(rstr.string) #k += len(rstr.string)
k += rstr.width(w)
# draw the actual slot # draw the actual slot
self._draw_slot(i) self._draw_slot(i)
@ -1001,17 +1006,23 @@ class Application(object):
for j in xrange(k, len(rlines)): for j in xrange(k, len(rlines)):
y2 = slot.y_offset + count y2 = slot.y_offset + count
if lm: if lm:
i = 0
lcont = j > 0 lcont = j > 0
rstrs = slot.window.mode.get_lmargin(w, y, x, ended, lcont) rstrs = w.mode.get_lmargin(w, y, x, ended, lcont)
for rstr in rstrs: for rstr in rstrs:
rstr.draw(self.win, y2, 0) rstr.draw(self.win, y2, i)
i += rstr.width(w)
i = lm
for rstr in rlines[j]: for rstr in rlines[j]:
rstr.draw(self.win, y2, 0 + lm) rstr.draw(self.win, y2, i)
i += rstr.width(w)
if rm: if rm:
i = slot.width - rm
rcont = j < len(rlines) - 1 rcont = j < len(rlines) - 1
rstrs = slot.window.mode.get_rmargin(w, y, x, ended, rcont) rstrs = w.mode.get_rmargin(w, y, x, ended, rcont)
for rstr in rstrs: for rstr in rstrs:
rstr.draw(self.win, y2, slot.width - rm) rstr.draw(self.win, y2, i)
i += rstr.width(w)
count += 1 count += 1
if count >= slot.height: if count >= slot.height:
break break

View File

@ -30,15 +30,13 @@ class RenderString(object):
self.y = y self.y = y
self.x = x self.x = x
self.attrs = attrs self.attrs = attrs
def draw(self, cwin, y, x, x2=None): def width(self, w):
l = len(self.string)
#l += self.string.count('\t') * (w.mode.tabwidth - 1)
return l
def draw(self, cwin, y, x):
try: try:
if x2: s = self.string.encode('utf-8')
s = '%-*s' % (x2 - x, self.string) cwin.addstr(self.y + y, x, s, self.attrs)
else:
s = self.string
s2 = s.encode('utf-8')
cwin.addstr(self.y + y, self.x + x, s2, self.attrs)
except curses.error: except curses.error:
raise raise
#v = (self.y, y, self.x, x, self.string, self.attrs, str(e))
#raise Exception, "cwin.addstr(%d + %d, %d + %d, %r, %r) failed:\n%s" % v