From c5b6cbc9bbaa6cd57e35d0f6584c22dc4e5563c3 2020-10-13 17:37:36 From: Martin Skarzynski Date: 2020-10-13 17:37:36 Subject: [PATCH] cursor shape changes with vi editing mode --- diff --git a/IPython/terminal/interactiveshell.py b/IPython/terminal/interactiveshell.py index 0ed9e83..c4be945 100644 --- a/IPython/terminal/interactiveshell.py +++ b/IPython/terminal/interactiveshell.py @@ -12,8 +12,19 @@ from IPython.utils.py3compat import input from IPython.utils.terminal import toggle_set_term_title, set_term_title, restore_term_title from IPython.utils.process import abbrev_cwd from traitlets import ( - Bool, Unicode, Dict, Integer, observe, Instance, Type, default, Enum, Union, - Any, validate + Bool, + Unicode, + Dict, + Integer, + observe, + Instance, + Type, + default, + Enum, + Union, + Any, + validate, + Float, ) from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode @@ -142,6 +153,25 @@ class TerminalInteractiveShell(InteractiveShell): help="Add shortcuts from 'emacs' insert mode to 'vi' insert mode.", ).tag(config=True) + modal_cursor = Bool( + True, + help=""" + Cursor shape changes depending on vi mode: beam in vi insert mode, + block in nav mode, underscore in replace mode.""", + ).tag(config=True) + + ttimeoutlen = Float( + 0.01, + help="""The time in milliseconds that is waited for a key code + to complete.""", + ).tag(config=True) + + timeoutlen = Float( + 0.5, + help="""The time in milliseconds that is waited for a mapped key + sequence to complete.""", + ).tag(config=True) + autoformatter = Unicode(None, help="Autoformatter to reformat Terminal code. Can be `'black'` or `None`", allow_none=True diff --git a/IPython/terminal/shortcuts.py b/IPython/terminal/shortcuts.py index ed35b2a..f92babd 100644 --- a/IPython/terminal/shortcuts.py +++ b/IPython/terminal/shortcuts.py @@ -19,6 +19,7 @@ from prompt_toolkit.filters import (has_focus, has_selection, Condition, from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline from prompt_toolkit.key_binding import KeyBindings from prompt_toolkit.key_binding.bindings import named_commands as nc +from prompt_toolkit.key_binding.vi_state import InputMode, ViState from IPython.utils.decorators import undoc @@ -160,6 +161,32 @@ def create_ipython_shortcuts(shell): for keys, cmd in keys_cmd_dict.items(): kb.add(*keys, filter=focused_insert & ebivim)(cmd) + def get_input_mode(self): + if sys.version_info[0] == 3: + app = get_app() + app.ttimeoutlen = shell.ttimeoutlen + app.timeoutlen = shell.timeoutlen + + return self._input_mode + + def set_input_mode(self, mode): + shape = {InputMode.NAVIGATION: 2, InputMode.REPLACE: 4}.get(mode, 6) + cursor = "\x1b[{} q".format(shape) + + if hasattr(sys.stdout, "_cli"): + write = sys.stdout._cli.output.write_raw + else: + write = sys.stdout.write + + write(cursor) + sys.stdout.flush() + + self._input_mode = mode + + if shell.editing_mode == "vi" and shell.modal_cursor: + ViState._input_mode = InputMode.INSERT + ViState.input_mode = property(get_input_mode, set_input_mode) + return kb @@ -341,4 +368,4 @@ if sys.platform == 'win32': return except ClipboardEmpty: return - event.current_buffer.insert_text(text.replace('\t', ' ' * 4)) + event.current_buffer.insert_text(text.replace("\t", " " * 4))