Add support for pdb prompt

Note: pdbpp is not supported, it has lots of problems with unicode<-->str
conversion (either explicit or implicit).
This commit is contained in:
ZyX 2015-01-27 22:15:26 +03:00
parent 7250cd4bd8
commit 9bbec772e0
8 changed files with 194 additions and 0 deletions

View File

@ -469,6 +469,12 @@ Ipython
Attribute ``prompt_count`` contains the so-called “history count”
(equivalent to ``\N`` in ``in_template``).
Pdb
---
``pdb``
Currently active :py:class:`pdb.Pdb` instance.
Segment class
=============

View File

@ -124,3 +124,30 @@ the used profile:
IPython=0.11* is not supported and does not work. IPython<0.10 was not
tested (not installable by pip).
PDB prompt
==========
To use Powerline with PDB prompt you need to use custom class. Inherit your
class from :py:class:`pdb.Pdb` and decorate it with
:py:func:`powerline.bindings.pdb.use_powerline_prompt`:
.. code-block:: Python
import pdb
from powerline.bindings.pdb import use_powerline_prompt
@use_powerline_prompt
class MyPdb(pdb.Pdb):
pass
MyPdb.run('some.code.to.debug()')
. Alternatively you may use
.. code-block:: bash
python -mpowerline.bindings.pdb path/to/script.py
just like you used ``python -m pdb``.

View File

@ -0,0 +1,54 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from powerline.pdb import PDBPowerline
from powerline.lib.encoding import get_preferred_output_encoding
def use_powerline_prompt(cls):
'''Decorator that installs powerline prompt to the class
:param pdb.Pdb cls:
Class that should be decorated.
:return:
``cls`` argument or a class derived from it. Latter is used to turn
old-style classes into new-style classes.
'''
encoding = get_preferred_output_encoding()
@property
def prompt(self):
try:
powerline = self.powerline
except AttributeError:
powerline = PDBPowerline()
powerline.setup(self)
self.powerline = powerline
ret = powerline.render(side='left')
if not isinstance(ret, str):
# Python-2
ret = ret.encode(encoding)
return ret
@prompt.setter
def prompt(self, _):
pass
@prompt.deleter
def prompt(self):
pass
if not hasattr(cls, '__class__'):
# Old-style class: make it new-style or @property will not work.
old_cls = cls
class cls(cls, object):
__module__ = cls.__module__
__doc__ = cls.__doc__
cls.__name__ = old_cls.__name__
cls.prompt = prompt
return cls

View File

@ -0,0 +1,29 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import pdb
from powerline.bindings.pdb import use_powerline_prompt
def main():
'''Run module as a script
Uses :py:func:`pdb.main` function directly, but prior to that it mocks
:py:class:`pdb.Pdb` class with powerline-specific class instance.
'''
orig_pdb = pdb.Pdb
@use_powerline_prompt
class Pdb(pdb.Pdb, object):
def __init__(self):
orig_pdb.__init__(self)
pdb.Pdb = Pdb
return pdb.main()
if __name__ == '__main__':
main()

View File

@ -12,6 +12,10 @@
"in2": "in2"
}
},
"pdb": {
"colorscheme": "default",
"theme": "default"
},
"shell": {
"colorscheme": "default",
"theme": "default",

View File

@ -0,0 +1,21 @@
{
"segments": {
"left": [
{
"function": "powerline.segments.common.env.virtualenv",
"priority": 10
},
{
"type": "string",
"contents": "In [",
"draw_soft_divider": false,
"highlight_groups": ["virtualenv"]
},
{
"type": "string",
"contents": "]",
"highlight_groups": ["virtualenv"]
}
]
}
}

19
powerline/pdb.py Normal file
View File

@ -0,0 +1,19 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from powerline import Powerline
class PDBPowerline(Powerline):
'''PDB-specific powerline bindings
'''
def init(self, **kwargs):
return super(PDBPowerline, self).init(
ext='pdb',
renderer_module='pdb',
**kwargs
)
def do_setup(self, pdb):
self.update_renderer()
self.renderer.set_pdb(pdb)

View File

@ -0,0 +1,34 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from powerline.renderers.shell.readline import ReadlineRenderer
from powerline.renderer import Renderer
class PDBRenderer(ReadlineRenderer):
'''PDB-specific powerline renderer
'''
pdb = None
def get_segment_info(self, segment_info, mode):
r = self.segment_info.copy()
r['pdb'] = self.pdb
return r
def set_pdb(self, pdb):
'''Record currently used :py:class:`pdb.Pdb` instance
Must be called before first calling :py:meth:`render` method.
:param pdb.Pdb pdb:
Used :py:class:`pdb.Pdb` instance. This instance will later be used
by :py:meth:`get_segment_info` for patching :ref:`segment_info
<dev-segments-info>` dictionary.
'''
self.pdb = pdb
def render(self, **kwargs):
return Renderer.render(self, **kwargs)
renderer = PDBRenderer