diff options
author | Ivan Blinkov <ivan@blinkov.ru> | 2022-02-10 16:47:10 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:47:10 +0300 |
commit | 1aeb9a455974457866f78722ad98114bafc84e8a (patch) | |
tree | e4340eaf1668684d83a0a58c36947c5def5350ad /contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding | |
parent | bd5ef432f5cfb1e18851381329d94665a4c22470 (diff) | |
download | ydb-1aeb9a455974457866f78722ad98114bafc84e8a.tar.gz |
Restoring authorship annotation for Ivan Blinkov <ivan@blinkov.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding')
10 files changed, 2077 insertions, 2077 deletions
diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/__init__.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/__init__.py index baffc48825..a8b3a591b2 100644 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/__init__.py +++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/__init__.py @@ -1 +1 @@ -from __future__ import unicode_literals +from __future__ import unicode_literals diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/basic.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/basic.py index 401135dec0..3593df43e5 100644 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/basic.py +++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/basic.py @@ -1,123 +1,123 @@ -# pylint: disable=function-redefined -from __future__ import unicode_literals - -from prompt_toolkit.enums import DEFAULT_BUFFER +# pylint: disable=function-redefined +from __future__ import unicode_literals + +from prompt_toolkit.enums import DEFAULT_BUFFER from prompt_toolkit.filters import HasSelection, Condition, EmacsInsertMode, ViInsertMode -from prompt_toolkit.keys import Keys -from prompt_toolkit.layout.screen import Point +from prompt_toolkit.keys import Keys +from prompt_toolkit.layout.screen import Point from prompt_toolkit.mouse_events import MouseEventType, MouseEvent -from prompt_toolkit.renderer import HeightIsUnknownError -from prompt_toolkit.utils import suspend_to_background_supported, is_windows - +from prompt_toolkit.renderer import HeightIsUnknownError +from prompt_toolkit.utils import suspend_to_background_supported, is_windows + from .named_commands import get_by_name from ..registry import Registry - - -__all__ = ( - 'load_basic_bindings', - 'load_abort_and_exit_bindings', - 'load_basic_system_bindings', - 'load_auto_suggestion_bindings', -) - -def if_no_repeat(event): - """ Callable that returns True when the previous event was delivered to - another handler. """ - return not event.is_repeat - - + + +__all__ = ( + 'load_basic_bindings', + 'load_abort_and_exit_bindings', + 'load_basic_system_bindings', + 'load_auto_suggestion_bindings', +) + +def if_no_repeat(event): + """ Callable that returns True when the previous event was delivered to + another handler. """ + return not event.is_repeat + + def load_basic_bindings(): registry = Registry() insert_mode = ViInsertMode() | EmacsInsertMode() handle = registry.add_binding - has_selection = HasSelection() - - @handle(Keys.ControlA) - @handle(Keys.ControlB) - @handle(Keys.ControlC) - @handle(Keys.ControlD) - @handle(Keys.ControlE) - @handle(Keys.ControlF) - @handle(Keys.ControlG) - @handle(Keys.ControlH) - @handle(Keys.ControlI) - @handle(Keys.ControlJ) - @handle(Keys.ControlK) - @handle(Keys.ControlL) - @handle(Keys.ControlM) - @handle(Keys.ControlN) - @handle(Keys.ControlO) - @handle(Keys.ControlP) - @handle(Keys.ControlQ) - @handle(Keys.ControlR) - @handle(Keys.ControlS) - @handle(Keys.ControlT) - @handle(Keys.ControlU) - @handle(Keys.ControlV) - @handle(Keys.ControlW) - @handle(Keys.ControlX) - @handle(Keys.ControlY) - @handle(Keys.ControlZ) - @handle(Keys.F1) - @handle(Keys.F2) - @handle(Keys.F3) - @handle(Keys.F4) - @handle(Keys.F5) - @handle(Keys.F6) - @handle(Keys.F7) - @handle(Keys.F8) - @handle(Keys.F9) - @handle(Keys.F10) - @handle(Keys.F11) - @handle(Keys.F12) - @handle(Keys.F13) - @handle(Keys.F14) - @handle(Keys.F15) - @handle(Keys.F16) - @handle(Keys.F17) - @handle(Keys.F18) - @handle(Keys.F19) - @handle(Keys.F20) - @handle(Keys.ControlSpace) - @handle(Keys.ControlBackslash) - @handle(Keys.ControlSquareClose) - @handle(Keys.ControlCircumflex) - @handle(Keys.ControlUnderscore) - @handle(Keys.Backspace) - @handle(Keys.Up) - @handle(Keys.Down) - @handle(Keys.Right) - @handle(Keys.Left) + has_selection = HasSelection() + + @handle(Keys.ControlA) + @handle(Keys.ControlB) + @handle(Keys.ControlC) + @handle(Keys.ControlD) + @handle(Keys.ControlE) + @handle(Keys.ControlF) + @handle(Keys.ControlG) + @handle(Keys.ControlH) + @handle(Keys.ControlI) + @handle(Keys.ControlJ) + @handle(Keys.ControlK) + @handle(Keys.ControlL) + @handle(Keys.ControlM) + @handle(Keys.ControlN) + @handle(Keys.ControlO) + @handle(Keys.ControlP) + @handle(Keys.ControlQ) + @handle(Keys.ControlR) + @handle(Keys.ControlS) + @handle(Keys.ControlT) + @handle(Keys.ControlU) + @handle(Keys.ControlV) + @handle(Keys.ControlW) + @handle(Keys.ControlX) + @handle(Keys.ControlY) + @handle(Keys.ControlZ) + @handle(Keys.F1) + @handle(Keys.F2) + @handle(Keys.F3) + @handle(Keys.F4) + @handle(Keys.F5) + @handle(Keys.F6) + @handle(Keys.F7) + @handle(Keys.F8) + @handle(Keys.F9) + @handle(Keys.F10) + @handle(Keys.F11) + @handle(Keys.F12) + @handle(Keys.F13) + @handle(Keys.F14) + @handle(Keys.F15) + @handle(Keys.F16) + @handle(Keys.F17) + @handle(Keys.F18) + @handle(Keys.F19) + @handle(Keys.F20) + @handle(Keys.ControlSpace) + @handle(Keys.ControlBackslash) + @handle(Keys.ControlSquareClose) + @handle(Keys.ControlCircumflex) + @handle(Keys.ControlUnderscore) + @handle(Keys.Backspace) + @handle(Keys.Up) + @handle(Keys.Down) + @handle(Keys.Right) + @handle(Keys.Left) @handle(Keys.ShiftUp) @handle(Keys.ShiftDown) @handle(Keys.ShiftRight) @handle(Keys.ShiftLeft) - @handle(Keys.Home) - @handle(Keys.End) - @handle(Keys.Delete) - @handle(Keys.ShiftDelete) + @handle(Keys.Home) + @handle(Keys.End) + @handle(Keys.Delete) + @handle(Keys.ShiftDelete) @handle(Keys.ControlDelete) - @handle(Keys.PageUp) - @handle(Keys.PageDown) - @handle(Keys.BackTab) - @handle(Keys.Tab) - @handle(Keys.ControlLeft) - @handle(Keys.ControlRight) - @handle(Keys.ControlUp) - @handle(Keys.ControlDown) - @handle(Keys.Insert) + @handle(Keys.PageUp) + @handle(Keys.PageDown) + @handle(Keys.BackTab) + @handle(Keys.Tab) + @handle(Keys.ControlLeft) + @handle(Keys.ControlRight) + @handle(Keys.ControlUp) + @handle(Keys.ControlDown) + @handle(Keys.Insert) @handle(Keys.Ignore) - def _(event): - """ - First, for any of these keys, Don't do anything by default. Also don't - catch them in the 'Any' handler which will insert them as data. - - If people want to insert these characters as a literal, they can always - do by doing a quoted insert. (ControlQ in emacs mode, ControlV in Vi - mode.) - """ - pass - + def _(event): + """ + First, for any of these keys, Don't do anything by default. Also don't + catch them in the 'Any' handler which will insert them as data. + + If people want to insert these characters as a literal, they can always + do by doing a quoted insert. (ControlQ in emacs mode, ControlV in Vi + mode.) + """ + pass + # Readline-style bindings. handle(Keys.Home)(get_by_name('beginning-of-line')) handle(Keys.End)(get_by_name('end-of-line')) @@ -126,7 +126,7 @@ def load_basic_bindings(): handle(Keys.ControlUp)(get_by_name('previous-history')) handle(Keys.ControlDown)(get_by_name('next-history')) handle(Keys.ControlL)(get_by_name('clear-screen')) - + handle(Keys.ControlK, filter=insert_mode)(get_by_name('kill-line')) handle(Keys.ControlU, filter=insert_mode)(get_by_name('unix-line-discard')) handle(Keys.ControlH, filter=insert_mode, save_before=if_no_repeat)( @@ -143,76 +143,76 @@ def load_basic_bindings(): handle(Keys.ControlW, filter=insert_mode)(get_by_name('unix-word-rubout')) handle(Keys.ControlI, filter=insert_mode)(get_by_name('menu-complete')) handle(Keys.BackTab, filter=insert_mode)(get_by_name('menu-complete-backward')) - + handle(Keys.PageUp, filter= ~has_selection)(get_by_name('previous-history')) handle(Keys.PageDown, filter= ~has_selection)(get_by_name('next-history')) - # CTRL keys. - + # CTRL keys. + text_before_cursor = Condition(lambda cli: cli.current_buffer.text) handle(Keys.ControlD, filter=text_before_cursor & insert_mode)(get_by_name('delete-char')) - + is_multiline = Condition(lambda cli: cli.current_buffer.is_multiline()) is_returnable = Condition(lambda cli: cli.current_buffer.accept_action.is_returnable) - + @handle(Keys.ControlJ, filter=is_multiline & insert_mode) - def _(event): + def _(event): " Newline (in case of multiline input. " event.current_buffer.newline(copy_margin=not event.cli.in_paste_mode) - + @handle(Keys.ControlJ, filter=~is_multiline & is_returnable) - def _(event): + def _(event): " Enter, accept input. " buff = event.current_buffer buff.accept_action.validate_and_handle(event.cli, buff) - + # Delete the word before the cursor. - + @handle(Keys.Up) - def _(event): - event.current_buffer.auto_up(count=event.arg) - + def _(event): + event.current_buffer.auto_up(count=event.arg) + @handle(Keys.Down) - def _(event): - event.current_buffer.auto_down(count=event.arg) - - @handle(Keys.Delete, filter=has_selection) - def _(event): - data = event.current_buffer.cut_selection() - event.cli.clipboard.set_data(data) - + def _(event): + event.current_buffer.auto_down(count=event.arg) + + @handle(Keys.Delete, filter=has_selection) + def _(event): + data = event.current_buffer.cut_selection() + event.cli.clipboard.set_data(data) + # Global bindings. - - @handle(Keys.ControlZ) - def _(event): - """ - By default, control-Z should literally insert Ctrl-Z. - (Ansi Ctrl-Z, code 26 in MSDOS means End-Of-File. - In a Python REPL for instance, it's possible to type - Control-Z followed by enter to quit.) - - When the system bindings are loaded and suspend-to-background is - supported, that will override this binding. - """ - event.current_buffer.insert_text(event.data) - + + @handle(Keys.ControlZ) + def _(event): + """ + By default, control-Z should literally insert Ctrl-Z. + (Ansi Ctrl-Z, code 26 in MSDOS means End-Of-File. + In a Python REPL for instance, it's possible to type + Control-Z followed by enter to quit.) + + When the system bindings are loaded and suspend-to-background is + supported, that will override this binding. + """ + event.current_buffer.insert_text(event.data) + @handle(Keys.CPRResponse, save_before=lambda e: False) - def _(event): - """ - Handle incoming Cursor-Position-Request response. - """ - # The incoming data looks like u'\x1b[35;1R' - # Parse row/col information. - row, col = map(int, event.data[2:-1].split(';')) - - # Report absolute cursor position to the renderer. - event.cli.renderer.report_absolute_cursor_row(row) - + def _(event): + """ + Handle incoming Cursor-Position-Request response. + """ + # The incoming data looks like u'\x1b[35;1R' + # Parse row/col information. + row, col = map(int, event.data[2:-1].split(';')) + + # Report absolute cursor position to the renderer. + event.cli.renderer.report_absolute_cursor_row(row) + @handle(Keys.BracketedPaste) - def _(event): - " Pasting from clipboard. " + def _(event): + " Pasting from clipboard. " data = event.data - + # Be sure to use \n as line ending. # Some terminals (Like iTerm2) seem to paste \r\n line endings in a # bracketed paste. See: https://github.com/ipython/ipython/issues/9737 @@ -239,169 +239,169 @@ def load_mouse_bindings(): """ registry = Registry() - @registry.add_binding(Keys.Vt100MouseEvent) - def _(event): - """ - Handling of incoming mouse event. - """ - # Typical: "Esc[MaB*" - # Urxvt: "Esc[96;14;13M" - # Xterm SGR: "Esc[<64;85;12M" - - # Parse incoming packet. - if event.data[2] == 'M': - # Typical. - mouse_event, x, y = map(ord, event.data[3:]) - mouse_event = { + @registry.add_binding(Keys.Vt100MouseEvent) + def _(event): + """ + Handling of incoming mouse event. + """ + # Typical: "Esc[MaB*" + # Urxvt: "Esc[96;14;13M" + # Xterm SGR: "Esc[<64;85;12M" + + # Parse incoming packet. + if event.data[2] == 'M': + # Typical. + mouse_event, x, y = map(ord, event.data[3:]) + mouse_event = { 32: MouseEventType.MOUSE_DOWN, 35: MouseEventType.MOUSE_UP, 96: MouseEventType.SCROLL_UP, 97: MouseEventType.SCROLL_DOWN, - }.get(mouse_event) + }.get(mouse_event) # Handle situations where `PosixStdinReader` used surrogateescapes. if x >= 0xdc00: x-= 0xdc00 if y >= 0xdc00: y-= 0xdc00 - x -= 32 - y -= 32 - else: - # Urxvt and Xterm SGR. - # When the '<' is not present, we are not using the Xterm SGR mode, - # but Urxvt instead. - data = event.data[2:] - if data[:1] == '<': - sgr = True - data = data[1:] - else: - sgr = False - - # Extract coordinates. - mouse_event, x, y = map(int, data[:-1].split(';')) - m = data[-1] - - # Parse event type. - if sgr: - mouse_event = { + x -= 32 + y -= 32 + else: + # Urxvt and Xterm SGR. + # When the '<' is not present, we are not using the Xterm SGR mode, + # but Urxvt instead. + data = event.data[2:] + if data[:1] == '<': + sgr = True + data = data[1:] + else: + sgr = False + + # Extract coordinates. + mouse_event, x, y = map(int, data[:-1].split(';')) + m = data[-1] + + # Parse event type. + if sgr: + mouse_event = { (0, 'M'): MouseEventType.MOUSE_DOWN, (0, 'm'): MouseEventType.MOUSE_UP, (64, 'M'): MouseEventType.SCROLL_UP, (65, 'M'): MouseEventType.SCROLL_DOWN, - }.get((mouse_event, m)) - else: - mouse_event = { + }.get((mouse_event, m)) + else: + mouse_event = { 32: MouseEventType.MOUSE_DOWN, 35: MouseEventType.MOUSE_UP, 96: MouseEventType.SCROLL_UP, 97: MouseEventType.SCROLL_DOWN, - }.get(mouse_event) - - x -= 1 - y -= 1 - - # Only handle mouse events when we know the window height. - if event.cli.renderer.height_is_known and mouse_event is not None: - # Take region above the layout into account. The reported - # coordinates are absolute to the visible part of the terminal. - try: - y -= event.cli.renderer.rows_above_layout - except HeightIsUnknownError: - return - - # Call the mouse handler from the renderer. - handler = event.cli.renderer.mouse_handlers.mouse_handlers[x,y] - handler(event.cli, MouseEvent(position=Point(x=x, y=y), - event_type=mouse_event)) - - @registry.add_binding(Keys.WindowsMouseEvent) - def _(event): - """ - Handling of mouse events for Windows. - """ - assert is_windows() # This key binding should only exist for Windows. - - # Parse data. - event_type, x, y = event.data.split(';') - x = int(x) - y = int(y) - - # Make coordinates absolute to the visible part of the terminal. - screen_buffer_info = event.cli.renderer.output.get_win32_screen_buffer_info() - rows_above_cursor = screen_buffer_info.dwCursorPosition.Y - event.cli.renderer._cursor_pos.y - y -= rows_above_cursor - - # Call the mouse event handler. - handler = event.cli.renderer.mouse_handlers.mouse_handlers[x,y] - handler(event.cli, MouseEvent(position=Point(x=x, y=y), - event_type=event_type)) - + }.get(mouse_event) + + x -= 1 + y -= 1 + + # Only handle mouse events when we know the window height. + if event.cli.renderer.height_is_known and mouse_event is not None: + # Take region above the layout into account. The reported + # coordinates are absolute to the visible part of the terminal. + try: + y -= event.cli.renderer.rows_above_layout + except HeightIsUnknownError: + return + + # Call the mouse handler from the renderer. + handler = event.cli.renderer.mouse_handlers.mouse_handlers[x,y] + handler(event.cli, MouseEvent(position=Point(x=x, y=y), + event_type=mouse_event)) + + @registry.add_binding(Keys.WindowsMouseEvent) + def _(event): + """ + Handling of mouse events for Windows. + """ + assert is_windows() # This key binding should only exist for Windows. + + # Parse data. + event_type, x, y = event.data.split(';') + x = int(x) + y = int(y) + + # Make coordinates absolute to the visible part of the terminal. + screen_buffer_info = event.cli.renderer.output.get_win32_screen_buffer_info() + rows_above_cursor = screen_buffer_info.dwCursorPosition.Y - event.cli.renderer._cursor_pos.y + y -= rows_above_cursor + + # Call the mouse event handler. + handler = event.cli.renderer.mouse_handlers.mouse_handlers[x,y] + handler(event.cli, MouseEvent(position=Point(x=x, y=y), + event_type=event_type)) + return registry - + def load_abort_and_exit_bindings(): - """ - Basic bindings for abort (Ctrl-C) and exit (Ctrl-D). - """ + """ + Basic bindings for abort (Ctrl-C) and exit (Ctrl-D). + """ registry = Registry() handle = registry.add_binding - - @handle(Keys.ControlC) - def _(event): - " Abort when Control-C has been pressed. " - event.cli.abort() - - @Condition - def ctrl_d_condition(cli): - """ Ctrl-D binding is only active when the default buffer is selected - and empty. """ - return (cli.current_buffer_name == DEFAULT_BUFFER and - not cli.current_buffer.text) - + + @handle(Keys.ControlC) + def _(event): + " Abort when Control-C has been pressed. " + event.cli.abort() + + @Condition + def ctrl_d_condition(cli): + """ Ctrl-D binding is only active when the default buffer is selected + and empty. """ + return (cli.current_buffer_name == DEFAULT_BUFFER and + not cli.current_buffer.text) + handle(Keys.ControlD, filter=ctrl_d_condition)(get_by_name('end-of-file')) - + return registry - + def load_basic_system_bindings(): - """ - Basic system bindings (For both Emacs and Vi mode.) - """ + """ + Basic system bindings (For both Emacs and Vi mode.) + """ registry = Registry() - - suspend_supported = Condition( - lambda cli: suspend_to_background_supported()) - + + suspend_supported = Condition( + lambda cli: suspend_to_background_supported()) + @registry.add_binding(Keys.ControlZ, filter=suspend_supported) - def _(event): - """ - Suspend process to background. - """ - event.cli.suspend_to_background() - + def _(event): + """ + Suspend process to background. + """ + event.cli.suspend_to_background() + return registry - + def load_auto_suggestion_bindings(): - """ - Key bindings for accepting auto suggestion text. - """ + """ + Key bindings for accepting auto suggestion text. + """ registry = Registry() handle = registry.add_binding - - suggestion_available = Condition( - lambda cli: - cli.current_buffer.suggestion is not None and - cli.current_buffer.document.is_cursor_at_the_end) - - @handle(Keys.ControlF, filter=suggestion_available) - @handle(Keys.ControlE, filter=suggestion_available) - @handle(Keys.Right, filter=suggestion_available) - def _(event): - " Accept suggestion. " - b = event.current_buffer - suggestion = b.suggestion - - if suggestion: - b.insert_text(suggestion.text) + + suggestion_available = Condition( + lambda cli: + cli.current_buffer.suggestion is not None and + cli.current_buffer.document.is_cursor_at_the_end) + + @handle(Keys.ControlF, filter=suggestion_available) + @handle(Keys.ControlE, filter=suggestion_available) + @handle(Keys.Right, filter=suggestion_available) + def _(event): + " Accept suggestion. " + b = event.current_buffer + suggestion = b.suggestion + + if suggestion: + b.insert_text(suggestion.text) return registry diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/emacs.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/emacs.py index bccdb04ff3..5a0c502a57 100644 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/emacs.py +++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/emacs.py @@ -1,47 +1,47 @@ -# pylint: disable=function-redefined -from __future__ import unicode_literals -from prompt_toolkit.buffer import SelectionType, indent, unindent -from prompt_toolkit.keys import Keys -from prompt_toolkit.enums import IncrementalSearchDirection, SEARCH_BUFFER, SYSTEM_BUFFER +# pylint: disable=function-redefined +from __future__ import unicode_literals +from prompt_toolkit.buffer import SelectionType, indent, unindent +from prompt_toolkit.keys import Keys +from prompt_toolkit.enums import IncrementalSearchDirection, SEARCH_BUFFER, SYSTEM_BUFFER from prompt_toolkit.filters import Condition, EmacsMode, HasSelection, EmacsInsertMode, HasFocus, HasArg from prompt_toolkit.completion import CompleteEvent - -from .scroll import scroll_page_up, scroll_page_down + +from .scroll import scroll_page_up, scroll_page_down from .named_commands import get_by_name from ..registry import Registry, ConditionalRegistry - -__all__ = ( - 'load_emacs_bindings', - 'load_emacs_search_bindings', - 'load_emacs_system_bindings', - 'load_extra_emacs_page_navigation_bindings', -) - - + +__all__ = ( + 'load_emacs_bindings', + 'load_emacs_search_bindings', + 'load_emacs_system_bindings', + 'load_extra_emacs_page_navigation_bindings', +) + + def load_emacs_bindings(): - """ - Some e-macs extensions. - """ - # Overview of Readline emacs commands: - # http://www.catonmat.net/download/readline-emacs-editing-mode-cheat-sheet.pdf + """ + Some e-macs extensions. + """ + # Overview of Readline emacs commands: + # http://www.catonmat.net/download/readline-emacs-editing-mode-cheat-sheet.pdf registry = ConditionalRegistry(Registry(), EmacsMode()) handle = registry.add_binding - + insert_mode = EmacsInsertMode() has_selection = HasSelection() - - @handle(Keys.Escape) - def _(event): - """ - By default, ignore escape key. - - (If we don't put this here, and Esc is followed by a key which sequence - is not handled, we'll insert an Escape character in the input stream. - Something we don't want and happens to easily in emacs mode. - Further, people can always use ControlQ to do a quoted insert.) - """ - pass - + + @handle(Keys.Escape) + def _(event): + """ + By default, ignore escape key. + + (If we don't put this here, and Esc is followed by a key which sequence + is not handled, we'll insert an Escape character in the input stream. + Something we don't want and happens to easily in emacs mode. + Further, people can always use ControlQ to do a quoted insert.) + """ + pass + handle(Keys.ControlA)(get_by_name('beginning-of-line')) handle(Keys.ControlB)(get_by_name('backward-char')) handle(Keys.ControlDelete, filter=insert_mode)(get_by_name('kill-word')) @@ -61,14 +61,14 @@ def load_emacs_bindings(): handle(Keys.Escape, Keys.ControlH, filter=insert_mode)(get_by_name('backward-kill-word')) handle(Keys.Escape, Keys.Backspace, filter=insert_mode)(get_by_name('backward-kill-word')) handle(Keys.Escape, '\\', filter=insert_mode)(get_by_name('delete-horizontal-space')) - + handle(Keys.ControlUnderscore, save_before=(lambda e: False), filter=insert_mode)( get_by_name('undo')) - + handle(Keys.ControlX, Keys.ControlU, save_before=(lambda e: False), filter=insert_mode)( get_by_name('undo')) - - + + handle(Keys.Escape, '<', filter= ~has_selection)(get_by_name('beginning-of-history')) handle(Keys.Escape, '>', filter= ~has_selection)(get_by_name('end-of-history')) @@ -88,365 +88,365 @@ def load_emacs_bindings(): handle(Keys.ControlX, 'e')(get_by_name('call-last-kbd-macro')) @handle(Keys.ControlN) - def _(event): + def _(event): " Next line. " - event.current_buffer.auto_down() - + event.current_buffer.auto_down() + @handle(Keys.ControlP) - def _(event): + def _(event): " Previous line. " - event.current_buffer.auto_up(count=event.arg) - - def handle_digit(c): - """ + event.current_buffer.auto_up(count=event.arg) + + def handle_digit(c): + """ Handle input of arguments. The first number needs to be preceeded by escape. - """ + """ @handle(c, filter=HasArg()) - @handle(Keys.Escape, c) - def _(event): - event.append_to_arg_count(c) - - for c in '0123456789': - handle_digit(c) - + @handle(Keys.Escape, c) + def _(event): + event.append_to_arg_count(c) + + for c in '0123456789': + handle_digit(c) + @handle(Keys.Escape, '-', filter=~HasArg()) - def _(event): - """ - """ - if event._arg is None: - event.append_to_arg_count('-') - + def _(event): + """ + """ + if event._arg is None: + event.append_to_arg_count('-') + @handle('-', filter=Condition(lambda cli: cli.input_processor.arg == '-')) - def _(event): - """ + def _(event): + """ When '-' is typed again, after exactly '-' has been given as an argument, ignore this. - """ + """ event.cli.input_processor.arg = '-' - + is_returnable = Condition( lambda cli: cli.current_buffer.accept_action.is_returnable) - + # Meta + Newline: always accept input. handle(Keys.Escape, Keys.ControlJ, filter=insert_mode & is_returnable)( get_by_name('accept-line')) - + def character_search(buff, char, count): if count < 0: match = buff.document.find_backwards(char, in_current_line=True, count=-count) else: match = buff.document.find(char, in_current_line=True, count=count) - + if match is not None: buff.cursor_position += match - + @handle(Keys.ControlSquareClose, Keys.Any) - def _(event): + def _(event): " When Ctl-] + a character is pressed. go to that character. " # Also named 'character-search' character_search(event.current_buffer, event.data, event.arg) - + @handle(Keys.Escape, Keys.ControlSquareClose, Keys.Any) - def _(event): + def _(event): " Like Ctl-], but backwards. " # Also named 'character-search-backward' character_search(event.current_buffer, event.data, -event.arg) - + @handle(Keys.Escape, 'a') - def _(event): + def _(event): " Previous sentence. " # TODO: - + @handle(Keys.Escape, 'e') - def _(event): + def _(event): " Move to end of sentence. " - # TODO: - + # TODO: + @handle(Keys.Escape, 't', filter=insert_mode) - def _(event): - """ - Swap the last two words before the cursor. - """ - # TODO - + def _(event): + """ + Swap the last two words before the cursor. + """ + # TODO + @handle(Keys.Escape, '*', filter=insert_mode) - def _(event): - """ + def _(event): + """ `meta-*`: Insert all possible completions of the preceding text. - """ + """ buff = event.current_buffer - + # List all completions. complete_event = CompleteEvent(text_inserted=False, completion_requested=True) completions = list(buff.completer.get_completions(buff.document, complete_event)) - + # Insert them. text_to_insert = ' '.join(c.text for c in completions) buff.insert_text(text_to_insert) - - @handle(Keys.ControlX, Keys.ControlX) - def _(event): - """ - Move cursor back and forth between the start and end of the current - line. - """ - buffer = event.current_buffer - + + @handle(Keys.ControlX, Keys.ControlX) + def _(event): + """ + Move cursor back and forth between the start and end of the current + line. + """ + buffer = event.current_buffer + if buffer.document.is_cursor_at_the_end_of_line: - buffer.cursor_position += buffer.document.get_start_of_line_position(after_whitespace=False) - else: - buffer.cursor_position += buffer.document.get_end_of_line_position() - - @handle(Keys.ControlSpace) - def _(event): - """ + buffer.cursor_position += buffer.document.get_start_of_line_position(after_whitespace=False) + else: + buffer.cursor_position += buffer.document.get_end_of_line_position() + + @handle(Keys.ControlSpace) + def _(event): + """ Start of the selection (if the current buffer is not empty). - """ - # Take the current cursor position as the start of this selection. + """ + # Take the current cursor position as the start of this selection. buff = event.current_buffer if buff.text: buff.start_selection(selection_type=SelectionType.CHARACTERS) - - @handle(Keys.ControlG, filter= ~has_selection) - def _(event): - """ - Control + G: Cancel completion menu and validation state. - """ - event.current_buffer.complete_state = None - event.current_buffer.validation_error = None - - @handle(Keys.ControlG, filter=has_selection) - def _(event): - """ - Cancel selection. - """ - event.current_buffer.exit_selection() - - @handle(Keys.ControlW, filter=has_selection) - @handle(Keys.ControlX, 'r', 'k', filter=has_selection) - def _(event): - """ - Cut selected text. - """ - data = event.current_buffer.cut_selection() - event.cli.clipboard.set_data(data) - - @handle(Keys.Escape, 'w', filter=has_selection) - def _(event): - """ - Copy selected text. - """ - data = event.current_buffer.copy_selection() - event.cli.clipboard.set_data(data) - - @handle(Keys.Escape, Keys.Left) - def _(event): - """ - Cursor to start of previous word. - """ - buffer = event.current_buffer - buffer.cursor_position += buffer.document.find_previous_word_beginning(count=event.arg) or 0 - - @handle(Keys.Escape, Keys.Right) - def _(event): - """ - Cursor to start of next word. - """ - buffer = event.current_buffer - buffer.cursor_position += buffer.document.find_next_word_beginning(count=event.arg) or \ - buffer.document.get_end_of_document_position() - + + @handle(Keys.ControlG, filter= ~has_selection) + def _(event): + """ + Control + G: Cancel completion menu and validation state. + """ + event.current_buffer.complete_state = None + event.current_buffer.validation_error = None + + @handle(Keys.ControlG, filter=has_selection) + def _(event): + """ + Cancel selection. + """ + event.current_buffer.exit_selection() + + @handle(Keys.ControlW, filter=has_selection) + @handle(Keys.ControlX, 'r', 'k', filter=has_selection) + def _(event): + """ + Cut selected text. + """ + data = event.current_buffer.cut_selection() + event.cli.clipboard.set_data(data) + + @handle(Keys.Escape, 'w', filter=has_selection) + def _(event): + """ + Copy selected text. + """ + data = event.current_buffer.copy_selection() + event.cli.clipboard.set_data(data) + + @handle(Keys.Escape, Keys.Left) + def _(event): + """ + Cursor to start of previous word. + """ + buffer = event.current_buffer + buffer.cursor_position += buffer.document.find_previous_word_beginning(count=event.arg) or 0 + + @handle(Keys.Escape, Keys.Right) + def _(event): + """ + Cursor to start of next word. + """ + buffer = event.current_buffer + buffer.cursor_position += buffer.document.find_next_word_beginning(count=event.arg) or \ + buffer.document.get_end_of_document_position() + @handle(Keys.Escape, '/', filter=insert_mode) - def _(event): - """ - M-/: Complete. - """ - b = event.current_buffer - if b.complete_state: - b.complete_next() - else: - event.cli.start_completion(select_first=True) - - @handle(Keys.ControlC, '>', filter=has_selection) - def _(event): - """ - Indent selected text. - """ - buffer = event.current_buffer - - buffer.cursor_position += buffer.document.get_start_of_line_position(after_whitespace=True) - - from_, to = buffer.document.selection_range() - from_, _ = buffer.document.translate_index_to_position(from_) - to, _ = buffer.document.translate_index_to_position(to) - - indent(buffer, from_, to + 1, count=event.arg) - - @handle(Keys.ControlC, '<', filter=has_selection) - def _(event): - """ - Unindent selected text. - """ - buffer = event.current_buffer - - from_, to = buffer.document.selection_range() - from_, _ = buffer.document.translate_index_to_position(from_) - to, _ = buffer.document.translate_index_to_position(to) - - unindent(buffer, from_, to + 1, count=event.arg) - + def _(event): + """ + M-/: Complete. + """ + b = event.current_buffer + if b.complete_state: + b.complete_next() + else: + event.cli.start_completion(select_first=True) + + @handle(Keys.ControlC, '>', filter=has_selection) + def _(event): + """ + Indent selected text. + """ + buffer = event.current_buffer + + buffer.cursor_position += buffer.document.get_start_of_line_position(after_whitespace=True) + + from_, to = buffer.document.selection_range() + from_, _ = buffer.document.translate_index_to_position(from_) + to, _ = buffer.document.translate_index_to_position(to) + + indent(buffer, from_, to + 1, count=event.arg) + + @handle(Keys.ControlC, '<', filter=has_selection) + def _(event): + """ + Unindent selected text. + """ + buffer = event.current_buffer + + from_, to = buffer.document.selection_range() + from_, _ = buffer.document.translate_index_to_position(from_) + to, _ = buffer.document.translate_index_to_position(to) + + unindent(buffer, from_, to + 1, count=event.arg) + return registry - + def load_emacs_open_in_editor_bindings(): - """ - Pressing C-X C-E will open the buffer in an external editor. - """ + """ + Pressing C-X C-E will open the buffer in an external editor. + """ registry = Registry() - + registry.add_binding(Keys.ControlX, Keys.ControlE, filter=EmacsMode() & ~HasSelection())( get_by_name('edit-and-execute-command')) - + return registry - + def load_emacs_system_bindings(): registry = ConditionalRegistry(Registry(), EmacsMode()) handle = registry.add_binding has_focus = HasFocus(SYSTEM_BUFFER) - - @handle(Keys.Escape, '!', filter= ~has_focus) - def _(event): - """ - M-'!' opens the system prompt. - """ - event.cli.push_focus(SYSTEM_BUFFER) - - @handle(Keys.Escape, filter=has_focus) - @handle(Keys.ControlG, filter=has_focus) - @handle(Keys.ControlC, filter=has_focus) - def _(event): - """ - Cancel system prompt. - """ - event.cli.buffers[SYSTEM_BUFFER].reset() - event.cli.pop_focus() - - @handle(Keys.ControlJ, filter=has_focus) - def _(event): - """ - Run system command. - """ - system_line = event.cli.buffers[SYSTEM_BUFFER] - event.cli.run_system_command(system_line.text) - system_line.reset(append_to_history=True) - - # Focus previous buffer again. - event.cli.pop_focus() - + + @handle(Keys.Escape, '!', filter= ~has_focus) + def _(event): + """ + M-'!' opens the system prompt. + """ + event.cli.push_focus(SYSTEM_BUFFER) + + @handle(Keys.Escape, filter=has_focus) + @handle(Keys.ControlG, filter=has_focus) + @handle(Keys.ControlC, filter=has_focus) + def _(event): + """ + Cancel system prompt. + """ + event.cli.buffers[SYSTEM_BUFFER].reset() + event.cli.pop_focus() + + @handle(Keys.ControlJ, filter=has_focus) + def _(event): + """ + Run system command. + """ + system_line = event.cli.buffers[SYSTEM_BUFFER] + event.cli.run_system_command(system_line.text) + system_line.reset(append_to_history=True) + + # Focus previous buffer again. + event.cli.pop_focus() + return registry - - + + def load_emacs_search_bindings(get_search_state=None): registry = ConditionalRegistry(Registry(), EmacsMode()) handle = registry.add_binding has_focus = HasFocus(SEARCH_BUFFER) - assert get_search_state is None or callable(get_search_state) - - if not get_search_state: - def get_search_state(cli): return cli.search_state - - @handle(Keys.ControlG, filter=has_focus) - @handle(Keys.ControlC, filter=has_focus) - # NOTE: the reason for not also binding Escape to this one, is that we want - # Alt+Enter to accept input directly in incremental search mode. - def _(event): - """ - Abort an incremental search and restore the original line. - """ - search_buffer = event.cli.buffers[SEARCH_BUFFER] - - search_buffer.reset() - event.cli.pop_focus() - - @handle(Keys.ControlJ, filter=has_focus) + assert get_search_state is None or callable(get_search_state) + + if not get_search_state: + def get_search_state(cli): return cli.search_state + + @handle(Keys.ControlG, filter=has_focus) + @handle(Keys.ControlC, filter=has_focus) + # NOTE: the reason for not also binding Escape to this one, is that we want + # Alt+Enter to accept input directly in incremental search mode. + def _(event): + """ + Abort an incremental search and restore the original line. + """ + search_buffer = event.cli.buffers[SEARCH_BUFFER] + + search_buffer.reset() + event.cli.pop_focus() + + @handle(Keys.ControlJ, filter=has_focus) @handle(Keys.Escape, filter=has_focus, eager=True) - def _(event): - """ - When enter pressed in isearch, quit isearch mode. (Multiline - isearch would be too complicated.) - """ - input_buffer = event.cli.buffers.previous(event.cli) - search_buffer = event.cli.buffers[SEARCH_BUFFER] - - # Update search state. - if search_buffer.text: - get_search_state(event.cli).text = search_buffer.text - - # Apply search. - input_buffer.apply_search(get_search_state(event.cli), include_current_position=True) - - # Add query to history of search line. - search_buffer.append_to_history() - search_buffer.reset() - - # Focus previous document again. - event.cli.pop_focus() - - @handle(Keys.ControlR, filter= ~has_focus) - def _(event): - get_search_state(event.cli).direction = IncrementalSearchDirection.BACKWARD - event.cli.push_focus(SEARCH_BUFFER) - - @handle(Keys.ControlS, filter= ~has_focus) - def _(event): - get_search_state(event.cli).direction = IncrementalSearchDirection.FORWARD - event.cli.push_focus(SEARCH_BUFFER) - + def _(event): + """ + When enter pressed in isearch, quit isearch mode. (Multiline + isearch would be too complicated.) + """ + input_buffer = event.cli.buffers.previous(event.cli) + search_buffer = event.cli.buffers[SEARCH_BUFFER] + + # Update search state. + if search_buffer.text: + get_search_state(event.cli).text = search_buffer.text + + # Apply search. + input_buffer.apply_search(get_search_state(event.cli), include_current_position=True) + + # Add query to history of search line. + search_buffer.append_to_history() + search_buffer.reset() + + # Focus previous document again. + event.cli.pop_focus() + + @handle(Keys.ControlR, filter= ~has_focus) + def _(event): + get_search_state(event.cli).direction = IncrementalSearchDirection.BACKWARD + event.cli.push_focus(SEARCH_BUFFER) + + @handle(Keys.ControlS, filter= ~has_focus) + def _(event): + get_search_state(event.cli).direction = IncrementalSearchDirection.FORWARD + event.cli.push_focus(SEARCH_BUFFER) + def incremental_search(cli, direction, count=1): " Apply search, but keep search buffer focussed. " - # Update search_state. + # Update search_state. search_state = get_search_state(cli) direction_changed = search_state.direction != direction - + search_state.text = cli.buffers[SEARCH_BUFFER].text search_state.direction = direction - - # Apply search to current buffer. - if not direction_changed: + + # Apply search to current buffer. + if not direction_changed: input_buffer = cli.buffers.previous(cli) - input_buffer.apply_search(search_state, + input_buffer.apply_search(search_state, include_current_position=False, count=count) - + @handle(Keys.ControlR, filter=has_focus) @handle(Keys.Up, filter=has_focus) def _(event): incremental_search(event.cli, IncrementalSearchDirection.BACKWARD, count=event.arg) - @handle(Keys.ControlS, filter=has_focus) - @handle(Keys.Down, filter=has_focus) - def _(event): + @handle(Keys.ControlS, filter=has_focus) + @handle(Keys.Down, filter=has_focus) + def _(event): incremental_search(event.cli, IncrementalSearchDirection.FORWARD, count=event.arg) - + return registry - + def load_extra_emacs_page_navigation_bindings(): - """ - Key bindings, for scrolling up and down through pages. - This are separate bindings, because GNU readline doesn't have them. - """ + """ + Key bindings, for scrolling up and down through pages. + This are separate bindings, because GNU readline doesn't have them. + """ registry = ConditionalRegistry(Registry(), EmacsMode()) handle = registry.add_binding - - handle(Keys.ControlV)(scroll_page_down) - handle(Keys.PageDown)(scroll_page_down) - handle(Keys.Escape, 'v')(scroll_page_up) - handle(Keys.PageUp)(scroll_page_up) + + handle(Keys.ControlV)(scroll_page_down) + handle(Keys.PageDown)(scroll_page_down) + handle(Keys.Escape, 'v')(scroll_page_up) + handle(Keys.PageUp)(scroll_page_up) return registry diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/scroll.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/scroll.py index 2cc58129ff..169517942c 100644 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/scroll.py +++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/scroll.py @@ -1,139 +1,139 @@ -""" -Key bindings, for scrolling up and down through pages. - -This are separate bindings, because GNU readline doesn't have them, but -they are very useful for navigating through long multiline buffers, like in -Vi, Emacs, etc... -""" -from __future__ import unicode_literals - -from prompt_toolkit.layout.utils import find_window_for_buffer_name +""" +Key bindings, for scrolling up and down through pages. + +This are separate bindings, because GNU readline doesn't have them, but +they are very useful for navigating through long multiline buffers, like in +Vi, Emacs, etc... +""" +from __future__ import unicode_literals + +from prompt_toolkit.layout.utils import find_window_for_buffer_name from six.moves import range - -__all__ = ( - 'scroll_forward', - 'scroll_backward', - 'scroll_half_page_up', - 'scroll_half_page_down', - 'scroll_one_line_up', - 'scroll_one_line_down', -) - - -def _current_window_for_event(event): - """ - Return the `Window` for the currently focussed Buffer. - """ - return find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) - - -def scroll_forward(event, half=False): - """ - Scroll window down. - """ - w = _current_window_for_event(event) - b = event.cli.current_buffer - - if w and w.render_info: + +__all__ = ( + 'scroll_forward', + 'scroll_backward', + 'scroll_half_page_up', + 'scroll_half_page_down', + 'scroll_one_line_up', + 'scroll_one_line_down', +) + + +def _current_window_for_event(event): + """ + Return the `Window` for the currently focussed Buffer. + """ + return find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) + + +def scroll_forward(event, half=False): + """ + Scroll window down. + """ + w = _current_window_for_event(event) + b = event.cli.current_buffer + + if w and w.render_info: info = w.render_info ui_content = info.ui_content # Height to scroll. scroll_height = info.window_height - if half: + if half: scroll_height //= 2 - + # Calculate how many lines is equivalent to that vertical space. y = b.document.cursor_position_row + 1 height = 0 while y < ui_content.line_count: line_height = info.get_height_for_line(y) - + if height + line_height < scroll_height: height += line_height y += 1 else: break - + b.cursor_position = b.document.translate_row_col_to_index(y, 0) -def scroll_backward(event, half=False): - """ - Scroll window up. - """ - w = _current_window_for_event(event) - b = event.cli.current_buffer - - if w and w.render_info: +def scroll_backward(event, half=False): + """ + Scroll window up. + """ + w = _current_window_for_event(event) + b = event.cli.current_buffer + + if w and w.render_info: info = w.render_info # Height to scroll. scroll_height = info.window_height - if half: + if half: scroll_height //= 2 - + # Calculate how many lines is equivalent to that vertical space. y = max(0, b.document.cursor_position_row - 1) height = 0 while y > 0: line_height = info.get_height_for_line(y) - + if height + line_height < scroll_height: height += line_height y -= 1 else: break - + b.cursor_position = b.document.translate_row_col_to_index(y, 0) -def scroll_half_page_down(event): - """ - Same as ControlF, but only scroll half a page. - """ - scroll_forward(event, half=True) - - -def scroll_half_page_up(event): - """ - Same as ControlB, but only scroll half a page. - """ - scroll_backward(event, half=True) - - -def scroll_one_line_down(event): - """ - scroll_offset += 1 - """ - w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) - b = event.cli.current_buffer - - if w: - # When the cursor is at the top, move to the next line. (Otherwise, only scroll.) - if w.render_info: - info = w.render_info - - if w.vertical_scroll < info.content_height - info.window_height: - if info.cursor_position.y <= info.configured_scroll_offsets.top: - b.cursor_position += b.document.get_cursor_down_position() - - w.vertical_scroll += 1 - - -def scroll_one_line_up(event): - """ - scroll_offset -= 1 - """ - w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) - b = event.cli.current_buffer - - if w: - # When the cursor is at the bottom, move to the previous line. (Otherwise, only scroll.) - if w.render_info: - info = w.render_info - - if w.vertical_scroll > 0: +def scroll_half_page_down(event): + """ + Same as ControlF, but only scroll half a page. + """ + scroll_forward(event, half=True) + + +def scroll_half_page_up(event): + """ + Same as ControlB, but only scroll half a page. + """ + scroll_backward(event, half=True) + + +def scroll_one_line_down(event): + """ + scroll_offset += 1 + """ + w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) + b = event.cli.current_buffer + + if w: + # When the cursor is at the top, move to the next line. (Otherwise, only scroll.) + if w.render_info: + info = w.render_info + + if w.vertical_scroll < info.content_height - info.window_height: + if info.cursor_position.y <= info.configured_scroll_offsets.top: + b.cursor_position += b.document.get_cursor_down_position() + + w.vertical_scroll += 1 + + +def scroll_one_line_up(event): + """ + scroll_offset -= 1 + """ + w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) + b = event.cli.current_buffer + + if w: + # When the cursor is at the bottom, move to the previous line. (Otherwise, only scroll.) + if w.render_info: + info = w.render_info + + if w.vertical_scroll > 0: first_line_height = info.get_height_for_line(info.first_visible_line()) cursor_up = info.cursor_position.y - (info.window_height - 1 - first_line_height - @@ -142,44 +142,44 @@ def scroll_one_line_up(event): # Move cursor up, as many steps as the height of the first line. # TODO: not entirely correct yet, in case of line wrapping and many long lines. for _ in range(max(0, cursor_up)): - b.cursor_position += b.document.get_cursor_up_position() - - # Scroll window - w.vertical_scroll -= 1 - - -def scroll_page_down(event): - """ - Scroll page down. (Prefer the cursor at the top of the page, after scrolling.) - """ - w = _current_window_for_event(event) - b = event.cli.current_buffer - - if w and w.render_info: - # Scroll down one page. + b.cursor_position += b.document.get_cursor_up_position() + + # Scroll window + w.vertical_scroll -= 1 + + +def scroll_page_down(event): + """ + Scroll page down. (Prefer the cursor at the top of the page, after scrolling.) + """ + w = _current_window_for_event(event) + b = event.cli.current_buffer + + if w and w.render_info: + # Scroll down one page. line_index = max(w.render_info.last_visible_line(), w.vertical_scroll + 1) w.vertical_scroll = line_index - + b.cursor_position = b.document.translate_row_col_to_index(line_index, 0) - b.cursor_position += b.document.get_start_of_line_position(after_whitespace=True) - - -def scroll_page_up(event): - """ - Scroll page up. (Prefer the cursor at the bottom of the page, after scrolling.) - """ - w = _current_window_for_event(event) - b = event.cli.current_buffer - - if w and w.render_info: + b.cursor_position += b.document.get_start_of_line_position(after_whitespace=True) + + +def scroll_page_up(event): + """ + Scroll page up. (Prefer the cursor at the bottom of the page, after scrolling.) + """ + w = _current_window_for_event(event) + b = event.cli.current_buffer + + if w and w.render_info: # Put cursor at the first visible line. (But make sure that the cursor # moves at least one line up.) line_index = max(0, min(w.render_info.first_visible_line(), b.document.cursor_position_row - 1)) - + b.cursor_position = b.document.translate_row_col_to_index(line_index, 0) b.cursor_position += b.document.get_start_of_line_position(after_whitespace=True) - + # Set the scroll offset. We can safely set it to zero; the Window will # make sure that it scrolls at least until the cursor becomes visible. w.vertical_scroll = 0 diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/utils.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/utils.py index caf08c5c1b..226ae8a5c5 100644 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/utils.py +++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/utils.py @@ -1,25 +1,25 @@ -from __future__ import unicode_literals -from prompt_toolkit.filters import CLIFilter, Always - -__all__ = ( - 'create_handle_decorator', -) - -def create_handle_decorator(registry, filter=Always()): - """ +from __future__ import unicode_literals +from prompt_toolkit.filters import CLIFilter, Always + +__all__ = ( + 'create_handle_decorator', +) + +def create_handle_decorator(registry, filter=Always()): + """ Create a key handle decorator, which is compatible with `Registry.handle`, but will chain the given filter to every key binding. - + :param filter: `CLIFilter` - """ - assert isinstance(filter, CLIFilter) - - def handle(*keys, **kw): - # Chain the given filter to the filter of this specific binding. - if 'filter' in kw: - kw['filter'] = kw['filter'] & filter - else: - kw['filter'] = filter - + """ + assert isinstance(filter, CLIFilter) + + def handle(*keys, **kw): + # Chain the given filter to the filter of this specific binding. + if 'filter' in kw: + kw['filter'] = kw['filter'] & filter + else: + kw['filter'] = filter + return registry.add_binding(*keys, **kw) - return handle + return handle diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/vi.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/vi.py index 72568ee273..a436edf3a7 100644 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/vi.py +++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/bindings/vi.py @@ -1,26 +1,26 @@ -# pylint: disable=function-redefined -from __future__ import unicode_literals +# pylint: disable=function-redefined +from __future__ import unicode_literals from prompt_toolkit.buffer import ClipboardData, indent, unindent, reshape_text -from prompt_toolkit.document import Document -from prompt_toolkit.enums import IncrementalSearchDirection, SEARCH_BUFFER, SYSTEM_BUFFER +from prompt_toolkit.document import Document +from prompt_toolkit.enums import IncrementalSearchDirection, SEARCH_BUFFER, SYSTEM_BUFFER from prompt_toolkit.filters import Filter, Condition, HasArg, Always, IsReadOnly from prompt_toolkit.filters.cli import ViNavigationMode, ViInsertMode, ViInsertMultipleMode, ViReplaceMode, ViSelectionMode, ViWaitingForTextObjectMode, ViDigraphMode, ViMode from prompt_toolkit.key_binding.digraphs import DIGRAPHS -from prompt_toolkit.key_binding.vi_state import CharacterFind, InputMode -from prompt_toolkit.keys import Keys -from prompt_toolkit.layout.utils import find_window_for_buffer_name +from prompt_toolkit.key_binding.vi_state import CharacterFind, InputMode +from prompt_toolkit.keys import Keys +from prompt_toolkit.layout.utils import find_window_for_buffer_name from prompt_toolkit.selection import SelectionType, SelectionState, PasteMode - -from .scroll import scroll_forward, scroll_backward, scroll_half_page_up, scroll_half_page_down, scroll_one_line_up, scroll_one_line_down, scroll_page_up, scroll_page_down + +from .scroll import scroll_forward, scroll_backward, scroll_half_page_up, scroll_half_page_down, scroll_one_line_up, scroll_one_line_down, scroll_page_up, scroll_page_down from .named_commands import get_by_name from ..registry import Registry, ConditionalRegistry, BaseRegistry - -import prompt_toolkit.filters as filters + +import prompt_toolkit.filters as filters from six.moves import range -import codecs +import codecs import six import string - + try: from itertools import accumulate except ImportError: # < Python 3.2 @@ -31,38 +31,38 @@ except ImportError: # < Python 3.2 total += item yield total -__all__ = ( - 'load_vi_bindings', - 'load_vi_search_bindings', - 'load_vi_system_bindings', - 'load_extra_vi_page_navigation_bindings', -) - +__all__ = ( + 'load_vi_bindings', + 'load_vi_search_bindings', + 'load_vi_system_bindings', + 'load_extra_vi_page_navigation_bindings', +) + if six.PY2: ascii_lowercase = string.ascii_lowercase.decode('ascii') else: ascii_lowercase = string.ascii_lowercase - + vi_register_names = ascii_lowercase + '0123456789' - - + + class TextObjectType(object): EXCLUSIVE = 'EXCLUSIVE' INCLUSIVE = 'INCLUSIVE' LINEWISE = 'LINEWISE' BLOCK = 'BLOCK' - - + + class TextObject(object): - """ + """ Return struct for functions wrapped in ``text_object``. - Both `start` and `end` are relative to the current cursor position. - """ + Both `start` and `end` are relative to the current cursor position. + """ def __init__(self, start, end=0, type=TextObjectType.EXCLUSIVE): - self.start = start - self.end = end + self.start = start + self.end = end self.type = type - + @property def selection_type(self): if self.type == TextObjectType.LINEWISE: @@ -72,15 +72,15 @@ class TextObject(object): else: return SelectionType.CHARACTERS - def sorted(self): - """ - Return a (start, end) tuple where start <= end. - """ - if self.start < self.end: - return self.start, self.end - else: - return self.end, self.start - + def sorted(self): + """ + Return a (start, end) tuple where start <= end. + """ + if self.start < self.end: + return self.start, self.end + else: + return self.end, self.start + def operator_range(self, document): """ Return a (start, end) tuple with start <= end that indicates the range @@ -89,7 +89,7 @@ class TextObject(object): """ start, end = self.sorted() doc = document - + if (self.type == TextObjectType.EXCLUSIVE and doc.translate_index_to_position(end + doc.cursor_position)[1] == 0): # If the motion is exclusive and the end of motion is on the first @@ -138,7 +138,7 @@ class TextObject(object): def create_text_object_decorator(registry): - """ + """ Create a decorator that can be used to register Vi text object implementations. """ assert isinstance(registry, BaseRegistry) @@ -299,30 +299,30 @@ def create_operator_decorator(registry): def load_vi_bindings(get_search_state=None): """ - Vi extensions. - - # Overview of Readline Vi commands: - # http://www.catonmat.net/download/bash-vi-editing-mode-cheat-sheet.pdf - + Vi extensions. + + # Overview of Readline Vi commands: + # http://www.catonmat.net/download/bash-vi-editing-mode-cheat-sheet.pdf + :param get_search_state: None or a callable that takes a CommandLineInterface and returns a SearchState. - """ - # Note: Some key bindings have the "~IsReadOnly()" filter added. This - # prevents the handler to be executed when the focus is on a - # read-only buffer. - # This is however only required for those that change the ViState to - # INSERT mode. The `Buffer` class itself throws the - # `EditReadOnlyBuffer` exception for any text operations which is - # handled correctly. There is no need to add "~IsReadOnly" to all key - # bindings that do text manipulation. - + """ + # Note: Some key bindings have the "~IsReadOnly()" filter added. This + # prevents the handler to be executed when the focus is on a + # read-only buffer. + # This is however only required for those that change the ViState to + # INSERT mode. The `Buffer` class itself throws the + # `EditReadOnlyBuffer` exception for any text operations which is + # handled correctly. There is no need to add "~IsReadOnly" to all key + # bindings that do text manipulation. + registry = ConditionalRegistry(Registry(), ViMode()) handle = registry.add_binding - - # Default get_search_state. - if get_search_state is None: - def get_search_state(cli): return cli.search_state - + + # Default get_search_state. + if get_search_state is None: + def get_search_state(cli): return cli.search_state + # (Note: Always take the navigation bindings in read-only mode, even when # ViState says different.) navigation_mode = ViNavigationMode() @@ -332,63 +332,63 @@ def load_vi_bindings(get_search_state=None): selection_mode = ViSelectionMode() operator_given = ViWaitingForTextObjectMode() digraph_mode = ViDigraphMode() - - vi_transform_functions = [ - # Rot 13 transformation + + vi_transform_functions = [ + # Rot 13 transformation (('g', '?'), Always(), lambda string: codecs.encode(string, 'rot_13')), - - # To lowercase + + # To lowercase (('g', 'u'), Always(), lambda string: string.lower()), - - # To uppercase. + + # To uppercase. (('g', 'U'), Always(), lambda string: string.upper()), - - # Swap case. + + # Swap case. (('g', '~'), Always(), lambda string: string.swapcase()), (('~', ), Condition(lambda cli: cli.vi_state.tilde_operator), lambda string: string.swapcase()), - ] - + ] + # Insert a character literally (quoted insert). handle(Keys.ControlV, filter=insert_mode)(get_by_name('quoted-insert')) - @handle(Keys.Escape) - def _(event): - """ - Escape goes to vi navigation mode. - """ - buffer = event.current_buffer + @handle(Keys.Escape) + def _(event): + """ + Escape goes to vi navigation mode. + """ + buffer = event.current_buffer vi_state = event.cli.vi_state - - if vi_state.input_mode in (InputMode.INSERT, InputMode.REPLACE): - buffer.cursor_position += buffer.document.get_cursor_left_position() - + + if vi_state.input_mode in (InputMode.INSERT, InputMode.REPLACE): + buffer.cursor_position += buffer.document.get_cursor_left_position() + vi_state.reset(InputMode.NAVIGATION) - - if bool(buffer.selection_state): - buffer.exit_selection() - - @handle('k', filter=selection_mode) - def _(event): - """ - Arrow up in selection mode. - """ - event.current_buffer.cursor_up(count=event.arg) - - @handle('j', filter=selection_mode) - def _(event): - """ - Arrow down in selection mode. - """ - event.current_buffer.cursor_down(count=event.arg) - - @handle(Keys.Up, filter=navigation_mode) - @handle(Keys.ControlP, filter=navigation_mode) - def _(event): - """ - Arrow up and ControlP in navigation mode go up. - """ + + if bool(buffer.selection_state): + buffer.exit_selection() + + @handle('k', filter=selection_mode) + def _(event): + """ + Arrow up in selection mode. + """ + event.current_buffer.cursor_up(count=event.arg) + + @handle('j', filter=selection_mode) + def _(event): + """ + Arrow down in selection mode. + """ + event.current_buffer.cursor_down(count=event.arg) + + @handle(Keys.Up, filter=navigation_mode) + @handle(Keys.ControlP, filter=navigation_mode) + def _(event): + """ + Arrow up and ControlP in navigation mode go up. + """ event.current_buffer.auto_up(count=event.arg) - + @handle('k', filter=navigation_mode) def _(event): """ @@ -398,14 +398,14 @@ def load_vi_bindings(get_search_state=None): event.current_buffer.auto_up( count=event.arg, go_to_start_of_line_if_history_changes=True) - @handle(Keys.Down, filter=navigation_mode) - @handle(Keys.ControlN, filter=navigation_mode) - def _(event): - """ - Arrow down and Control-N in navigation mode. - """ + @handle(Keys.Down, filter=navigation_mode) + @handle(Keys.ControlN, filter=navigation_mode) + def _(event): + """ + Arrow down and Control-N in navigation mode. + """ event.current_buffer.auto_down(count=event.arg) - + @handle('j', filter=navigation_mode) def _(event): """ @@ -415,143 +415,143 @@ def load_vi_bindings(get_search_state=None): count=event.arg, go_to_start_of_line_if_history_changes=True) @handle(Keys.ControlH, filter=navigation_mode) - @handle(Keys.Backspace, filter=navigation_mode) - def _(event): - """ - In navigation-mode, move cursor. - """ - event.current_buffer.cursor_position += \ - event.current_buffer.document.get_cursor_left_position(count=event.arg) - - @handle(Keys.ControlN, filter=insert_mode) - def _(event): - b = event.current_buffer - - if b.complete_state: - b.complete_next() - else: - event.cli.start_completion(select_first=True) - - @handle(Keys.ControlP, filter=insert_mode) - def _(event): - """ - Control-P: To previous completion. - """ - b = event.current_buffer - - if b.complete_state: - b.complete_previous() - else: - event.cli.start_completion(select_last=True) - - @handle(Keys.ControlY, filter=insert_mode) - def _(event): - """ - Accept current completion. - """ - event.current_buffer.complete_state = None - - @handle(Keys.ControlE, filter=insert_mode) - def _(event): - """ - Cancel completion. Go back to originally typed text. - """ - event.current_buffer.cancel_completion() - + @handle(Keys.Backspace, filter=navigation_mode) + def _(event): + """ + In navigation-mode, move cursor. + """ + event.current_buffer.cursor_position += \ + event.current_buffer.document.get_cursor_left_position(count=event.arg) + + @handle(Keys.ControlN, filter=insert_mode) + def _(event): + b = event.current_buffer + + if b.complete_state: + b.complete_next() + else: + event.cli.start_completion(select_first=True) + + @handle(Keys.ControlP, filter=insert_mode) + def _(event): + """ + Control-P: To previous completion. + """ + b = event.current_buffer + + if b.complete_state: + b.complete_previous() + else: + event.cli.start_completion(select_last=True) + + @handle(Keys.ControlY, filter=insert_mode) + def _(event): + """ + Accept current completion. + """ + event.current_buffer.complete_state = None + + @handle(Keys.ControlE, filter=insert_mode) + def _(event): + """ + Cancel completion. Go back to originally typed text. + """ + event.current_buffer.cancel_completion() + @handle(Keys.ControlJ, filter=navigation_mode) # XXX: only if the selected buffer has a return handler. - def _(event): - """ - In navigation mode, pressing enter will always return the input. - """ - b = event.current_buffer - - if b.accept_action.is_returnable: - b.accept_action.validate_and_handle(event.cli, b) - - # ** In navigation mode ** - - # List of navigation commands: http://hea-www.harvard.edu/~fine/Tech/vi.html - - @handle(Keys.Insert, filter=navigation_mode) - def _(event): - " Presing the Insert key. " + def _(event): + """ + In navigation mode, pressing enter will always return the input. + """ + b = event.current_buffer + + if b.accept_action.is_returnable: + b.accept_action.validate_and_handle(event.cli, b) + + # ** In navigation mode ** + + # List of navigation commands: http://hea-www.harvard.edu/~fine/Tech/vi.html + + @handle(Keys.Insert, filter=navigation_mode) + def _(event): + " Presing the Insert key. " event.cli.vi_state.input_mode = InputMode.INSERT - - @handle('a', filter=navigation_mode & ~IsReadOnly()) - # ~IsReadOnly, because we want to stay in navigation mode for - # read-only buffers. - def _(event): - event.current_buffer.cursor_position += event.current_buffer.document.get_cursor_right_position() + + @handle('a', filter=navigation_mode & ~IsReadOnly()) + # ~IsReadOnly, because we want to stay in navigation mode for + # read-only buffers. + def _(event): + event.current_buffer.cursor_position += event.current_buffer.document.get_cursor_right_position() event.cli.vi_state.input_mode = InputMode.INSERT - - @handle('A', filter=navigation_mode & ~IsReadOnly()) - def _(event): - event.current_buffer.cursor_position += event.current_buffer.document.get_end_of_line_position() + + @handle('A', filter=navigation_mode & ~IsReadOnly()) + def _(event): + event.current_buffer.cursor_position += event.current_buffer.document.get_end_of_line_position() event.cli.vi_state.input_mode = InputMode.INSERT - - @handle('C', filter=navigation_mode & ~IsReadOnly()) - def _(event): - """ - # Change to end of line. - # Same as 'c$' (which is implemented elsewhere.) - """ - buffer = event.current_buffer - - deleted = buffer.delete(count=buffer.document.get_end_of_line_position()) - event.cli.clipboard.set_text(deleted) + + @handle('C', filter=navigation_mode & ~IsReadOnly()) + def _(event): + """ + # Change to end of line. + # Same as 'c$' (which is implemented elsewhere.) + """ + buffer = event.current_buffer + + deleted = buffer.delete(count=buffer.document.get_end_of_line_position()) + event.cli.clipboard.set_text(deleted) event.cli.vi_state.input_mode = InputMode.INSERT - - @handle('c', 'c', filter=navigation_mode & ~IsReadOnly()) - @handle('S', filter=navigation_mode & ~IsReadOnly()) - def _(event): # TODO: implement 'arg' - """ - Change current line - """ - buffer = event.current_buffer - - # We copy the whole line. - data = ClipboardData(buffer.document.current_line, SelectionType.LINES) - event.cli.clipboard.set_data(data) - - # But we delete after the whitespace - buffer.cursor_position += buffer.document.get_start_of_line_position(after_whitespace=True) - buffer.delete(count=buffer.document.get_end_of_line_position()) + + @handle('c', 'c', filter=navigation_mode & ~IsReadOnly()) + @handle('S', filter=navigation_mode & ~IsReadOnly()) + def _(event): # TODO: implement 'arg' + """ + Change current line + """ + buffer = event.current_buffer + + # We copy the whole line. + data = ClipboardData(buffer.document.current_line, SelectionType.LINES) + event.cli.clipboard.set_data(data) + + # But we delete after the whitespace + buffer.cursor_position += buffer.document.get_start_of_line_position(after_whitespace=True) + buffer.delete(count=buffer.document.get_end_of_line_position()) event.cli.vi_state.input_mode = InputMode.INSERT - - @handle('D', filter=navigation_mode) - def _(event): - buffer = event.current_buffer - deleted = buffer.delete(count=buffer.document.get_end_of_line_position()) - event.cli.clipboard.set_text(deleted) - - @handle('d', 'd', filter=navigation_mode) - def _(event): - """ - Delete line. (Or the following 'n' lines.) - """ - buffer = event.current_buffer - - # Split string in before/deleted/after text. - lines = buffer.document.lines - - before = '\n'.join(lines[:buffer.document.cursor_position_row]) + + @handle('D', filter=navigation_mode) + def _(event): + buffer = event.current_buffer + deleted = buffer.delete(count=buffer.document.get_end_of_line_position()) + event.cli.clipboard.set_text(deleted) + + @handle('d', 'd', filter=navigation_mode) + def _(event): + """ + Delete line. (Or the following 'n' lines.) + """ + buffer = event.current_buffer + + # Split string in before/deleted/after text. + lines = buffer.document.lines + + before = '\n'.join(lines[:buffer.document.cursor_position_row]) deleted = '\n'.join(lines[buffer.document.cursor_position_row: buffer.document.cursor_position_row + event.arg]) - after = '\n'.join(lines[buffer.document.cursor_position_row + event.arg:]) - - # Set new text. - if before and after: - before = before + '\n' - - # Set text and cursor position. - buffer.document = Document( - text=before + after, - # Cursor At the start of the first 'after' line, after the leading whitespace. - cursor_position = len(before) + len(after) - len(after.lstrip(' '))) - - # Set clipboard data - event.cli.clipboard.set_data(ClipboardData(deleted, SelectionType.LINES)) - + after = '\n'.join(lines[buffer.document.cursor_position_row + event.arg:]) + + # Set new text. + if before and after: + before = before + '\n' + + # Set text and cursor position. + buffer.document = Document( + text=before + after, + # Cursor At the start of the first 'after' line, after the leading whitespace. + cursor_position = len(before) + len(after) - len(after.lstrip(' '))) + + # Set clipboard data + event.cli.clipboard.set_data(ClipboardData(deleted, SelectionType.LINES)) + @handle('x', filter=selection_mode) def _(event): """ @@ -561,16 +561,16 @@ def load_vi_bindings(get_search_state=None): clipboard_data = event.current_buffer.cut_selection() event.cli.clipboard.set_data(clipboard_data) - @handle('i', filter=navigation_mode & ~IsReadOnly()) - def _(event): + @handle('i', filter=navigation_mode & ~IsReadOnly()) + def _(event): event.cli.vi_state.input_mode = InputMode.INSERT - - @handle('I', filter=navigation_mode & ~IsReadOnly()) - def _(event): + + @handle('I', filter=navigation_mode & ~IsReadOnly()) + def _(event): event.cli.vi_state.input_mode = InputMode.INSERT event.current_buffer.cursor_position += \ event.current_buffer.document.get_start_of_line_position(after_whitespace=True) - + @Condition def in_block_selection(cli): buff = cli.current_buffer @@ -603,17 +603,17 @@ def load_vi_bindings(get_search_state=None): buff.exit_selection() @handle('A', filter=in_block_selection & ~IsReadOnly()) - def _(event): + def _(event): go_to_block_selection(event, after=True) @handle('J', filter=navigation_mode & ~IsReadOnly()) def _(event): " Join lines. " - for i in range(event.arg): - event.current_buffer.join_next_line() - + for i in range(event.arg): + event.current_buffer.join_next_line() + @handle('g', 'J', filter=navigation_mode & ~IsReadOnly()) - def _(event): + def _(event): " Join lines without space. " for i in range(event.arg): event.current_buffer.join_next_line(separator='') @@ -621,33 +621,33 @@ def load_vi_bindings(get_search_state=None): @handle('J', filter=selection_mode & ~IsReadOnly()) def _(event): " Join selected lines. " - event.current_buffer.join_selected_lines() - + event.current_buffer.join_selected_lines() + @handle('g', 'J', filter=selection_mode & ~IsReadOnly()) def _(event): " Join selected lines without space. " event.current_buffer.join_selected_lines(separator='') - - @handle('p', filter=navigation_mode) - def _(event): - """ - Paste after - """ - event.current_buffer.paste_clipboard_data( - event.cli.clipboard.get_data(), + + @handle('p', filter=navigation_mode) + def _(event): + """ + Paste after + """ + event.current_buffer.paste_clipboard_data( + event.cli.clipboard.get_data(), count=event.arg, paste_mode=PasteMode.VI_AFTER) - - @handle('P', filter=navigation_mode) - def _(event): - """ - Paste before - """ - event.current_buffer.paste_clipboard_data( - event.cli.clipboard.get_data(), + + @handle('P', filter=navigation_mode) + def _(event): + """ + Paste before + """ + event.current_buffer.paste_clipboard_data( + event.cli.clipboard.get_data(), count=event.arg, paste_mode=PasteMode.VI_BEFORE) - + @handle('"', Keys.Any, 'p', filter=navigation_mode) def _(event): " Paste from named register. " @@ -668,190 +668,190 @@ def load_vi_bindings(get_search_state=None): event.current_buffer.paste_clipboard_data( data, count=event.arg, paste_mode=PasteMode.VI_BEFORE) - @handle('r', Keys.Any, filter=navigation_mode) - def _(event): - """ - Replace single character under cursor - """ - event.current_buffer.insert_text(event.data * event.arg, overwrite=True) - event.current_buffer.cursor_position -= 1 - - @handle('R', filter=navigation_mode) - def _(event): - """ - Go to 'replace'-mode. - """ + @handle('r', Keys.Any, filter=navigation_mode) + def _(event): + """ + Replace single character under cursor + """ + event.current_buffer.insert_text(event.data * event.arg, overwrite=True) + event.current_buffer.cursor_position -= 1 + + @handle('R', filter=navigation_mode) + def _(event): + """ + Go to 'replace'-mode. + """ event.cli.vi_state.input_mode = InputMode.REPLACE - - @handle('s', filter=navigation_mode & ~IsReadOnly()) - def _(event): - """ - Substitute with new text - (Delete character(s) and go to insert mode.) - """ - text = event.current_buffer.delete(count=event.arg) - event.cli.clipboard.set_text(text) + + @handle('s', filter=navigation_mode & ~IsReadOnly()) + def _(event): + """ + Substitute with new text + (Delete character(s) and go to insert mode.) + """ + text = event.current_buffer.delete(count=event.arg) + event.cli.clipboard.set_text(text) event.cli.vi_state.input_mode = InputMode.INSERT - - @handle('u', filter=navigation_mode, save_before=(lambda e: False)) - def _(event): - for i in range(event.arg): - event.current_buffer.undo() - - @handle('V', filter=navigation_mode) - def _(event): - """ - Start lines selection. - """ - event.current_buffer.start_selection(selection_type=SelectionType.LINES) - - @handle(Keys.ControlV, filter=navigation_mode) - def _(event): - " Enter block selection mode. " - event.current_buffer.start_selection(selection_type=SelectionType.BLOCK) - - @handle('V', filter=selection_mode) - def _(event): - """ - Exit line selection mode, or go from non line selection mode to line - selection mode. - """ - selection_state = event.current_buffer.selection_state - - if selection_state.type != SelectionType.LINES: - selection_state.type = SelectionType.LINES - else: - event.current_buffer.exit_selection() - + + @handle('u', filter=navigation_mode, save_before=(lambda e: False)) + def _(event): + for i in range(event.arg): + event.current_buffer.undo() + + @handle('V', filter=navigation_mode) + def _(event): + """ + Start lines selection. + """ + event.current_buffer.start_selection(selection_type=SelectionType.LINES) + + @handle(Keys.ControlV, filter=navigation_mode) + def _(event): + " Enter block selection mode. " + event.current_buffer.start_selection(selection_type=SelectionType.BLOCK) + + @handle('V', filter=selection_mode) + def _(event): + """ + Exit line selection mode, or go from non line selection mode to line + selection mode. + """ + selection_state = event.current_buffer.selection_state + + if selection_state.type != SelectionType.LINES: + selection_state.type = SelectionType.LINES + else: + event.current_buffer.exit_selection() + @handle('v', filter=navigation_mode) - def _(event): - " Enter character selection mode. " - event.current_buffer.start_selection(selection_type=SelectionType.CHARACTERS) - - @handle('v', filter=selection_mode) - def _(event): - """ - Exit character selection mode, or go from non-character-selection mode - to character selection mode. - """ - selection_state = event.current_buffer.selection_state - - if selection_state.type != SelectionType.CHARACTERS: - selection_state.type = SelectionType.CHARACTERS - else: - event.current_buffer.exit_selection() - - @handle(Keys.ControlV, filter=selection_mode) - def _(event): - """ - Exit block selection mode, or go from non block selection mode to block - selection mode. - """ - selection_state = event.current_buffer.selection_state - - if selection_state.type != SelectionType.BLOCK: - selection_state.type = SelectionType.BLOCK - else: - event.current_buffer.exit_selection() - - - @handle('a', 'w', filter=selection_mode) - @handle('a', 'W', filter=selection_mode) - def _(event): - """ - Switch from visual linewise mode to visual characterwise mode. - """ - buffer = event.current_buffer - - if buffer.selection_state and buffer.selection_state.type == SelectionType.LINES: - buffer.selection_state.type = SelectionType.CHARACTERS - - @handle('x', filter=navigation_mode) - def _(event): - """ - Delete character. - """ - text = event.current_buffer.delete(count=event.arg) - event.cli.clipboard.set_text(text) - - @handle('X', filter=navigation_mode) - def _(event): - text = event.current_buffer.delete_before_cursor() - event.cli.clipboard.set_text(text) - - @handle('y', 'y', filter=navigation_mode) - @handle('Y', filter=navigation_mode) - def _(event): - """ - Yank the whole line. - """ - text = '\n'.join(event.current_buffer.document.lines_from_current[:event.arg]) - event.cli.clipboard.set_data(ClipboardData(text, SelectionType.LINES)) - - @handle('+', filter=navigation_mode) - def _(event): - """ - Move to first non whitespace of next line - """ - buffer = event.current_buffer - buffer.cursor_position += buffer.document.get_cursor_down_position(count=event.arg) - buffer.cursor_position += buffer.document.get_start_of_line_position(after_whitespace=True) - - @handle('-', filter=navigation_mode) - def _(event): - """ - Move to first non whitespace of previous line - """ - buffer = event.current_buffer - buffer.cursor_position += buffer.document.get_cursor_up_position(count=event.arg) - buffer.cursor_position += buffer.document.get_start_of_line_position(after_whitespace=True) - - @handle('>', '>', filter=navigation_mode) - def _(event): - """ - Indent lines. - """ - buffer = event.current_buffer - current_row = buffer.document.cursor_position_row - indent(buffer, current_row, current_row + event.arg) - - @handle('<', '<', filter=navigation_mode) - def _(event): - """ - Unindent lines. - """ - current_row = event.current_buffer.document.cursor_position_row - unindent(event.current_buffer, current_row, current_row + event.arg) - - @handle('O', filter=navigation_mode & ~IsReadOnly()) - def _(event): - """ - Open line above and enter insertion mode - """ - event.current_buffer.insert_line_above( - copy_margin=not event.cli.in_paste_mode) + def _(event): + " Enter character selection mode. " + event.current_buffer.start_selection(selection_type=SelectionType.CHARACTERS) + + @handle('v', filter=selection_mode) + def _(event): + """ + Exit character selection mode, or go from non-character-selection mode + to character selection mode. + """ + selection_state = event.current_buffer.selection_state + + if selection_state.type != SelectionType.CHARACTERS: + selection_state.type = SelectionType.CHARACTERS + else: + event.current_buffer.exit_selection() + + @handle(Keys.ControlV, filter=selection_mode) + def _(event): + """ + Exit block selection mode, or go from non block selection mode to block + selection mode. + """ + selection_state = event.current_buffer.selection_state + + if selection_state.type != SelectionType.BLOCK: + selection_state.type = SelectionType.BLOCK + else: + event.current_buffer.exit_selection() + + + @handle('a', 'w', filter=selection_mode) + @handle('a', 'W', filter=selection_mode) + def _(event): + """ + Switch from visual linewise mode to visual characterwise mode. + """ + buffer = event.current_buffer + + if buffer.selection_state and buffer.selection_state.type == SelectionType.LINES: + buffer.selection_state.type = SelectionType.CHARACTERS + + @handle('x', filter=navigation_mode) + def _(event): + """ + Delete character. + """ + text = event.current_buffer.delete(count=event.arg) + event.cli.clipboard.set_text(text) + + @handle('X', filter=navigation_mode) + def _(event): + text = event.current_buffer.delete_before_cursor() + event.cli.clipboard.set_text(text) + + @handle('y', 'y', filter=navigation_mode) + @handle('Y', filter=navigation_mode) + def _(event): + """ + Yank the whole line. + """ + text = '\n'.join(event.current_buffer.document.lines_from_current[:event.arg]) + event.cli.clipboard.set_data(ClipboardData(text, SelectionType.LINES)) + + @handle('+', filter=navigation_mode) + def _(event): + """ + Move to first non whitespace of next line + """ + buffer = event.current_buffer + buffer.cursor_position += buffer.document.get_cursor_down_position(count=event.arg) + buffer.cursor_position += buffer.document.get_start_of_line_position(after_whitespace=True) + + @handle('-', filter=navigation_mode) + def _(event): + """ + Move to first non whitespace of previous line + """ + buffer = event.current_buffer + buffer.cursor_position += buffer.document.get_cursor_up_position(count=event.arg) + buffer.cursor_position += buffer.document.get_start_of_line_position(after_whitespace=True) + + @handle('>', '>', filter=navigation_mode) + def _(event): + """ + Indent lines. + """ + buffer = event.current_buffer + current_row = buffer.document.cursor_position_row + indent(buffer, current_row, current_row + event.arg) + + @handle('<', '<', filter=navigation_mode) + def _(event): + """ + Unindent lines. + """ + current_row = event.current_buffer.document.cursor_position_row + unindent(event.current_buffer, current_row, current_row + event.arg) + + @handle('O', filter=navigation_mode & ~IsReadOnly()) + def _(event): + """ + Open line above and enter insertion mode + """ + event.current_buffer.insert_line_above( + copy_margin=not event.cli.in_paste_mode) event.cli.vi_state.input_mode = InputMode.INSERT - - @handle('o', filter=navigation_mode & ~IsReadOnly()) - def _(event): - """ - Open line below and enter insertion mode - """ - event.current_buffer.insert_line_below( - copy_margin=not event.cli.in_paste_mode) + + @handle('o', filter=navigation_mode & ~IsReadOnly()) + def _(event): + """ + Open line below and enter insertion mode + """ + event.current_buffer.insert_line_below( + copy_margin=not event.cli.in_paste_mode) event.cli.vi_state.input_mode = InputMode.INSERT - - @handle('~', filter=navigation_mode) - def _(event): - """ - Reverse case of current character and move cursor forward. - """ - buffer = event.current_buffer - c = buffer.document.current_char - - if c is not None and c != '\n': + + @handle('~', filter=navigation_mode) + def _(event): + """ + Reverse case of current character and move cursor forward. + """ + buffer = event.current_buffer + c = buffer.document.current_char + + if c is not None and c != '\n': buffer.insert_text(c.swapcase(), overwrite=True) - + @handle('g', 'u', 'u', filter=navigation_mode & ~IsReadOnly()) def _(event): " Lowercase current line. " @@ -870,64 +870,64 @@ def load_vi_bindings(get_search_state=None): buff = event.current_buffer buff.transform_current_line(lambda s: s.swapcase()) - @handle('#', filter=navigation_mode) - def _(event): - """ - Go to previous occurence of this word. - """ - b = event.cli.current_buffer - - search_state = get_search_state(event.cli) - search_state.text = b.document.get_word_under_cursor() - search_state.direction = IncrementalSearchDirection.BACKWARD - - b.apply_search(search_state, count=event.arg, - include_current_position=False) - - @handle('*', filter=navigation_mode) - def _(event): - """ - Go to next occurence of this word. - """ - b = event.cli.current_buffer - - search_state = get_search_state(event.cli) - search_state.text = b.document.get_word_under_cursor() - search_state.direction = IncrementalSearchDirection.FORWARD - - b.apply_search(search_state, count=event.arg, - include_current_position=False) - - @handle('(', filter=navigation_mode) - def _(event): - # TODO: go to begin of sentence. + @handle('#', filter=navigation_mode) + def _(event): + """ + Go to previous occurence of this word. + """ + b = event.cli.current_buffer + + search_state = get_search_state(event.cli) + search_state.text = b.document.get_word_under_cursor() + search_state.direction = IncrementalSearchDirection.BACKWARD + + b.apply_search(search_state, count=event.arg, + include_current_position=False) + + @handle('*', filter=navigation_mode) + def _(event): + """ + Go to next occurence of this word. + """ + b = event.cli.current_buffer + + search_state = get_search_state(event.cli) + search_state.text = b.document.get_word_under_cursor() + search_state.direction = IncrementalSearchDirection.FORWARD + + b.apply_search(search_state, count=event.arg, + include_current_position=False) + + @handle('(', filter=navigation_mode) + def _(event): + # TODO: go to begin of sentence. # XXX: should become text_object. - pass - - @handle(')', filter=navigation_mode) - def _(event): - # TODO: go to end of sentence. + pass + + @handle(')', filter=navigation_mode) + def _(event): + # TODO: go to end of sentence. # XXX: should become text_object. - pass - + pass + operator = create_operator_decorator(registry) text_object = create_text_object_decorator(registry) - + @text_object(Keys.Any, filter=operator_given) def _(event): """ Unknown key binding while waiting for a text object. """ event.cli.output.bell() - + # # *** Operators *** # - + def create_delete_and_change_operators(delete_only, with_register=False): """ Delete and change operators. - + :param delete_only: Create an operator that deletes, but doesn't go to insert mode. :param with_register: Copy the deleted text to this named register instead of the clipboard. """ @@ -935,16 +935,16 @@ def load_vi_bindings(get_search_state=None): handler_keys = ('"', Keys.Any, 'cd'[delete_only]) else: handler_keys = 'cd'[delete_only] - + @operator(*handler_keys, filter=~IsReadOnly()) def delete_or_change_operator(event, text_object): clipboard_data = None buff = event.current_buffer - + if text_object: new_document, clipboard_data = text_object.cut(buff) buff.document = new_document - + # Set deleted/changed text to clipboard or named register. if clipboard_data and clipboard_data.text: if with_register: @@ -953,11 +953,11 @@ def load_vi_bindings(get_search_state=None): event.cli.vi_state.named_registers[reg_name] = clipboard_data else: event.cli.clipboard.set_data(clipboard_data) - + # Only go back to insert mode in case of 'change'. if not delete_only: event.cli.vi_state.input_mode = InputMode.INSERT - + create_delete_and_change_operators(False, False) create_delete_and_change_operators(False, True) create_delete_and_change_operators(True, False) @@ -1034,68 +1034,68 @@ def load_vi_bindings(get_search_state=None): # @text_object('b') - def _(event): - """ Move one word or token left. """ + def _(event): + """ Move one word or token left. """ return TextObject(event.current_buffer.document.find_start_of_previous_word(count=event.arg) or 0) - + @text_object('B') - def _(event): - """ Move one non-blank word left """ + def _(event): + """ Move one non-blank word left """ return TextObject(event.current_buffer.document.find_start_of_previous_word(count=event.arg, WORD=True) or 0) - + @text_object('$') - def key_dollar(event): - """ 'c$', 'd$' and '$': Delete/change/move until end of line. """ + def key_dollar(event): + """ 'c$', 'd$' and '$': Delete/change/move until end of line. """ return TextObject(event.current_buffer.document.get_end_of_line_position()) - + @text_object('w') - def _(event): - """ 'word' forward. 'cw', 'dw', 'w': Delete/change/move one word. """ + def _(event): + """ 'word' forward. 'cw', 'dw', 'w': Delete/change/move one word. """ return TextObject(event.current_buffer.document.find_next_word_beginning(count=event.arg) or - event.current_buffer.document.get_end_of_document_position()) - + event.current_buffer.document.get_end_of_document_position()) + @text_object('W') - def _(event): - """ 'WORD' forward. 'cW', 'dW', 'W': Delete/change/move one WORD. """ + def _(event): + """ 'WORD' forward. 'cW', 'dW', 'W': Delete/change/move one WORD. """ return TextObject(event.current_buffer.document.find_next_word_beginning(count=event.arg, WORD=True) or - event.current_buffer.document.get_end_of_document_position()) - + event.current_buffer.document.get_end_of_document_position()) + @text_object('e') - def _(event): - """ End of 'word': 'ce', 'de', 'e' """ - end = event.current_buffer.document.find_next_word_ending(count=event.arg) + def _(event): + """ End of 'word': 'ce', 'de', 'e' """ + end = event.current_buffer.document.find_next_word_ending(count=event.arg) return TextObject(end - 1 if end else 0, type=TextObjectType.INCLUSIVE) - + @text_object('E') - def _(event): - """ End of 'WORD': 'cE', 'dE', 'E' """ - end = event.current_buffer.document.find_next_word_ending(count=event.arg, WORD=True) + def _(event): + """ End of 'WORD': 'cE', 'dE', 'E' """ + end = event.current_buffer.document.find_next_word_ending(count=event.arg, WORD=True) return TextObject(end - 1 if end else 0, type=TextObjectType.INCLUSIVE) - + @text_object('i', 'w', no_move_handler=True) - def _(event): - """ Inner 'word': ciw and diw """ - start, end = event.current_buffer.document.find_boundaries_of_current_word() + def _(event): + """ Inner 'word': ciw and diw """ + start, end = event.current_buffer.document.find_boundaries_of_current_word() return TextObject(start, end) - + @text_object('a', 'w', no_move_handler=True) - def _(event): - """ A 'word': caw and daw """ - start, end = event.current_buffer.document.find_boundaries_of_current_word(include_trailing_whitespace=True) + def _(event): + """ A 'word': caw and daw """ + start, end = event.current_buffer.document.find_boundaries_of_current_word(include_trailing_whitespace=True) return TextObject(start, end) - + @text_object('i', 'W', no_move_handler=True) - def _(event): - """ Inner 'WORD': ciW and diW """ - start, end = event.current_buffer.document.find_boundaries_of_current_word(WORD=True) + def _(event): + """ Inner 'WORD': ciW and diW """ + start, end = event.current_buffer.document.find_boundaries_of_current_word(WORD=True) return TextObject(start, end) - + @text_object('a', 'W', no_move_handler=True) - def _(event): - """ A 'WORD': caw and daw """ - start, end = event.current_buffer.document.find_boundaries_of_current_word(WORD=True, include_trailing_whitespace=True) + def _(event): + """ A 'WORD': caw and daw """ + start, end = event.current_buffer.document.find_boundaries_of_current_word(WORD=True, include_trailing_whitespace=True) return TextObject(start, end) - + @text_object('a', 'p', no_move_handler=True) def _(event): """ @@ -1106,24 +1106,24 @@ def load_vi_bindings(get_search_state=None): return TextObject(start, end) @text_object('^') - def key_circumflex(event): - """ 'c^', 'd^' and '^': Soft start of line, after whitespace. """ + def key_circumflex(event): + """ 'c^', 'd^' and '^': Soft start of line, after whitespace. """ return TextObject(event.current_buffer.document.get_start_of_line_position(after_whitespace=True)) - + @text_object('0') - def key_zero(event): - """ - 'c0', 'd0': Hard start of line, before whitespace. - (The move '0' key is implemented elsewhere, because a '0' could also change the `arg`.) - """ + def key_zero(event): + """ + 'c0', 'd0': Hard start of line, before whitespace. + (The move '0' key is implemented elsewhere, because a '0' could also change the `arg`.) + """ return TextObject(event.current_buffer.document.get_start_of_line_position(after_whitespace=False)) - + def create_ci_ca_handles(ci_start, ci_end, inner, key=None): - # TODO: 'dat', 'dit', (tags (like xml) - """ - Delete/Change string between this start and stop character. But keep these characters. - This implements all the ci", ci<, ci{, ci(, di", di<, ca", ca<, ... combinations. - """ + # TODO: 'dat', 'dit', (tags (like xml) + """ + Delete/Change string between this start and stop character. But keep these characters. + This implements all the ci", ci<, ci{, ci(, di", di<, ca", ca<, ... combinations. + """ def handler(event): if ci_start == ci_end: # Quotes @@ -1133,53 +1133,53 @@ def load_vi_bindings(get_search_state=None): # Brackets start = event.current_buffer.document.find_enclosing_bracket_left(ci_start, ci_end) end = event.current_buffer.document.find_enclosing_bracket_right(ci_start, ci_end) - - if start is not None and end is not None: - offset = 0 if inner else 1 + + if start is not None and end is not None: + offset = 0 if inner else 1 return TextObject(start + 1 - offset, end + offset) - else: - # Nothing found. + else: + # Nothing found. return TextObject(0) - + if key is None: text_object('ai'[inner], ci_start, no_move_handler=True)(handler) text_object('ai'[inner], ci_end, no_move_handler=True)(handler) else: text_object('ai'[inner], key, no_move_handler=True)(handler) - for inner in (False, True): - for ci_start, ci_end in [('"', '"'), ("'", "'"), ("`", "`"), - ('[', ']'), ('<', '>'), ('{', '}'), ('(', ')')]: - create_ci_ca_handles(ci_start, ci_end, inner) - + for inner in (False, True): + for ci_start, ci_end in [('"', '"'), ("'", "'"), ("`", "`"), + ('[', ']'), ('<', '>'), ('{', '}'), ('(', ')')]: + create_ci_ca_handles(ci_start, ci_end, inner) + create_ci_ca_handles('(', ')', inner, 'b') # 'dab', 'dib' create_ci_ca_handles('{', '}', inner, 'B') # 'daB', 'diB' @text_object('{') - def _(event): - """ - Move to previous blank-line separated section. - Implements '{', 'c{', 'd{', 'y{' - """ + def _(event): + """ + Move to previous blank-line separated section. + Implements '{', 'c{', 'd{', 'y{' + """ index = event.current_buffer.document.start_of_paragraph( count=event.arg, before=True) return TextObject(index) - + @text_object('}') - def _(event): - """ - Move to next blank-line separated section. - Implements '}', 'c}', 'd}', 'y}' - """ + def _(event): + """ + Move to next blank-line separated section. + Implements '}', 'c}', 'd}', 'y}' + """ index = event.current_buffer.document.end_of_paragraph(count=event.arg, after=True) return TextObject(index) - + @text_object('f', Keys.Any) - def _(event): - """ - Go to next occurance of character. Typing 'fx' will move the - cursor to the next occurance of character. 'x'. - """ + def _(event): + """ + Go to next occurance of character. Typing 'fx' will move the + cursor to the next occurance of character. 'x'. + """ event.cli.vi_state.last_character_find = CharacterFind(event.data, False) match = event.current_buffer.document.find( event.data, in_current_line=True, count=event.arg) @@ -1187,22 +1187,22 @@ def load_vi_bindings(get_search_state=None): return TextObject(match, type=TextObjectType.INCLUSIVE) else: return TextObject(0) - + @text_object('F', Keys.Any) - def _(event): - """ - Go to previous occurance of character. Typing 'Fx' will move the - cursor to the previous occurance of character. 'x'. - """ + def _(event): + """ + Go to previous occurance of character. Typing 'Fx' will move the + cursor to the previous occurance of character. 'x'. + """ event.cli.vi_state.last_character_find = CharacterFind(event.data, True) return TextObject(event.current_buffer.document.find_backwards( event.data, in_current_line=True, count=event.arg) or 0) - + @text_object('t', Keys.Any) - def _(event): - """ - Move right to the next occurance of c, then one char backward. - """ + def _(event): + """ + Move right to the next occurance of c, then one char backward. + """ event.cli.vi_state.last_character_find = CharacterFind(event.data, False) match = event.current_buffer.document.find( event.data, in_current_line=True, count=event.arg) @@ -1210,138 +1210,138 @@ def load_vi_bindings(get_search_state=None): return TextObject(match - 1, type=TextObjectType.INCLUSIVE) else: return TextObject(0) - + @text_object('T', Keys.Any) - def _(event): - """ - Move left to the previous occurance of c, then one char forward. - """ + def _(event): + """ + Move left to the previous occurance of c, then one char forward. + """ event.cli.vi_state.last_character_find = CharacterFind(event.data, True) match = event.current_buffer.document.find_backwards( event.data, in_current_line=True, count=event.arg) return TextObject(match + 1 if match else 0) - - def repeat(reverse): - """ - Create ',' and ';' commands. - """ + + def repeat(reverse): + """ + Create ',' and ';' commands. + """ @text_object(',' if reverse else ';') - def _(event): - # Repeat the last 'f'/'F'/'t'/'T' command. - pos = 0 + def _(event): + # Repeat the last 'f'/'F'/'t'/'T' command. + pos = 0 vi_state = event.cli.vi_state - + type = TextObjectType.EXCLUSIVE - if vi_state.last_character_find: - char = vi_state.last_character_find.character - backwards = vi_state.last_character_find.backwards - - if reverse: - backwards = not backwards - - if backwards: - pos = event.current_buffer.document.find_backwards(char, in_current_line=True, count=event.arg) - else: - pos = event.current_buffer.document.find(char, in_current_line=True, count=event.arg) + if vi_state.last_character_find: + char = vi_state.last_character_find.character + backwards = vi_state.last_character_find.backwards + + if reverse: + backwards = not backwards + + if backwards: + pos = event.current_buffer.document.find_backwards(char, in_current_line=True, count=event.arg) + else: + pos = event.current_buffer.document.find(char, in_current_line=True, count=event.arg) type = TextObjectType.INCLUSIVE if pos: return TextObject(pos, type=type) else: return TextObject(0) - repeat(True) - repeat(False) - + repeat(True) + repeat(False) + @text_object('h') @text_object(Keys.Left) - def _(event): - """ Implements 'ch', 'dh', 'h': Cursor left. """ + def _(event): + """ Implements 'ch', 'dh', 'h': Cursor left. """ return TextObject(event.current_buffer.document.get_cursor_left_position(count=event.arg)) - + @text_object('j', no_move_handler=True, no_selection_handler=True) # Note: We also need `no_selection_handler`, because we in # selection mode, we prefer the other 'j' binding that keeps # `buffer.preferred_column`. - def _(event): - """ Implements 'cj', 'dj', 'j', ... Cursor up. """ + def _(event): + """ Implements 'cj', 'dj', 'j', ... Cursor up. """ return TextObject(event.current_buffer.document.get_cursor_down_position(count=event.arg), type=TextObjectType.LINEWISE) - + @text_object('k', no_move_handler=True, no_selection_handler=True) - def _(event): - """ Implements 'ck', 'dk', 'k', ... Cursor up. """ + def _(event): + """ Implements 'ck', 'dk', 'k', ... Cursor up. """ return TextObject(event.current_buffer.document.get_cursor_up_position(count=event.arg), type=TextObjectType.LINEWISE) - + @text_object('l') @text_object(' ') @text_object(Keys.Right) - def _(event): - """ Implements 'cl', 'dl', 'l', 'c ', 'd ', ' '. Cursor right. """ + def _(event): + """ Implements 'cl', 'dl', 'l', 'c ', 'd ', ' '. Cursor right. """ return TextObject(event.current_buffer.document.get_cursor_right_position(count=event.arg)) - + @text_object('H') - def _(event): - """ - Moves to the start of the visible region. (Below the scroll offset.) - Implements 'cH', 'dH', 'H'. - """ - w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) - b = event.current_buffer - + def _(event): + """ + Moves to the start of the visible region. (Below the scroll offset.) + Implements 'cH', 'dH', 'H'. + """ + w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) + b = event.current_buffer + if w and w.render_info: - # When we find a Window that has BufferControl showing this window, - # move to the start of the visible area. - pos = (b.document.translate_row_col_to_index( - w.render_info.first_visible_line(after_scroll_offset=True), 0) - - b.cursor_position) - - else: - # Otherwise, move to the start of the input. - pos = -len(b.document.text_before_cursor) + # When we find a Window that has BufferControl showing this window, + # move to the start of the visible area. + pos = (b.document.translate_row_col_to_index( + w.render_info.first_visible_line(after_scroll_offset=True), 0) - + b.cursor_position) + + else: + # Otherwise, move to the start of the input. + pos = -len(b.document.text_before_cursor) return TextObject(pos, type=TextObjectType.LINEWISE) - + @text_object('M') - def _(event): - """ - Moves cursor to the vertical center of the visible region. - Implements 'cM', 'dM', 'M'. - """ - w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) - b = event.current_buffer - + def _(event): + """ + Moves cursor to the vertical center of the visible region. + Implements 'cM', 'dM', 'M'. + """ + w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) + b = event.current_buffer + if w and w.render_info: - # When we find a Window that has BufferControl showing this window, - # move to the center of the visible area. - pos = (b.document.translate_row_col_to_index( - w.render_info.center_visible_line(), 0) - - b.cursor_position) - - else: - # Otherwise, move to the start of the input. - pos = -len(b.document.text_before_cursor) + # When we find a Window that has BufferControl showing this window, + # move to the center of the visible area. + pos = (b.document.translate_row_col_to_index( + w.render_info.center_visible_line(), 0) - + b.cursor_position) + + else: + # Otherwise, move to the start of the input. + pos = -len(b.document.text_before_cursor) return TextObject(pos, type=TextObjectType.LINEWISE) - + @text_object('L') - def _(event): - """ - Moves to the end of the visible region. (Above the scroll offset.) - """ - w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) - b = event.current_buffer - + def _(event): + """ + Moves to the end of the visible region. (Above the scroll offset.) + """ + w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) + b = event.current_buffer + if w and w.render_info: - # When we find a Window that has BufferControl showing this window, - # move to the end of the visible area. - pos = (b.document.translate_row_col_to_index( - w.render_info.last_visible_line(before_scroll_offset=True), 0) - - b.cursor_position) - - else: - # Otherwise, move to the end of the input. - pos = len(b.document.text_after_cursor) + # When we find a Window that has BufferControl showing this window, + # move to the end of the visible area. + pos = (b.document.translate_row_col_to_index( + w.render_info.last_visible_line(before_scroll_offset=True), 0) - + b.cursor_position) + + else: + # Otherwise, move to the end of the input. + pos = len(b.document.text_after_cursor) return TextObject(pos, type=TextObjectType.LINEWISE) - + @text_object('n', no_move_handler=True) def _(event): " Search next. " @@ -1374,50 +1374,50 @@ def load_vi_bindings(get_search_state=None): ~get_search_state(event.cli), include_current_position=False, count=event.arg) - @handle('z', '+', filter=navigation_mode|selection_mode) - @handle('z', 't', filter=navigation_mode|selection_mode) - @handle('z', Keys.ControlJ, filter=navigation_mode|selection_mode) - def _(event): - """ - Scrolls the window to makes the current line the first line in the visible region. - """ - w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) - b = event.cli.current_buffer + @handle('z', '+', filter=navigation_mode|selection_mode) + @handle('z', 't', filter=navigation_mode|selection_mode) + @handle('z', Keys.ControlJ, filter=navigation_mode|selection_mode) + def _(event): + """ + Scrolls the window to makes the current line the first line in the visible region. + """ + w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) + b = event.cli.current_buffer w.vertical_scroll = b.document.cursor_position_row - - @handle('z', '-', filter=navigation_mode|selection_mode) - @handle('z', 'b', filter=navigation_mode|selection_mode) - def _(event): - """ - Scrolls the window to makes the current line the last line in the visible region. - """ - w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) - + + @handle('z', '-', filter=navigation_mode|selection_mode) + @handle('z', 'b', filter=navigation_mode|selection_mode) + def _(event): + """ + Scrolls the window to makes the current line the last line in the visible region. + """ + w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) + # We can safely set the scroll offset to zero; the Window will meke # sure that it scrolls at least enough to make the cursor visible # again. w.vertical_scroll = 0 - - @handle('z', 'z', filter=navigation_mode|selection_mode) - def _(event): - """ - Center Window vertically around cursor. - """ - w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) - b = event.cli.current_buffer - - if w and w.render_info: + + @handle('z', 'z', filter=navigation_mode|selection_mode) + def _(event): + """ + Center Window vertically around cursor. + """ + w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) + b = event.cli.current_buffer + + if w and w.render_info: info = w.render_info - # Calculate the offset that we need in order to position the row - # containing the cursor in the center. + # Calculate the offset that we need in order to position the row + # containing the cursor in the center. scroll_height = info.window_height // 2 - + y = max(0, b.document.cursor_position_row - 1) height = 0 while y > 0: line_height = info.get_height_for_line(y) - + if height + line_height < scroll_height: height += line_height y -= 1 @@ -1427,81 +1427,81 @@ def load_vi_bindings(get_search_state=None): w.vertical_scroll = y @text_object('%') - def _(event): - """ - Implements 'c%', 'd%', '%, 'y%' (Move to corresponding bracket.) - If an 'arg' has been given, go this this % position in the file. - """ - buffer = event.current_buffer - - if event._arg: - # If 'arg' has been given, the meaning of % is to go to the 'x%' - # row in the file. - if 0 < event.arg <= 100: - absolute_index = buffer.document.translate_row_col_to_index( + def _(event): + """ + Implements 'c%', 'd%', '%, 'y%' (Move to corresponding bracket.) + If an 'arg' has been given, go this this % position in the file. + """ + buffer = event.current_buffer + + if event._arg: + # If 'arg' has been given, the meaning of % is to go to the 'x%' + # row in the file. + if 0 < event.arg <= 100: + absolute_index = buffer.document.translate_row_col_to_index( int((event.arg * buffer.document.line_count - 1) / 100), 0) return TextObject(absolute_index - buffer.document.cursor_position, type=TextObjectType.LINEWISE) - else: + else: return TextObject(0) # Do nothing. - - else: - # Move to the corresponding opening/closing bracket (()'s, []'s and {}'s). + + else: + # Move to the corresponding opening/closing bracket (()'s, []'s and {}'s). match = buffer.document.find_matching_bracket_position() if match: return TextObject(match, type=TextObjectType.INCLUSIVE) else: return TextObject(0) - + @text_object('|') - def _(event): - # Move to the n-th column (you may specify the argument n by typing - # it on number keys, for example, 20|). + def _(event): + # Move to the n-th column (you may specify the argument n by typing + # it on number keys, for example, 20|). return TextObject(event.current_buffer.document.get_column_cursor_position(event.arg - 1)) - + @text_object('g', 'g') - def _(event): - """ - Implements 'gg', 'cgg', 'ygg' - """ - d = event.current_buffer.document - - if event._arg: - # Move to the given line. + def _(event): + """ + Implements 'gg', 'cgg', 'ygg' + """ + d = event.current_buffer.document + + if event._arg: + # Move to the given line. return TextObject(d.translate_row_col_to_index(event.arg - 1, 0) - d.cursor_position, type=TextObjectType.LINEWISE) - else: - # Move to the top of the input. + else: + # Move to the top of the input. return TextObject(d.get_start_of_document_position(), type=TextObjectType.LINEWISE) - + @text_object('g', '_') - def _(event): - """ - Go to last non-blank of line. - 'g_', 'cg_', 'yg_', etc.. - """ + def _(event): + """ + Go to last non-blank of line. + 'g_', 'cg_', 'yg_', etc.. + """ return TextObject( event.current_buffer.document.last_non_blank_of_current_line_position(), type=TextObjectType.INCLUSIVE) - + @text_object('g', 'e') - def _(event): - """ - Go to last character of previous word. - 'ge', 'cge', 'yge', etc.. - """ + def _(event): + """ + Go to last character of previous word. + 'ge', 'cge', 'yge', etc.. + """ prev_end = event.current_buffer.document.find_previous_word_ending(count=event.arg) return TextObject(prev_end - 1 if prev_end is not None else 0, type=TextObjectType.INCLUSIVE) - + @text_object('g', 'E') - def _(event): - """ - Go to last character of previous WORD. - 'gE', 'cgE', 'ygE', etc.. - """ + def _(event): + """ + Go to last character of previous WORD. + 'gE', 'cgE', 'ygE', etc.. + """ prev_end = event.current_buffer.document.find_previous_word_ending(count=event.arg, WORD=True) return TextObject(prev_end - 1 if prev_end is not None else 0, type=TextObjectType.INCLUSIVE) - + @text_object('g', 'm') - def _(event): - """ + def _(event): + """ Like g0, but half a screenwidth to the right. (Or as much as possible.) """ w = find_window_for_buffer_name(event.cli, event.cli.current_buffer_name) @@ -1518,58 +1518,58 @@ def load_vi_bindings(get_search_state=None): @text_object('G') def _(event): """ - Go to the end of the document. (If no arg has been given.) - """ + Go to the end of the document. (If no arg has been given.) + """ buf = event.current_buffer return TextObject(buf.document.translate_row_col_to_index(buf.document.line_count - 1, 0) - buf.cursor_position, type=TextObjectType.LINEWISE) - + # # *** Other *** # - @handle('G', filter=HasArg()) - def _(event): - """ - If an argument is given, move to this line in the history. (for - example, 15G) - """ - event.current_buffer.go_to_history(event.arg - 1) - + @handle('G', filter=HasArg()) + def _(event): + """ + If an argument is given, move to this line in the history. (for + example, 15G) + """ + event.current_buffer.go_to_history(event.arg - 1) + for n in '123456789': @handle(n, filter=navigation_mode|selection_mode|operator_given) def _(event): """ Always handle numberics in navigation mode as arg. """ - event.append_to_arg_count(event.data) - + event.append_to_arg_count(event.data) + @handle('0', filter=(navigation_mode|selection_mode|operator_given) & HasArg()) def _(event): " Zero when an argument was already give. " event.append_to_arg_count(event.data) - @handle(Keys.Any, filter=replace_mode) - def _(event): - """ - Insert data at cursor position. - """ - event.current_buffer.insert_text(event.data, overwrite=True) - + @handle(Keys.Any, filter=replace_mode) + def _(event): + """ + Insert data at cursor position. + """ + event.current_buffer.insert_text(event.data, overwrite=True) + @handle(Keys.Any, filter=insert_multiple_mode, save_before=(lambda e: not e.is_repeat)) def _(event): - """ + """ Insert data at multiple cursor positions at once. (Usually a result of pressing 'I' or 'A' in block-selection mode.) - """ + """ buff = event.current_buffer original_text = buff.text - + # Construct new text. text = [] p = 0 - + for p2 in buff.multiple_cursor_positions: text.append(original_text[p:p2]) text.append(event.data) @@ -1654,27 +1654,27 @@ def load_vi_bindings(get_search_state=None): event.cli.output.bell() - @handle(Keys.ControlX, Keys.ControlL, filter=insert_mode) - def _(event): - """ - Pressing the ControlX - ControlL sequence in Vi mode does line - completion based on the other lines in the document and the history. - """ - event.current_buffer.start_history_lines_completion() - - @handle(Keys.ControlX, Keys.ControlF, filter=insert_mode) - def _(event): - """ - Complete file names. - """ - # TODO - pass - + @handle(Keys.ControlX, Keys.ControlL, filter=insert_mode) + def _(event): + """ + Pressing the ControlX - ControlL sequence in Vi mode does line + completion based on the other lines in the document and the history. + """ + event.current_buffer.start_history_lines_completion() + + @handle(Keys.ControlX, Keys.ControlF, filter=insert_mode) + def _(event): + """ + Complete file names. + """ + # TODO + pass + @handle(Keys.ControlK, filter=insert_mode|replace_mode) def _(event): " Go into digraph mode. " event.cli.vi_state.waiting_for_digraph = True - + @Condition def digraph_symbol_1_given(cli): return cli.vi_state.digraph_symbol1 is not None @@ -1709,128 +1709,128 @@ def load_vi_bindings(get_search_state=None): def load_vi_open_in_editor_bindings(): - """ - Pressing 'v' in navigation mode will open the buffer in an external editor. - """ + """ + Pressing 'v' in navigation mode will open the buffer in an external editor. + """ registry = Registry() navigation_mode = ViNavigationMode() - + registry.add_binding('v', filter=navigation_mode)( get_by_name('edit-and-execute-command')) return registry - - + + def load_vi_system_bindings(): registry = ConditionalRegistry(Registry(), ViMode()) handle = registry.add_binding - has_focus = filters.HasFocus(SYSTEM_BUFFER) + has_focus = filters.HasFocus(SYSTEM_BUFFER) navigation_mode = ViNavigationMode() - - @handle('!', filter=~has_focus & navigation_mode) - def _(event): - """ - '!' opens the system prompt. - """ - event.cli.push_focus(SYSTEM_BUFFER) + + @handle('!', filter=~has_focus & navigation_mode) + def _(event): + """ + '!' opens the system prompt. + """ + event.cli.push_focus(SYSTEM_BUFFER) event.cli.vi_state.input_mode = InputMode.INSERT - - @handle(Keys.Escape, filter=has_focus) - @handle(Keys.ControlC, filter=has_focus) - def _(event): - """ - Cancel system prompt. - """ + + @handle(Keys.Escape, filter=has_focus) + @handle(Keys.ControlC, filter=has_focus) + def _(event): + """ + Cancel system prompt. + """ event.cli.vi_state.input_mode = InputMode.NAVIGATION - event.cli.buffers[SYSTEM_BUFFER].reset() - event.cli.pop_focus() - - @handle(Keys.ControlJ, filter=has_focus) - def _(event): - """ - Run system command. - """ + event.cli.buffers[SYSTEM_BUFFER].reset() + event.cli.pop_focus() + + @handle(Keys.ControlJ, filter=has_focus) + def _(event): + """ + Run system command. + """ event.cli.vi_state.input_mode = InputMode.NAVIGATION - - system_buffer = event.cli.buffers[SYSTEM_BUFFER] - event.cli.run_system_command(system_buffer.text) - system_buffer.reset(append_to_history=True) - - # Focus previous buffer again. - event.cli.pop_focus() - + + system_buffer = event.cli.buffers[SYSTEM_BUFFER] + event.cli.run_system_command(system_buffer.text) + system_buffer.reset(append_to_history=True) + + # Focus previous buffer again. + event.cli.pop_focus() + return registry - + def load_vi_search_bindings(get_search_state=None, search_buffer_name=SEARCH_BUFFER): - assert get_search_state is None or callable(get_search_state) - - if not get_search_state: - def get_search_state(cli): return cli.search_state - + assert get_search_state is None or callable(get_search_state) + + if not get_search_state: + def get_search_state(cli): return cli.search_state + registry = ConditionalRegistry(Registry(), ViMode()) handle = registry.add_binding - has_focus = filters.HasFocus(search_buffer_name) + has_focus = filters.HasFocus(search_buffer_name) navigation_mode = ViNavigationMode() selection_mode = ViSelectionMode() - + reverse_vi_search_direction = Condition( lambda cli: cli.application.reverse_vi_search_direction(cli)) @handle('/', filter=(navigation_mode|selection_mode)&~reverse_vi_search_direction) @handle('?', filter=(navigation_mode|selection_mode)&reverse_vi_search_direction) - @handle(Keys.ControlS, filter=~has_focus) - def _(event): - """ - Vi-style forward search. - """ - # Set the ViState. - get_search_state(event.cli).direction = IncrementalSearchDirection.FORWARD + @handle(Keys.ControlS, filter=~has_focus) + def _(event): + """ + Vi-style forward search. + """ + # Set the ViState. + get_search_state(event.cli).direction = IncrementalSearchDirection.FORWARD event.cli.vi_state.input_mode = InputMode.INSERT - - # Focus search buffer. - event.cli.push_focus(search_buffer_name) - + + # Focus search buffer. + event.cli.push_focus(search_buffer_name) + @handle('?', filter=(navigation_mode|selection_mode)&~reverse_vi_search_direction) @handle('/', filter=(navigation_mode|selection_mode)&reverse_vi_search_direction) - @handle(Keys.ControlR, filter=~has_focus) - def _(event): - """ - Vi-style backward search. - """ - # Set the ViState. - get_search_state(event.cli).direction = IncrementalSearchDirection.BACKWARD - - # Focus search buffer. - event.cli.push_focus(search_buffer_name) + @handle(Keys.ControlR, filter=~has_focus) + def _(event): + """ + Vi-style backward search. + """ + # Set the ViState. + get_search_state(event.cli).direction = IncrementalSearchDirection.BACKWARD + + # Focus search buffer. + event.cli.push_focus(search_buffer_name) event.cli.vi_state.input_mode = InputMode.INSERT - - @handle(Keys.ControlJ, filter=has_focus) + + @handle(Keys.ControlJ, filter=has_focus) @handle(Keys.Escape, filter=has_focus) - def _(event): - """ - Apply the search. (At the / or ? prompt.) - """ - input_buffer = event.cli.buffers.previous(event.cli) - search_buffer = event.cli.buffers[search_buffer_name] - - # Update search state. - if search_buffer.text: - get_search_state(event.cli).text = search_buffer.text - - # Apply search. - input_buffer.apply_search(get_search_state(event.cli)) - - # Add query to history of search line. - search_buffer.append_to_history() - search_buffer.reset() - - # Focus previous document again. + def _(event): + """ + Apply the search. (At the / or ? prompt.) + """ + input_buffer = event.cli.buffers.previous(event.cli) + search_buffer = event.cli.buffers[search_buffer_name] + + # Update search state. + if search_buffer.text: + get_search_state(event.cli).text = search_buffer.text + + # Apply search. + input_buffer.apply_search(get_search_state(event.cli)) + + # Add query to history of search line. + search_buffer.append_to_history() + search_buffer.reset() + + # Focus previous document again. event.cli.vi_state.input_mode = InputMode.NAVIGATION - event.cli.pop_focus() - + event.cli.pop_focus() + def incremental_search(cli, direction, count=1): " Apply search, but keep search buffer focussed. " # Update search_state. @@ -1854,41 +1854,41 @@ def load_vi_search_bindings(get_search_state=None, def _(event): incremental_search(event.cli, IncrementalSearchDirection.FORWARD, count=event.arg) - def search_buffer_is_empty(cli): - """ Returns True when the search buffer is empty. """ - return cli.buffers[search_buffer_name].text == '' - - @handle(Keys.ControlC, filter=has_focus) + def search_buffer_is_empty(cli): + """ Returns True when the search buffer is empty. """ + return cli.buffers[search_buffer_name].text == '' + + @handle(Keys.ControlC, filter=has_focus) @handle(Keys.ControlH, filter=has_focus & Condition(search_buffer_is_empty)) - @handle(Keys.Backspace, filter=has_focus & Condition(search_buffer_is_empty)) - def _(event): - """ - Cancel search. - """ + @handle(Keys.Backspace, filter=has_focus & Condition(search_buffer_is_empty)) + def _(event): + """ + Cancel search. + """ event.cli.vi_state.input_mode = InputMode.NAVIGATION - - event.cli.pop_focus() - event.cli.buffers[search_buffer_name].reset() - + + event.cli.pop_focus() + event.cli.buffers[search_buffer_name].reset() + return registry - + def load_extra_vi_page_navigation_bindings(): - """ - Key bindings, for scrolling up and down through pages. - This are separate bindings, because GNU readline doesn't have them. - """ + """ + Key bindings, for scrolling up and down through pages. + This are separate bindings, because GNU readline doesn't have them. + """ registry = ConditionalRegistry(Registry(), ViMode()) handle = registry.add_binding - - handle(Keys.ControlF)(scroll_forward) - handle(Keys.ControlB)(scroll_backward) - handle(Keys.ControlD)(scroll_half_page_down) - handle(Keys.ControlU)(scroll_half_page_up) - handle(Keys.ControlE)(scroll_one_line_down) - handle(Keys.ControlY)(scroll_one_line_up) - handle(Keys.PageDown)(scroll_page_down) - handle(Keys.PageUp)(scroll_page_up) + + handle(Keys.ControlF)(scroll_forward) + handle(Keys.ControlB)(scroll_backward) + handle(Keys.ControlD)(scroll_half_page_down) + handle(Keys.ControlU)(scroll_half_page_up) + handle(Keys.ControlE)(scroll_one_line_down) + handle(Keys.ControlY)(scroll_one_line_up) + handle(Keys.PageDown)(scroll_page_down) + handle(Keys.PageUp)(scroll_page_up) return registry diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/input_processor.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/input_processor.py index 51a3110827..a94acad31c 100644 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/input_processor.py +++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/input_processor.py @@ -1,35 +1,35 @@ -# *** encoding: utf-8 *** -""" -An :class:`~.InputProcessor` receives callbacks for the keystrokes parsed from -the input in the :class:`~prompt_toolkit.inputstream.InputStream` instance. - -The `InputProcessor` will according to the implemented keybindings call the +# *** encoding: utf-8 *** +""" +An :class:`~.InputProcessor` receives callbacks for the keystrokes parsed from +the input in the :class:`~prompt_toolkit.inputstream.InputStream` instance. + +The `InputProcessor` will according to the implemented keybindings call the correct callbacks when new key presses are feed through `feed`. -""" -from __future__ import unicode_literals -from prompt_toolkit.buffer import EditReadOnlyBuffer +""" +from __future__ import unicode_literals +from prompt_toolkit.buffer import EditReadOnlyBuffer from prompt_toolkit.filters.cli import ViNavigationMode from prompt_toolkit.keys import Keys, Key from prompt_toolkit.utils import Event - + from .registry import BaseRegistry from collections import deque from six.moves import range -import weakref +import weakref import six - -__all__ = ( - 'InputProcessor', - 'KeyPress', -) - - -class KeyPress(object): - """ + +__all__ = ( + 'InputProcessor', + 'KeyPress', +) + + +class KeyPress(object): + """ :param key: A `Keys` instance or text (one character). - :param data: The received string on stdin. (Often vt100 escape codes.) - """ + :param data: The received string on stdin. (Often vt100 escape codes.) + """ def __init__(self, key, data=None): assert isinstance(key, (six.text_type, Key)) assert data is None or isinstance(data, six.text_type) @@ -37,44 +37,44 @@ class KeyPress(object): if data is None: data = key.name if isinstance(key, Key) else key - self.key = key - self.data = data - - def __repr__(self): - return '%s(key=%r, data=%r)' % ( - self.__class__.__name__, self.key, self.data) - - def __eq__(self, other): - return self.key == other.key and self.data == other.data - - -class InputProcessor(object): - """ - Statemachine that receives :class:`KeyPress` instances and according to the - key bindings in the given :class:`Registry`, calls the matching handlers. - - :: - - p = InputProcessor(registry) - - # Send keys into the processor. + self.key = key + self.data = data + + def __repr__(self): + return '%s(key=%r, data=%r)' % ( + self.__class__.__name__, self.key, self.data) + + def __eq__(self, other): + return self.key == other.key and self.data == other.data + + +class InputProcessor(object): + """ + Statemachine that receives :class:`KeyPress` instances and according to the + key bindings in the given :class:`Registry`, calls the matching handlers. + + :: + + p = InputProcessor(registry) + + # Send keys into the processor. p.feed(KeyPress(Keys.ControlX, '\x18')) p.feed(KeyPress(Keys.ControlC, '\x03') - + # Process all the keys in the queue. p.process_keys() - # Now the ControlX-ControlC callback will be called if this sequence is - # registered in the registry. - + # Now the ControlX-ControlC callback will be called if this sequence is + # registered in the registry. + :param registry: `BaseRegistry` instance. - :param cli_ref: weakref to `CommandLineInterface`. - """ - def __init__(self, registry, cli_ref): + :param cli_ref: weakref to `CommandLineInterface`. + """ + def __init__(self, registry, cli_ref): assert isinstance(registry, BaseRegistry) - self._registry = registry - self._cli_ref = cli_ref + self._registry = registry + self._cli_ref = cli_ref self.beforeKeyPress = Event(self) self.afterKeyPress = Event(self) @@ -90,19 +90,19 @@ class InputProcessor(object): self.record_macro = False self.macro = [] - self.reset() - - def reset(self): + self.reset() + + def reset(self): self._previous_key_sequence = [] - self._previous_handler = None - - self._process_coroutine = self._process() - self._process_coroutine.send(None) - - #: Readline argument (for repetition of commands.) - #: https://www.gnu.org/software/bash/manual/html_node/Readline-Arguments.html - self.arg = None - + self._previous_handler = None + + self._process_coroutine = self._process() + self._process_coroutine.send(None) + + #: Readline argument (for repetition of commands.) + #: https://www.gnu.org/software/bash/manual/html_node/Readline-Arguments.html + self.arg = None + def start_macro(self): " Start recording macro. " self.record_macro = True @@ -116,106 +116,106 @@ class InputProcessor(object): for k in self.macro: self.feed(k) - def _get_matches(self, key_presses): - """ - For a list of :class:`KeyPress` instances. Give the matching handlers - that would handle this. - """ - keys = tuple(k.key for k in key_presses) - cli = self._cli_ref() - - # Try match, with mode flag + def _get_matches(self, key_presses): + """ + For a list of :class:`KeyPress` instances. Give the matching handlers + that would handle this. + """ + keys = tuple(k.key for k in key_presses) + cli = self._cli_ref() + + # Try match, with mode flag return [b for b in self._registry.get_bindings_for_keys(keys) if b.filter(cli)] - - def _is_prefix_of_longer_match(self, key_presses): - """ - For a list of :class:`KeyPress` instances. Return True if there is any - handler that is bound to a suffix of this keys. - """ - keys = tuple(k.key for k in key_presses) - cli = self._cli_ref() - - # Get the filters for all the key bindings that have a longer match. - # Note that we transform it into a `set`, because we don't care about - # the actual bindings and executing it more than once doesn't make - # sense. (Many key bindings share the same filter.) - filters = set(b.filter for b in self._registry.get_bindings_starting_with_keys(keys)) - - # When any key binding is active, return True. - return any(f(cli) for f in filters) - - def _process(self): - """ - Coroutine implementing the key match algorithm. Key strokes are sent - into this generator, and it calls the appropriate handlers. - """ + + def _is_prefix_of_longer_match(self, key_presses): + """ + For a list of :class:`KeyPress` instances. Return True if there is any + handler that is bound to a suffix of this keys. + """ + keys = tuple(k.key for k in key_presses) + cli = self._cli_ref() + + # Get the filters for all the key bindings that have a longer match. + # Note that we transform it into a `set`, because we don't care about + # the actual bindings and executing it more than once doesn't make + # sense. (Many key bindings share the same filter.) + filters = set(b.filter for b in self._registry.get_bindings_starting_with_keys(keys)) + + # When any key binding is active, return True. + return any(f(cli) for f in filters) + + def _process(self): + """ + Coroutine implementing the key match algorithm. Key strokes are sent + into this generator, and it calls the appropriate handlers. + """ buffer = self.key_buffer - retry = False - - while True: - if retry: - retry = False - else: - buffer.append((yield)) - - # If we have some key presses, check for matches. - if buffer: - is_prefix_of_longer_match = self._is_prefix_of_longer_match(buffer) - matches = self._get_matches(buffer) - + retry = False + + while True: + if retry: + retry = False + else: + buffer.append((yield)) + + # If we have some key presses, check for matches. + if buffer: + is_prefix_of_longer_match = self._is_prefix_of_longer_match(buffer) + matches = self._get_matches(buffer) + # When eager matches were found, give priority to them and also # ignore all the longer matches. eager_matches = [m for m in matches if m.eager(self._cli_ref())] if eager_matches: matches = eager_matches - is_prefix_of_longer_match = False - - # Exact matches found, call handler. - if not is_prefix_of_longer_match and matches: + is_prefix_of_longer_match = False + + # Exact matches found, call handler. + if not is_prefix_of_longer_match and matches: self._call_handler(matches[-1], key_sequence=buffer[:]) del buffer[:] # Keep reference. - - # No match found. - elif not is_prefix_of_longer_match and not matches: - retry = True - found = False - - # Loop over the input, try longest match first and shift. - for i in range(len(buffer), 0, -1): - matches = self._get_matches(buffer[:i]) - if matches: - self._call_handler(matches[-1], key_sequence=buffer[:i]) + + # No match found. + elif not is_prefix_of_longer_match and not matches: + retry = True + found = False + + # Loop over the input, try longest match first and shift. + for i in range(len(buffer), 0, -1): + matches = self._get_matches(buffer[:i]) + if matches: + self._call_handler(matches[-1], key_sequence=buffer[:i]) del buffer[:i] - found = True + found = True break - - if not found: + + if not found: del buffer[:1] - + def feed(self, key_press): - """ + """ Add a new :class:`KeyPress` to the input queue. (Don't forget to call `process_keys` in order to process the queue.) - """ - assert isinstance(key_press, KeyPress) + """ + assert isinstance(key_press, KeyPress) self.input_queue.append(key_press) - + def process_keys(self): """ Process all the keys in the `input_queue`. (To be called after `feed`.) - + Note: because of the `feed`/`process_keys` separation, it is possible to call `feed` from inside a key binding. This function keeps looping until the queue is empty. """ while self.input_queue: key_press = self.input_queue.popleft() - + if key_press.key != Keys.CPRResponse: self.beforeKeyPress.fire() - + self._process_coroutine.send(key_press) if key_press.key != Keys.CPRResponse: @@ -226,16 +226,16 @@ class InputProcessor(object): if cli: cli.invalidate() - def _call_handler(self, handler, key_sequence=None): + def _call_handler(self, handler, key_sequence=None): was_recording = self.record_macro - arg = self.arg - self.arg = None - + arg = self.arg + self.arg = None + event = KeyPressEvent( weakref.ref(self), arg=arg, key_sequence=key_sequence, previous_key_sequence=self._previous_key_sequence, is_repeat=(handler == self._previous_handler)) - + # Save the state of the current buffer. cli = event.cli # Can be `None` (In unit-tests only.) @@ -243,18 +243,18 @@ class InputProcessor(object): cli.current_buffer.save_to_undo_stack() # Call handler. - try: - handler.call(event) + try: + handler.call(event) self._fix_vi_cursor_position(event) - - except EditReadOnlyBuffer: + + except EditReadOnlyBuffer: # When a key binding does an attempt to change a buffer which is # read-only, we can just silently ignore that. - pass - - self._previous_key_sequence = key_sequence - self._previous_handler = handler - + pass + + self._previous_key_sequence = key_sequence + self._previous_handler = handler + # Record the key sequence in our macro. (Only if we're in macro mode # before and after executing the key.) if self.record_macro and was_recording: @@ -266,16 +266,16 @@ class InputProcessor(object): never put the cursor after the last character of a line. (Unless it's an empty line.) """ - cli = self._cli_ref() + cli = self._cli_ref() if cli: buff = cli.current_buffer preferred_column = buff.preferred_column - + if (ViNavigationMode()(event.cli) and buff.document.is_cursor_at_the_end_of_line and len(buff.document.current_line) > 0): buff.cursor_position -= 1 - + # Set the preferred_column for arrow up/down again. # (This was cleared after changing the cursor position.) buff.preferred_column = preferred_column @@ -283,60 +283,60 @@ class InputProcessor(object): class KeyPressEvent(object): - """ - Key press event, delivered to key bindings. - - :param input_processor_ref: Weak reference to the `InputProcessor`. - :param arg: Repetition argument. - :param key_sequence: List of `KeyPress` instances. - :param previouskey_sequence: Previous list of `KeyPress` instances. - :param is_repeat: True when the previous event was delivered to the same handler. - """ - def __init__(self, input_processor_ref, arg=None, key_sequence=None, - previous_key_sequence=None, is_repeat=False): - self._input_processor_ref = input_processor_ref - self.key_sequence = key_sequence - self.previous_key_sequence = previous_key_sequence - - #: True when the previous key sequence was handled by the same handler. - self.is_repeat = is_repeat - - self._arg = arg - - def __repr__(self): + """ + Key press event, delivered to key bindings. + + :param input_processor_ref: Weak reference to the `InputProcessor`. + :param arg: Repetition argument. + :param key_sequence: List of `KeyPress` instances. + :param previouskey_sequence: Previous list of `KeyPress` instances. + :param is_repeat: True when the previous event was delivered to the same handler. + """ + def __init__(self, input_processor_ref, arg=None, key_sequence=None, + previous_key_sequence=None, is_repeat=False): + self._input_processor_ref = input_processor_ref + self.key_sequence = key_sequence + self.previous_key_sequence = previous_key_sequence + + #: True when the previous key sequence was handled by the same handler. + self.is_repeat = is_repeat + + self._arg = arg + + def __repr__(self): return 'KeyPressEvent(arg=%r, key_sequence=%r, is_repeat=%r)' % ( - self.arg, self.key_sequence, self.is_repeat) - - @property - def data(self): - return self.key_sequence[-1].data - - @property - def input_processor(self): - return self._input_processor_ref() - - @property - def cli(self): - """ - Command line interface. - """ - return self.input_processor._cli_ref() - - @property - def current_buffer(self): - """ - The current buffer. - """ - return self.cli.current_buffer - - @property - def arg(self): - """ - Repetition argument. - """ + self.arg, self.key_sequence, self.is_repeat) + + @property + def data(self): + return self.key_sequence[-1].data + + @property + def input_processor(self): + return self._input_processor_ref() + + @property + def cli(self): + """ + Command line interface. + """ + return self.input_processor._cli_ref() + + @property + def current_buffer(self): + """ + The current buffer. + """ + return self.cli.current_buffer + + @property + def arg(self): + """ + Repetition argument. + """ if self._arg == '-': return -1 - + result = int(self._arg or 1) # Don't exceed a million. @@ -352,21 +352,21 @@ class KeyPressEvent(object): """ return self._arg is not None - def append_to_arg_count(self, data): - """ - Add digit to the input argument. - - :param data: the typed digit as string - """ - assert data in '-0123456789' - current = self._arg - + def append_to_arg_count(self, data): + """ + Add digit to the input argument. + + :param data: the typed digit as string + """ + assert data in '-0123456789' + current = self._arg + if data == '-': assert current is None or current == '-' result = data elif current is None: result = data - else: + else: result = "%s%s" % (current, data) - - self.input_processor.arg = result + + self.input_processor.arg = result diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/manager.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/manager.py index 83612c2a5c..3e4bf7ff1f 100644 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/manager.py +++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/manager.py @@ -1,61 +1,61 @@ -""" +""" DEPRECATED: Use `prompt_toolkit.key_binding.defaults.load_key_bindings` instead. -:class:`KeyBindingManager` is a utility (or shortcut) for loading all the key -bindings in a key binding registry, with a logic set of filters to quickly to -quickly change from Vi to Emacs key bindings at runtime. - -You don't have to use this, but it's practical. - -Usage:: - - manager = KeyBindingManager() +:class:`KeyBindingManager` is a utility (or shortcut) for loading all the key +bindings in a key binding registry, with a logic set of filters to quickly to +quickly change from Vi to Emacs key bindings at runtime. + +You don't have to use this, but it's practical. + +Usage:: + + manager = KeyBindingManager() app = Application(key_bindings_registry=manager.registry) -""" -from __future__ import unicode_literals +""" +from __future__ import unicode_literals from .defaults import load_key_bindings -from prompt_toolkit.filters import to_cli_filter +from prompt_toolkit.filters import to_cli_filter from prompt_toolkit.key_binding.registry import Registry, ConditionalRegistry, MergedRegistry - -__all__ = ( - 'KeyBindingManager', -) - - -class KeyBindingManager(object): - """ - Utility for loading all key bindings into memory. - - :param registry: Optional `Registry` instance. - :param enable_abort_and_exit_bindings: Filter to enable Ctrl-C and Ctrl-D. - :param enable_system_bindings: Filter to enable the system bindings - (meta-! prompt and Control-Z suspension.) - :param enable_search: Filter to enable the search bindings. - :param enable_open_in_editor: Filter to enable open-in-editor. - :param enable_open_in_editor: Filter to enable open-in-editor. - :param enable_extra_page_navigation: Filter for enabling extra page navigation. - (Bindings for up/down scrolling through long pages, like in Emacs or Vi.) - :param enable_auto_suggest_bindings: Filter to enable fish-style suggestions. + +__all__ = ( + 'KeyBindingManager', +) + + +class KeyBindingManager(object): + """ + Utility for loading all key bindings into memory. + + :param registry: Optional `Registry` instance. + :param enable_abort_and_exit_bindings: Filter to enable Ctrl-C and Ctrl-D. + :param enable_system_bindings: Filter to enable the system bindings + (meta-! prompt and Control-Z suspension.) + :param enable_search: Filter to enable the search bindings. + :param enable_open_in_editor: Filter to enable open-in-editor. + :param enable_open_in_editor: Filter to enable open-in-editor. + :param enable_extra_page_navigation: Filter for enabling extra page navigation. + (Bindings for up/down scrolling through long pages, like in Emacs or Vi.) + :param enable_auto_suggest_bindings: Filter to enable fish-style suggestions. :param enable_vi_mode: Deprecated! - """ + """ def __init__(self, registry=None, # XXX: not used anymore. enable_vi_mode=None, # (`enable_vi_mode` is deprecated.) enable_all=True, # - get_search_state=None, - enable_abort_and_exit_bindings=False, + get_search_state=None, + enable_abort_and_exit_bindings=False, enable_system_bindings=False, enable_search=False, enable_open_in_editor=False, enable_extra_page_navigation=False, enable_auto_suggest_bindings=False): - - assert registry is None or isinstance(registry, Registry) - assert get_search_state is None or callable(get_search_state) - enable_all = to_cli_filter(enable_all) - + + assert registry is None or isinstance(registry, Registry) + assert get_search_state is None or callable(get_search_state) + enable_all = to_cli_filter(enable_all) + defaults = load_key_bindings( get_search_state=get_search_state, enable_abort_and_exit_bindings=enable_abort_and_exit_bindings, @@ -64,30 +64,30 @@ class KeyBindingManager(object): enable_open_in_editor=enable_open_in_editor, enable_extra_page_navigation=enable_extra_page_navigation, enable_auto_suggest_bindings=enable_auto_suggest_bindings) - + # Note, we wrap this whole thing again in a MergedRegistry, because we # don't want the `enable_all` settings to apply on items that were # added to the registry as a whole. self.registry = MergedRegistry([ ConditionalRegistry(defaults, enable_all) ]) - - @classmethod - def for_prompt(cls, **kw): - """ - Create a ``KeyBindingManager`` with the defaults for an input prompt. + + @classmethod + def for_prompt(cls, **kw): + """ + Create a ``KeyBindingManager`` with the defaults for an input prompt. This activates the key bindings for abort/exit (Ctrl-C/Ctrl-D), - incremental search and auto suggestions. - - (Not for full screen applications.) - """ - kw.setdefault('enable_abort_and_exit_bindings', True) - kw.setdefault('enable_search', True) - kw.setdefault('enable_auto_suggest_bindings', True) - - return cls(**kw) - - def reset(self, cli): + incremental search and auto suggestions. + + (Not for full screen applications.) + """ + kw.setdefault('enable_abort_and_exit_bindings', True) + kw.setdefault('enable_search', True) + kw.setdefault('enable_auto_suggest_bindings', True) + + return cls(**kw) + + def reset(self, cli): # For backwards compatibility. pass diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/registry.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/registry.py index 24d0e729a1..5df089b20c 100644 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/registry.py +++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/registry.py @@ -23,110 +23,110 @@ others contain the Vi bindings. They are merged together using a We also have a `ConditionalRegistry` object that can enable/disable a group of key bindings at once. """ -from __future__ import unicode_literals +from __future__ import unicode_literals from abc import ABCMeta, abstractmethod from prompt_toolkit.cache import SimpleCache from prompt_toolkit.filters import CLIFilter, to_cli_filter, Never from prompt_toolkit.keys import Key, Keys - + from six import text_type, with_metaclass - -__all__ = ( + +__all__ = ( 'BaseRegistry', - 'Registry', + 'Registry', 'ConditionalRegistry', 'MergedRegistry', -) - - -class _Binding(object): - """ - (Immutable binding class.) - """ +) + + +class _Binding(object): + """ + (Immutable binding class.) + """ def __init__(self, keys, handler, filter=None, eager=None, save_before=None): - assert isinstance(keys, tuple) - assert callable(handler) - assert isinstance(filter, CLIFilter) - assert isinstance(eager, CLIFilter) + assert isinstance(keys, tuple) + assert callable(handler) + assert isinstance(filter, CLIFilter) + assert isinstance(eager, CLIFilter) assert callable(save_before) - - self.keys = keys - self.handler = handler - self.filter = filter - self.eager = eager + + self.keys = keys + self.handler = handler + self.filter = filter + self.eager = eager self.save_before = save_before - - def call(self, event): - return self.handler(event) - - def __repr__(self): - return '%s(keys=%r, handler=%r)' % ( - self.__class__.__name__, self.keys, self.handler) - - + + def call(self, event): + return self.handler(event) + + def __repr__(self): + return '%s(keys=%r, handler=%r)' % ( + self.__class__.__name__, self.keys, self.handler) + + class BaseRegistry(with_metaclass(ABCMeta, object)): - """ + """ Interface for a Registry. """ _version = 0 # For cache invalidation. - + @abstractmethod def get_bindings_for_keys(self, keys): pass - + @abstractmethod def get_bindings_starting_with_keys(self, keys): pass - + # `add_binding` and `remove_binding` don't have to be part of this # interface. class Registry(BaseRegistry): - """ + """ Key binding registry. """ - def __init__(self): - self.key_bindings = [] + def __init__(self): + self.key_bindings = [] self._get_bindings_for_keys_cache = SimpleCache(maxsize=10000) self._get_bindings_starting_with_keys_cache = SimpleCache(maxsize=1000) self._version = 0 # For cache invalidation. - + def _clear_cache(self): self._version += 1 self._get_bindings_for_keys_cache.clear() self._get_bindings_starting_with_keys_cache.clear() - - def add_binding(self, *keys, **kwargs): - """ - Decorator for annotating key bindings. - - :param filter: :class:`~prompt_toolkit.filters.CLIFilter` to determine - when this key binding is active. - :param eager: :class:`~prompt_toolkit.filters.CLIFilter` or `bool`. - When True, ignore potential longer matches when this key binding is - hit. E.g. when there is an active eager key binding for Ctrl-X, - execute the handler immediately and ignore the key binding for - Ctrl-X Ctrl-E of which it is a prefix. + + def add_binding(self, *keys, **kwargs): + """ + Decorator for annotating key bindings. + + :param filter: :class:`~prompt_toolkit.filters.CLIFilter` to determine + when this key binding is active. + :param eager: :class:`~prompt_toolkit.filters.CLIFilter` or `bool`. + When True, ignore potential longer matches when this key binding is + hit. E.g. when there is an active eager key binding for Ctrl-X, + execute the handler immediately and ignore the key binding for + Ctrl-X Ctrl-E of which it is a prefix. :param save_before: Callable that takes an `Event` and returns True if we should save the current buffer, before handling the event. (That's the default.) - """ - filter = to_cli_filter(kwargs.pop('filter', True)) - eager = to_cli_filter(kwargs.pop('eager', False)) + """ + filter = to_cli_filter(kwargs.pop('filter', True)) + eager = to_cli_filter(kwargs.pop('eager', False)) save_before = kwargs.pop('save_before', lambda e: True) to_cli_filter(kwargs.pop('invalidate_ui', True)) # Deprecated! (ignored.) - - assert not kwargs - assert keys - assert all(isinstance(k, (Key, text_type)) for k in keys), \ - 'Key bindings should consist of Key and string (unicode) instances.' + + assert not kwargs + assert keys + assert all(isinstance(k, (Key, text_type)) for k in keys), \ + 'Key bindings should consist of Key and string (unicode) instances.' assert callable(save_before) - + if isinstance(filter, Never): - # When a filter is Never, it will always stay disabled, so in that case - # don't bother putting it in the registry. It will slow down every key + # When a filter is Never, it will always stay disabled, so in that case + # don't bother putting it in the registry. It will slow down every key # press otherwise. def decorator(func): return func @@ -136,44 +136,44 @@ class Registry(BaseRegistry): _Binding(keys, func, filter=filter, eager=eager, save_before=save_before)) self._clear_cache() - + return func - return decorator - - def remove_binding(self, function): - """ - Remove a key binding. - - This expects a function that was given to `add_binding` method as - parameter. Raises `ValueError` when the given function was not - registered before. - """ - assert callable(function) - - for b in self.key_bindings: - if b.handler == function: - self.key_bindings.remove(b) + return decorator + + def remove_binding(self, function): + """ + Remove a key binding. + + This expects a function that was given to `add_binding` method as + parameter. Raises `ValueError` when the given function was not + registered before. + """ + assert callable(function) + + for b in self.key_bindings: + if b.handler == function: + self.key_bindings.remove(b) self._clear_cache() - return - - # No key binding found for this function. Raise ValueError. - raise ValueError('Binding not found: %r' % (function, )) - - def get_bindings_for_keys(self, keys): - """ - Return a list of key bindings that can handle this key. - (This return also inactive bindings, so the `filter` still has to be - called, for checking it.) - - :param keys: tuple of keys. - """ + return + + # No key binding found for this function. Raise ValueError. + raise ValueError('Binding not found: %r' % (function, )) + + def get_bindings_for_keys(self, keys): + """ + Return a list of key bindings that can handle this key. + (This return also inactive bindings, so the `filter` still has to be + called, for checking it.) + + :param keys: tuple of keys. + """ def get(): result = [] for b in self.key_bindings: if len(keys) == len(b.keys): match = True any_count = 0 - + for i, j in zip(b.keys, keys): if i != j and i != Keys.Any: match = False @@ -192,15 +192,15 @@ class Registry(BaseRegistry): return self._get_bindings_for_keys_cache.get(keys, get) - def get_bindings_starting_with_keys(self, keys): - """ - Return a list of key bindings that handle a key sequence starting with - `keys`. (It does only return bindings for which the sequences are - longer than `keys`. And like `get_bindings_for_keys`, it also includes - inactive bindings.) - - :param keys: tuple of keys. - """ + def get_bindings_starting_with_keys(self, keys): + """ + Return a list of key bindings that handle a key sequence starting with + `keys`. (It does only return bindings for which the sequences are + longer than `keys`. And like `get_bindings_for_keys`, it also includes + inactive bindings.) + + :param keys: tuple of keys. + """ def get(): result = [] for b in self.key_bindings: diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/vi_state.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/vi_state.py index 92ce3cbd29..c6e3e366b0 100644 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/vi_state.py +++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/key_binding/vi_state.py @@ -1,34 +1,34 @@ -from __future__ import unicode_literals - -__all__ = ( - 'InputMode', - 'CharacterFind', - 'ViState', -) - - -class InputMode(object): - INSERT = 'vi-insert' +from __future__ import unicode_literals + +__all__ = ( + 'InputMode', + 'CharacterFind', + 'ViState', +) + + +class InputMode(object): + INSERT = 'vi-insert' INSERT_MULTIPLE = 'vi-insert-multiple' - NAVIGATION = 'vi-navigation' - REPLACE = 'vi-replace' - - -class CharacterFind(object): - def __init__(self, character, backwards=False): - self.character = character - self.backwards = backwards - - -class ViState(object): - """ - Mutable class to hold the state of the Vi navigation. - """ - def __init__(self): - #: None or CharacterFind instance. (This is used to repeat the last - #: search in Vi mode, by pressing the 'n' or 'N' in navigation mode.) - self.last_character_find = None - + NAVIGATION = 'vi-navigation' + REPLACE = 'vi-replace' + + +class CharacterFind(object): + def __init__(self, character, backwards=False): + self.character = character + self.backwards = backwards + + +class ViState(object): + """ + Mutable class to hold the state of the Vi navigation. + """ + def __init__(self): + #: None or CharacterFind instance. (This is used to repeat the last + #: search in Vi mode, by pressing the 'n' or 'N' in navigation mode.) + self.last_character_find = None + # When an operator is given and we are waiting for text object, # -- e.g. in the case of 'dw', after the 'd' --, an operator callback # is set here. @@ -39,9 +39,9 @@ class ViState(object): #: :class:`ClipboardData` instances. self.named_registers = {} - #: The Vi mode we're currently in to. - self.input_mode = InputMode.INSERT - + #: The Vi mode we're currently in to. + self.input_mode = InputMode.INSERT + #: Waiting for digraph. self.waiting_for_digraph = False self.digraph_symbol1 = None # (None or a symbol.) @@ -53,7 +53,7 @@ class ViState(object): """ Reset state, go back to the given mode. INSERT by default. """ - # Go back to insert mode. + # Go back to insert mode. self.input_mode = mode self.waiting_for_digraph = False |