diff --git a/examples/ptpython_config/config.py b/examples/ptpython_config/config.py index aa0bb635..1a009018 100644 --- a/examples/ptpython_config/config.py +++ b/examples/ptpython_config/config.py @@ -119,6 +119,12 @@ def configure(repl): # Syntax. repl.enable_syntax_highlighting = True + # Get into Vi navigation mode at startup + repl.vi_start_in_navigation_mode = False + + # Preserve last used Vi input mode between main loop iterations + repl.vi_keep_last_used_mode = False + # Install custom colorscheme named 'my-colorscheme' and use it. """ repl.install_ui_colorscheme('my-colorscheme', Style.from_dict(_custom_ui_colorscheme)) diff --git a/ptpython/python_input.py b/ptpython/python_input.py index e41b921f..18b9ef69 100644 --- a/ptpython/python_input.py +++ b/ptpython/python_input.py @@ -300,6 +300,12 @@ def __init__( # (Never run more than one at the same time.) self._get_signatures_thread_running: bool = False + # Get into Vi navigation mode at startup + self.vi_start_in_navigation_mode: bool = False + + # Preserve last used Vi input mode between main loop iterations + self.vi_keep_last_used_mode: bool = False + self.style_transformation = merge_style_transformations( [ ConditionalStyleTransformation( diff --git a/ptpython/repl.py b/ptpython/repl.py index cbfb33b5..ba95a3d5 100644 --- a/ptpython/repl.py +++ b/ptpython/repl.py @@ -23,6 +23,8 @@ merge_formatted_text, to_formatted_text, ) +from prompt_toolkit.formatted_text.utils import fragment_list_width +from prompt_toolkit.key_binding.vi_state import InputMode from prompt_toolkit.patch_stdout import patch_stdout as patch_stdout_context from prompt_toolkit.shortcuts import clear_title, print_formatted_text, set_title from prompt_toolkit.utils import DummyContext @@ -79,9 +81,21 @@ async def run_async(self) -> None: set_title(self.terminal_title) while True: + # Capture the current input_mode in order to restore it after reset, + # for ViState.reset() sets it to InputMode.INSERT unconditionally and + # doesn't accept any arguments. + def pre_run( + last_input_mode: InputMode = self.app.vi_state.input_mode, + ) -> None: + if self.vi_keep_last_used_mode: + self.app.vi_state.input_mode = last_input_mode + + if not self.vi_keep_last_used_mode and self.vi_start_in_navigation_mode: + self.app.vi_state.input_mode = InputMode.NAVIGATION + # Run the UI. try: - text = await self.app.run_async() + text = await self.app.run_async(pre_run=pre_run) except EOFError: return except KeyboardInterrupt: