[python console] Match key up / down behavior to that of bash and

allow for a 'soft' history to be editable

This commit reverts the recent behavior change of a key up / down
press event which meant to prevent accidental loss of content of
a command being edited when pressing the up key on the second line
of a reflowed text.

This new approach has the python console input line behave like
bash, whereas a key up / down will always move to the next /
previous history item wherever the cursor is located. However until
the user hits enter, any edits to historical items or the new
line will be remembered.

This insures that an accidental move back in history doesn't
lead to unwanted code loss.
This commit is contained in:
Mathieu Pellerin 2020-07-11 20:23:31 +07:00
parent f90497db2d
commit ebd4cd8c13

View File

@ -104,7 +104,8 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
self.runsource(line)
self.history = []
self.historyIndex = 0
self.softHistory = []
self.softHistoryIndex = 0
# Read history command file
self.readHistoryFile()
@ -342,7 +343,15 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
def displayPrompt(self, more=False):
self.SendScintilla(QsciScintilla.SCI_MARGINSETTEXT, 0, str.encode("..." if more else ">>>"))
def updateHistory(self, command):
def syncSoftHistory(self):
self.softHistory = self.history[:]
self.softHistory.append('')
self.softHistoryIndex = len(self.softHistory) - 1
def updateSoftHistory(self):
self.softHistory[self.softHistoryIndex] = self.text()
def updateHistory(self, command, skipSoftHistory=False):
if isinstance(command, list):
for line in command:
self.history.append(line)
@ -350,7 +359,8 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
if len(self.history) <= 0 or \
command != self.history[-1]:
self.history.append(command)
self.historyIndex = len(self.history)
if not skipSoftHistory:
self.syncSoftHistory()
def writeHistoryFile(self, fromCloseConsole=False):
ok = False
@ -374,13 +384,15 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
for line in rH:
if line != "\n":
l = line.rstrip('\n')
self.updateHistory(l)
self.updateHistory(l, True)
self.syncSoftHistory()
else:
return
def clearHistory(self, clearSession=False):
if clearSession:
self.history = []
self.syncSoftHistory()
msgText = QCoreApplication.translate('PythonConsole',
'Session and file history cleared successfully.')
self.parent.callWidgetMessageBar(msgText)
@ -401,27 +413,23 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
self.clearHistory(True)
def showPrevious(self):
if self.historyIndex < len(self.history) and self.history:
self.historyIndex += 1
if self.historyIndex == len(self.history):
self.setText("")
pass
else:
self.setText(self.history[self.historyIndex])
if self.softHistoryIndex < len(self.softHistory) - 1 and self.softHistory:
self.softHistoryIndex += 1
self.setText(self.softHistory[self.softHistoryIndex])
self.move_cursor_to_end()
# self.SendScintilla(QsciScintilla.SCI_DELETEBACK)
def showNext(self):
if self.historyIndex > 0 and self.history:
self.historyIndex -= 1
if self.historyIndex == len(self.history):
self.setText("")
else:
self.setText(self.history[self.historyIndex])
self.move_cursor_to_start()
if self.softHistoryIndex > 0 and self.softHistory:
self.softHistoryIndex -= 1
self.setText(self.softHistory[self.softHistoryIndex])
self.move_cursor_to_end()
# self.SendScintilla(QsciScintilla.SCI_DELETEBACK)
def keyPressEvent(self, e):
# update the live history
self.updateSoftHistory()
startLine, startPos, endLine, endPos = self.getSelection()
# handle invalid cursor position and multiline selections
@ -472,16 +480,11 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
e.accept()
elif e.key() == Qt.Key_Down and not self.isListActive():
if self.is_cursor_at_end():
self.showPrevious()
else:
QsciScintilla.keyPressEvent(self, e)
self.showPrevious()
elif e.key() == Qt.Key_Up and not self.isListActive():
if self.is_cursor_at_start():
self.showNext()
else:
QsciScintilla.keyPressEvent(self, e)
self.showNext()
# TODO: press event for auto-completion file directory
else:
t = e.text()