##// END OF EJS Templates
Merge branch 'blockbreaker' of git://github.com/fperez/ipython into qtfrontend
Merge branch 'blockbreaker' of git://github.com/fperez/ipython into qtfrontend

File last commit:

r2779:fec899c0
r2788:45fee7db merge
Show More
ipython_widget.py
188 lines | 7.2 KiB | text/x-python | PythonLexer
epatters
* Updated FrontendWidget to use BlockBreaker for parsing input...
r2630 # System library imports
from PyQt4 import QtCore, QtGui
# Local imports
epatters
Added banners to FrontendWidget and IPythonWidget.
r2714 from IPython.core.usage import default_banner
epatters
* Created an IPythonWidget subclass of FrontendWidget to contain IPython specific functionality....
r2627 from frontend_widget import FrontendWidget
class IPythonWidget(FrontendWidget):
""" A FrontendWidget for an IPython kernel.
"""
epatters
* Fleshed out IPythonWidget's style control....
r2725 # The default stylesheet: black text on a white background.
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 default_stylesheet = """
epatters
* Moved AnsiCodeProcessor to separate file, refactored its API, and added unit tests....
r2716 .error { color: red; }
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 .in-prompt { color: navy; }
.in-prompt-number { font-weight: bold; }
.out-prompt { color: darkred; }
.out-prompt-number { font-weight: bold; }
"""
epatters
* Fleshed out IPythonWidget's style control....
r2725 # A dark stylesheet: white text on a black background.
dark_stylesheet = """
QPlainTextEdit { background-color: black; color: white }
QFrame { border: 1px solid grey; }
.error { color: red; }
.in-prompt { color: lime; }
.in-prompt-number { color: lime; font-weight: bold; }
.out-prompt { color: red; }
.out-prompt-number { color: red; font-weight: bold; }
"""
epatters
Added machinery to IPythonWidget for updating the previous prompt number.
r2733 # Default prompts.
in_prompt = '<br/>In [<span class="in-prompt-number">%i</span>]: '
out_prompt = 'Out[<span class="out-prompt-number">%i</span>]: '
epatters
* Created an IPythonWidget subclass of FrontendWidget to contain IPython specific functionality....
r2627 #---------------------------------------------------------------------------
epatters
Refactored ConsoleWidget to encapsulate, rather than inherit from, QPlainTextEdit. This permits a QTextEdit to be substituted for a QPlainTextEdit if desired. It also makes it more clear what is the public interface of ConsoleWidget.
r2736 # 'object' interface
epatters
* Created an IPythonWidget subclass of FrontendWidget to contain IPython specific functionality....
r2627 #---------------------------------------------------------------------------
epatters
Refactored ConsoleWidget to encapsulate, rather than inherit from, QPlainTextEdit. This permits a QTextEdit to be substituted for a QPlainTextEdit if desired. It also makes it more clear what is the public interface of ConsoleWidget.
r2736 def __init__(self, *args, **kw):
super(IPythonWidget, self).__init__(*args, **kw)
epatters
* Created an IPythonWidget subclass of FrontendWidget to contain IPython specific functionality....
r2627
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 # Initialize protected variables.
epatters
Added machinery to IPythonWidget for updating the previous prompt number.
r2733 self._previous_prompt_blocks = []
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 self._prompt_count = 0
# Set a default stylesheet.
epatters
IPythonWidget now supports styling the syntax highlighting.
r2728 self.reset_styling()
epatters
* Refactored ConsoleWidget execution API for greater flexibility and clarity....
r2688
#---------------------------------------------------------------------------
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 # 'BaseFrontendMixin' abstract interface
#---------------------------------------------------------------------------
def _handle_pyout(self, msg):
""" Reimplemented for IPython-style "display hook".
"""
self._append_html(self._make_out_prompt(self._prompt_count))
self._save_prompt_block()
self._append_plain_text(msg['content']['data'] + '\n')
#---------------------------------------------------------------------------
epatters
* Refactored ConsoleWidget execution API for greater flexibility and clarity....
r2688 # 'FrontendWidget' interface
#---------------------------------------------------------------------------
def execute_file(self, path, hidden=False):
""" Reimplemented to use the 'run' magic.
"""
self.execute('run %s' % path, hidden=hidden)
epatters
* Created an IPythonWidget subclass of FrontendWidget to contain IPython specific functionality....
r2627
#---------------------------------------------------------------------------
epatters
Added banners to FrontendWidget and IPythonWidget.
r2714 # 'FrontendWidget' protected interface
#---------------------------------------------------------------------------
def _get_banner(self):
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 """ Reimplemented to return IPython's default banner.
epatters
Added banners to FrontendWidget and IPythonWidget.
r2714 """
return default_banner
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 def _process_execute_error(self, msg):
""" Reimplemented for IPython-style traceback formatting.
"""
content = msg['content']
traceback_lines = content['traceback'][:]
traceback = ''.join(traceback_lines)
traceback = traceback.replace(' ', '&nbsp;')
traceback = traceback.replace('\n', '<br/>')
ename = content['ename']
ename_styled = '<span class="error">%s</span>' % ename
traceback = traceback.replace(ename, ename_styled)
self._append_html(traceback)
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 def _show_interpreter_prompt(self):
""" Reimplemented for IPython-style prompts.
"""
epatters
Added machinery to IPythonWidget for updating the previous prompt number.
r2733 # Update old prompt numbers if necessary.
previous_prompt_number = self._prompt_count
if previous_prompt_number != self._prompt_count:
for i, (block, length) in enumerate(self._previous_prompt_blocks):
if block.isValid():
cursor = QtGui.QTextCursor(block)
cursor.movePosition(QtGui.QTextCursor.Right,
QtGui.QTextCursor.KeepAnchor, length-1)
if i == 0:
prompt = self._make_in_prompt(previous_prompt_number)
else:
prompt = self._make_out_prompt(previous_prompt_number)
self._insert_html(cursor, prompt)
self._previous_prompt_blocks = []
# Show a new prompt.
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 self._prompt_count += 1
epatters
Added machinery to IPythonWidget for updating the previous prompt number.
r2733 self._show_prompt(self._make_in_prompt(self._prompt_count), html=True)
self._save_prompt_block()
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715
# Update continuation prompt to reflect (possibly) new prompt length.
epatters
Added machinery to IPythonWidget for updating the previous prompt number.
r2733 self._set_continuation_prompt(
self._make_continuation_prompt(self._prompt), html=True)
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715
epatters
Added banners to FrontendWidget and IPythonWidget.
r2714 #---------------------------------------------------------------------------
epatters
* Created an IPythonWidget subclass of FrontendWidget to contain IPython specific functionality....
r2627 # 'IPythonWidget' interface
#---------------------------------------------------------------------------
epatters
IPythonWidget now supports styling the syntax highlighting.
r2728 def reset_styling(self):
""" Restores the default IPythonWidget styling.
epatters
* Created an IPythonWidget subclass of FrontendWidget to contain IPython specific functionality....
r2627 """
epatters
IPythonWidget now supports styling the syntax highlighting.
r2728 self.set_styling(self.default_stylesheet, syntax_style='default')
#self.set_styling(self.dark_stylesheet, syntax_style='monokai')
def set_styling(self, stylesheet, syntax_style=None):
""" Sets the IPythonWidget styling.
Parameters:
-----------
stylesheet : str
A CSS stylesheet. The stylesheet can contain classes for:
1. Qt: QPlainTextEdit, QFrame, QWidget, etc
2. Pygments: .c, .k, .o, etc (see PygmentsHighlighter)
3. IPython: .error, .in-prompt, .out-prompt, etc.
syntax_style : str or None [default None]
If specified, use the Pygments style with given name. Otherwise,
the stylesheet is queried for Pygments style information.
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 """
epatters
* Fleshed out IPythonWidget's style control....
r2725 self.setStyleSheet(stylesheet)
epatters
Refactored ConsoleWidget to encapsulate, rather than inherit from, QPlainTextEdit. This permits a QTextEdit to be substituted for a QPlainTextEdit if desired. It also makes it more clear what is the public interface of ConsoleWidget.
r2736 self._control.document().setDefaultStyleSheet(stylesheet)
epatters
Fix to ensure that the paging widget is styled appropriately.
r2779 if self._page_control:
self._page_control.document().setDefaultStyleSheet(stylesheet)
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715
epatters
IPythonWidget now supports styling the syntax highlighting.
r2728 if syntax_style is None:
self._highlighter.set_style_sheet(stylesheet)
else:
self._highlighter.set_style(syntax_style)
epatters
Added machinery to IPythonWidget for updating the previous prompt number.
r2733 #---------------------------------------------------------------------------
# 'IPythonWidget' protected interface
#---------------------------------------------------------------------------
def _make_in_prompt(self, number):
""" Given a prompt number, returns an HTML In prompt.
"""
body = self.in_prompt % number
return '<span class="in-prompt">%s</span>' % body
def _make_continuation_prompt(self, prompt):
""" Given a plain text version of an In prompt, returns an HTML
continuation prompt.
"""
end_chars = '...: '
space_count = len(prompt.lstrip('\n')) - len(end_chars)
body = '&nbsp;' * space_count + end_chars
return '<span class="in-prompt">%s</span>' % body
def _make_out_prompt(self, number):
""" Given a prompt number, returns an HTML Out prompt.
"""
body = self.out_prompt % number
return '<span class="out-prompt">%s</span>' % body
def _save_prompt_block(self):
""" Assuming a prompt has just been written at the end of the buffer,
store the QTextBlock that contains it and its length.
"""
epatters
Refactored ConsoleWidget to encapsulate, rather than inherit from, QPlainTextEdit. This permits a QTextEdit to be substituted for a QPlainTextEdit if desired. It also makes it more clear what is the public interface of ConsoleWidget.
r2736 block = self._control.document().lastBlock()
epatters
Added machinery to IPythonWidget for updating the previous prompt number.
r2733 self._previous_prompt_blocks.append((block, block.length()))