示例#1
0
文件: abbrevs.py 项目: sthagen/xonsh
def custom_keybindings(bindings, **kw):

    from prompt_toolkit.filters import EmacsInsertMode, ViInsertMode

    from xonsh.ptk_shell.key_bindings import carriage_return

    handler = bindings.add
    insert_mode = ViInsertMode() | EmacsInsertMode()
    abbrev = Abbreviation()

    @handler(" ", filter=IsMultiline() & insert_mode)
    def handle_space(event):
        buffer = event.app.current_buffer

        add_space = True
        if not abbrev.revert(buffer):
            position_changed = abbrev.expand(buffer)
            if position_changed:
                add_space = False
        if add_space:
            buffer.insert_text(" ")

    @handler(Keys.ControlJ,
             filter=IsMultiline() & insert_mode & ~completion_is_selected)
    @handler(Keys.ControlM,
             filter=IsMultiline() & insert_mode & ~completion_is_selected)
    def multiline_carriage_return(event):
        buffer = event.app.current_buffer
        current_char = buffer.document.current_char
        if not current_char or current_char.isspace():
            abbrev.expand(buffer)
        carriage_return(buffer, event.cli)
示例#2
0
def custom_keybindings(bindings, **kw):

    from xonsh2.ptk_shell.key_bindings import carriage_return
    from prompt_toolkit.filters import EmacsInsertMode, ViInsertMode

    handler = bindings.add
    insert_mode = ViInsertMode() | EmacsInsertMode()

    @handler(" ", filter=IsMultiline() & insert_mode)
    def handle_space(event):
        buffer = event.app.current_buffer
        if not revert_abbrev(buffer):
            expand_abbrev(buffer)
        if last_expanded is None or not set_cursor_position(buffer):
            buffer.insert_text(" ")

    @handler(Keys.ControlJ,
             filter=IsMultiline() & insert_mode & ~completion_is_selected)
    @handler(Keys.ControlM,
             filter=IsMultiline() & insert_mode & ~completion_is_selected)
    def multiline_carriage_return(event):
        buffer = event.app.current_buffer
        current_char = buffer.document.current_char
        if not current_char or current_char.isspace():
            expand_abbrev(buffer)
        carriage_return(buffer, event.cli)
示例#3
0
文件: abbrevs.py 项目: tianhm/xonsh
def custom_keybindings(bindings, **kw):

    if ptk_shell_type() == "prompt_toolkit2":
        from xonsh.ptk2.key_bindings import carriage_return
        from prompt_toolkit.filters import EmacsInsertMode, ViInsertMode

        handler = bindings.add
        insert_mode = ViInsertMode() | EmacsInsertMode()
    else:
        from xonsh.ptk.key_bindings import carriage_return
        from prompt_toolkit.filters import to_filter

        handler = bindings.registry.add_binding
        insert_mode = to_filter(True)

    @handler(" ", filter=IsMultiline() & insert_mode)
    def handle_space(event):
        buffer = event.app.current_buffer
        expand_abbrev(buffer)
        buffer.insert_text(" ")

    @handler(
        Keys.ControlJ, filter=IsMultiline() & insert_mode & ~completion_is_selected
    )
    @handler(
        Keys.ControlM, filter=IsMultiline() & insert_mode & ~completion_is_selected
    )
    def multiline_carriage_return(event):
        buffer = event.app.current_buffer
        current_char = buffer.document.current_char
        if not current_char or current_char.isspace():
            expand_abbrev(buffer)
        carriage_return(buffer, event.cli)
示例#4
0
def load_xonsh_bindings(key_bindings_manager):
    """
    Load custom key bindings.
    """
    handle = key_bindings_manager.registry.add_binding
    has_selection = HasSelection()

    @handle(Keys.Tab, filter=TabShouldInsertIndentFilter())
    def _(event):
        """
        If there are only whitespaces before current cursor position insert
        indent instead of autocompleting.
        """
        event.cli.current_buffer.insert_text(env.get('INDENT'))

    @handle(Keys.ControlX, Keys.ControlE, filter=~has_selection)
    def open_editor(event):
        """ Open current buffer in editor """
        event.current_buffer.open_in_editor(event.cli)

    @handle(Keys.BackTab)
    def insert_literal_tab(event):
        """ Insert literal tab on Shift+Tab instead of autocompleting """
        event.cli.current_buffer.insert_text(env.get('INDENT'))

    @handle(Keys.ControlD, filter=ctrl_d_condition)
    def call_exit_alias(event):
        """Use xonsh exit function"""
        b = event.cli.current_buffer
        b.accept_action.validate_and_handle(event.cli, b)
        exit([])

    @handle(Keys.ControlJ, filter=IsMultiline())
    def multiline_carriage_return(event):
        """ Wrapper around carriage_return multiline parser """
        b = event.cli.current_buffer
        carriage_return(b, event.cli)

    @handle(Keys.Left, filter=BeginningOfLine())
    def wrap_cursor_back(event):
        """Move cursor to end of previous line unless at beginning of document"""
        b = event.cli.current_buffer
        b.cursor_up(count=1)
        relative_end_index = b.document.get_end_of_line_position()
        b.cursor_right(count=relative_end_index)

    @handle(Keys.Right, filter=EndOfLine())
    def wrap_cursor_forward(event):
        """Move cursor to beginning of next line unless at end of document"""
        b = event.cli.current_buffer
        relative_begin_index = b.document.get_start_of_line_position()
        b.cursor_left(count=abs(relative_begin_index))
        b.cursor_down(count=1)
示例#5
0
def load_modified_bindings(registry, filter=Always()):
    handle = create_handle_decorator(registry, filter)
    has_selection = HasSelection()

    def at_the_end(b):
        text = b.document.text_after_cursor
        return text == '' or (text.isspace() and not '\n' in text)

    def lexes(b):
        try:
            tokenize(b.text)
        except Exception:
            return False
        return True

    @handle(Keys.ControlJ,
            filter=~has_selection & IsMultiline() & ~HasSearch(),
            save_before=False)
    def _(event):
        b = event.current_buffer

        # We don't need full validation here, just test if hy
        # can lex the text
        if at_the_end(b) and lexes(b):
            b.document = Document(text=b.text.rstrip(),
                                  cursor_position=len(b.text.rstrip()))

            b.accept_action.validate_and_handle(event.cli, b)
        else:
            auto_newline(b)

    @handle(Keys.ControlJ,
            filter=~has_selection & ~IsMultiline() & ~HasSearch(),
            save_before=False)
    def _(event):
        b = event.current_buffer
        if at_the_end(b) and lexes(b):
            b.accept_action.validate_and_handle(event.cli, b)
        else:
            auto_newline(b)
