##// END OF EJS Templates

File last commit:

r4793:00f1dcf9
r4870:fcafc407
Show More
frontend_widget.py
636 lines | 26.3 KiB | text/x-python | PythonLexer
Fernando Perez
Implement support for 'cell' mode with Ctrl-Enter....
r3004 from __future__ import print_function
epatters
* Added ability to interrupt a kernel to FrontendWidget...
r2687 # Standard library imports
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 from collections import namedtuple
epatters
Added banners to FrontendWidget and IPythonWidget.
r2714 import sys
MinRK
added shutdown notification handling to ipythonqt
r3090 import time
epatters
* Added ability to interrupt a kernel to FrontendWidget...
r2687
epatters
Initial checkin of Qt frontend code.
r2602 # System library imports
from pygments.lexers import PythonLexer
Evan Patterson
Paved the way for PySide support....
r3304 from IPython.external.qt import QtCore, QtGui
epatters
Initial checkin of Qt frontend code.
r2602
# Local imports
epatters
* Added "smart copy" support to FrontendWidget and ConsoleWidget. Tabs are expanded and prompts are stripped....
r2971 from IPython.core.inputsplitter import InputSplitter, transform_classic_prompt
Fernando Perez
Add function signature info to calltips....
r3051 from IPython.core.oinspect import call_tip
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 from IPython.frontend.qt.base_frontend_mixin import BaseFrontendMixin
epatters
ENH: Allow FrontendWidget banner to be changed without subclassing.
r4689 from IPython.utils.traitlets import Bool, Instance, Unicode
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 from bracket_matcher import BracketMatcher
epatters
Initial checkin of Qt frontend code.
r2602 from call_tip_widget import CallTipWidget
from completion_lexer import CompletionLexer
epatters
Moved HistoryConsoleWidget to its own file to make console_widget.py a little smaller.
r2983 from history_console_widget import HistoryConsoleWidget
epatters
Fixed imports and removed references to ETS/EPD
r2603 from pygments_highlighter import PygmentsHighlighter
epatters
Initial checkin of Qt frontend code.
r2602
class FrontendHighlighter(PygmentsHighlighter):
epatters
Improve Qt console's placement of text appended before a prompt.
r4058 """ A PygmentsHighlighter that understands and ignores prompts.
epatters
Initial checkin of Qt frontend code.
r2602 """
def __init__(self, frontend):
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 super(FrontendHighlighter, self).__init__(frontend._control.document())
epatters
Initial checkin of Qt frontend code.
r2602 self._current_offset = 0
self._frontend = frontend
self.highlighting_on = False
Evan Patterson
Paved the way for PySide support....
r3304 def highlightBlock(self, string):
epatters
Initial checkin of Qt frontend code.
r2602 """ Highlight a block of text. Reimplemented to highlight selectively.
"""
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 if not self.highlighting_on:
return
Evan Patterson
Paved the way for PySide support....
r3304 # The input to this function is a unicode string that may contain
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 # paragraph break characters, non-breaking spaces, etc. Here we acquire
# the string as plain text so we can compare it.
current_block = self.currentBlock()
string = self._frontend._get_block_plain_text(current_block)
# Decide whether to check for the regular or continuation prompt.
if current_block.contains(self._frontend._prompt_pos):
prompt = self._frontend._prompt
else:
prompt = self._frontend._continuation_prompt
epatters
Improve Qt console's placement of text appended before a prompt.
r4058 # Only highlight if we can identify a prompt, but make sure not to
# highlight the prompt.
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 if string.startswith(prompt):
self._current_offset = len(prompt)
Evan Patterson
Paved the way for PySide support....
r3304 string = string[len(prompt):]
epatters
Improve Qt console's placement of text appended before a prompt.
r4058 super(FrontendHighlighter, self).highlightBlock(string)
epatters
Initial checkin of Qt frontend code.
r2602
epatters
Minor cleanup.
r2825 def rehighlightBlock(self, block):
""" Reimplemented to temporarily enable highlighting if disabled.
"""
old = self.highlighting_on
self.highlighting_on = True
super(FrontendHighlighter, self).rehighlightBlock(block)
self.highlighting_on = old
epatters
Initial checkin of Qt frontend code.
r2602 def setFormat(self, start, count, format):
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 """ Reimplemented to highlight selectively.
epatters
Initial checkin of Qt frontend code.
r2602 """
start += self._current_offset
epatters
Improve Qt console's placement of text appended before a prompt.
r4058 super(FrontendHighlighter, self).setFormat(start, count, format)
epatters
Initial checkin of Qt frontend code.
r2602
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 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
epatters
* Created an IPythonWidget subclass of FrontendWidget to contain IPython specific functionality....
r2627 """ A Qt frontend for a generic Python kernel.
epatters
Initial checkin of Qt frontend code.
r2602 """
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851
epatters
ENH: Allow FrontendWidget banner to be changed without subclassing.
r4689 # The text to show when the kernel is (re)started.
banner = Unicode()
MinRK
make calltips configurable in qtconsole...
r4569
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 # An option and corresponding signal for overriding the default kernel
# interrupt behavior.
epatters
Made IPythonWidget and its subclasses Configurable.
r2884 custom_interrupt = Bool(False)
Evan Patterson
Paved the way for PySide support....
r3304 custom_interrupt_requested = QtCore.Signal()
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851
epatters
* Improved frontend-side kernel restart support....
r2913 # An option and corresponding signals for overriding the default kernel
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 # restart behavior.
epatters
Made IPythonWidget and its subclasses Configurable.
r2884 custom_restart = Bool(False)
Evan Patterson
Paved the way for PySide support....
r3304 custom_restart_kernel_died = QtCore.Signal(float)
custom_restart_requested = QtCore.Signal()
epatters
Add history_tail method to ConsoleWidget for retreiving the local history.
r3516
epatters
ENH: Allow FrontendWidget banner to be changed without subclassing.
r4689 # Whether to automatically show calltips on open-parentheses.
enable_calltips = Bool(True, config=True,
help="Whether to draw information calltips on open-parentheses.")
epatters
Add 'executing' signal to FrontendWidget for symmetry with 'executed' signal.
r3682 # Emitted when a user visible 'execute_request' has been submitted to the
# kernel from the FrontendWidget. Contains the code to be executed.
executing = QtCore.Signal(object)
epatters
Add history_tail method to ConsoleWidget for retreiving the local history.
r3516 # Emitted when a user-visible 'execute_reply' has been received from the
# kernel and processed by the FrontendWidget. Contains the response message.
Evan Patterson
Paved the way for PySide support....
r3304 executed = QtCore.Signal(object)
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961
# Emitted when an exit request has been received from the kernel.
Evan Patterson
Paved the way for PySide support....
r3304 exit_requested = QtCore.Signal()
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851
# Protected class variables.
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos'])
_CompletionRequest = namedtuple('_CompletionRequest', ['id', 'pos'])
_ExecutionRequest = namedtuple('_ExecutionRequest', ['id', 'kind'])
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 _input_splitter_class = InputSplitter
MinRK
tweaked close dialog and added prompts to prevent silent remote close
r3129 _local_kernel = False
MinRK
QtConsole now uses newapp
r3971 _highlighter = Instance(FrontendHighlighter)
epatters
* Fixed bug where syntax highlighting was lost after updating a prompt with a bad number....
r2800
epatters
Initial checkin of Qt frontend code.
r2602 #---------------------------------------------------------------------------
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
Initial checkin of Qt frontend code.
r2602 #---------------------------------------------------------------------------
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(FrontendWidget, self).__init__(*args, **kw)
epatters
Initial checkin of Qt frontend code.
r2602
epatters
* Added 'started_listening' and 'stopped_listening' signals to QtKernelManager. The FrontendWidget listens for these signals....
r2643 # FrontendWidget protected variables.
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 self._bracket_matcher = BracketMatcher(self._control)
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._call_tip_widget = CallTipWidget(self._control)
epatters
Initial checkin of Qt frontend code.
r2602 self._completion_lexer = CompletionLexer(PythonLexer())
epatters
* Added Cut support to ConsoleWidget....
r2990 self._copy_raw_action = QtGui.QAction('Copy (Raw Text)', None)
epatters
* The Qt console frontend now ignores cross chatter from other frontends....
r2824 self._hidden = False
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 self._highlighter = FrontendHighlighter(self)
Fernando Perez
Implement support for 'cell' mode with Ctrl-Enter....
r3004 self._input_splitter = self._input_splitter_class(input_mode='cell')
epatters
* Refactored KernelManager to use Traitlets and to have its channels as attributes...
r2611 self._kernel_manager = None
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 self._request_info = {}
epatters
Initial checkin of Qt frontend code.
r2602
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 # Configure the ConsoleWidget.
epatters
* ConsoleWidget now has better support for non-GUI tab completion. Multiple matches are formatted into columns....
r2723 self.tab_width = 4
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 self._set_continuation_prompt('... ')
epatters
Fixed font changes not being propagated to CallTipWidget.
r3031 # Configure the CallTipWidget.
self._call_tip_widget.setFont(self.font)
self.font_changed.connect(self._call_tip_widget.setFont)
epatters
* Added Cut support to ConsoleWidget....
r2990 # Configure actions.
action = self._copy_raw_action
key = QtCore.Qt.CTRL | QtCore.Qt.SHIFT | QtCore.Qt.Key_C
action.setEnabled(False)
action.setShortcut(QtGui.QKeySequence(key))
action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
action.triggered.connect(self.copy_raw)
self.copy_available.connect(action.setEnabled)
self.addAction(action)
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 # Connect signal handlers.
document = self._control.document()
document.contentsChange.connect(self._document_contents_change)
MinRK
tweaked close dialog and added prompts to prevent silent remote close
r3129
epatters
Refactored ConsoleWidget's HTML exportaton code + other minor code cleanup.
r3361 # Set flag for whether we are connected via localhost.
self._local_kernel = kw.get('local_kernel',
FrontendWidget._local_kernel)
epatters
* Adding object_info_request support to prototype kernel....
r2612
epatters
Minor comment cleanup.
r2669 #---------------------------------------------------------------------------
epatters
* Added "smart copy" support to FrontendWidget and ConsoleWidget. Tabs are expanded and prompts are stripped....
r2971 # 'ConsoleWidget' public interface
#---------------------------------------------------------------------------
def copy(self):
""" Copy the currently selected text to the clipboard, removing prompts.
"""
Evan Patterson
Paved the way for PySide support....
r3304 text = self._control.textCursor().selection().toPlainText()
epatters
* Added "smart copy" support to FrontendWidget and ConsoleWidget. Tabs are expanded and prompts are stripped....
r2971 if text:
lines = map(transform_classic_prompt, text.splitlines())
text = '\n'.join(lines)
epatters
Removed use of hard tabs in FrontendWidget and implemented "smart" backspace.
r3022 QtGui.QApplication.clipboard().setText(text)
epatters
* Added "smart copy" support to FrontendWidget and ConsoleWidget. Tabs are expanded and prompts are stripped....
r2971
#---------------------------------------------------------------------------
epatters
Initial checkin of Qt frontend code.
r2602 # 'ConsoleWidget' abstract interface
#---------------------------------------------------------------------------
epatters
* Refactored ConsoleWidget execution API for greater flexibility and clarity....
r2688 def _is_complete(self, source, interactive):
""" Returns whether 'source' can be completely processed and a new
prompt created. When triggered by an Enter/Return key press,
'interactive' is True; otherwise, it is False.
epatters
Initial checkin of Qt frontend code.
r2602 """
epatters
Removed use of hard tabs in FrontendWidget and implemented "smart" backspace.
r3022 complete = self._input_splitter.push(source)
epatters
* Refactored ConsoleWidget execution API for greater flexibility and clarity....
r2688 if interactive:
complete = not self._input_splitter.push_accepts_more()
return complete
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 def _execute(self, source, hidden):
epatters
* Refactored ConsoleWidget execution API for greater flexibility and clarity....
r2688 """ Execute 'source'. If 'hidden', do not show any output.
Fernando Perez
Rework messaging to better conform to our spec....
r2926
See parent class :meth:`execute` docstring for full details.
epatters
* Refactored ConsoleWidget execution API for greater flexibility and clarity....
r2688 """
MinRK
cleanup channel names to match function not socket...
r3974 msg_id = self.kernel_manager.shell_channel.execute(source, hidden)
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 self._request_info['execute'] = self._ExecutionRequest(msg_id, 'user')
epatters
* Refactored ConsoleWidget execution API for greater flexibility and clarity....
r2688 self._hidden = hidden
epatters
Add 'executing' signal to FrontendWidget for symmetry with 'executed' signal.
r3682 if not hidden:
self.executing.emit(source)
epatters
Initial checkin of Qt frontend code.
r2602
def _prompt_started_hook(self):
""" Called immediately after a new prompt is displayed.
"""
epatters
Fixed bug where syntax highlighting was enabled during raw_input mode.
r2709 if not self._reading:
self._highlighter.highlighting_on = True
epatters
Initial checkin of Qt frontend code.
r2602
def _prompt_finished_hook(self):
""" Called immediately after a prompt is finished, i.e. when some input
will be processed and a new prompt displayed.
"""
epatters
Refactored ConsoleWidget's HTML exportaton code + other minor code cleanup.
r3361 # Flush all state from the input splitter so the next round of
# reading input starts with a clean buffer.
self._input_splitter.reset()
epatters
Fixed bug where syntax highlighting was enabled during raw_input mode.
r2709 if not self._reading:
self._highlighter.highlighting_on = False
epatters
Initial checkin of Qt frontend code.
r2602
def _tab_pressed(self):
""" Called when the tab key is pressed. Returns whether to continue
processing the event.
"""
epatters
The FrontendWidget now performs tab-completion more aggressively.
r2847 # Perform tab completion if:
# 1) The cursor is in the input buffer.
# 2) There is a non-whitespace character before the cursor.
text = self._get_input_buffer_cursor_line()
if text is None:
return False
complete = bool(text[:self._get_input_buffer_cursor_column()].strip())
if complete:
self._complete()
return not complete
epatters
Initial checkin of Qt frontend code.
r2602
#---------------------------------------------------------------------------
epatters
Fixed bug with ConsoleWidget smart paste.
r2787 # 'ConsoleWidget' protected interface
#---------------------------------------------------------------------------
epatters
* Added Cut support to ConsoleWidget....
r2990 def _context_menu_make(self, pos):
""" Reimplemented to add an action for raw copy.
"""
menu = super(FrontendWidget, self)._context_menu_make(pos)
for before_action in menu.actions():
if before_action.shortcut().matches(QtGui.QKeySequence.Paste) == \
QtGui.QKeySequence.ExactMatch:
menu.insertAction(before_action, self._copy_raw_action)
break
return menu
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 def _event_filter_console_keypress(self, event):
epatters
Removed use of hard tabs in FrontendWidget and implemented "smart" backspace.
r3022 """ Reimplemented for execution interruption and smart backspace.
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 """
key = event.key()
epatters
Cmd-C will no longer interrupt the kernel in Mac OS (only Ctrl-C will do this).
r2941 if self._control_key_down(event.modifiers(), include_command=False):
epatters
Removed use of hard tabs in FrontendWidget and implemented "smart" backspace.
r3022
epatters
Numerous usability enhancements to the Qt console widget, particularly with regard to key bindings.
r2897 if key == QtCore.Qt.Key_C and self._executing:
epatters
* Improved frontend-side kernel restart support....
r2913 self.interrupt_kernel()
epatters
Fixed scrolling bugs when using rich text mode. (Work around probable bug in Qt.)
r2914 return True
epatters
Removed use of hard tabs in FrontendWidget and implemented "smart" backspace.
r3022
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 elif key == QtCore.Qt.Key_Period:
Brian Granger
Added heartbeat support.
r2910 message = 'Are you sure you want to restart the kernel?'
Fernando Perez
Rename 'instant_death' to 'now' as per code review.
r3030 self.restart_kernel(message, now=False)
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 return True
epatters
Removed use of hard tabs in FrontendWidget and implemented "smart" backspace.
r3022
elif not event.modifiers() & QtCore.Qt.AltModifier:
# Smart backspace: remove four characters in one backspace if:
# 1) everything left of the cursor is whitespace
# 2) the four characters immediately left of the cursor are spaces
if key == QtCore.Qt.Key_Backspace:
col = self._get_input_buffer_cursor_column()
cursor = self._control.textCursor()
if col > 3 and not cursor.hasSelection():
text = self._get_input_buffer_cursor_line()[:col]
if text.endswith(' ') and not text.strip():
cursor.movePosition(QtGui.QTextCursor.Left,
QtGui.QTextCursor.KeepAnchor, 4)
cursor.removeSelectedText()
return True
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 return super(FrontendWidget, self)._event_filter_console_keypress(event)
epatters
Fixed several bugs involving the insertion of new lines. Pressing Enter in the ConsoleWidget now works as expected.
r2896 def _insert_continuation_prompt(self, cursor):
epatters
Fixed bug with ConsoleWidget smart paste.
r2787 """ Reimplemented for auto-indentation.
"""
epatters
Fixed several bugs involving the insertion of new lines. Pressing Enter in the ConsoleWidget now works as expected.
r2896 super(FrontendWidget, self)._insert_continuation_prompt(cursor)
epatters
Removed use of hard tabs in FrontendWidget and implemented "smart" backspace.
r3022 cursor.insertText(' ' * self._input_splitter.indent_spaces)
epatters
Fixed bug with ConsoleWidget smart paste.
r2787
#---------------------------------------------------------------------------
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
epatters
Initial checkin of Qt frontend code.
r2602 #---------------------------------------------------------------------------
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 _handle_complete_reply(self, rep):
""" Handle replies for tab completion.
epatters
Initial checkin of Qt frontend code.
r2602 """
MinRK
add debug messages to qt handlers
r4793 self.log.debug("complete: %s", rep.get('content', ''))
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 cursor = self._get_cursor()
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 info = self._request_info.get('complete')
if info and info.id == rep['parent_header']['msg_id'] and \
info.pos == cursor.position():
epatters
Fixed regressions in the pure Python kernel.
r2867 text = '.'.join(self._get_context())
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 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
self._complete_with_items(cursor, rep['content']['matches'])
epatters
Initial checkin of Qt frontend code.
r2602
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 _handle_execute_reply(self, msg):
""" Handles replies for code execution.
epatters
Initial checkin of Qt kernel manager. Began refactor of FrontendWidget.
r2609 """
MinRK
add debug messages to qt handlers
r4793 self.log.debug("execute: %s", msg.get('content', ''))
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 info = self._request_info.get('execute')
if info and info.id == msg['parent_header']['msg_id'] and \
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 info.kind == 'user' and not self._hidden:
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 # Make sure that all output from the SUB channel has been processed
# before writing a new prompt.
self.kernel_manager.sub_channel.flush()
epatters
Fixed ANSI compliance issue in AnsiCodeProcessor....
r3000 # Reset the ANSI style information to prevent bad text in stdout
# from messing up our colors. We're not a true terminal so we're
# allowed to do this.
if self.ansi_codes:
self._ansi_processor.reset_sgr()
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 content = msg['content']
status = content['status']
if status == 'ok':
self._process_execute_ok(msg)
elif status == 'error':
self._process_execute_error(msg)
elif status == 'abort':
self._process_execute_abort(msg)
epatters
Updated IPythonWidget to use new prompt information. Initial prompt requests are not implemented.
r2797 self._show_interpreter_prompt_for_reply(msg)
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 self.executed.emit(msg)
def _handle_input_request(self, msg):
""" Handle requests for raw_input.
"""
MinRK
add debug messages to qt handlers
r4793 self.log.debug("input: %s", msg.get('content', ''))
epatters
Minor cleanup and bug fix.
r2771 if self._hidden:
raise RuntimeError('Request for raw input during hidden execution.')
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 # Make sure that all output from the SUB channel has been processed
# before entering readline mode.
self.kernel_manager.sub_channel.flush()
def callback(line):
MinRK
cleanup channel names to match function not socket...
r3974 self.kernel_manager.stdin_channel.input(line)
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 self._readline(msg['content']['prompt'], callback=callback)
epatters
Initial checkin of Qt kernel manager. Began refactor of FrontendWidget.
r2609
epatters
* Improved frontend-side kernel restart support....
r2913 def _handle_kernel_died(self, since_last_heartbeat):
""" Handle the kernel's death by asking if the user wants to restart.
"""
MinRK
add debug messages to qt handlers
r4793 self.log.debug("kernel died: %s", since_last_heartbeat)
epatters
* Improved frontend-side kernel restart support....
r2913 if self.custom_restart:
self.custom_restart_kernel_died.emit(since_last_heartbeat)
else:
epatters
Cleaned up frontend-level kernel restart logic.
r3033 message = 'The kernel heartbeat has been inactive for %.2f ' \
'seconds. Do you want to restart the kernel? You may ' \
'first want to check the network connection.' % \
since_last_heartbeat
Fernando Perez
Rename 'instant_death' to 'now' as per code review.
r3030 self.restart_kernel(message, now=True)
epatters
* Improved frontend-side kernel restart support....
r2913
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 _handle_object_info_reply(self, rep):
""" Handle replies for call tips.
epatters
Initial checkin of Qt kernel manager. Began refactor of FrontendWidget.
r2609 """
MinRK
add debug messages to qt handlers
r4793 self.log.debug("oinfo: %s", rep.get('content', ''))
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 cursor = self._get_cursor()
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 info = self._request_info.get('call_tip')
if info and info.id == rep['parent_header']['msg_id'] and \
info.pos == cursor.position():
Fernando Perez
Add function signature info to calltips....
r3051 # Get the information for a call tip. For now we format the call
# line as string, later we can pass False to format_call and
# syntax-highlight it ourselves for nicer formatting in the
# calltip.
MinRK
use dict.get(key) instead of dict[key] for pure kernel...
r3934 content = rep['content']
# if this is from pykernel, 'docstring' will be the only key
if content.get('ismagic', False):
David Warde-Farley
fix issue 337 with incorrect calltips being generated for magics
r3685 # Don't generate a call-tip for magics. Ideally, we should
# generate a tooltip, but not on ( like we do for actual
# callables.
call_info, doc = None, None
else:
MinRK
use dict.get(key) instead of dict[key] for pure kernel...
r3934 call_info, doc = call_tip(content, format_call=True)
Fernando Perez
Add function signature info to calltips....
r3051 if call_info or doc:
self._call_tip_widget.show_call_info(call_info, doc)
epatters
* Added 'started_listening' and 'stopped_listening' signals to QtKernelManager. The FrontendWidget listens for these signals....
r2643
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 _handle_pyout(self, msg):
""" Handle display hook output.
"""
MinRK
add debug messages to qt handlers
r4793 self.log.debug("pyout: %s", msg.get('content', ''))
epatters
* The Qt console frontend now ignores cross chatter from other frontends....
r2824 if not self._hidden and self._is_from_this_session(msg):
epatters
First cut at safe appending in the Qt console.
r4056 text = msg['content']['data']
self._append_plain_text(text + '\n', before_prompt=True)
epatters
Initial checkin of Qt kernel manager. Began refactor of FrontendWidget.
r2609
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 _handle_stream(self, msg):
""" Handle stdout, stderr, and stdin.
"""
MinRK
add debug messages to qt handlers
r4793 self.log.debug("stream: %s", msg.get('content', ''))
epatters
* The Qt console frontend now ignores cross chatter from other frontends....
r2824 if not self._hidden and self._is_from_this_session(msg):
Evan Patterson
FrontendWidget now treats tab characters in the std* streams like most consoles....
r2997 # Most consoles treat tabs as being 8 space characters. Convert tabs
# to spaces so that output looks as expected regardless of this
# widget's tab width.
text = msg['content']['data'].expandtabs(8)
epatters
First cut at safe appending in the Qt console.
r4056 self._append_plain_text(text, before_prompt=True)
epatters
* The Qt console frontend now ignores cross chatter from other frontends....
r2824 self._control.moveCursor(QtGui.QTextCursor.End)
Brian Granger
Implementing kernel status messages.
r3035
MinRK
added shutdown notification handling to ipythonqt
r3090 def _handle_shutdown_reply(self, msg):
""" Handle shutdown signal, only if from other console.
"""
MinRK
add debug messages to qt handlers
r4793 self.log.debug("shutdown: %s", msg.get('content', ''))
MinRK
added shutdown notification handling to ipythonqt
r3090 if not self._hidden and not self._is_from_this_session(msg):
MinRK
tweaked close dialog and added prompts to prevent silent remote close
r3129 if self._local_kernel:
if not msg['content']['restart']:
sys.exit(0)
else:
# we just got notified of a restart!
time.sleep(0.25) # wait 1/4 sec to reset
# lest the request for a new prompt
# goes to the old kernel
self.reset()
else: # remote kernel, prompt on Kernel shutdown/reset
title = self.window().windowTitle()
if not msg['content']['restart']:
reply = QtGui.QMessageBox.question(self, title,
epatters
Refactored ConsoleWidget's HTML exportaton code + other minor code cleanup.
r3361 "Kernel has been shutdown permanently. "
"Close the Console?",
MinRK
tweaked close dialog and added prompts to prevent silent remote close
r3129 QtGui.QMessageBox.Yes,QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
sys.exit(0)
else:
reply = QtGui.QMessageBox.question(self, title,
"Kernel has been reset. Clear the Console?",
QtGui.QMessageBox.Yes,QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
time.sleep(0.25) # wait 1/4 sec to reset
# lest the request for a new prompt
# goes to the old kernel
self.reset()
MinRK
added shutdown notification handling to ipythonqt
r3090
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 _started_channels(self):
""" Called when the KernelManager channels have started listening or
when the frontend is assigned an already listening KernelManager.
"""
epatters
Cleaned up frontend-level kernel restart logic.
r3033 self.reset()
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
#---------------------------------------------------------------------------
epatters
* Added "smart copy" support to FrontendWidget and ConsoleWidget. Tabs are expanded and prompts are stripped....
r2971 # 'FrontendWidget' public interface
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 #---------------------------------------------------------------------------
epatters
* Added Cut support to ConsoleWidget....
r2990 def copy_raw(self):
""" Copy the currently selected text to the clipboard without attempting
to remove prompts or otherwise alter the text.
"""
self._control.copy()
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 execute_file(self, path, hidden=False):
""" Attempts to execute file with 'path'. If 'hidden', no output is
shown.
"""
Evan Patterson
Fix Windows-specific bug in path handling for Qt console.
r3797 self.execute('execfile(%r)' % path, hidden=hidden)
epatters
Initial checkin of Qt kernel manager. Began refactor of FrontendWidget.
r2609
epatters
* Improved frontend-side kernel restart support....
r2913 def interrupt_kernel(self):
""" Attempts to interrupt the running kernel.
"""
if self.custom_interrupt:
self.custom_interrupt_requested.emit()
elif self.kernel_manager.has_kernel:
epatters
Implemented kernel interrupts for Windows.
r3027 self.kernel_manager.interrupt_kernel()
epatters
* Improved frontend-side kernel restart support....
r2913 else:
self._append_plain_text('Kernel process is either remote or '
'unspecified. Cannot interrupt.\n')
epatters
Cleaned up frontend-level kernel restart logic.
r3033 def reset(self):
""" Resets the widget to its initial state. Similar to ``clear``, but
also re-writes the banner and aborts execution if necessary.
"""
if self._executing:
self._executing = False
self._request_info['execute'] = None
self._reading = False
self._highlighter.highlighting_on = False
self._control.clear()
epatters
ENH: Allow FrontendWidget banner to be changed without subclassing.
r4689 self._append_plain_text(self.banner)
epatters
Cleaned up frontend-level kernel restart logic.
r3033 self._show_interpreter_prompt()
Fernando Perez
Rename 'instant_death' to 'now' as per code review.
r3030 def restart_kernel(self, message, now=False):
epatters
* Improved frontend-side kernel restart support....
r2913 """ Attempts to restart the running kernel.
"""
epatters
Cleaned up frontend-level kernel restart logic.
r3033 # FIXME: now should be configurable via a checkbox in the dialog. Right
# now at least the heartbeat path sets it to True and the manual restart
# to False. But those should just be the pre-selected states of a
# checkbox that the user could override if so desired. But I don't know
# enough Qt to go implementing the checkbox now.
if self.custom_restart:
self.custom_restart_requested.emit()
elif self.kernel_manager.has_kernel:
# Pause the heart beat channel to prevent further warnings.
self.kernel_manager.hb_channel.pause()
# Prompt the user to restart the kernel. Un-pause the heartbeat if
# they decline. (If they accept, the heartbeat will be un-paused
# automatically when the kernel is restarted.)
buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
result = QtGui.QMessageBox.question(self, 'Restart kernel?',
message, buttons)
if result == QtGui.QMessageBox.Yes:
try:
self.kernel_manager.restart_kernel(now=now)
except RuntimeError:
self._append_plain_text('Kernel started externally. '
'Cannot restart.\n')
else:
self.reset()
epatters
* Improved frontend-side kernel restart support....
r2913 else:
epatters
Cleaned up frontend-level kernel restart logic.
r3033 self.kernel_manager.hb_channel.unpause()
else:
self._append_plain_text('Kernel process is either remote or '
'unspecified. Cannot restart.\n')
epatters
* Improved frontend-side kernel restart support....
r2913
epatters
Initial checkin of Qt frontend code.
r2602 #---------------------------------------------------------------------------
# 'FrontendWidget' protected interface
#---------------------------------------------------------------------------
def _call_tip(self):
""" Shows a call tip, if appropriate, at the current cursor location.
"""
# Decide if it makes sense to show a call tip
MinRK
make calltips configurable in qtconsole...
r4569 if not self.enable_calltips:
return False
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 cursor = self._get_cursor()
epatters
Initial checkin of Qt frontend code.
r2602 cursor.movePosition(QtGui.QTextCursor.Left)
Evan Patterson
Paved the way for PySide support....
r3304 if cursor.document().characterAt(cursor.position()) != '(':
epatters
Initial checkin of Qt frontend code.
r2602 return False
context = self._get_context(cursor)
if not context:
return False
# Send the metadata request to the kernel
epatters
* Adding object_info_request support to prototype kernel....
r2612 name = '.'.join(context)
MinRK
cleanup channel names to match function not socket...
r3974 msg_id = self.kernel_manager.shell_channel.object_info(name)
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 pos = self._get_cursor().position()
self._request_info['call_tip'] = self._CallTipRequest(msg_id, pos)
epatters
Initial checkin of Qt frontend code.
r2602 return True
def _complete(self):
""" Performs completion at the current cursor location.
"""
epatters
Fixed regressions in the pure Python kernel.
r2867 context = self._get_context()
if context:
# Send the completion request to the kernel
MinRK
cleanup channel names to match function not socket...
r3974 msg_id = self.kernel_manager.shell_channel.complete(
epatters
Fixed regressions in the pure Python kernel.
r2867 '.'.join(context), # text
self._get_input_buffer_cursor_line(), # line
self._get_input_buffer_cursor_column(), # cursor_pos
self.input_buffer) # block
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 pos = self._get_cursor().position()
info = self._CompletionRequest(msg_id, pos)
self._request_info['complete'] = info
epatters
Initial checkin of Qt frontend code.
r2602
def _get_context(self, cursor=None):
epatters
* The ConsoleWidget now has full undo/redo support. Previously, the undo/redo history was cleared after every continuation prompt. This is no longer the case....
r2864 """ Gets the context for the specified cursor (or the current cursor
if none is specified).
epatters
Initial checkin of Qt frontend code.
r2602 """
if cursor is None:
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 cursor = self._get_cursor()
epatters
Numerous fixes to ConsoleWidget editing region maintenence code. It now impossible (or at least very difficult :) to break the input region.
r2764 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
epatters
Initial checkin of Qt frontend code.
r2602 QtGui.QTextCursor.KeepAnchor)
Evan Patterson
Paved the way for PySide support....
r3304 text = cursor.selection().toPlainText()
epatters
Initial checkin of Qt frontend code.
r2602 return self._completion_lexer.get_context(text)
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_abort(self, msg):
""" Process a reply for an aborted execution request.
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 """
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 self._append_plain_text("ERROR: execution aborted\n")
epatters
Initial checkin of Qt frontend code.
r2602
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):
""" Process a reply for an execution request that resulted in an error.
epatters
Progress on raw_input.
r2705 """
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 content = msg['content']
Erik Tollerud
qtconsole with pure python kernel now properly catches the SystemExit exception, allowing python exit() function to work correctly
r3187 # If a SystemExit is passed along, this means exit() was called - also
# all the ipython %exit magic syntax of '-k' to be used to keep
# the kernel running
if content['ename']=='SystemExit':
keepkernel = content['evalue']=='-k' or content['evalue']=='True'
self._keep_kernel_on_exit = keepkernel
self.exit_requested.emit()
else:
traceback = ''.join(content['traceback'])
self._append_plain_text(traceback)
epatters
Progress on raw_input.
r2705
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_ok(self, msg):
""" Process a reply for a successful execution equest.
epatters
Progress on raw_input.
r2705 """
epatters
* Refactored payload handling mechanism....
r2835 payload = msg['content']['payload']
for item in payload:
if not self._process_execute_payload(item):
epatters
* ConsoleWidget no longer stores contiguous identical lines...
r2969 warning = 'Warning: received unknown payload of type %s'
epatters
Form feeds are now properly supported by ConsoleWidget.
r3006 print(warning % repr(item['source']))
epatters
* Refactored payload handling mechanism....
r2835
def _process_execute_payload(self, item):
""" Process a single payload item from the list of payload items in an
execution reply. Returns whether the payload was handled.
"""
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 # The basic FrontendWidget doesn't handle payloads, as they are a
# mechanism for going beyond the standard Python interpreter model.
epatters
* Refactored payload handling mechanism....
r2835 return False
epatters
Progress on raw_input.
r2705
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 _show_interpreter_prompt(self):
""" Shows a prompt for the interpreter.
"""
self._show_prompt('>>> ')
epatters
Updated IPythonWidget to use new prompt information. Initial prompt requests are not implemented.
r2797 def _show_interpreter_prompt_for_reply(self, msg):
""" Shows a prompt for the interpreter given an 'execute_reply' message.
"""
self._show_interpreter_prompt()
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 #------ Signal handlers ----------------------------------------------------
epatters
Initial checkin of Qt frontend code.
r2602 def _document_contents_change(self, position, removed, added):
epatters
* CallTipWidget and CompletionWidget no longer need to be fed key presses. This means that can be attached to any Q[Plain]TextEdit with zero hassle....
r2744 """ Called whenever the document's content changes. Display a call tip
epatters
Initial checkin of Qt frontend code.
r2602 if appropriate.
"""
# Calculate where the cursor should be *after* the change:
position += added
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 document = self._control.document()
if position == self._get_cursor().position():
epatters
Initial checkin of Qt frontend code.
r2602 self._call_tip()
epatters
ENH: Allow FrontendWidget banner to be changed without subclassing.
r4689
#------ Trait default initializers -----------------------------------------
def _banner_default(self):
""" Returns the standard Python banner.
"""
banner = 'Python %s on %s\nType "help", "copyright", "credits" or ' \
'"license" for more information.'
return banner % (sys.version, sys.platform)