From 8cf908a0d57b85974d3c3415c594d88efbab8fbb Mon Sep 17 00:00:00 2001 From: Anton Alekseev Date: Wed, 5 Feb 2020 01:31:30 +0300 Subject: [PATCH] Add config options related to Vi input mode Setting `vi_start_in_nav_mode` to `True` enables `NAVIGATION` mode on startup. The issue is that due to the current behaviour of `ViState.reset()` input mode gets resetted back to `INSERT` on the every iteration of the main loop. In order to at one hand to provide the user with desired behaviour and on the other hand doesn't introduce breaking changes the other option `vi_keep_last_used_mode` was introduced which sets `input_mode` to the state observed before reset. `vi_keep_last_used_mode` can be useful even with `vi_start_in_nav_mode` set to `False` in the case the user prefer to start in `INSERT` mode but still wants to maintain the last mode he was in. In the case of `vi_keep_last_used_mode` set to `False` and `vi_start_in_nav_mode` to `True` `NAVIGATION` mode is set on every iteration the same way `INSERT` was set before this commit. Fixes #258. --- examples/ptpython_config/config.py | 6 ++++++ ptpython/python_input.py | 9 +++++++++ ptpython/repl.py | 13 ++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/examples/ptpython_config/config.py b/examples/ptpython_config/config.py index ff8b8ac1..371421fe 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_nav_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', _custom_ui_colorscheme) diff --git a/ptpython/python_input.py b/ptpython/python_input.py index c4bbbd0c..2f66e804 100644 --- a/ptpython/python_input.py +++ b/ptpython/python_input.py @@ -298,6 +298,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_nav_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( @@ -327,6 +333,9 @@ def __init__( if vi_mode: self.app.editing_mode = EditingMode.VI + if vi_mode and self.vi_start_in_nav_mode: + self.app.vi_state.input_mode = InputMode.NAVIGATION + def _accept_handler(self, buff: Buffer) -> bool: app = get_app() app.exit(result=buff.text) diff --git a/ptpython/repl.py b/ptpython/repl.py index 4b8edf2a..473dd683 100644 --- a/ptpython/repl.py +++ b/ptpython/repl.py @@ -22,6 +22,7 @@ merge_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 @@ -70,9 +71,19 @@ def prompt() -> str: # This happens when the user used `asyncio.run()`. old_loop = None + # 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 despite the docstring says otherwise. + def pre_run(last_input_mode=self.app.vi_state.input_mode): + 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_nav_mode: + self.app.vi_state.input_mode = InputMode.NAVIGATION + asyncio.set_event_loop(self.pt_loop) try: - return self.app.run() # inputhook=inputhook) + return self.app.run(pre_run) # inputhook=inputhook) finally: # Restore the original event loop. asyncio.set_event_loop(old_loop)