示例#6
0
文件: pthy.py 项目: ALSchwalm/pthy
def main():
    hy_repl = HyREPL()
    eventloop = create_eventloop()
    validator = HyValidator()
    history = FileHistory(expanduser("~/.pthy_history"))

    def src_is_multiline():
        if app and app.buffer:
            text = app.buffer.document.text
            if '\n' in text:
                return True
        return False

    app = create_default_application(
        "λ: ",
        validator=validator,
        multiline=Condition(src_is_multiline),
        lexer=HyLexer,
        style=HyStyle,
        history=history,
        completer=HyCompleter(hy_repl),
        display_completions_in_columns=True,
        extra_input_processors=[
            ConditionalProcessor(processor=HighlightMatchingBracketProcessor(),
                                 filter=~IsDone())
        ])

    # Somewhat ugly trick to add a margin to the multiline input
    # without needing to define a custom layout
    app.layout.children[0].children[
        1].content.content.margin = ConditionalMargin(NumberredMargin(),
                                                      filter=IsMultiline())

    cli = CommandLineInterface(application=app, eventloop=eventloop)
    load_modified_bindings(app.key_bindings_registry)

    hy_repl.cli = cli

    try:
        while True:
            try:
                code_obj = cli.run()
                hy_repl.evaluate(code_obj.text)
            except KeyboardInterrupt:
                pass
    except EOFError:
        pass
    finally:
        eventloop.close()
示例#7
0
    def load_bindings(key_bindings_manager):
        handle = key_bindings_manager.registry.add_binding
        has_selection = HasSelection()

        @key_bindings_manager.registry.add_binding(Keys.ControlL)#, eager=True)
        def clear_(event):
            clear()
            print(env.welcome)
            PROMPT = env.prompt
            PROMPT = PROMPT.replace(r"\u", env.user).replace(r"\w", env.directory)
            print(unicode_(PROMPT), end="")

        @key_bindings_manager.registry.add_binding(Keys.ControlB)
        def list_(event):
            print("\n".join(ls(env, [], {})))
            PROMPT = env.prompt
            PROMPT = PROMPT.replace(r"\u", env.user).replace(r"\w", env.directory)
            print(env.default_color, end="")
            print(unicode_(PROMPT), end="")
            
        @handle(Keys.ControlJ, filter= ~has_selection &
            (ViInsertMode() | EmacsInsertMode()) &
            HasFocus(DEFAULT_BUFFER) & IsMultiline())
        def _(event):
            """
            Behaviour of the Enter key.
            
            Auto indent after newline/Enter.
            (When not in Vi navigaton mode, and when multiline is enabled.)
            """
            b = event.current_buffer
            empty_lines_required = 2

            def at_the_end(b):
                """ we consider the cursor at the end when there is no text after
                the cursor, or only whitespace. """
                text = b.document.text_after_cursor
                return text == '' or (text.isspace() and not '\n' in text)

            if at_the_end(b) and (b.document.text.replace(' ', '').endswith('\n' * (empty_lines_required - 1)) or (b.document.text.replace("\n", "").endswith(";"))):
                # When the cursor is at the end, and we have an empty line:
                # drop the empty lines, but return the value.
                b.document = Document(
                    text=b.text.rstrip(),
                    cursor_position=len(b.text.rstrip()))

                b.accept_action.validate_and_handle(event.cli, b)
            else:
                _auto_newline(b)
示例#8
0
def load_xonsh_bindings(key_bindings_manager):
    """
    Load custom key bindings.
    """
    handle = key_bindings_manager.registry.add_binding

    @handle(Keys.Tab, filter=TabShouldInsertIndentFilter())
    def _(event):
        """
        If there are only whitespaces before current cursor position insert
        indent instead of autocompleting.
        """
        event.cli.current_buffer.insert_text(env.get('INDENT'))

    @handle(Keys.BackTab)
    def insert_literal_tab(event):
        """ Insert literal tab on Shift+Tab instead of autocompleting """
        event.cli.current_buffer.insert_text(env.get('INDENT'))

    @handle(Keys.ControlJ, filter=IsMultiline())
    def multiline_carriage_return(event):
        """ Wrapper around carriage_return multiline parser """
        b = event.cli.current_buffer
        carriage_return(b, event.cli)
