diff --git a/IDEAS b/IDEAS index 8843663..63d5e68 100644 --- a/IDEAS +++ b/IDEAS @@ -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: More reasonable: diff --git a/application.py b/application.py index f05ece5..6fa2281 100755 --- a/application.py +++ b/application.py @@ -782,21 +782,25 @@ class Application(object): # NOTE: this is taken from the cursor code def map_point(self, slot, p): - w = slot.window + w = slot.window swidth = slot.width - w.mode.lmargin - w.mode.rmargin - blen = len(w.buffer.lines) - count = w.mode.header - (x, y) = w.first.xy() - (vy, vx) = (None, None) + blen = len(w.buffer.lines) + count = w.mode.header + x, y = w.first.xy() + vy, vx = None, None + 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: 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 vy += 1 break - if y >= blen or x + swidth >= len(w.buffer.lines[y]): + if y >= blen or x + swidth >= l: x = 0 y += 1 else: @@ -942,7 +946,8 @@ class Application(object): k = 0 for rstr in rstrs[j]: 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 self._draw_slot(i) @@ -1001,17 +1006,23 @@ class Application(object): for j in xrange(k, len(rlines)): y2 = slot.y_offset + count if lm: + i = 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: - rstr.draw(self.win, y2, 0) + rstr.draw(self.win, y2, i) + i += rstr.width(w) + i = lm for rstr in rlines[j]: - rstr.draw(self.win, y2, 0 + lm) + rstr.draw(self.win, y2, i) + i += rstr.width(w) if rm: + i = slot.width - rm 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: - rstr.draw(self.win, y2, slot.width - rm) + rstr.draw(self.win, y2, i) + i += rstr.width(w) count += 1 if count >= slot.height: break diff --git a/render.py b/render.py index a299aaa..12d3036 100644 --- a/render.py +++ b/render.py @@ -30,15 +30,13 @@ class RenderString(object): self.y = y self.x = x 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: - if x2: - s = '%-*s' % (x2 - x, self.string) - else: - s = self.string - s2 = s.encode('utf-8') - cwin.addstr(self.y + y, self.x + x, s2, self.attrs) + s = self.string.encode('utf-8') + cwin.addstr(self.y + y, x, s, self.attrs) except curses.error: 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