##// END OF EJS Templates
Initial support in ipkernel for proper displayhook handling.
Initial support in ipkernel for proper displayhook handling.

File last commit:

r2786:a522a5c7
r2786:a522a5c7
Show More
ipython_widget.py
212 lines | 8.0 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
#---------------------------------------------------------------------------
# '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
* 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
#------ Signal handlers ----------------------------------------------------
epatters
* Moved AnsiCodeProcessor to separate file, refactored its API, and added unit tests....
r2716 def _handle_execute_error(self, reply):
""" Reimplemented for IPython-style traceback formatting.
"""
content = reply['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)
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._append_html(traceback)
epatters
* Moved AnsiCodeProcessor to separate file, refactored its API, and added unit tests....
r2716
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 def _handle_pyout(self, omsg):
""" Reimplemented for IPython-style "display hook".
"""
Brian Granger
Initial support in ipkernel for proper displayhook handling.
r2786 # self._append_html(self._make_out_prompt(self._prompt_count))
# TODO: Also look at the output_sep, output_sep2 keys of content.
# They are used in terminal based frontends to add empty spaces before
# and after the Out[]: prompt. I doubt you want to use them, but they
# are there. I am thinking we should even take them out of the msg.
prompt_number = omsg['content']['prompt_number']
data = omsg['content']['data']
self._append_html(self._make_out_prompt(prompt_number))
epatters
Added machinery to IPythonWidget for updating the previous prompt number.
r2733 self._save_prompt_block()
Brian Granger
Initial support in ipkernel for proper displayhook handling.
r2786 self._append_plain_text(data + '\n')
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
* 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()))
epatters
* Created an IPythonWidget subclass of FrontendWidget to contain IPython specific functionality....
r2627
if __name__ == '__main__':
epatters
* Implemented a proper main() function for kernel.py that reads command line input....
r2667 from IPython.frontend.qt.kernelmanager import QtKernelManager
epatters
* Added a function for spawning a localhost kernel in a new process on random ports....
r2641
epatters
* Added 'independent' argument to 'launch_kernel' for setting subprocess persistence goals. The case for 'independent=False' is only partially implemented....
r2700 # Don't let Qt or ZMQ swallow KeyboardInterupts.
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
epatters
* Implemented a proper main() function for kernel.py that reads command line input....
r2667 # Create a KernelManager.
kernel_manager = QtKernelManager()
kernel_manager.start_kernel()
Brian Granger
Kernel manager is cleaned up and simplified. Still bugs though.
r2699 kernel_manager.start_channels()
epatters
* Created an IPythonWidget subclass of FrontendWidget to contain IPython specific functionality....
r2627
epatters
* Implemented a proper main() function for kernel.py that reads command line input....
r2667 # Launch the application.
epatters
* Added 'independent' argument to 'launch_kernel' for setting subprocess persistence goals. The case for 'independent=False' is only partially implemented....
r2700 app = QtGui.QApplication([])
epatters
* Added 'started_listening' and 'stopped_listening' signals to QtKernelManager. The FrontendWidget listens for these signals....
r2643 widget = IPythonWidget()
widget.kernel_manager = kernel_manager
epatters
* Created an IPythonWidget subclass of FrontendWidget to contain IPython specific functionality....
r2627 widget.setWindowTitle('Python')
widget.resize(640, 480)
widget.show()
epatters
* Added a function for spawning a localhost kernel in a new process on random ports....
r2641 app.exec_()