示例#9
0
def load_xonsh_bindings(key_bindings):
    """
    Load custom key bindings.
    """
    handle = key_bindings.add
    has_selection = HasSelection()
    insert_mode = ViInsertMode() | EmacsInsertMode()

    @handle(Keys.Tab, filter=tab_insert_indent)
    def insert_indent(event):
        """
        If there are only whitespaces before current cursor position insert
        indent instead of autocompleting.
        """
        env = builtins.__xonsh__.env
        event.cli.current_buffer.insert_text(env.get("INDENT"))

    @handle(Keys.ControlX, Keys.ControlE, filter=~has_selection)
    def open_editor(event):
        """ Open current buffer in editor """
        event.current_buffer.open_in_editor(event.cli)

    @handle(Keys.BackTab, filter=insert_mode)
    def insert_literal_tab(event):
        """ Insert literal tab on Shift+Tab instead of autocompleting """
        b = event.current_buffer
        if b.complete_state:
            b.complete_previous()
        else:
            env = builtins.__xonsh__.env
            event.cli.current_buffer.insert_text(env.get("INDENT"))

    @handle("(", filter=autopair_condition & whitespace_or_bracket_after)
    def insert_right_parens(event):
        event.cli.current_buffer.insert_text("(")
        event.cli.current_buffer.insert_text(")", move_cursor=False)

    @handle(")", filter=autopair_condition)
    def overwrite_right_parens(event):
        buffer = event.cli.current_buffer
        if buffer.document.current_char == ")":
            buffer.cursor_position += 1
        else:
            buffer.insert_text(")")

    @handle("[", filter=autopair_condition & whitespace_or_bracket_after)
    def insert_right_bracket(event):
        event.cli.current_buffer.insert_text("[")
        event.cli.current_buffer.insert_text("]", move_cursor=False)

    @handle("]", filter=autopair_condition)
    def overwrite_right_bracket(event):
        buffer = event.cli.current_buffer

        if buffer.document.current_char == "]":
            buffer.cursor_position += 1
        else:
            buffer.insert_text("]")

    @handle("{", filter=autopair_condition & whitespace_or_bracket_after)
    def insert_right_brace(event):
        event.cli.current_buffer.insert_text("{")
        event.cli.current_buffer.insert_text("}", move_cursor=False)

    @handle("}", filter=autopair_condition)
    def overwrite_right_brace(event):
        buffer = event.cli.current_buffer

        if buffer.document.current_char == "}":
            buffer.cursor_position += 1
        else:
            buffer.insert_text("}")

    @handle("'", filter=autopair_condition)
    def insert_right_quote(event):
        buffer = event.cli.current_buffer

        if buffer.document.current_char == "'":
            buffer.cursor_position += 1
        elif whitespace_or_bracket_before() and whitespace_or_bracket_after():
            buffer.insert_text("'")
            buffer.insert_text("'", move_cursor=False)
        else:
            buffer.insert_text("'")

    @handle('"', filter=autopair_condition)
    def insert_right_double_quote(event):
        buffer = event.cli.current_buffer

        if buffer.document.current_char == '"':
            buffer.cursor_position += 1
        elif whitespace_or_bracket_before() and whitespace_or_bracket_after():
            buffer.insert_text('"')
            buffer.insert_text('"', move_cursor=False)
        else:
            buffer.insert_text('"')

    @handle(Keys.Backspace, filter=autopair_condition)
    def delete_brackets_or_quotes(event):
        """Delete empty pair of brackets or quotes"""
        buffer = event.cli.current_buffer
        before = buffer.document.char_before_cursor
        after = buffer.document.current_char

        if any(
            [before == b and after == a for (b, a) in ["()", "[]", "{}", "''", '""']]
        ):
            buffer.delete(1)

        buffer.delete_before_cursor(1)

    @handle(Keys.ControlD, filter=ctrl_d_condition)
    def call_exit_alias(event):
        """Use xonsh exit function"""
        b = event.cli.current_buffer
        b.validate_and_handle()
        xonsh_exit([])

    @handle(Keys.ControlJ, filter=IsMultiline())
    @handle(Keys.ControlM, filter=IsMultiline())
    def multiline_carriage_return(event):
        """ Wrapper around carriage_return multiline parser """
        b = event.cli.current_buffer
        carriage_return(b, event.cli)

    @handle(Keys.ControlJ, filter=should_confirm_completion)
    @handle(Keys.ControlM, filter=should_confirm_completion)
    def enter_confirm_completion(event):
        """Ignore <enter> (confirm completion)"""
        event.current_buffer.complete_state = None

    @handle(Keys.Escape, filter=should_confirm_completion)
    def esc_cancel_completion(event):
        """Use <ESC> to cancel completion"""
        event.cli.current_buffer.cancel_completion()

    @handle(Keys.Escape, Keys.ControlJ)
    def execute_block_now(event):
        """Execute a block of text irrespective of cursor position"""
        b = event.cli.current_buffer
        b.validate_and_handle()

    @handle(Keys.Left, filter=beginning_of_line)
    def wrap_cursor_back(event):
        """Move cursor to end of previous line unless at beginning of
        document
        """
        b = event.cli.current_buffer
        b.cursor_up(count=1)
        relative_end_index = b.document.get_end_of_line_position()
        b.cursor_right(count=relative_end_index)

    @handle(Keys.Right, filter=end_of_line)
    def wrap_cursor_forward(event):
        """Move cursor to beginning of next line unless at end of document"""
        b = event.cli.current_buffer
        relative_begin_index = b.document.get_start_of_line_position()
        b.cursor_left(count=abs(relative_begin_index))
        b.cursor_down(count=1)

    @handle(Keys.ControlM, filter=IsSearching())
    @handle(Keys.ControlJ, filter=IsSearching())
    def accept_search(event):
        search.accept_search()
示例#10
0
def load_xonsh_bindings(key_bindings_manager):
    """
    Load custom key bindings.
    """
    handle = key_bindings_manager.registry.add_binding
    has_selection = HasSelection()
    insert_mode = ViInsertMode() | EmacsInsertMode()

    @handle(Keys.Tab, filter=tab_insert_indent)
    def insert_indent(event):
        """
        If there are only whitespaces before current cursor position insert
        indent instead of autocompleting.
        """
        event.cli.current_buffer.insert_text(env.get('INDENT'))

    @handle(Keys.ControlX, Keys.ControlE, filter=~has_selection)
    def open_editor(event):
        """ Open current buffer in editor """
        event.current_buffer.open_in_editor(event.cli)

    @handle(Keys.BackTab, filter=insert_mode)
    def insert_literal_tab(event):
        """ Insert literal tab on Shift+Tab instead of autocompleting """
        b = event.current_buffer
        if b.complete_state:
            b.complete_previous()
        else:
            event.cli.current_buffer.insert_text(env.get('INDENT'))

    @handle('(', filter=autopair_condition)
    def insert_right_parens(event):
        event.cli.current_buffer.insert_text('(')
        event.cli.current_buffer.insert_text(')', move_cursor=False)

    @handle(')', filter=autopair_condition)
    def overwrite_right_parens(event):
        buffer = event.cli.current_buffer
        if buffer.document.current_char == ')':
            buffer.cursor_position += 1
        else:
            buffer.insert_text(')')

    @handle('[', filter=autopair_condition)
    def insert_right_bracket(event):
        event.cli.current_buffer.insert_text('[')
        event.cli.current_buffer.insert_text(']', move_cursor=False)

    @handle(']', filter=autopair_condition)
    def overwrite_right_bracket(event):
        buffer = event.cli.current_buffer

        if buffer.document.current_char == ']':
            buffer.cursor_position += 1
        else:
            buffer.insert_text(']')

    @handle('\'', filter=autopair_condition)
    def insert_right_quote(event):
        buffer = event.cli.current_buffer

        if buffer.document.current_char == '\'':
            buffer.cursor_position += 1
        else:
            buffer.insert_text('\'')
            buffer.insert_text('\'', move_cursor=False)

    @handle('"', filter=autopair_condition)
    def insert_right_double_quote(event):
        buffer = event.cli.current_buffer

        if buffer.document.current_char == '"':
            buffer.cursor_position += 1
        else:
            buffer.insert_text('"')
            buffer.insert_text('"', move_cursor=False)

    @handle(Keys.ControlD, filter=ctrl_d_condition)
    def call_exit_alias(event):
        """Use xonsh exit function"""
        b = event.cli.current_buffer
        b.accept_action.validate_and_handle(event.cli, b)
        xonsh_exit([])

    @handle(Keys.ControlJ, filter=IsMultiline())
    def multiline_carriage_return(event):
        """ Wrapper around carriage_return multiline parser """
        b = event.cli.current_buffer
        carriage_return(b, event.cli)

    @handle(Keys.ControlJ, filter=should_confirm_completion)
    def enter_confirm_completion(event):
        """Ignore <enter> (confirm completion)"""
        event.current_buffer.complete_state = None

    @handle(Keys.Escape, filter=should_confirm_completion)
    def esc_cancel_completion(event):
        """Use <ESC> to cancel completion"""
        event.cli.current_buffer.cancel_completion()

    @handle(Keys.Escape, Keys.ControlJ)
    def execute_block_now(event):
        """Execute a block of text irrespective of cursor position"""
        b = event.cli.current_buffer
        b.accept_action.validate_and_handle(event.cli, b)

    @handle(Keys.Left, filter=beginning_of_line)
    def wrap_cursor_back(event):
        """Move cursor to end of previous line unless at beginning of
        document
        """
        b = event.cli.current_buffer
        b.cursor_up(count=1)
        relative_end_index = b.document.get_end_of_line_position()
        b.cursor_right(count=relative_end_index)

    @handle(Keys.Right, filter=end_of_line)
    def wrap_cursor_forward(event):
        """Move cursor to beginning of next line unless at end of document"""
        b = event.cli.current_buffer
        relative_begin_index = b.document.get_start_of_line_position()
        b.cursor_left(count=abs(relative_begin_index))
        b.cursor_down(count=1)

    @handle(Keys.ControlI, filter=insert_mode)
    def generate_completions(event):
        """
        Tab-completion: where the first tab completes the common suffix and the
        second tab lists all the completions.

        Notes
        -----
        This method was forked from the mainline prompt-toolkit repo.
        Copyright (c) 2014, Jonathan Slenders, All rights reserved.
        """
        b = event.current_buffer

        def second_tab():
            if b.complete_state:
                b.complete_next()
            else:
                event.cli.start_completion(select_first=False)

        # On the second tab-press, or when already navigating through
        # completions.
        if event.is_repeat or b.complete_state:
            second_tab()
        else:
            event.cli.start_completion(insert_common_part=True,
                                       select_first=False)
示例#11
0
def load_python_bindings(key_bindings_manager, settings):
    """
    Custom key bindings.
    """
    handle = key_bindings_manager.registry.add_binding
    has_selection = HasSelection()

    @handle(Keys.F2)
    def _(event):
        """
        Show/hide sidebar.
        """
        settings.show_sidebar = not settings.show_sidebar

    @handle(Keys.F3)
    def _(event):
        """
        Shange completion style.
        """
        # Toggle between combinations.
        settings.show_completions_toolbar, settings.show_completions_menu = {
            (False, False): (False, True),
            (False, True): (True, False),
            (True, False): (False, False),
        }[settings.show_completions_toolbar, settings.show_completions_menu]

    @handle(Keys.F4)
    def _(event):
        """
        Toggle between Vi and Emacs mode.
        """
        key_bindings_manager.enable_vi_mode = not key_bindings_manager.enable_vi_mode

    @handle(Keys.F5)
    def _(event):
        """
        Enable/Disable complete while typing.
        """
        settings.complete_while_typing = not settings.complete_while_typing

    @handle(Keys.F6)
    def _(event):
        """
        Enable/Disable paste mode.
        """
        settings.paste_mode = not settings.paste_mode

    @handle(Keys.F8)
    def _(event):
        """
        Show/hide signature.
        """
        settings.show_signature = not settings.show_signature

    @handle(Keys.F9)
    def _(event):
        """
        Show/hide docstring window.
        """
        settings.show_docstring = not settings.show_docstring

    @handle(Keys.F10)
    def _(event):
        """
        Show/hide line numbers
        """
        settings.show_line_numbers = not settings.show_line_numbers

    @handle(Keys.Tab,
            filter=~has_selection & TabShouldInsertWhitespaceFilter())
    def _(event):
        """
        When tab should insert whitespace, do that instead of completion.
        """
        event.cli.current_buffer.insert_text('    ')

    @handle(Keys.ControlJ,
            filter=~has_selection
            & ~(ViModeEnabled(key_bindings_manager) & ViStateFilter(
                key_bindings_manager.vi_state, InputMode.NAVIGATION))
            & HasFocus('default') & IsMultiline())
    def _(event):
        """
        Behaviour of the Enter key.

        Auto indent after newline/Enter.
        (When not in Vi navigaton mode, and when multiline is enabled.)
        """
        b = event.current_buffer

        def at_the_end(b):
            """ we consider the cursor at the end when there is no text after
            the cursor, or only whitespace. """
            text = b.document.text_after_cursor
            return text == '' or (text.isspace() and not '\n' in text)

        if settings.paste_mode:
            # In paste mode, always insert text.
            b.insert_text('\n')

        elif at_the_end(b) and b.document.text.replace(' ', '').endswith('\n'):
            if b.validate():
                # When the cursor is at the end, and we have an empty line:
                # drop the empty lines, but return the value.
                b.document = Document(text=b.text.rstrip(),
                                      cursor_position=len(b.text.rstrip()))

                b.append_to_history()
                event.cli.set_return_value(b.document)
        else:
            auto_newline(b)
示例#12
0
def load_xonsh_bindings(key_bindings_manager):
    """
    Load custom key bindings.
    """
    handle = key_bindings_manager.registry.add_binding
    has_selection = HasSelection()
    insert_mode = ViInsertMode() | EmacsInsertMode()

    @handle(Keys.Tab, filter=TabShouldInsertIndentFilter())
    def _(event):
        """
        If there are only whitespaces before current cursor position insert
        indent instead of autocompleting.
        """
        event.cli.current_buffer.insert_text(env.get('INDENT'))

    @handle(Keys.ControlX, Keys.ControlE, filter=~has_selection)
    def open_editor(event):
        """ Open current buffer in editor """
        event.current_buffer.open_in_editor(event.cli)

    @handle(Keys.BackTab)
    def insert_literal_tab(event):
        """ Insert literal tab on Shift+Tab instead of autocompleting """
        event.cli.current_buffer.insert_text(env.get('INDENT'))

    @handle(Keys.ControlD, filter=ctrl_d_condition)
    def call_exit_alias(event):
        """Use xonsh exit function"""
        b = event.cli.current_buffer
        b.accept_action.validate_and_handle(event.cli, b)
        xonsh_exit([])

    @handle(Keys.ControlJ, filter=IsMultiline())
    def multiline_carriage_return(event):
        """ Wrapper around carriage_return multiline parser """
        b = event.cli.current_buffer
        carriage_return(b, event.cli)

    @handle(Keys.Left, filter=BeginningOfLine())
    def wrap_cursor_back(event):
        """Move cursor to end of previous line unless at beginning of document"""
        b = event.cli.current_buffer
        b.cursor_up(count=1)
        relative_end_index = b.document.get_end_of_line_position()
        b.cursor_right(count=relative_end_index)

    @handle(Keys.Right, filter=EndOfLine())
    def wrap_cursor_forward(event):
        """Move cursor to beginning of next line unless at end of document"""
        b = event.cli.current_buffer
        relative_begin_index = b.document.get_start_of_line_position()
        b.cursor_left(count=abs(relative_begin_index))
        b.cursor_down(count=1)

    @handle(Keys.ControlI, filter=insert_mode)
    def generate_completions(event):
        """
        Tab-completion: where the first tab completes the common suffix and the
        second tab lists all the completions.

        Notes
        -----
        This method was forked from the mainline prompt-toolkit repo.
        Copyright (c) 2014, Jonathan Slenders, All rights reserved.
        """
        b = event.current_buffer

        def second_tab():
            if b.complete_state:
                b.complete_next()
            else:
                event.cli.start_completion(select_first=False)

        # On the second tab-press, or when already navigating through
        # completions.
        if event.is_repeat or b.complete_state:
            second_tab()
        else:
            event.cli.start_completion(insert_common_part=True,
                                       select_first=False)
