Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions prompt_toolkit/buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ class Buffer:
:param multiline: :class:`~prompt_toolkit.filters.Filter` or `bool`. When
not set, pressing `Enter` will call the `accept_handler`. Otherwise,
pressing `Esc-Enter` is required.
:param enable_undo_redo: :class:`~prompt_toolkit.filters.Filter` or `bool`.
When False, undo and redo stacks will never get populated.
"""

def __init__(
Expand All @@ -245,6 +247,7 @@ def __init__(
accept_handler: Optional[BufferAcceptHandler] = None,
read_only: FilterOrBool = False,
multiline: FilterOrBool = True,
enable_undo_redo: FilterOrBool = True,
on_text_changed: Optional[BufferEventHandler] = None,
on_text_insert: Optional[BufferEventHandler] = None,
on_cursor_position_changed: Optional[BufferEventHandler] = None,
Expand Down Expand Up @@ -273,6 +276,7 @@ def __init__(
self.enable_history_search = enable_history_search
self.read_only = read_only
self.multiline = multiline
self.enable_undo_redo = enable_undo_redo

# Text width. (For wrapping, used by the Vi 'gq' operator.)
self.text_width = 0
Expand Down Expand Up @@ -639,12 +643,14 @@ def save_to_undo_stack(self, clear_redo_stack: bool = True) -> None:
Safe current state (input text and cursor position), so that we can
restore it by calling undo.
"""
# Safe if the text is different from the text at the top of the stack
# is different. If the text is the same, just update the cursor position.
if self._undo_stack and self._undo_stack[-1][0] == self.text:
self._undo_stack[-1] = (self._undo_stack[-1][0], self.cursor_position)
else:
self._undo_stack.append((self.text, self.cursor_position))

if self.enable_undo_redo:
# Safe if the text is different from the text at the top of the stack
# is different. If the text is the same, just update the cursor position.
if self._undo_stack and self._undo_stack[-1][0] == self.text:
self._undo_stack[-1] = (self._undo_stack[-1][0], self.cursor_position)
else:
self._undo_stack.append((self.text, self.cursor_position))

# Saving anything to the undo stack, clears the redo stack.
if clear_redo_stack:
Expand Down Expand Up @@ -1280,7 +1286,7 @@ def undo(self) -> None:
# the current text. (The current logic of `save_to_undo_stack` will
# cause that the top of the undo stack is usually the same as the
# current text, so in that case we have to pop twice.)
while self._undo_stack:
while self._undo_stack and self.enable_undo_redo:
text, pos = self._undo_stack.pop()

if text != self.text:
Expand All @@ -1292,7 +1298,7 @@ def undo(self) -> None:
break

def redo(self) -> None:
if self._redo_stack:
if self._redo_stack and self.enable_undo_redo:
# Copy current state on undo stack.
self.save_to_undo_stack(clear_redo_stack=False)

Expand Down
6 changes: 6 additions & 0 deletions prompt_toolkit/shortcuts/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,8 @@ class PromptSession(Generic[_T]):
:param input: `Input` object. (Note that the preferred way to change the
input/output is by creating an `AppSession`.)
:param output: `Output` object.
:param enable_undo_redo: :class:`~prompt_toolkit.filters.Filter` or `bool`.
When False, undo and redo stacks will never get populated.
"""

_fields = (
Expand Down Expand Up @@ -365,6 +367,7 @@ class PromptSession(Generic[_T]):
"reserve_space_for_menu",
"tempfile_suffix",
"tempfile",
"enable_undo_redo",
)

def __init__(
Expand Down Expand Up @@ -410,6 +413,7 @@ def __init__(
refresh_interval: float = 0,
input: Optional[Input] = None,
output: Optional[Output] = None,
enable_undo_redo: FilterOrBool = True,
) -> None:

history = history or InMemoryHistory()
Expand Down Expand Up @@ -459,6 +463,7 @@ def __init__(
self.reserve_space_for_menu = reserve_space_for_menu
self.tempfile_suffix = tempfile_suffix
self.tempfile = tempfile
self.enable_undo_redo = enable_undo_redo

# Create buffers, layout and Application.
self.history = history
Expand Down Expand Up @@ -520,6 +525,7 @@ def accept(buff: Buffer) -> bool:
accept_handler=accept,
tempfile_suffix=lambda: to_str(self.tempfile_suffix or ""),
tempfile=lambda: to_str(self.tempfile or ""),
enable_undo_redo=self.enable_undo_redo,
)

def _create_search_buffer(self) -> Buffer:
Expand Down