def __init__(self, text=None, attr=None, cs=None, cursor=None, maxcol=None, check_width=True): """ text -- list of strings, one for each line attr -- list of run length encoded attributes for text cs -- list of run length encoded character set for text cursor -- (x,y) of cursor or None maxcol -- screen columns taken by this canvas check_width -- check and fix width of all lines in text """ Canvas.__init__(self) if text == None: text = [] if check_width: widths = [] for t in text: if type(t) != bytes: raise CanvasError("Canvas text must be plain strings encoded in the screen's encoding", repr(text)) widths.append( calc_width( t, 0, len(t)) ) else: assert type(maxcol) == int widths = [maxcol] * len(text) if maxcol is None: if widths: # find maxcol ourselves maxcol = max(widths) else: maxcol = 0 if attr == None: attr = [[] for x in range(len(text))] if cs == None: cs = [[] for x in range(len(text))] # pad text and attr to maxcol for i in range(len(text)): w = widths[i] if w > maxcol: raise CanvasError("Canvas text is wider than the maxcol specified \n%r\n%r\n%r"%(maxcol,widths,text)) if w < maxcol: text[i] = text[i] + bytes().rjust(maxcol-w) a_gap = len(text[i]) - rle_len( attr[i] ) if a_gap < 0: raise CanvasError("Attribute extends beyond text \n%r\n%r" % (text[i],attr[i]) ) if a_gap: rle_append_modify( attr[i], (None, a_gap)) cs_gap = len(text[i]) - rle_len( cs[i] ) if cs_gap < 0: raise CanvasError("Character Set extends beyond text \n%r\n%r" % (text[i],cs[i]) ) if cs_gap: rle_append_modify( cs[i], (None, cs_gap)) self._attr = attr self._cs = cs self.cursor = cursor self._text = text self._maxcol = maxcol
def attrrange( start_offs, end_offs, destw ): """ Add attributes based on attributes between start_offs and end_offs. """ if start_offs == end_offs: [(at,run)] = arange(start_offs,end_offs) rle_append_modify( linea, ( at, destw )) return if destw == end_offs-start_offs: for at, run in arange(start_offs,end_offs): rle_append_modify( linea, ( at, run )) return # encoded version has different width o = start_offs for at, run in arange(start_offs, end_offs): if o+run == end_offs: rle_append_modify( linea, ( at, destw )) return tseg = text[o:o+run] tseg, cs = apply_target_encoding( tseg ) segw = rle_len(cs) rle_append_modify( linea, ( at, segw )) o += run destw -= segw
def render(self, size, focus=False): from pudb.debugger import CONFIG render_line_nr = CONFIG["line_numbers"] maxcol = size[0] hscroll = self.dbg_ui.source_hscroll_start attrs = [] if self.is_current: crnt = ">" attrs.append("current") else: crnt = " " if self.has_breakpoint: bp = "*" attrs.append("breakpoint") else: bp = " " if focus: attrs.append("focused") elif self.highlight: if not self.has_breakpoint: attrs.append("highlighted") if render_line_nr: line_nr_len = len(self.line_nr) else: line_nr_len = 0 text = self.text if not attrs and self.attr is not None: attr = self.attr else: attr = [(" ".join(attrs+["source"]), hscroll+maxcol-2-line_nr_len)] from urwid.util import rle_subseg, rle_len if hscroll: text = text[hscroll:] attr = rle_subseg(attr, hscroll, rle_len(attr)) if render_line_nr: attr = [("line number", len(self.line_nr))] + attr text = self.line_nr + text text = crnt+bp+text attr = [("source", 1), ("bp_star", 1)] + attr # clipping ------------------------------------------------------------ if len(text) > maxcol: text = text[:maxcol] attr = rle_subseg(attr, 0, maxcol) # shipout ------------------------------------------------------------- from urwid.util import apply_target_encoding txt, cs = apply_target_encoding(text) return urwid.TextCanvas([txt], [attr], [cs], maxcol=maxcol)
def apply_text_layout(text, attr, ls, maxcol): t = [] a = [] c = [] class AttrWalk: pass aw = AttrWalk aw.k = 0 # counter for moving through elements of a aw.off = 0 # current offset into text of attr[ak] def arange( start_offs, end_offs ): """Return an attribute list for the range of text specified.""" if start_offs < aw.off: aw.k = 0 aw.off = 0 o = [] while aw.off < end_offs: if len(attr)<=aw.k: # run out of attributes o.append((None,end_offs-max(start_offs,aw.off))) break at,run = attr[aw.k] if aw.off+run <= start_offs: # move forward through attr to find start_offs aw.k += 1 aw.off += run continue if end_offs <= aw.off+run: o.append((at, end_offs-max(start_offs,aw.off))) break o.append((at, aw.off+run-max(start_offs, aw.off))) aw.k += 1 aw.off += run return o for line_layout in ls: # trim the line to fit within maxcol line_layout = trim_line( line_layout, text, 0, maxcol ) line = [] linea = [] linec = [] def attrrange( start_offs, end_offs, destw ): """ Add attributes based on attributes between start_offs and end_offs. """ if start_offs == end_offs: [(at,run)] = arange(start_offs,end_offs) rle_append_modify( linea, ( at, destw )) return if destw == end_offs-start_offs: for at, run in arange(start_offs,end_offs): rle_append_modify( linea, ( at, run )) return # encoded version has different width o = start_offs for at, run in arange(start_offs, end_offs): if o+run == end_offs: rle_append_modify( linea, ( at, destw )) return tseg = text[o:o+run] tseg, cs = apply_target_encoding( tseg ) segw = rle_len(cs) rle_append_modify( linea, ( at, segw )) o += run destw -= segw for seg in line_layout: #if seg is None: assert 0, ls s = LayoutSegment(seg) if s.end: tseg, cs = apply_target_encoding( text[s.offs:s.end]) line.append(tseg) attrrange(s.offs, s.end, rle_len(cs)) rle_join_modify( linec, cs ) elif s.text: tseg, cs = apply_target_encoding( s.text ) line.append(tseg) attrrange( s.offs, s.offs, len(tseg) ) rle_join_modify( linec, cs ) elif s.offs: if s.sc: line.append(bytes().rjust(s.sc)) attrrange( s.offs, s.offs, s.sc ) else: line.append(bytes().rjust(s.sc)) linea.append((None, s.sc)) linec.append((None, s.sc)) t.append(bytes().join(line)) a.append(linea) c.append(linec) return TextCanvas(t, a, c, maxcol=maxcol)
if not attrs and self.attr is not None: attr = self.attr if render_line_nr: attr = [("line number", len(self.line_nr))] + attr else: attr = [(" ".join(attrs+["source"]), hscroll+maxcol-2)] from urwid.util import rle_subseg, rle_len text = self.text if self.dbg_ui.source_hscroll_start: text = text[hscroll:] attr = rle_subseg(attr, self.dbg_ui.source_hscroll_start, rle_len(attr)) if render_line_nr: text = self.line_nr + text text = crnt+bp+text attr = [("source", 1), ("bp_star", 1)] + attr # clipping ------------------------------------------------------------ if len(text) > maxcol: text = text[:maxcol] attr = rle_subseg(attr, 0, maxcol) # shipout ------------------------------------------------------------- from urwid.util import apply_target_encoding txt, cs = apply_target_encoding(text)
attrs.append("highlighted") if not attrs and self.attr is not None: attr = self.attr if render_line_nr: attr = [("line number", len(self.line_nr))] + attr else: attr = [(" ".join(attrs + ["source"]), hscroll + maxcol - 2)] from urwid.util import rle_subseg, rle_len text = self.text if self.dbg_ui.source_hscroll_start: text = text[hscroll:] attr = rle_subseg(attr, self.dbg_ui.source_hscroll_start, rle_len(attr)) if render_line_nr: text = self.line_nr + text text = crnt + bp + text attr = [("source", 1), ("bp_star", 1)] + attr # clipping ------------------------------------------------------------ if len(text) > maxcol: text = text[:maxcol] attr = rle_subseg(attr, 0, maxcol) # shipout ------------------------------------------------------------- from urwid.util import apply_target_encoding txt, cs = apply_target_encoding(text)