示例#13
0
def load_python_bindings(key_bindings_manager, settings, add_buffer,
                         close_current_buffer):
    """
    Custom key bindings.
    """
    handle = key_bindings_manager.registry.add_binding
    has_selection = HasSelection()

    vi_navigation_mode = ViStateFilter(key_bindings_manager.vi_state, InputMode.NAVIGATION) & \
        ~ HasSelection()

    @handle(Keys.F2)
    def _(event):
        """
        Show/hide sidebar.
        """
        settings.show_sidebar = not settings.show_sidebar

    @handle(Keys.F3)
    def _(event):
        """
        Shange completion style.
        """
        # Toggle between combinations.
        settings.show_completions_toolbar, settings.show_completions_menu = {
            (False, False): (False, True),
            (False, True): (True, False),
            (True, False): (False, False),
        }[settings.show_completions_toolbar, settings.show_completions_menu]

    @handle(Keys.F4)
    def _(event):
        """
        Toggle between Vi and Emacs mode.
        """
        key_bindings_manager.enable_vi_mode = not key_bindings_manager.enable_vi_mode

    @handle(Keys.F6)
    def _(event):
        """
        Enable/Disable paste mode.
        """
        settings.paste_mode = not settings.paste_mode

    @handle(Keys.F7)
    def _(event):
        """
        Enable/Disable multiline mode.
        """
        settings.currently_multiline = not settings.currently_multiline

    @handle(Keys.F8)
    def _(event):
        """
        Show/hide signature.
        """
        settings.show_signature = not settings.show_signature

    @handle(Keys.F9)
    def _(event):
        """
        Show/hide docstring window.
        """
        settings.show_docstring = not settings.show_docstring

    @handle(Keys.F10)
    def _(event):
        """
        Show/hide line numbers
        """
        settings.show_line_numbers = not settings.show_line_numbers

    @handle(Keys.F5)
    def _(event):
        """
        Show all buffers
        """
        settings.show_all_buffers = not settings.show_all_buffers

    @handle('g', 't', filter=vi_navigation_mode)
    @handle(Keys.ControlRight)
    def _(event):
        """
        Focus next tab.
        """
        focus_next_buffer(event.cli)

    @handle('g', 'T', filter=vi_navigation_mode)
    @handle(Keys.ControlLeft)
    def _(event):
        """
        Focus previous tab.
        """
        focus_previous_buffer(event.cli)


#    @handle(Keys.F5, filter=filters.HasFocus('default') & ~has_selection)  # XXX: use current tab
#    def _(event):
#        """
#        Merge the previous entry from the history on top.
#        """
#        buffer = event.cli.buffers['default']
#
#        buffer.text = buffer._working_lines[buffer.working_index - 1] + '\n' + buffer.text
#        buffer._working_lines = buffer._working_lines[:buffer.working_index - 1] + buffer._working_lines[buffer.working_index:]
#        buffer.working_index -= 1

    @handle(Keys.ControlT, filter=IsPythonBufferFocussed() & ~has_selection)
    def _(event):
        """
        Create a new Python buffer.
        """
        add_buffer()

    @handle(Keys.ControlD, filter=IsPythonBufferFocussed())
    def _(event):
        """
        Close Python buffer.
        """
        close_current_buffer()

    @handle(Keys.Tab, filter=~has_selection)
    def _(event):
        """
        When the 'tab' key is pressed with only whitespace character before the
        cursor, do autocompletion. Otherwise, insert indentation.
        """
        buffer = event.cli.current_buffer
        current_char = buffer.document.current_line_before_cursor

        if not current_char or current_char.isspace():
            buffer.insert_text('    ')
        else:
            buffer.complete_next()

    @handle(Keys.ControlJ,
            filter=~has_selection
            & ~(ViModeEnabled(key_bindings_manager) & ViStateFilter(
                key_bindings_manager.vi_state, InputMode.NAVIGATION))
            & IsPythonBufferFocussed() & IsMultiline())
    def _(event):
        """
        Auto indent after newline/Enter.
        (When not in Vi navigaton mode, and when multiline is enabled.)
        """
        buffer = event.current_buffer

        if settings.paste_mode:
            buffer.insert_text('\n')
        else:
            auto_newline(buffer)
示例#14
0
def load_python_bindings(key_bindings_manager, python_input):
    """
    Custom key bindings.
    """
    sidebar_visible = Condition(lambda cli: python_input.show_sidebar)
    handle = key_bindings_manager.registry.add_binding
    has_selection = HasSelection()
    vi_mode_enabled = Condition(lambda cli: python_input.vi_mode)

    @handle(Keys.ControlL)
    def _(event):
        """
        Clear whole screen and render again -- also when the sidebar is visible.
        """
        event.cli.renderer.clear()

    @handle(Keys.F2)
    def _(event):
        """
        Show/hide sidebar.
        """
        python_input.show_sidebar = not python_input.show_sidebar

    @handle(Keys.F3)
    def _(event):
        """
        Select from the history.
        """
        python_input.enter_history(event.cli)

    @handle(Keys.F4)
    def _(event):
        """
        Toggle between Vi and Emacs mode.
        """
        python_input.vi_mode = not python_input.vi_mode

    @handle(Keys.F6)
    def _(event):
        """
        Enable/Disable paste mode.
        """
        python_input.paste_mode = not python_input.paste_mode

    @handle(Keys.Tab, filter= ~sidebar_visible & ~has_selection & TabShouldInsertWhitespaceFilter())
    def _(event):
        """
        When tab should insert whitespace, do that instead of completion.
        """
        event.cli.current_buffer.insert_text('    ')

    @handle(Keys.ControlJ, filter= ~sidebar_visible & ~has_selection &
            (ViInsertMode() | EmacsInsertMode()) &
            HasFocus(DEFAULT_BUFFER) & IsMultiline())
    def _(event):
        """
        Behaviour of the Enter key.

        Auto indent after newline/Enter.
        (When not in Vi navigaton mode, and when multiline is enabled.)
        """
        b = event.current_buffer
        empty_lines_required = python_input.accept_input_on_enter or 10000

        def at_the_end(b):
            """ we consider the cursor at the end when there is no text after
            the cursor, or only whitespace. """
            text = b.document.text_after_cursor
            return text == '' or (text.isspace() and not '\n' in text)

        if python_input.paste_mode:
            # In paste mode, always insert text.
            b.insert_text('\n')

        elif at_the_end(b) and b.document.text.replace(' ', '').endswith(
                    '\n' * (empty_lines_required - 1)):
            if b.validate():
                # When the cursor is at the end, and we have an empty line:
                # drop the empty lines, but return the value.
                b.document = Document(
                    text=b.text.rstrip(),
                    cursor_position=len(b.text.rstrip()))

                b.accept_action.validate_and_handle(event.cli, b)
        else:
            auto_newline(b)

    @handle(Keys.ControlD, filter=~sidebar_visible & Condition(lambda cli:
            # Only when the `confirm_exit` flag is set.
            python_input.confirm_exit and
            # And the current buffer is empty.
            cli.current_buffer_name == DEFAULT_BUFFER and
            not cli.current_buffer.text))
    def _(event):
        """
        Override Control-D exit, to ask for confirmation.
        """
        python_input.show_exit_confirmation = True
