debug console: refactoring
This commit is contained in:
parent
2280250c16
commit
8017dae75d
@ -40,33 +40,24 @@ class ConsoleLineEdit(misc.CommandLineEdit):
|
|||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
_history: The command history of executed commands.
|
_history: The command history of executed commands.
|
||||||
_more: A flag which is set when more input is expected.
|
|
||||||
_buffer: The buffer for multiline commands.
|
|
||||||
_interpreter: The InteractiveInterpreter to execute code with.
|
|
||||||
_rlcompleter: The rlcompleter.Completer instance.
|
_rlcompleter: The rlcompleter.Completer instance.
|
||||||
_qcompleter: The QCompleter instance.
|
_qcompleter: The QCompleter instance.
|
||||||
|
|
||||||
|
Signals:
|
||||||
|
execute: Emitted when a commandline should be executed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
write = pyqtSignal(str)
|
execute = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, namespace, parent):
|
||||||
if not hasattr(sys, 'ps1'):
|
"""Constructor.
|
||||||
sys.ps1 = '>>> '
|
|
||||||
if not hasattr(sys, 'ps2'):
|
Args:
|
||||||
sys.ps2 = '... '
|
namespace: The local namespace of the interpreter.
|
||||||
|
"""
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.update_font()
|
self.update_font()
|
||||||
config.on_change(self.update_font, 'fonts', 'debug-console')
|
config.on_change(self.update_font, 'fonts', 'debug-console')
|
||||||
self._more = False
|
|
||||||
self._buffer = []
|
|
||||||
namespace = {
|
|
||||||
'__name__': '__console__',
|
|
||||||
'__doc__': None,
|
|
||||||
'qApp': QApplication.instance(),
|
|
||||||
# We use parent as self here because the user "feels" the whole
|
|
||||||
# console, not just the line edit.
|
|
||||||
'self': parent,
|
|
||||||
}
|
|
||||||
self.textChanged.connect(self.on_text_changed)
|
self.textChanged.connect(self.on_text_changed)
|
||||||
|
|
||||||
self._rlcompleter = rlcompleter.Completer(namespace)
|
self._rlcompleter = rlcompleter.Completer(namespace)
|
||||||
@ -77,17 +68,8 @@ class ConsoleLineEdit(misc.CommandLineEdit):
|
|||||||
QCompleter.UnfilteredPopupCompletion)
|
QCompleter.UnfilteredPopupCompletion)
|
||||||
self.setCompleter(qcompleter)
|
self.setCompleter(qcompleter)
|
||||||
|
|
||||||
self._interpreter = code.InteractiveInterpreter(namespace)
|
|
||||||
self._history = cmdhistory.History()
|
self._history = cmdhistory.History()
|
||||||
self.returnPressed.connect(self.execute)
|
self.returnPressed.connect(self.on_return_pressed)
|
||||||
|
|
||||||
def write_prompt(self):
|
|
||||||
"""Emit the write signal with the current prompt."""
|
|
||||||
self.write.emit(self._curprompt())
|
|
||||||
|
|
||||||
def _curprompt(self):
|
|
||||||
"""Get the prompt which is visible currently."""
|
|
||||||
return sys.ps2 if self._more else sys.ps1
|
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def on_text_changed(self, text):
|
def on_text_changed(self, text):
|
||||||
@ -103,33 +85,15 @@ class ConsoleLineEdit(misc.CommandLineEdit):
|
|||||||
self._model.setStringList(strings)
|
self._model.setStringList(strings)
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def execute(self):
|
def on_return_pressed(self):
|
||||||
"""Execute the line of code which was entered."""
|
"""Execute the line of code which was entered."""
|
||||||
self._history.stop()
|
self._history.stop()
|
||||||
text = self.text()
|
text = self.text()
|
||||||
if text:
|
if text:
|
||||||
self._history.append(text)
|
self._history.append(text)
|
||||||
self.push(text)
|
self.execute.emit(text)
|
||||||
self.setText('')
|
self.setText('')
|
||||||
|
|
||||||
def push(self, line):
|
|
||||||
"""Push a line to the interpreter."""
|
|
||||||
self._buffer.append(line)
|
|
||||||
source = '\n'.join(self._buffer)
|
|
||||||
self.write.emit(line + '\n')
|
|
||||||
# We do two special things with the contextmanagers here:
|
|
||||||
# - We replace stdout/stderr to capture output. Even if we could
|
|
||||||
# override InteractiveInterpreter's write method, most things are
|
|
||||||
# printed elsewhere (e.g. by exec). Other Python GUI shells do the
|
|
||||||
# same.
|
|
||||||
# - We disable our exception hook, so exceptions from the console get
|
|
||||||
# printed and don't ooen a crashdialog.
|
|
||||||
with utils.fake_io(self.write.emit), utils.disabled_excepthook():
|
|
||||||
self._more = self._interpreter.runsource(source, '<console>')
|
|
||||||
self.write_prompt()
|
|
||||||
if not self._more:
|
|
||||||
self._buffer = []
|
|
||||||
|
|
||||||
def history_prev(self):
|
def history_prev(self):
|
||||||
"""Go back in the history."""
|
"""Go back in the history."""
|
||||||
try:
|
try:
|
||||||
@ -210,20 +174,65 @@ class ConsoleWidget(QWidget):
|
|||||||
_lineedit: The line edit in the console.
|
_lineedit: The line edit in the console.
|
||||||
_output: The output widget in the console.
|
_output: The output widget in the console.
|
||||||
_vbox: The layout which contains everything.
|
_vbox: The layout which contains everything.
|
||||||
|
_more: A flag which is set when more input is expected.
|
||||||
|
_buffer: The buffer for multiline commands.
|
||||||
|
_interpreter: The InteractiveInterpreter to execute code with.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self._lineedit = ConsoleLineEdit(self)
|
if not hasattr(sys, 'ps1'):
|
||||||
|
sys.ps1 = '>>> '
|
||||||
|
if not hasattr(sys, 'ps2'):
|
||||||
|
sys.ps2 = '... '
|
||||||
|
namespace = {
|
||||||
|
'__name__': '__console__',
|
||||||
|
'__doc__': None,
|
||||||
|
'qApp': QApplication.instance(),
|
||||||
|
# We use parent as self here because the user "feels" the whole
|
||||||
|
# console, not just the line edit.
|
||||||
|
'self': parent,
|
||||||
|
}
|
||||||
|
self._more = False
|
||||||
|
self._buffer = []
|
||||||
|
self._lineedit = ConsoleLineEdit(namespace, self)
|
||||||
|
self._lineedit.execute.connect(self.push)
|
||||||
self._output = ConsoleTextEdit()
|
self._output = ConsoleTextEdit()
|
||||||
self._lineedit.write.connect(self._output.append_text)
|
self.write(self._curprompt())
|
||||||
self._lineedit.write_prompt()
|
|
||||||
self._vbox = QVBoxLayout()
|
self._vbox = QVBoxLayout()
|
||||||
self._vbox.setSpacing(0)
|
self._vbox.setSpacing(0)
|
||||||
self._vbox.addWidget(self._output)
|
self._vbox.addWidget(self._output)
|
||||||
self._vbox.addWidget(self._lineedit)
|
self._vbox.addWidget(self._lineedit)
|
||||||
self.setLayout(self._vbox)
|
self.setLayout(self._vbox)
|
||||||
self._lineedit.setFocus()
|
self._lineedit.setFocus()
|
||||||
|
self._interpreter = code.InteractiveInterpreter(namespace)
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return utils.get_repr(self, visible=self.isVisible())
|
return utils.get_repr(self, visible=self.isVisible())
|
||||||
|
|
||||||
|
def write(self, line):
|
||||||
|
self._output.append_text(line)
|
||||||
|
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def push(self, line):
|
||||||
|
"""Push a line to the interpreter."""
|
||||||
|
self._buffer.append(line)
|
||||||
|
source = '\n'.join(self._buffer)
|
||||||
|
self.write(line + '\n')
|
||||||
|
# We do two special things with the contextmanagers here:
|
||||||
|
# - We replace stdout/stderr to capture output. Even if we could
|
||||||
|
# override InteractiveInterpreter's write method, most things are
|
||||||
|
# printed elsewhere (e.g. by exec). Other Python GUI shells do the
|
||||||
|
# same.
|
||||||
|
# - We disable our exception hook, so exceptions from the console get
|
||||||
|
# printed and don't ooen a crashdialog.
|
||||||
|
with utils.fake_io(self.write), utils.disabled_excepthook():
|
||||||
|
self._more = self._interpreter.runsource(source, '<console>')
|
||||||
|
self.write(self._curprompt())
|
||||||
|
if not self._more:
|
||||||
|
self._buffer = []
|
||||||
|
|
||||||
|
def _curprompt(self):
|
||||||
|
"""Get the prompt which is visible currently."""
|
||||||
|
return sys.ps2 if self._more else sys.ps1
|
||||||
|
Loading…
Reference in New Issue
Block a user