Skip to content

Commit

Permalink
Restore cmdline text input when browsing history
Browse files Browse the repository at this point in the history
Text input to the internal command line is now restored and not lost
after browsing the history. It is designed to behave just like a
dedicated history item at the end of the history. This matches the
behavior of readline in most shells.
For example, writing a command without executing it, then moving up to
the most recent history item and down again restores the typed command.

The pudb special behavior of clearing the command when moving down from
the end of the history is also preserved. In that case the text can be
restored too by moving up in the history again before typing anything
new.
This is akin to using Ctrl-C in common shells to clear the current
command, but with the ability to restore the input again.

Using the clear button which empties the displayed shell history now
also clears the command input, since it can be easily restored.

This fixes one of my pain points with the internal pudb command line:
When writing a lengthy command, accidentally hitting Ctrl-N or Ctrl-P
overwrites the input text field with no possibility to get the content
back.
This is particularly bad after using vim's word completion with Ctrl-N
for an extensive amount of time, and then accidentally hitting the same
shortcut in pudb instead of tab completion.
  • Loading branch information
raphCode committed Apr 25, 2023
1 parent be01f05 commit 6c4eeeb
Showing 1 changed file with 39 additions and 11 deletions.
50 changes: 39 additions & 11 deletions pudb/debugger.py
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,10 @@ def add_help_keys(widget, helpfunc):

def clear_cmdline_history(btn):
del self.cmdline_contents[:]
# clear the command input text too,
# but save it to be retrieved on cmdline_history_prev()
self.cmdline_history_position = -1
cmdline_history_browse(1)

def initialize_cmdline_history(path):
dq = partial(deque, maxlen=5000)
Expand All @@ -863,6 +867,7 @@ def initialize_cmdline_history(path):
"internal-cmdline-history.txt")

self.cmdline_history = initialize_cmdline_history(self.cmdline_history_path)
self.cmdline_saved_edit_text = ""
self.cmdline_history_position = -1

self.cmdline_edit_bar = urwid.Columns([
Expand Down Expand Up @@ -1882,17 +1887,40 @@ def cmdline_exec(w, size, key):
sys.stderr = prev_sys_stderr

def cmdline_history_browse(direction):
if self.cmdline_history_position == -1:
self.cmdline_history_position = len(self.cmdline_history)

self.cmdline_history_position += direction

if 0 <= self.cmdline_history_position < len(self.cmdline_history):
self.cmdline_edit.edit_text = \
self.cmdline_history[self.cmdline_history_position]
else:
self.cmdline_history_position = -1
self.cmdline_edit.edit_text = ""
# Browsing the command line history can be illustrated by moving up/down
# in the following table (no wrap-around).
# The first column shows what is written in the command input text field,
# the second one the corresponding value of self.cmdline_history_position
# The actual index into the history list is given by the last column.
# | history | history
# command line text | position | list index
# ----------------------------|----------|-----------
# oldest_command | 2 | 0
# medium_command | 1 | 1
# recent_command | 0 | 2
# <current / saved edit text> | -1 |
# <edit text cleared> | -1 |
def pos_text(pos, text):
if pos == -1:
if text:
# currently editing a command, save it to return to it later
self.cmdline_saved_edit_text = text
if direction > 0:
# clear command to be able to write a different one
return -1, ""
if direction < 0 and not text and self.cmdline_saved_edit_text:
# return to last saved command
return -1, self.cmdline_saved_edit_text

max_hist_index = len(self.cmdline_history) - 1
pos = max(-1, min(pos - direction, max_hist_index))

if pos == -1:
return -1, self.cmdline_saved_edit_text
return pos, self.cmdline_history[max_hist_index - pos]

self.cmdline_history_position, self.cmdline_edit.edit_text = pos_text(
self.cmdline_history_position, self.cmdline_edit.edit_text)
self.cmdline_edit.edit_pos = len(self.cmdline_edit.edit_text)

def cmdline_history_prev(w, size, key):
Expand Down

0 comments on commit 6c4eeeb

Please sign in to comment.