示例#15
0
def load_xonsh_bindings(key_bindings_manager):
    """
    Load custom key bindings.
    """
    handle = key_bindings_manager.registry.add_binding
    env = builtins.__xonsh_env__
    indent_ = env.get('INDENT')

    DEDENT_TOKENS = frozenset(['raise', 'return', 'pass', 'break', 'continue'])

    @handle(Keys.Tab, filter=TabShouldInsertIndentFilter())
    def _(event):
        """
        If there are only whitespaces before current cursor position insert
        indent instead of autocompleting.
        """
        event.cli.current_buffer.insert_text(env.get('INDENT'))

    @handle(Keys.BackTab)
    def insert_literal_tab(event):
        """
        Insert literal tab on Shift+Tab instead of autocompleting
        """
        event.cli.current_buffer.insert_text(env.get('INDENT'))

    @handle(Keys.ControlJ, filter=IsMultiline())
    def multiline_carriage_return(event):
        """
        Preliminary parser to determine if 'Enter' key should send command to
        the xonsh parser for execution or should insert a newline for continued
        input.

        Current 'triggers' for inserting a newline are:
        - Not on first line of buffer and line is non-empty
        - Previous character is a colon (covers if, for, etc...)
        - User is in an open paren-block
        - Line ends with backslash
        - Any text exists below cursor position (relevant when editing previous
        multiline blocks)
        """

        b = event.cli.current_buffer

        # indent after a colon
        if b.document.char_before_cursor == ':':
            b.newline()
            b.insert_text(indent_, fire_event=False)
        # if current line isn't blank, check dedent tokens
        elif (not (len(b.document.current_line) == 0
                   or b.document.current_line.isspace()) and
              b.document.current_line.split(maxsplit=1)[0] in DEDENT_TOKENS):
            b.newline(copy_margin=True)
            _ = b.delete_before_cursor(count=len(indent_))
        elif (not b.document.on_first_line
              and not (len(b.document.current_line) == 0
                       or b.document.current_line.isspace())):
            b.newline(copy_margin=True)
        elif b.document.char_before_cursor == '\\':
            b.newline()
        elif b.document.find_next_word_beginning() is not None:
            b.newline(copy_margin=True)
        elif not can_compile(b.document.text):
            b.newline()
        else:
            b.accept_action.validate_and_handle(event.cli, b)
