示例#1
0
def load_emacs_system_bindings(registry, filter=None):
    handle = create_handle_decorator(registry, filter)
    has_focus = filters.HasFocus(SYSTEM_BUFFER)

    @handle(Keys.Escape, '!', filter=~has_focus)
    def _(event):
        """
        M-'!' opens the system prompt.
        """
        event.cli.focus_stack.push(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.focus_stack.pop()

    @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.focus_stack.pop()
示例#2
0
def load_emacs_search_bindings(registry,
                               filter=None,
                               search_buffer_name='search'):
    handle = create_handle_decorator(registry, filter)
    has_focus = filters.HasFocus(search_buffer_name)

    @handle(Keys.ControlG, 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_line = event.cli.buffers[search_buffer_name]

        event.current_buffer.exit_isearch(restore_original_line=True)
        search_line.reset()
        event.cli.focus_stack.pop()

    @handle(Keys.ControlJ, filter=has_focus)
    def _(event):
        """
        When enter pressed in isearch, quit isearch mode. (Multiline
        isearch would be too complicated.)
        """
        search_line = event.cli.buffers[search_buffer_name]
        search_line.reset()

        event.cli.buffers[event.cli.focus_stack.previous].exit_isearch()
        event.cli.focus_stack.pop()

    @handle(Keys.ControlR, filter=~has_focus)
    def _(event):
        event.cli.focus_stack.push(search_buffer_name)

        buffer = event.cli.buffers[event.cli.focus_stack.previous]
        buffer.incremental_search(IncrementalSearchDirection.BACKWARD)

    @handle(Keys.ControlS, filter=~has_focus)
    def _(event):
        event.cli.focus_stack.push(search_buffer_name)

        buffer = event.cli.buffers[event.cli.focus_stack.previous]
        buffer.incremental_search(IncrementalSearchDirection.FORWARD)

    @handle(Keys.ControlR, filter=has_focus)
    @handle(Keys.Up, filter=has_focus)
    def _(event):
        buffer = event.cli.buffers[event.cli.focus_stack.previous]
        buffer.incremental_search(IncrementalSearchDirection.BACKWARD)

    @handle(Keys.ControlS, filter=has_focus)
    @handle(Keys.Down, filter=has_focus)
    def _(event):
        buffer = event.cli.buffers[event.cli.focus_stack.previous]
        buffer.incremental_search(IncrementalSearchDirection.FORWARD)
示例#3
0
def load_vi_system_bindings(registry,
                            vi_state,
                            filter=None,
                            system_buffer_name='system'):
    assert isinstance(vi_state, ViState)

    has_focus = filters.HasFocus(system_buffer_name)
    navigation_mode = ViStateFilter(
        vi_state, InputMode.NAVIGATION) & ~filters.HasSelection()

    handle = create_handle_decorator(registry, filter)

    @handle('!', filter=~has_focus & navigation_mode)
    def _(event):
        """
        '!' opens the system prompt.
        """
        event.cli.focus_stack.push(system_buffer_name)
        vi_state.input_mode = InputMode.INSERT

    @handle(Keys.Escape, filter=has_focus)
    @handle(Keys.ControlC, filter=has_focus)
    def _(event):
        """
        Cancel system prompt.
        """
        vi_state.input_mode = InputMode.NAVIGATION
        event.cli.buffers[system_buffer_name].reset()
        event.cli.focus_stack.pop()

    @handle(Keys.ControlJ, filter=has_focus)
    def _(event):
        """
        Run system command.
        """
        vi_state.input_mode = InputMode.NAVIGATION

        system_buffer = event.cli.buffers[system_buffer_name]
        event.cli.run_system_command(system_buffer.text)
        system_buffer.reset(append_to_history=True)

        # Focus previous buffer again.
        event.cli.focus_stack.pop()
def CreatePromptLayout(config,
                       lexer=None,
                       is_password=False,
                       get_prompt_tokens=None,
                       get_continuation_tokens=None,
                       get_bottom_status_tokens=None,
                       get_bottom_toolbar_tokens=None,
                       extra_input_processors=None,
                       multiline=False,
                       show_help=True,
                       wrap_lines=True):
    """Create a container instance for the prompt."""
    assert get_bottom_status_tokens is None or callable(
        get_bottom_status_tokens)
    assert get_bottom_toolbar_tokens is None or callable(
        get_bottom_toolbar_tokens)
    assert get_prompt_tokens is None or callable(get_prompt_tokens)
    assert not (config.prompt and get_prompt_tokens)

    multi_column_completion_menu = filters.to_cli_filter(
        config.multi_column_completion_menu)
    multiline = filters.to_cli_filter(multiline)

    if get_prompt_tokens is None:
        get_prompt_tokens = lambda _: [(token.Token.Prompt, config.prompt)]

    has_before_tokens, get_prompt_tokens_1, get_prompt_tokens_2 = (
        shortcuts._split_multiline_prompt(get_prompt_tokens))  # pylint: disable=protected-access
    # TODO(b/35347840): reimplement _split_multiline_prompt to remove
    #                   protected-access.

    # Create processors list.
    input_processors = [
        processors.ConditionalProcessor(
            # By default, only highlight search when the search
            # input has the focus. (Note that this doesn't mean
            # there is no search: the Vi 'n' binding for instance
            # still allows to jump to the next match in
            # navigation mode.)
            processors.HighlightSearchProcessor(preview_search=True),
            filters.HasFocus(enums.SEARCH_BUFFER)),
        processors.HighlightSelectionProcessor(),
        processors.ConditionalProcessor(
            processors.AppendAutoSuggestion(),
            filters.HasFocus(enums.DEFAULT_BUFFER)
            & ~filters.IsDone()),
        processors.ConditionalProcessor(processors.PasswordProcessor(),
                                        is_password),
    ]

    if extra_input_processors:
        input_processors.extend(extra_input_processors)

    # Show the prompt before the input using the DefaultPrompt processor.
    # This also replaces it with reverse-i-search and 'arg' when required.
    # (Only for single line mode.)
    # (DefaultPrompt should always be at the end of the processors.)
    input_processors.append(
        processors.ConditionalProcessor(
            prompt.DefaultPrompt(get_prompt_tokens_2), ~multiline))

    # Create toolbars
    toolbars = []
    if config.fixed_prompt_position:
        help_height = dimension.LayoutDimension.exact(config.help_lines)
        help_filter = (show_help & ~filters.IsDone()
                       & filters.RendererHeightIsKnown())
    else:
        help_height = dimension.LayoutDimension(preferred=config.help_lines,
                                                max=config.help_lines)
        help_filter = (show_help & UserTypingFilter & ~filters.IsDone()
                       & filters.RendererHeightIsKnown())
    toolbars.append(
        containers.ConditionalContainer(layout.HSplit([
            layout.Window(
                controls.FillControl(char=screen.Char('_', token.Token.HSep)),
                height=dimension.LayoutDimension.exact(1)),
            layout.Window(help_window.HelpWindowControl(
                default_char=screen.Char(' ', token.Token.Toolbar)),
                          height=help_height),
        ]),
                                        filter=help_filter))
    if (config.bottom_status_line and get_bottom_status_tokens
            or config.bottom_bindings_line and get_bottom_toolbar_tokens):
        windows = []
        windows.append(
            layout.Window(
                controls.FillControl(char=screen.Char('_', token.Token.HSep)),
                height=dimension.LayoutDimension.exact(1)))
        if config.bottom_status_line and get_bottom_status_tokens:
            windows.append(
                layout.Window(controls.TokenListControl(
                    get_bottom_status_tokens,
                    default_char=screen.Char(' ', token.Token.Toolbar)),
                              height=dimension.LayoutDimension.exact(1)))
        if config.bottom_bindings_line and get_bottom_toolbar_tokens:
            windows.append(
                layout.Window(controls.TokenListControl(
                    get_bottom_toolbar_tokens,
                    default_char=screen.Char(' ', token.Token.Toolbar)),
                              height=dimension.LayoutDimension.exact(1)))
        toolbars.append(
            containers.ConditionalContainer(layout.HSplit(windows),
                                            filter=~filters.IsDone()
                                            & filters.RendererHeightIsKnown()))

    def GetHeight(cli):
        """Determine the height for the input buffer."""
        # If there is an autocompletion menu to be shown, make sure that our
        # layout has at least a minimal height in order to display it.
        if cli.config.completion_menu_lines and not cli.is_done:
            # Reserve the space, either when there are completions, or when
            # `complete_while_typing` is true and we expect completions very
            # soon.
            buf = cli.current_buffer
            # if UserTypingFilter(cli) or not buf.text or buf.complete_state:
            if UserTypingFilter(cli) or buf.complete_state:
                return dimension.LayoutDimension(
                    min=cli.config.completion_menu_lines + 1)
        return dimension.LayoutDimension()

    # Create and return Container instance.
    return layout.HSplit([
        # The main input, with completion menus floating on top of it.
        containers.FloatContainer(
            layout.HSplit([
                containers.ConditionalContainer(
                    layout.Window(
                        controls.TokenListControl(get_prompt_tokens_1),
                        dont_extend_height=True,
                        wrap_lines=wrap_lines,
                    ),
                    filters.Condition(has_before_tokens),
                ),
                layout.Window(
                    controls.BufferControl(
                        input_processors=input_processors,
                        lexer=lexer,
                        # Enable preview_search, we want to have immediate
                        # feedback in reverse-i-search mode.
                        preview_search=True,
                    ),
                    get_height=GetHeight,
                    left_margins=[
                        # In multiline mode, use the window margin to display
                        # the prompt and continuation tokens.
                        margins.ConditionalMargin(
                            margins.PromptMargin(get_prompt_tokens_2,
                                                 get_continuation_tokens),
                            filter=multiline,
                        ),
                    ],
                    wrap_lines=wrap_lines,
                ),
            ]),
            [
                # Completion menus.
                layout.Float(
                    xcursor=True,
                    ycursor=True,
                    content=menus.CompletionsMenu(
                        max_height=16,
                        scroll_offset=1,
                        extra_filter=(filters.HasFocus(enums.DEFAULT_BUFFER)
                                      & ~multi_column_completion_menu),
                    ),
                ),
                layout.Float(
                    ycursor=True,
                    content=menus.MultiColumnCompletionsMenu(
                        show_meta=True,
                        extra_filter=(filters.HasFocus(enums.DEFAULT_BUFFER)
                                      & multi_column_completion_menu),
                    ),
                ),
            ],
        ),
        pt_toolbars.ValidationToolbar(),
        pt_toolbars.SystemToolbar(),

        # In multiline mode, we use two toolbars for 'arg' and 'search'.
        containers.ConditionalContainer(pt_toolbars.ArgToolbar(), multiline),
        containers.ConditionalContainer(pt_toolbars.SearchToolbar(),
                                        multiline),
    ] + toolbars)
示例#5
0
def load_vi_search_bindings(registry,
                            vi_state,
                            filter=None,
                            search_buffer_name=SEARCH_BUFFER):
    assert isinstance(vi_state, ViState)

    has_focus = filters.HasFocus(search_buffer_name)
    navigation_mode = ~has_focus & (ViStateFilter(
        vi_state, InputMode.NAVIGATION) | filters.HasSelection())
    handle = create_handle_decorator(registry, filter)

    @handle('/', filter=navigation_mode)
    @handle(Keys.ControlS, filter=~has_focus)
    def _(event):
        """
        Vi-style forward search.
        """
        # Set the ViState.
        event.cli.search_state.direction = IncrementalSearchDirection.FORWARD
        vi_state.input_mode = InputMode.INSERT

        # Focus search buffer.
        event.cli.focus_stack.push(search_buffer_name)

    @handle('?', filter=navigation_mode)
    @handle(Keys.ControlR, filter=~has_focus)
    def _(event):
        """
        Vi-style backward search.
        """
        # Set the ViState.
        event.cli.search_state.direction = IncrementalSearchDirection.BACKWARD

        # Focus search buffer.
        event.cli.focus_stack.push(search_buffer_name)
        vi_state.input_mode = InputMode.INSERT

    @handle(Keys.ControlJ, filter=has_focus)
    def _(event):
        """
        Apply the search. (At the / or ? prompt.)
        """
        input_buffer = event.cli.buffers[event.cli.focus_stack.previous]
        search_buffer = event.cli.buffers[search_buffer_name]

        # Update search state.
        if search_buffer.text:
            event.cli.search_state.text = search_buffer.text

        # Apply search.
        input_buffer.apply_search(event.cli.search_state)

        # Add query to history of search line.
        search_buffer.append_to_history()
        search_buffer.reset()

        # Focus previous document again.
        vi_state.input_mode = InputMode.NAVIGATION
        event.cli.focus_stack.pop()

    def search_buffer_is_empty(cli):
        """ Returns True when the search buffer is empty. """
        return cli.buffers[search_buffer_name].text == ''

    @handle(Keys.Escape, filter=has_focus)
    @handle(Keys.ControlC, filter=has_focus)
    @handle(Keys.Backspace,
            filter=has_focus & Condition(search_buffer_is_empty))
    def _(event):
        """
        Cancel search.
        """
        vi_state.input_mode = InputMode.NAVIGATION

        event.cli.focus_stack.pop()
        event.cli.buffers[search_buffer_name].reset()
示例#6
0
def load_emacs_search_bindings(registry, filter=None):
    handle = create_handle_decorator(registry, filter)
    has_focus = filters.HasFocus(SEARCH_BUFFER)

    @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.focus_stack.pop()

    @handle(Keys.ControlJ, filter=has_focus)
    def _(event):
        """
        When enter pressed in isearch, quit isearch mode. (Multiline
        isearch would be too complicated.)
        """
        input_buffer = event.cli.buffers[event.cli.focus_stack.previous]
        search_buffer = event.cli.buffers[SEARCH_BUFFER]

        # Update search state.
        if search_buffer.text:
            event.cli.search_state.text = search_buffer.text

        # Apply search.
        input_buffer.apply_search(event.cli.search_state,
                                  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.focus_stack.pop()

    @handle(Keys.ControlR, filter=~has_focus)
    def _(event):
        event.cli.search_state.direction = IncrementalSearchDirection.BACKWARD
        event.cli.focus_stack.push(SEARCH_BUFFER)

    @handle(Keys.ControlS, filter=~has_focus)
    def _(event):
        event.cli.search_state.direction = IncrementalSearchDirection.FORWARD
        event.cli.focus_stack.push(SEARCH_BUFFER)

    @handle(Keys.ControlR, filter=has_focus)
    @handle(Keys.Up, filter=has_focus)
    def _(event):
        # Update search_state.
        search_state = event.cli.search_state
        direction_changed = search_state.direction != IncrementalSearchDirection.BACKWARD

        search_state.text = event.cli.buffers[SEARCH_BUFFER].text
        search_state.direction = IncrementalSearchDirection.BACKWARD

        # Apply search to current buffer.
        if not direction_changed:
            input_buffer = event.cli.buffers[event.cli.focus_stack.previous]
            input_buffer.apply_search(event.cli.search_state,
                                      include_current_position=False,
                                      count=event.arg)

    @handle(Keys.ControlS, filter=has_focus)
    @handle(Keys.Down, filter=has_focus)
    def _(event):
        # Update search_state.
        search_state = event.cli.search_state
        direction_changed = search_state.direction != IncrementalSearchDirection.FORWARD

        search_state.text = event.cli.buffers[SEARCH_BUFFER].text
        search_state.direction = IncrementalSearchDirection.FORWARD

        # Apply search to current buffer.
        if not direction_changed:
            input_buffer = event.cli.buffers[event.cli.focus_stack.previous]
            input_buffer.apply_search(event.cli.search_state,
                                      include_current_position=False,
                                      count=event.arg)
def load_emacs_search_bindings(registry, get_search_state=None, filter=None):
    handle = create_handle_decorator(registry, filter)
    has_focus = filters.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)
    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.
        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:
            input_buffer = cli.buffers.previous(cli)
            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):
        incremental_search(event.cli,
                           IncrementalSearchDirection.FORWARD,
                           count=event.arg)
示例#8
0
def load_vi_search_bindings(registry,
                            vi_state,
                            filter=None,
                            search_buffer_name='search'):
    assert isinstance(vi_state, ViState)

    has_focus = filters.HasFocus(search_buffer_name)
    navigation_mode = ~has_focus & (ViStateFilter(
        vi_state, InputMode.NAVIGATION) | filters.HasSelection())
    handle = create_handle_decorator(registry, filter)

    @handle('/', filter=navigation_mode)
    @handle(Keys.ControlS)
    def _(event):
        """
        Vi-style forward search.
        """
        vi_state.search_direction = direction = IncrementalSearchDirection.FORWARD
        vi_state.input_mode = InputMode.INSERT

        if event.cli.focus_stack.current != search_buffer_name:
            event.cli.focus_stack.push(search_buffer_name)

        event.cli.buffers[event.cli.focus_stack.previous].incremental_search(
            direction)

    @handle('?', filter=navigation_mode)
    @handle(Keys.ControlR)
    def _(event):
        """
        Vi-style backward search.
        """
        vi_state.search_direction = direction = IncrementalSearchDirection.BACKWARD
        vi_state.input_mode = InputMode.INSERT

        if event.cli.focus_stack.current != search_buffer_name:
            event.cli.focus_stack.push(search_buffer_name)

        event.cli.buffers[event.cli.focus_stack.previous].incremental_search(
            direction)

    @handle(Keys.ControlJ, filter=has_focus)
    def _(event):
        """
        Enter at the / or ? prompt.
        """
        search_buffer = event.cli.buffers[search_buffer_name]
        vi_state.input_mode = InputMode.NAVIGATION

        # Add query to history of search line.
        search_buffer.add_to_history()
        search_buffer.reset()

        # Focus previous document again.
        event.cli.focus_stack.pop()

    @handle(Keys.Any, filter=has_focus)
    def _(event):
        """
        Insert text after the / or ? prompt.
        """
        event.cli.current_buffer.insert_text(event.data)

        # Set current search search text as line search text.
        buffer = event.cli.buffers[event.cli.focus_stack.previous]
        buffer.set_search_text(event.cli.current_buffer.text)

    @handle(Keys.Escape, filter=has_focus)
    @handle(Keys.ControlC, filter=has_focus)
    def _(event):
        """
        Cancel search.
        """
        vi_state.input_mode = InputMode.NAVIGATION

        event.cli.focus_stack.pop()
        event.current_buffer.exit_isearch(restore_original_line=True)

        event.cli.buffers[search_buffer_name].reset()