[Urwid] palette container (SOLVED)

Alain Leufroy alain.leufroy at logilab.fr
Wed Aug 17 04:28:38 EDT 2011


>>> Running ``python test.py`` displays a highlighted source code. But it is not
>>> exactly what as I expect.
>>>
>>> For example, *Foo* is not highlighted because pygments sets the "style" to
>>> *token.Token.Name.Class*. But I'd like that *Foo* is in "dark blue" because
>>> *token.Token.Name.Class* is a "sub-style" of *token.Token.Name* (instead of
>>> defining all "sub-style of "token.Token.Name" to the same style).
>>>
>>> From now urwid stores the palette in a dictionary (ex: raw_display.py line 51
>>> changeset d6d6ae081dcf of https://excess.org/hg/urwid/).
>>> Is it possible to add a way to tune the palette container for a dict-like class
>>> that suite special needs?
>>
>> Hi Alain,
>>
>> I suppose you could replace the _palette dictionary in your screen with
>> your own dictionary-like object that does that sort of advanced lookup.
>>
>> Ian
>>
>
> This should get you started:
>
> ---
>
> [...]
>
> class CPDict(dict):
>    """Cascading (Escape) Palette for Pygments token
>
>    Only works if ancestor is already defined.
>    """
>    def __contains__(self, k):
>
>        if super(CPDict, self).__contains__(k):
>            return True
>        if not isinstance(k, token._TokenType) or not k.parent:
>            return False
>        # This will do a recursive search
>        if k.parent in self:
>            # Save it, so no need to find it again
>            self[k] = self[k.parent]
>            return True
>        return False
>
> text = highlight_code(str(Foo()))
> widget = urwid.Filler(urwid.Text(text))
> screen = urwid.raw_display.Screen()
> screen._pal_escape = CPDict(screen._pal_escape)
> mainloop = urwid.MainLoop(widget, PALETTE, screen)
> mainloop.run()


Thanks, it works as expected !

Here is an improved hack for others that are interested by this feature:

---

[...]

class Screen(urwid.raw_display.Screen):
     """Raw display screen with customizable palette dict-like container
     (default to dict).

     >>> screen = Screen(palette_cls=DictLikeContainerWithCoolFeatures)
     """
     def __init__(self, palette_cls=dict, **kwargs):
         self.palette_cls = palette_cls
         self.__pal_escape = None
         super(Screen, self).__init__(**kwargs)

     def _get_pal_escape(self):
         return self.__pal_escape
     def _set_pal_escape(self, hashable):
         self.__pal_escape = self.palette_cls()
         if values:
             self.__pal_escape.update(values)
     _pal_escape = property(_get_pal_escape, _set_pal_escape)

text = highlight_code(str(Foo()))
widget = urwid.Filler(urwid.Text(text))
screen = Screen(palette_cls=CPDict)
mainloop = urwid.MainLoop(widget, PALETTE, screen)
mainloop.run()

Alain



More information about the Urwid mailing list