示例#16
0
def load_xonsh_bindings(ptk_bindings: KeyBindingsBase) -> KeyBindingsBase:
    """
    Load custom key bindings.

    Parameters
    ----------
    ptk_bindings :
        The default prompt toolkit bindings. We need these to add aliases to them.
    """
    key_bindings = KeyBindings()
    handle = key_bindings.add
    has_selection = HasSelection()
    insert_mode = ViInsertMode() | EmacsInsertMode()

    if XSH.env["XONSH_CTRL_BKSP_DELETION"]:
        # Not all terminal emulators emit the same keys for backspace, therefore
        # ptk always maps backspace ("\x7f") to ^H ("\x08"), and all the backspace bindings are registered for ^H.
        # This means we can't re-map backspace and instead we register a new "real-ctrl-bksp" key.
        # See https://github.com/xonsh/xonsh/issues/4407

        if ON_WINDOWS:
            # On windows BKSP is "\x08" and CTRL-BKSP is "\x7f"
            REAL_CTRL_BKSP = "\x7f"

            # PTK uses a second mapping
            from prompt_toolkit.input import win32 as ptk_win32

            ptk_win32.ConsoleInputReader.mappings[b"\x7f"] = REAL_CTRL_BKSP  # type: ignore
        else:
            REAL_CTRL_BKSP = "\x08"

        # Prompt-toolkit allows using single-character keys that aren't in the `Keys` enum.
        ansi_escape_sequences.ANSI_SEQUENCES[REAL_CTRL_BKSP] = REAL_CTRL_BKSP  # type: ignore
        ansi_escape_sequences.REVERSE_ANSI_SEQUENCES[REAL_CTRL_BKSP] = REAL_CTRL_BKSP  # type: ignore

        @handle(REAL_CTRL_BKSP, filter=insert_mode)
        def delete_word(event):
            """Delete a single word (like ALT-backspace)"""
            get_by_name("backward-kill-word").call(event)

    @handle(Keys.Tab, filter=tab_insert_indent)
    def insert_indent(event):
        """
        If there are only whitespaces before current cursor position insert
        indent instead of autocompleting.
        """
        env = XSH.env
        event.cli.current_buffer.insert_text(env.get("INDENT"))

    @handle(Keys.Tab, filter=~tab_insert_indent & tab_menu_complete)
    def menu_complete_select(event):
        """Start completion in menu-complete mode, or tab to next completion"""
        b = event.current_buffer
        if b.complete_state:
            b.complete_next()
        else:
            b.start_completion(select_first=True)

    @handle(Keys.ControlX, Keys.ControlE, filter=~has_selection)
    def open_editor(event):
        """Open current buffer in editor"""
        event.current_buffer.open_in_editor(event.cli)

    @handle(Keys.BackTab, filter=insert_mode)
    def insert_literal_tab(event):
        """Insert literal tab on Shift+Tab instead of autocompleting"""
        b = event.current_buffer
        if b.complete_state:
            b.complete_previous()
        else:
            env = XSH.env
            event.cli.current_buffer.insert_text(env.get("INDENT"))

    def generate_parens_handlers(left, right):
        @handle(left, filter=autopair_condition)
        def insert_left_paren(event):
            buffer = event.cli.current_buffer

            if has_selection():
                wrap_selection(buffer, left, right)
            elif whitespace_or_bracket_after():
                buffer.insert_text(left)
                buffer.insert_text(right, move_cursor=False)
            else:
                buffer.insert_text(left)

        @handle(right, filter=autopair_condition)
        def overwrite_right_paren(event):
            buffer = event.cli.current_buffer

            if buffer.document.current_char == right:
                buffer.cursor_position += 1
            else:
                buffer.insert_text(right)

    generate_parens_handlers("(", ")")
    generate_parens_handlers("[", "]")
    generate_parens_handlers("{", "}")

    def generate_quote_handler(quote):
        @handle(quote, filter=autopair_condition)
        def insert_quote(event):
            buffer = event.cli.current_buffer

            if has_selection():
                wrap_selection(buffer, quote, quote)
            elif buffer.document.current_char == quote:
                buffer.cursor_position += 1
            elif whitespace_or_bracket_before() and whitespace_or_bracket_after():
                buffer.insert_text(quote)
                buffer.insert_text(quote, move_cursor=False)
            else:
                buffer.insert_text(quote)

    generate_quote_handler("'")
    generate_quote_handler('"')

    @handle(Keys.Backspace, filter=autopair_condition)
    def delete_brackets_or_quotes(event):
        """Delete empty pair of brackets or quotes"""
        buffer = event.cli.current_buffer
        before = buffer.document.char_before_cursor
        after = buffer.document.current_char

        if any(
            [before == b and after == a for (b, a) in ["()", "[]", "{}", "''", '""']]
        ):
            buffer.delete(1)

        buffer.delete_before_cursor(1)

    @handle(Keys.ControlD, filter=ctrl_d_condition)
    def call_exit_alias(event):
        """Use xonsh exit function"""
        b = event.cli.current_buffer
        b.validate_and_handle()
        xonsh_exit([])

    @handle(Keys.ControlJ, filter=IsMultiline() & insert_mode)
    @handle(Keys.ControlM, filter=IsMultiline() & insert_mode)
    def multiline_carriage_return(event):
        """Wrapper around carriage_return multiline parser"""
        b = event.cli.current_buffer
        carriage_return(b, event.cli)

    @handle(Keys.ControlJ, filter=should_confirm_completion)
    @handle(Keys.ControlM, filter=should_confirm_completion)
    def enter_confirm_completion(event):
        """Ignore <enter> (confirm completion)"""
        event.current_buffer.complete_state = None

    @handle(Keys.Escape, filter=should_confirm_completion)
    def esc_cancel_completion(event):
        """Use <ESC> to cancel completion"""
        event.cli.current_buffer.cancel_completion()

    @handle(Keys.Escape, Keys.ControlJ)
    def execute_block_now(event):
        """Execute a block of text irrespective of cursor position"""
        b = event.cli.current_buffer
        b.validate_and_handle()

    @handle(Keys.Left, filter=beginning_of_line)
    def wrap_cursor_back(event):
        """Move cursor to end of previous line unless at beginning of
        document
        """
        b = event.cli.current_buffer
        b.cursor_up(count=1)
        relative_end_index = b.document.get_end_of_line_position()
        b.cursor_right(count=relative_end_index)

    @handle(Keys.Right, filter=end_of_line)
    def wrap_cursor_forward(event):
        """Move cursor to beginning of next line unless at end of document"""
        b = event.cli.current_buffer
        relative_begin_index = b.document.get_start_of_line_position()
        b.cursor_left(count=abs(relative_begin_index))
        b.cursor_down(count=1)

    @handle(Keys.ControlM, filter=IsSearching())
    @handle(Keys.ControlJ, filter=IsSearching())
    def accept_search(event):
        search.accept_search()

    @handle(Keys.ControlZ)
    def skip_control_z(event):
        """Prevents the writing of ^Z to the prompt, if Ctrl+Z was pressed
        during the previous command.
        """
        pass

    @handle(Keys.ControlX, Keys.ControlX, filter=has_selection)
    def _cut(event):
        """Cut selected text."""
        data = event.current_buffer.cut_selection()
        event.app.clipboard.set_data(data)

    @handle(Keys.ControlX, Keys.ControlC, filter=has_selection)
    def _copy(event):
        """Copy selected text."""
        data = event.current_buffer.copy_selection()
        event.app.clipboard.set_data(data)

    @handle(Keys.ControlV, filter=insert_mode | has_selection)
    def _yank(event):
        """Paste selected text."""
        buff = event.current_buffer
        if buff.selection_state:
            buff.cut_selection()
        get_by_name("yank").call(event)

    def create_alias(new_keys, original_keys):
        bindings = ptk_bindings.get_bindings_for_keys(tuple(original_keys))
        for original_binding in bindings:
            handle(*new_keys, filter=original_binding.filter)(original_binding.handler)

    # Complete a single auto-suggestion word
    create_alias([Keys.ControlRight], ["escape", "f"])

    return key_bindings
    def load_bindings(key_bindings_manager):
        """
        Load keybindings into prompt_toolkit.
        """

        handle = key_bindings_manager.registry.add_binding
        has_selection = HasSelection()

        # for some reason Pylint doesn't think this function is "used"
        @key_bindings_manager.registry.add_binding(Keys.ControlL)
        def clear_(event):  # pylint: disable=unused-variable
            """
            Clear the screen.
            """

            clear()
            print(env.welcome)
            print(env.get_prompt(), end="")

        @handle(Keys.Tab, filter=TabShouldInsertWhitespaceFilter())
        def _(event):
            """
            When tab should insert whitespace, do that instead of completion.
            """
            event.cli.current_buffer.insert_text('   ')

        # prompt_toolkit _wants_ these two methods (they have different filter
        # attributes)
        @handle(Keys.ControlJ,
                filter=~has_selection & (ViInsertMode() | EmacsInsertMode())
                & HasFocus(DEFAULT_BUFFER) & IsMultiline())
        def _(event):  # pylint: disable=function-redefined
            """
            Behaviour of the Enter key.

            Auto indent after newline/Enter.
            (When not in Vi navigaton mode, and when multiline is enabled.)
            """
            current_buffer = event.current_buffer
            empty_lines_required = 2

            def at_the_end(ptk_buffer):
                """ we consider the cursor at the end when there is no text after
                the cursor, or only whitespace. """
                text = ptk_buffer.document.text_after_cursor
                return text == '' or (text.isspace() and not '\n' in text)

            def all_blocks_closed(ptk_buffer):
                """Return True when all Ergonomica code blocks are closed."""
                return tokenize(ptk_buffer.text).count("(") == tokenize(
                    ptk_buffer.text).count(")")

            if at_the_end(current_buffer)\
               and (current_buffer.document.text.replace(' ', '')
                    .endswith('\n' * (empty_lines_required - 1)
                             ) or all_blocks_closed(current_buffer)):
                current_buffer.document = Document(
                    text=current_buffer.text.rstrip(),
                    cursor_position=len(current_buffer.text.rstrip()))

                current_buffer.accept_action.validate_and_handle(
                    event.cli, current_buffer)
            else:
                _auto_newline(current_buffer)
示例#18
0
def load_xonsh_bindings() -> KeyBindingsBase:
    """
    Load custom key bindings.
    """
    key_bindings = KeyBindings()
    handle = key_bindings.add
    has_selection = HasSelection()
    insert_mode = ViInsertMode() | EmacsInsertMode()

    @handle(Keys.Tab, filter=tab_insert_indent)
    def insert_indent(event):
        """
        If there are only whitespaces before current cursor position insert
        indent instead of autocompleting.
        """
        env = builtins.__xonsh__.env
        event.cli.current_buffer.insert_text(env.get("INDENT"))

    @handle(Keys.Tab, filter=~tab_insert_indent & tab_menu_complete)
    def menu_complete_select(event):
        """Start completion in menu-complete mode, or tab to next completion"""
        b = event.current_buffer
        if b.complete_state:
            b.complete_next()
        else:
            b.start_completion(select_first=True)

    @handle(Keys.ControlX, Keys.ControlE, filter=~has_selection)
    def open_editor(event):
        """Open current buffer in editor"""
        event.current_buffer.open_in_editor(event.cli)

    @handle(Keys.BackTab, filter=insert_mode)
    def insert_literal_tab(event):
        """Insert literal tab on Shift+Tab instead of autocompleting"""
        b = event.current_buffer
        if b.complete_state:
            b.complete_previous()
        else:
            env = builtins.__xonsh__.env
            event.cli.current_buffer.insert_text(env.get("INDENT"))

    def generate_parens_handlers(left, right):
        @handle(left, filter=autopair_condition)
        def insert_left_paren(event):
            buffer = event.cli.current_buffer

            if has_selection():
                wrap_selection(buffer, left, right)
            elif whitespace_or_bracket_after():
                buffer.insert_text(left)
                buffer.insert_text(right, move_cursor=False)
            else:
                buffer.insert_text(left)

        @handle(right, filter=autopair_condition)
        def overwrite_right_paren(event):
            buffer = event.cli.current_buffer

            if buffer.document.current_char == right:
                buffer.cursor_position += 1
            else:
                buffer.insert_text(right)

    generate_parens_handlers("(", ")")
    generate_parens_handlers("[", "]")
    generate_parens_handlers("{", "}")

    def generate_quote_handler(quote):
        @handle(quote, filter=autopair_condition)
        def insert_quote(event):
            buffer = event.cli.current_buffer

            if has_selection():
                wrap_selection(buffer, quote, quote)
            elif buffer.document.current_char == quote:
                buffer.cursor_position += 1
            elif whitespace_or_bracket_before() and whitespace_or_bracket_after():
                buffer.insert_text(quote)
                buffer.insert_text(quote, move_cursor=False)
            else:
                buffer.insert_text(quote)

    generate_quote_handler("'")
    generate_quote_handler('"')

    @handle(Keys.Backspace, filter=autopair_condition)
    def delete_brackets_or_quotes(event):
        """Delete empty pair of brackets or quotes"""
        buffer = event.cli.current_buffer
        before = buffer.document.char_before_cursor
        after = buffer.document.current_char

        if any(
            [before == b and after == a for (b, a) in ["()", "[]", "{}", "''", '""']]
        ):
            buffer.delete(1)

        buffer.delete_before_cursor(1)

    @handle(Keys.ControlD, filter=ctrl_d_condition)
    def call_exit_alias(event):
        """Use xonsh exit function"""
        b = event.cli.current_buffer
        b.validate_and_handle()
        xonsh_exit([])

    @handle(Keys.ControlJ, filter=IsMultiline() & insert_mode)
    @handle(Keys.ControlM, filter=IsMultiline() & insert_mode)
    def multiline_carriage_return(event):
        """Wrapper around carriage_return multiline parser"""
        b = event.cli.current_buffer
        carriage_return(b, event.cli)

    @handle(Keys.ControlJ, filter=should_confirm_completion)
    @handle(Keys.ControlM, filter=should_confirm_completion)
    def enter_confirm_completion(event):
        """Ignore <enter> (confirm completion)"""
        event.current_buffer.complete_state = None

    @handle(Keys.Escape, filter=should_confirm_completion)
    def esc_cancel_completion(event):
        """Use <ESC> to cancel completion"""
        event.cli.current_buffer.cancel_completion()

    @handle(Keys.Escape, Keys.ControlJ)
    def execute_block_now(event):
        """Execute a block of text irrespective of cursor position"""
        b = event.cli.current_buffer
        b.validate_and_handle()

    @handle(Keys.Left, filter=beginning_of_line)
    def wrap_cursor_back(event):
        """Move cursor to end of previous line unless at beginning of
        document
        """
        b = event.cli.current_buffer
        b.cursor_up(count=1)
        relative_end_index = b.document.get_end_of_line_position()
        b.cursor_right(count=relative_end_index)

    @handle(Keys.Right, filter=end_of_line)
    def wrap_cursor_forward(event):
        """Move cursor to beginning of next line unless at end of document"""
        b = event.cli.current_buffer
        relative_begin_index = b.document.get_start_of_line_position()
        b.cursor_left(count=abs(relative_begin_index))
        b.cursor_down(count=1)

    @handle(Keys.ControlM, filter=IsSearching())
    @handle(Keys.ControlJ, filter=IsSearching())
    def accept_search(event):
        search.accept_search()

    @handle(Keys.ControlZ)
    def skip_control_z(event):
        """Prevents the writing of ^Z to the prompt, if Ctrl+Z was pressed
        during the previous command.
        """
        pass

    @handle(Keys.ControlX, Keys.ControlX, filter=has_selection)
    def _cut(event):
        """Cut selected text."""
        data = event.current_buffer.cut_selection()
        event.app.clipboard.set_data(data)

    @handle(Keys.ControlX, Keys.ControlC, filter=has_selection)
    def _copy(event):
        """Copy selected text."""
        data = event.current_buffer.copy_selection()
        event.app.clipboard.set_data(data)

    @handle(Keys.ControlV, filter=insert_mode | has_selection)
    def _yank(event):
        """Paste selected text."""
        buff = event.current_buffer
        if buff.selection_state:
            buff.cut_selection()
        get_by_name("yank").call(event)

    return key_bindings