From ab95c7cb5cbc2f3f52a70207abb0759b393e90c7 Mon Sep 17 00:00:00 2001 From: dagal Date: Wed, 14 Jul 2021 12:48:24 -0400 Subject: [PATCH 1/2] Possibility of disabling undo and redo stacks for Buffer. PromptSession was also accordingly modified in order to pass the parameter to the internal buffer it creates. --- prompt_toolkit/buffer.py | 22 ++++++++++++++-------- prompt_toolkit/shortcuts/prompt.py | 6 ++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/prompt_toolkit/buffer.py b/prompt_toolkit/buffer.py index ada644386..5327bbe44 100644 --- a/prompt_toolkit/buffer.py +++ b/prompt_toolkit/buffer.py @@ -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__( @@ -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, @@ -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 @@ -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: @@ -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: @@ -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) diff --git a/prompt_toolkit/shortcuts/prompt.py b/prompt_toolkit/shortcuts/prompt.py index 59851743f..9577747be 100644 --- a/prompt_toolkit/shortcuts/prompt.py +++ b/prompt_toolkit/shortcuts/prompt.py @@ -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 = ( @@ -365,6 +367,7 @@ class PromptSession(Generic[_T]): "reserve_space_for_menu", "tempfile_suffix", "tempfile", + "enable_undo_redo", ) def __init__( @@ -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() @@ -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 @@ -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: From aad38e4cdb08241560d34da418c5504f20f8879b Mon Sep 17 00:00:00 2001 From: dagal Date: Sat, 11 Sep 2021 15:45:57 -0400 Subject: [PATCH 2/2] Fix formatting issues with flake8 and black --- prompt_toolkit/buffer.py | 4 ++-- prompt_toolkit/shortcuts/prompt.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/prompt_toolkit/buffer.py b/prompt_toolkit/buffer.py index 5327bbe44..aea3ec9d6 100644 --- a/prompt_toolkit/buffer.py +++ b/prompt_toolkit/buffer.py @@ -227,7 +227,7 @@ 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`. + :param enable_undo_redo: :class:`~prompt_toolkit.filters.Filter` or `bool`. When False, undo and redo stacks will never get populated. """ @@ -643,7 +643,7 @@ 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. """ - + 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. diff --git a/prompt_toolkit/shortcuts/prompt.py b/prompt_toolkit/shortcuts/prompt.py index 9577747be..ba28b9268 100644 --- a/prompt_toolkit/shortcuts/prompt.py +++ b/prompt_toolkit/shortcuts/prompt.py @@ -326,7 +326,7 @@ 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`. + :param enable_undo_redo: :class:`~prompt_toolkit.filters.Filter` or `bool`. When False, undo and redo stacks will never get populated. """ @@ -525,7 +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 + enable_undo_redo=self.enable_undo_redo, ) def _create_search_buffer(self) -> Buffer: