Пример #1
0
    def __init__(self, pymux):
        self.pymux = pymux

        def get_search_state(cli):
            " Return the currently active SearchState. (The one for the focussed pane.) "
            return pymux.arrangement.get_active_pane(cli).search_state

        # Start from this KeyBindingManager from prompt_toolkit, to have basic
        # editing functionality for the command line. These key binding are
        # however only active when the following `enable_all` condition is met.
        self.registry = MergedRegistry([
            ConditionalRegistry(
                registry=load_key_bindings(
                    enable_auto_suggest_bindings=True,
                    enable_search=
                    False,  # We have our own search bindings, that support multiple panes.
                    enable_extra_page_navigation=True,
                    get_search_state=get_search_state),
                filter=(HasFocus(COMMAND) | HasFocus(PROMPT)
                        | InScrollBuffer(pymux)) & ~HasPrefix(pymux),
            ),
            load_mouse_bindings(),
            self._load_builtins(),
            _load_search_bindings(pymux),
        ])

        self._prefix = (Keys.ControlB, )
        self._prefix_binding = None

        # Load initial bindings.
        self._load_prefix_binding()

        # Custom user configured key bindings.
        # { (needs_prefix, key) -> (command, handler) }
        self.custom_bindings = {}
Пример #2
0
def register_ipython_shortcuts(registry, shell):
    """Set up the prompt_toolkit keyboard shortcuts for IPython"""
    insert_mode = ViInsertMode() | EmacsInsertMode()

    # Ctrl+J == Enter, seemingly
    registry.add_binding(Keys.ControlJ,
                         filter=(HasFocus(DEFAULT_BUFFER)
                                 & ~HasSelection()
                                 & insert_mode))(
                                     newline_or_execute_outer(shell))

    registry.add_binding(Keys.ControlBackslash)(force_exit)

    registry.add_binding(Keys.ControlP,
                         filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
                                 ))(previous_history_or_previous_completion)

    registry.add_binding(
        Keys.ControlN,
        filter=(ViInsertMode()
                & HasFocus(DEFAULT_BUFFER)))(next_history_or_next_completion)

    registry.add_binding(Keys.ControlG,
                         filter=(HasFocus(DEFAULT_BUFFER)
                                 & HasCompletions()))(dismiss_completion)

    registry.add_binding(Keys.ControlC,
                         filter=HasFocus(DEFAULT_BUFFER))(reset_buffer)

    registry.add_binding(Keys.ControlC,
                         filter=HasFocus(SEARCH_BUFFER))(reset_search_buffer)

    supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
    registry.add_binding(Keys.ControlZ, filter=supports_suspend)(suspend_to_bg)

    # Ctrl+I == Tab
    registry.add_binding(Keys.ControlI,
                         filter=(HasFocus(DEFAULT_BUFFER)
                                 & ~HasSelection()
                                 & insert_mode
                                 & cursor_in_leading_ws))(indent_buffer)

    registry.add_binding(
        Keys.ControlO, filter=(HasFocus(DEFAULT_BUFFER)
                               & EmacsInsertMode()))(newline_with_copy_margin)

    if shell.display_completions == 'readlinelike':
        registry.add_binding(
            Keys.ControlI,
            filter=(
                HasFocus(DEFAULT_BUFFER)
                & ~HasSelection()
                & insert_mode
                & ~cursor_in_leading_ws))(display_completions_like_readline)

    if sys.platform == 'win32':
        registry.add_binding(Keys.ControlV,
                             filter=(HasFocus(DEFAULT_BUFFER)
                                     & ~ViMode()))(win_paste)
Пример #3
0
    def __init__(self, editor, manager, window_arrangement):
        self.editor = editor  # Back reference to editor.
        self.manager = manager
        self.window_arrangement = window_arrangement

        # Mapping from (`window_arrangement.Window`, `EditorBuffer`) to a frame
        # (Layout instance).
        # We keep this as a cache in order to easily reuse the same frames when
        # the layout is updated. (We don't want to create new frames on every
        # update call, because that way, we would loose some state, like the
        # vertical scroll offset.)
        self._frames = {}

        self._fc = FloatContainer(
            content=VSplit([
                Window(BufferControl())  # Dummy window
            ]),
            floats=[
                Float(xcursor=True, ycursor=True,
                      content=CompletionsMenu(max_height=12,
                                              scroll_offset=2,
                                              extra_filter=~HasFocus(COMMAND_BUFFER))),
                Float(content=BufferListOverlay(editor), bottom=1, left=0),
                Float(bottom=1, left=0, right=0, height=1,
                      content=CompletionsToolbar(
                          extra_filter=HasFocus(COMMAND_BUFFER) &
                                       ~bufferlist_overlay_visible_filter &
                                       Condition(lambda cli: editor.show_wildmenu))),
                Float(bottom=1, left=0, right=0, height=1,
                      content=ValidationToolbar()),
                Float(bottom=1, left=0, right=0, height=1,
                      content=MessageToolbarBar(editor)),
                Float(content=WelcomeMessageWindow(editor),
                      height=WELCOME_MESSAGE_HEIGHT,
                      width=WELCOME_MESSAGE_WIDTH),
            ]
        )

        self.layout = FloatContainer(
            content=HSplit([
                TabsToolbar(editor),
                self._fc,
                CommandLine(),
                ReportMessageToolbar(editor),
                SystemToolbar(),
                SearchToolbar(vi_mode=True),
            ]),
            floats=[
                Float(right=0, height=1, bottom=0, width=5,
                      content=SimpleArgToolbar()),
            ]
        )
Пример #4
0
    def create_python_input_window():
        def menu_position(cli):
            """
            When there is no autocompletion menu to be shown, and we have a signature,
            set the pop-up position at `bracket_start`.
            """
            b = cli.buffers[DEFAULT_BUFFER]

            if b.complete_state is None and python_input.signatures:
                row, col = python_input.signatures[0].bracket_start
                index = b.document.translate_row_col_to_index(row - 1, col)
                return index

        return Window(
            BufferControl(
                buffer_name=DEFAULT_BUFFER,
                lexer=lexer,
                input_processors=[
                    ConditionalProcessor(
                        processor=HighlightSearchProcessor(
                            preview_search=True),
                        filter=HasFocus(SEARCH_BUFFER),
                    ),
                    HighlightSelectionProcessor(),
                    DisplayMultipleCursors(DEFAULT_BUFFER),
                    # Show matching parentheses, but only while editing.
                    ConditionalProcessor(
                        processor=HighlightMatchingBracketProcessor(
                            chars='[](){}'),
                        filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()
                        & Condition(lambda cli: python_input.
                                    highlight_matching_parenthesis)),
                    ConditionalProcessor(processor=AppendAutoSuggestion(),
                                         filter=~IsDone())
                ] + extra_buffer_processors,
                menu_position=menu_position,

                # Make sure that we always see the result of an reverse-i-search:
                preview_search=True,
            ),
            left_margins=[PythonPromptMargin(python_input)],
            # Scroll offsets. The 1 at the bottom is important to make sure the
            # cursor is never below the "Press [Meta+Enter]" message which is a float.
            scroll_offsets=ScrollOffsets(bottom=1, left=4, right=4),
            # As long as we're editing, prefer a minimal height of 6.
            get_height=(lambda cli:
                        (None if cli.is_done or python_input.
                         show_exit_confirmation else input_buffer_height)),
            wrap_lines=Condition(lambda cli: python_input.wrap_lines),
        )
Пример #5
0
    def _layout_options(self):
        """
        Return the current layout option for the current Terminal InteractiveShell
        """
        return {
            'lexer':
            IPythonPTLexer(),
            'reserve_space_for_menu':
            self.space_for_menu,
            'get_prompt_tokens':
            self.prompts.in_prompt_tokens,
            'get_continuation_tokens':
            self.prompts.continuation_prompt_tokens,
            'multiline':
            True,
            'display_completions_in_columns':
            (self.display_completions == 'multicolumn'),

            # Highlight matching brackets, but only when this setting is
            # enabled, and only when the DEFAULT_BUFFER has the focus.
            'extra_input_processors': [
                ConditionalProcessor(
                    processor=HighlightMatchingBracketProcessor(
                        chars='[](){}'),
                    filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()
                    & Condition(lambda cli: self.highlight_matching_brackets))
            ],
        }
Пример #6
0
def load_emacs_system_bindings(registry, filter=None):
    handle = create_handle_decorator(registry, filter & EmacsMode())
    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()
Пример #7
0
    def _build_cli(self, history):
        def set_vi_mode(value):
            self.vi_mode = value

        key_binding_manager = mssqlcli_bindings(
            get_vi_mode_enabled=lambda: self.vi_mode,
            set_vi_mode_enabled=set_vi_mode)

        def prompt_tokens(_):
            prompt = self.get_prompt()
            return [(Token.Prompt, prompt)]

        def get_continuation_tokens(cli, width):
            continuation = self.multiline_continuation_char * (width - 1) + ' '
            return [(Token.Continuation, continuation)]

        get_toolbar_tokens = create_toolbar_tokens_func(
            lambda: self.vi_mode, None, None, None)

        layout = create_prompt_layout(
            lexer=PygmentsLexer(PostgresLexer),
            reserve_space_for_menu=self.min_num_menu_lines,
            get_prompt_tokens=prompt_tokens,
            get_continuation_tokens=get_continuation_tokens,
            get_bottom_toolbar_tokens=get_toolbar_tokens,
            display_completions_in_columns=self.wider_completion_menu,
            multiline=True,
            extra_input_processors=[
                # Highlight matching brackets while editing.
                ConditionalProcessor(
                    processor=HighlightMatchingBracketProcessor(
                        chars='[](){}'),
                    filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()),
            ])

        with self._completer_lock:
            buf = MssqlBuffer(auto_suggest=AutoSuggestFromHistory(),
                              always_multiline=self.multi_line,
                              multiline_mode=self.multiline_mode,
                              completer=self.completer,
                              history=history,
                              complete_while_typing=Always(),
                              accept_action=AcceptAction.RETURN_DOCUMENT)

            editing_mode = EditingMode.VI if self.vi_mode else EditingMode.EMACS

            application = Application(
                style=style_factory(self.syntax_style, self.cli_style),
                layout=layout,
                buffer=buf,
                key_bindings_registry=key_binding_manager.registry,
                on_exit=AbortAction.RAISE_EXCEPTION,
                on_abort=AbortAction.RETRY,
                ignore_case=True,
                editing_mode=editing_mode)

            cli = CommandLineInterface(application=application,
                                       eventloop=self.eventloop)

            return cli
Пример #8
0
    def __init__(self, editor):
        def get_tokens(cli):
            eb = editor.window_arrangement.active_editor_buffer

            lineno = eb.buffer.document.cursor_position_row
            errors = eb.report_errors

            for e in errors:
                if e.lineno == lineno:
                    return e.message_token_list

            return []

        super(ReportMessageToolbar, self).__init__(
                get_tokens,
                filter=~HasFocus(COMMAND_BUFFER) & ~HasSearch() & ~HasFocus('system'))
Пример #9
0
    def _build_cli(self, history):
        def get_message():
            prompt = self.context.get_prompt(self.default_prompt)
            return [('class:prompt', prompt)]

        prompt_app = PromptSession(
            message=get_message,
            complete_style=CompleteStyle.COLUMN,
            completer=ThreadedCompleter(
                DynamicCompleter(lambda: self.completer)),
            complete_while_typing=True,
            editing_mode=EditingMode.VI,
            enable_system_prompt=True,
            enable_suspend=True,
            history=history,
            input_processors=[
                # Highlight matching brackets while editing.
                ConditionalProcessor(
                    processor=HighlightMatchingBracketProcessor(
                        chars='[](){}', ),
                    filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()),
                # Render \t as 4 spaces instead of "^I"
                TabsProcessor(char1=' ', char2=' ')
            ],
            key_bindings=get_key_bindings(),
            search_ignore_case=True,
        )

        return prompt_app
Пример #10
0
def create_tutorial_layout(lex):
    """ layout for example tutorial """
    lexer, _, _ = get_lexers(lex, None, None)
    layout_full = HSplit([
        FloatContainer(
            Window(BufferControl(input_processors=input_processors,
                                 lexer=lexer,
                                 preview_search=Always()),
                   get_height=get_height), [
                       Float(xcursor=True,
                             ycursor=True,
                             content=CompletionsMenu(
                                 max_height=MAX_COMPLETION,
                                 scroll_offset=1,
                                 extra_filter=(HasFocus(DEFAULT_BUFFER))))
                   ]),
        ConditionalContainer(HSplit([
            get_hline(),
            get_param(lexer),
            get_hline(),
            Window(content=BufferControl(buffer_name='example_line',
                                         lexer=lexer), ),
            Window(TokenListControl(get_tutorial_tokens,
                                    default_char=Char(' ', Token.Toolbar)),
                   height=D.exact(1)),
        ]),
                             filter=~IsDone() & RendererHeightIsKnown())
    ])
    return layout_full
Пример #11
0
    def _extra_prompt_options(self):
        """
        Return the current layout option for the current Terminal InteractiveShell
        """
        def get_message():
            return PygmentsTokens(self.prompts.in_prompt_tokens())

        return {
                'complete_in_thread': False,
                'lexer':IPythonPTLexer(),
                'reserve_space_for_menu':self.space_for_menu,
                'message': get_message,
                'prompt_continuation': (
                    lambda width, lineno, is_soft_wrap:
                        PygmentsTokens(self.prompts.continuation_prompt_tokens(width))),
                'multiline': True,
                'complete_style': self.pt_complete_style,

                # Highlight matching brackets, but only when this setting is
                # enabled, and only when the DEFAULT_BUFFER has the focus.
                'input_processors': [ConditionalProcessor(
                        processor=HighlightMatchingBracketProcessor(chars='[](){}'),
                        filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() &
                            Condition(lambda: self.highlight_matching_brackets))],
                }
Пример #12
0
 def __init__(self):
     super(CommandLine, self).__init__(BufferControl(
         buffer_name=COMMAND_BUFFER,
         input_processors=[BeforeInput.static(':')],
         lexer=create_command_lexer()),
                                       height=LayoutDimension.exact(1),
                                       filter=HasFocus(COMMAND_BUFFER))
Пример #13
0
    def build_cli(self):
        # TODO: Optimize index suggestion to serve indices options only at the needed position, such as 'from'
        indices_list = self.es_executor.indices_list
        sql_completer = WordCompleter(self.keywords_list +
                                      self.functions_list + indices_list,
                                      ignore_case=True)

        # https://stackoverflow.com/a/13726418 denote multiple unused arguments of callback in Python
        def get_continuation(width, *_):
            continuation = self.multiline_continuation_char * (width - 1) + " "
            return [("class:continuation", continuation)]

        prompt_app = PromptSession(
            lexer=PygmentsLexer(SqlLexer),
            completer=sql_completer,
            complete_while_typing=True,
            # TODO: add history, refer to pgcli approach
            # history=history,
            style=style_factory(self.syntax_style, self.cli_style),
            prompt_continuation=get_continuation,
            multiline=es_is_multiline(self),
            auto_suggest=AutoSuggestFromHistory(),
            input_processors=[
                ConditionalProcessor(
                    processor=HighlightMatchingBracketProcessor(
                        chars="[](){}"),
                    filter=HasFocus(DEFAULT_BUFFER) & ~IsDone(),
                )
            ],
            tempfile_suffix=".sql",
        )

        return prompt_app
Пример #14
0
    def create_python_input_window():
        def menu_position(cli):
            """
            When there is no autocompletion menu to be shown, and we have a signature,
            set the pop-up position at `bracket_start`.
            """
            b = cli.buffers['default']

            if b.complete_state is None and settings.signatures:
                row, col = settings.signatures[0].bracket_start
                index = b.document.translate_row_col_to_index(row - 1, col)
                return index

        return Window(
            BufferControl(
                buffer_name=DEFAULT_BUFFER,
                lexer=lexer,
                show_line_numbers=ShowLineNumbersFilter(settings, 'default'),
                input_processors=[
                                  # Show matching parentheses, but only while editing.
                                  ConditionalProcessor(
                                      processor=HighlightMatchingBracketProcessor(chars='[](){}'),
                                      filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()),
                                  HighlightSearchProcessor(preview_search=Always()),
                                  HighlightSelectionProcessor()] + extra_buffer_processors,
                menu_position=menu_position,

                # Make sure that we always see the result of an reverse-i-search:
                preview_search=Always(),
            ),
            # As long as we're editing, prefer a minimal height of 6.
            get_height=(lambda cli: (None if cli.is_done else D(min=6))),
        )
Пример #15
0
    def _build_cli(self):
        eventloop = create_eventloop()

        if self._options.persistent_history:
            history = FileHistory(
                os.path.join(
                    os.path.expanduser("~"), ".{}_history".format(self._ctx.binary_name)
                )
            )
        else:
            history = InMemoryHistory()

        layout = create_prompt_layout(
            lexer=PygmentsLexer(NubiaLexer),
            reserve_space_for_menu=5,
            get_prompt_tokens=self.get_prompt_tokens,
            get_rprompt_tokens=self._status_bar.get_rprompt_tokens,
            get_bottom_toolbar_tokens=self._status_bar.get_tokens,
            display_completions_in_columns=False,
            multiline=True,
            extra_input_processors=[
                ConditionalProcessor(
                    processor=HighlightMatchingBracketProcessor(chars="[](){}"),
                    filter=HasFocus(DEFAULT_BUFFER) & ~IsDone(),
                )
            ],
        )

        buf = Buffer(
            completer=self._completer,
            history=history,
            auto_suggest=self._suggestor,
            complete_while_typing=Always(),
            accept_action=AcceptAction.RETURN_DOCUMENT,
        )

        # If EDITOR does not exist, take EMACS
        # if it does, try fit the EMACS/VI pattern using upper
        editor = getattr(
            EditingMode,
            os.environ.get("EDITOR", EditingMode.EMACS).upper(),
            EditingMode.EMACS,
        )

        application = Application(
            style=shell_style,
            buffer=buf,
            editing_mode=editor,
            key_bindings_registry=self._registry,
            layout=layout,
            on_exit=AbortAction.RAISE_EXCEPTION,
            on_abort=AbortAction.RETRY,
            ignore_case=True,
        )

        cli = CommandLineInterface(application=application, eventloop=eventloop)
        return cli
Пример #16
0
    def _build_cli(self, history):
        def get_message():
            prompt = self.get_prompt(self.prompt_format)
            return [(u'class:prompt', prompt)]

        def get_continuation(width):
            continuation = self.multiline_continuation_char * (width - 1) + ' '
            return [(u'class:continuation', continuation)]

        get_toolbar_tokens = create_toolbar_tokens_func(self)

        if self.wider_completion_menu:
            complete_style = CompleteStyle.MULTI_COLUMN
        else:
            complete_style = CompleteStyle.COLUMN

        with self._completer_lock:
            self.prompt_session = PromptSession(
                message=get_message,
                style=style_factory(self.syntax_style, self.cli_style),

                # Layout options.
                lexer=PygmentsLexer(PostgresLexer),
                prompt_continuation=get_continuation,
                bottom_toolbar=get_toolbar_tokens,
                complete_style=complete_style,
                input_processors=[
                    ConditionalProcessor(
                        processor=HighlightMatchingBracketProcessor(
                            chars='[](){}'),
                        filter=HasFocus(DEFAULT_BUFFER)
                        & ~IsDone()),  #FIXME: what is this?
                    # Render \t as 4 spaces instead of "^I"
                    TabsProcessor(char1=u' ', char2=u' ')
                ],
                reserve_space_for_menu=self.min_num_menu_lines,

                # Buffer options.
                multiline=mssql_is_multiline(self),
                completer=ThreadedCompleter(
                    DynamicCompleter(lambda: self.completer)),
                history=history,
                auto_suggest=AutoSuggestFromHistory(),
                complete_while_typing=True,

                # Key bindings.
                enable_system_prompt=True,
                enable_open_in_editor=True,

                # Other options.
                key_bindings=mssqlcli_bindings(self),
                editing_mode=EditingMode.VI
                if self.vi_mode else EditingMode.EMACS,
                search_ignore_case=True)

            return self.prompt_session
Пример #17
0
    def add_custom_binding(self,
                           key_name,
                           command,
                           arguments,
                           needs_prefix=False):
        """
        Add custom binding (for the "bind-key" command.)
        Raises ValueError if the give `key_name` is an invalid name.

        :param key_name: Pymux key name, for instance "C-a" or "M-x".
        """
        assert isinstance(key_name, six.text_type)
        assert isinstance(command, six.text_type)
        assert isinstance(arguments, list)

        # Unbind previous key.
        self.remove_custom_binding(key_name, needs_prefix=needs_prefix)

        # Translate the pymux key name into a prompt_toolkit key sequence.
        # (Can raise ValueError.)
        keys_sequence = pymux_key_to_prompt_toolkit_key_sequence(key_name)

        # Create handler and add to Registry.
        if needs_prefix:
            filter = HasPrefix(self.pymux)
        else:
            filter = ~HasPrefix(self.pymux)

        filter = filter & ~(WaitsForConfirmation(self.pymux)
                            | HasFocus(COMMAND) | HasFocus(PROMPT))

        def key_handler(event):
            " The actual key handler. "
            call_command_handler(command, self.pymux, event.cli, arguments)
            self.pymux.get_client_state(event.cli).has_prefix = False

        self.registry.add_binding(*keys_sequence, filter=filter)(key_handler)

        # Store key in `custom_bindings` in order to be able to call
        # "unbind-key" later on.
        k = (needs_prefix, key_name)
        self.custom_bindings[k] = CustomBinding(key_handler, command,
                                                arguments)
Пример #18
0
    def _create_cli(self):
        """Creates the prompt_toolkit's CommandLineInterface.

        Args:
            * None.

        Returns:
            None.
        """
        history = FileHistory(os.path.expanduser('~/.saws-history'))
        toolbar = Toolbar(self.get_color,
                          self.get_fuzzy_match,
                          self.get_shortcut_match)
        layout = create_default_layout(
            message='saws> ',
            reserve_space_for_menu=8,
            lexer=CommandLexer,
            get_bottom_toolbar_tokens=toolbar.handler,
            extra_input_processors=[
                ConditionalProcessor(
                    processor=HighlightMatchingBracketProcessor(
                        chars='[](){}'),
                    filter=HasFocus(DEFAULT_BUFFER) & ~IsDone())
            ]
        )
        cli_buffer = Buffer(
            history=history,
            auto_suggest=AutoSuggestFromHistory(),
            enable_history_search=True,
            completer=self.completer,
            complete_while_typing=Always(),
            accept_action=AcceptAction.RETURN_DOCUMENT)
        self.key_manager = KeyManager(
            self.set_color,
            self.get_color,
            self.set_fuzzy_match,
            self.get_fuzzy_match,
            self.set_shortcut_match,
            self.get_shortcut_match,
            self.refresh_resources_and_options,
            self.handle_docs)
        style_factory = StyleFactory(self.theme)
        application = Application(
            mouse_support=False,
            style=style_factory.style,
            layout=layout,
            buffer=cli_buffer,
            key_bindings_registry=self.key_manager.manager.registry,
            on_exit=AbortAction.RAISE_EXCEPTION,
            on_abort=AbortAction.RETRY,
            ignore_case=True)
        eventloop = create_eventloop()
        self.aws_cli = CommandLineInterface(
            application=application,
            eventloop=eventloop)
Пример #19
0
    def __init__(self, pymux):
        self.pymux = pymux

        def enable_vi_mode(cli):
            " Return True when Vi mode is currently active. "
            client_state = pymux.get_client_state(cli)
            if client_state.confirm_text or client_state.prompt_command or client_state.command_mode:
                return pymux.status_keys_vi_mode
            else:
                return pymux.mode_keys_vi_mode

        def get_search_state(cli):
            " Return the currently active SearchState. (The one for the focussed pane.) "
            return pymux.arrangement.get_active_pane(cli).search_state

        # Start from this KeyBindingManager from prompt_toolkit, to have basic
        # editing functionality for the command line. These key binding are
        # however only active when the following `enable_all` condition is met.
        self.pt_key_bindings_manager = pt_KeyBindingManager(
            enable_vi_mode=Condition(enable_vi_mode),
            enable_all=(HasFocus(COMMAND) | HasFocus(PROMPT)
                        | InScrollBuffer(pymux)) & ~HasPrefix(pymux),
            enable_auto_suggest_bindings=True,
            enable_search=
            False,  # We have our own search bindings, that support multiple panes.
            enable_extra_page_navigation=True,
            get_vi_state=self._get_vi_state,
            get_search_state=get_search_state)

        self.registry = self.pt_key_bindings_manager.registry

        self._prefix = (Keys.ControlB, )
        self._prefix_binding = None

        # Load initial bindings.
        self._load_builtins()
        self._load_prefix_binding()
        _load_search_bindings(pymux, self.registry, self._get_vi_state)

        # Custom user configured key bindings.
        # { (needs_prefix, key) -> (command, handler) }
        self.custom_bindings = {}
Пример #20
0
    def __init__(self, shell_ctx):
        self.shell_ctx = shell_ctx

        @Condition
        def show_default(_):
            return self.shell_ctx.is_showing_default

        @Condition
        def show_symbol(_):
            return self.shell_ctx.is_symbols

        @Condition
        def show_progress(_):
            progress = get_progress_message()
            done = get_done()
            return progress != '' and not done

        @Condition
        def has_default_scope(_):
            return self.shell_ctx.default_command == ''

        self.has_default_scope = has_default_scope
        self.show_default = show_default
        self.show_symbol = show_symbol
        self.show_progress = show_progress

        # TODO fix this somehow
        self.input_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.)
                HighlightSearchProcessor(preview_search=Always()),
                HasFocus(SEARCH_BUFFER)),
            HighlightSelectionProcessor(),
            ConditionalProcessor(
                AppendAutoSuggestion(),
                HasFocus(DEFAULT_BUFFER) & self.has_default_scope)
        ]
Пример #21
0
    def _load_prefix_binding(self):
        """
        Load the prefix key binding.
        """
        pymux = self.pymux
        registry = self.registry

        # Remove previous binding.
        if self._prefix_binding:
            self.registry.remove_binding(self._prefix_binding)

        # Create new Python binding.
        @registry.add_binding(
            *self._prefix,
            filter=~(HasPrefix(pymux) | HasFocus(COMMAND) | HasFocus(PROMPT)
                     | WaitsForConfirmation(pymux)))
        def enter_prefix_handler(event):
            " Enter prefix mode. "
            pymux.get_client_state(event.cli).has_prefix = True

        self._prefix_binding = enter_prefix_handler
Пример #22
0
def loop(cmd, history_file):
    buf = create_buffer(cmd, history_file)
    key_bindings = KeyBindings()
    bind_keys(buf, key_bindings)
    layout = create_layout(
        buffer=buf,
        multiline=True,
        lexer=SqlLexer,
        extra_input_processors=[
            ConditionalProcessor(
                processor=HighlightMatchingBracketProcessor(chars='[](){}'),
                filter=HasFocus(DEFAULT_BUFFER) & ~IsDone())
        ],
        get_bottom_toolbar_tokens=lambda: get_toolbar_tokens(cmd),
        get_prompt_tokens=lambda: [('class:prompt', 'cr> ')])
    output = get_default_output()
    app = Application(layout=layout,
                      style=style_from_pygments_cls(CrateStyle),
                      key_bindings=merge_key_bindings(
                          [key_bindings,
                           load_open_in_editor_bindings()]),
                      editing_mode=_get_editing_mode(),
                      output=output)
    cmd.get_num_columns = lambda: output.get_size().columns

    while True:
        try:
            text = app.run()
            if text:
                cmd.process(text)
            buf.reset()
        except ProgrammingError as e:
            if '401' in e.message:
                username = cmd.username
                password = cmd.password
                cmd.username = input('Username: '******'Bye!')
            return
Пример #23
0
def create_default_layout(message='', lexer=None, is_password=False,
                          reserve_space_for_menu=False, get_bottom_toolbar_tokens=None):
    """
    Generate default layout.
    """
    assert get_bottom_toolbar_tokens is None or callable(get_bottom_toolbar_tokens)

    # Create processors list.
    input_processors = [HighlightSearchProcessor(), HighlightSelectionProcessor()]
    if is_password:
        input_processors.extend([PasswordProcessor(), DefaultPrompt(message)])
    else:
        input_processors.append(DefaultPrompt(message))

    # Create bottom toolbar.
    if get_bottom_toolbar_tokens:
        toolbars = [Window(TokenListControl(get_bottom_toolbar_tokens,
                                            default_char=Char(' ', Token.Toolbar)),
                           height=LayoutDimension.exact(1),
                           filter=~IsDone())]
    else:
        toolbars = []

    def get_height(cli):
        # 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 reserve_space_for_menu and not cli.is_done:
            return LayoutDimension(min=8)
        else:
            return LayoutDimension()

    # Create and return Layout instance.
    return HSplit([
        FloatContainer(
            Window(
                BufferControl(
                    input_processors=input_processors,
                    lexer=lexer,
                    # Enable preview_search, we want to have immediate feedback
                    # in reverse-i-search mode.
                    preview_search=Always()),
                get_height=get_height,
            ),
            [
                Float(xcursor=True,
                      ycursor=True,
                      content=CompletionsMenu(max_height=16,
                                              extra_filter=HasFocus(DEFAULT_BUFFER)))
            ]
        ),
        ValidationToolbar(),
        SystemToolbar(),
    ] + toolbars)
Пример #24
0
    def _build_cli(self, history):
        def set_vi_mode(value):
            self.vi_mode = value

        key_binding_manager = pgcli_bindings(
            get_vi_mode_enabled=lambda: self.vi_mode,
            set_vi_mode_enabled=set_vi_mode)

        def prompt_tokens(_):
            return [(Token.Prompt, '%s> ' % self.pgexecute.dbname)]

        def get_continuation_tokens(cli, width):
            return [(Token.Continuation, '.' * (width - 1) + ' ')]

        get_toolbar_tokens = create_toolbar_tokens_func(
            lambda: self.vi_mode, self.completion_refresher.is_refreshing)

        layout = create_prompt_layout(
            lexer=PygmentsLexer(PostgresLexer),
            reserve_space_for_menu=4,
            get_prompt_tokens=prompt_tokens,
            get_continuation_tokens=get_continuation_tokens,
            get_bottom_toolbar_tokens=get_toolbar_tokens,
            display_completions_in_columns=self.wider_completion_menu,
            multiline=True,
            extra_input_processors=[
                # Highlight matching brackets while editing.
                ConditionalProcessor(
                    processor=HighlightMatchingBracketProcessor(
                        chars='[](){}'),
                    filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()),
            ])

        with self._completer_lock:
            buf = PGBuffer(always_multiline=self.multi_line,
                           completer=self.completer,
                           history=history,
                           complete_while_typing=Always(),
                           accept_action=AcceptAction.RETURN_DOCUMENT)

            application = Application(
                style=style_factory(self.syntax_style, self.cli_style),
                layout=layout,
                buffer=buf,
                key_bindings_registry=key_binding_manager.registry,
                on_exit=AbortAction.RAISE_EXCEPTION,
                on_abort=AbortAction.RETRY,
                ignore_case=True)

            cli = CommandLineInterface(application=application)

            return cli
Пример #25
0
    def create_layout(self, exam_lex, toolbar_lex):
        """ creates the layout """
        lexer, exam_lex, toolbar_lex = get_lexers(self.shell_ctx.lexer,
                                                  exam_lex, toolbar_lex)

        if not any(
                isinstance(processor, DefaultPrompt)
                for processor in self.input_processors):
            self.input_processors.append(DefaultPrompt(self.get_prompt_tokens))

        layout_lower = ConditionalContainer(HSplit([
            get_anyhline(self.shell_ctx.config),
            get_descriptions(self.shell_ctx.config, exam_lex, lexer),
            get_examplehline(self.shell_ctx.config),
            get_example(self.shell_ctx.config, exam_lex),
            ConditionalContainer(get_hline(),
                                 filter=self.show_default | self.show_symbol),
            ConditionalContainer(Window(content=BufferControl(
                buffer_name='default_values', lexer=lexer)),
                                 filter=self.show_default),
            ConditionalContainer(get_hline(),
                                 filter=self.show_default & self.show_symbol),
            ConditionalContainer(Window(
                content=BufferControl(buffer_name='symbols', lexer=exam_lex)),
                                 filter=self.show_symbol),
            ConditionalContainer(Window(
                content=BufferControl(buffer_name='progress', lexer=lexer)),
                                 filter=self.show_progress),
            Window(content=BufferControl(buffer_name='bottom_toolbar',
                                         lexer=toolbar_lex), ),
        ]),
                                            filter=~IsDone()
                                            & RendererHeightIsKnown())

        layout_full = HSplit([
            FloatContainer(
                Window(
                    BufferControl(input_processors=self.input_processors,
                                  lexer=lexer,
                                  preview_search=Always()),
                    get_height=get_height,
                ), [
                    Float(xcursor=True,
                          ycursor=True,
                          content=CompletionsMenu(
                              max_height=MAX_COMPLETION,
                              scroll_offset=1,
                              extra_filter=(HasFocus(DEFAULT_BUFFER))))
                ]), layout_lower
        ])

        return layout_full
Пример #26
0
 def create_cli_layout(self):
     from .lexer import AzureShellLexer
     lexer = AzureShellLexer
     return create_default_layout(
         message=u'azure> ',
         reserve_space_for_menu=8,
         lexer=lexer,
         extra_input_processors=[
             ConditionalProcessor(
                 processor=HighlightMatchingBracketProcessor(
                     chars='[](){}'),
                 filter=HasFocus(DEFAULT_BUFFER) & ~IsDone())
         ])
Пример #27
0
    def _build_prompt_app(self, history):
        key_bindings = cli_bindings(self)

        def get_message():
            prompt = self.get_prompt(self.prompt)
            if len(prompt) > self.MAX_LEN_PROMPT:
                prompt = self.get_prompt('\\r:\\d> ')
            return [('class:prompt', prompt)]

        def get_continuation(width, line_number, is_soft_wrap):
            continuation = ' ' * (width - 1) + ' '
            return [('class:continuation', continuation)]

        def show_suggestion_tip():
            return self.iterations < 2

        get_toolbar_tokens = create_toolbar_tokens_func(
            self, show_suggestion_tip)

        with self._completer_lock:
            if self.key_bindings == 'vi':
                editing_mode = EditingMode.VI
            else:
                editing_mode = EditingMode.EMACS

            self.prompt_app = PromptSession(
                lexer=PygmentsLexer(Lexer),
                reserve_space_for_menu=self.get_reserved_space(),
                message=get_message,
                prompt_continuation=get_continuation,
                bottom_toolbar=get_toolbar_tokens,
                complete_style=CompleteStyle.COLUMN,
                input_processors=[
                    ConditionalProcessor(
                        processor=HighlightMatchingBracketProcessor(
                            chars='[](){}'),
                        filter=HasFocus(DEFAULT_BUFFER) & ~IsDone())
                ],
                tempfile_suffix='.sql',
                completer=DynamicCompleter(lambda: self.completer),
                history=history,
                auto_suggest=AutoSuggestFromHistory(),
                complete_while_typing=True,
                multiline=cli_is_multiline(self),
                style=style_factory(self.syntax_style, self.cli_style),
                include_default_pygments_style=False,
                key_bindings=key_bindings,
                enable_open_in_editor=True,
                enable_system_prompt=True,
                editing_mode=editing_mode,
                search_ignore_case=True)
Пример #28
0
def create_default_layout(message='', lexer=None, is_password=False,
                          reserve_space_for_menu=False, get_bottom_toolbar_tokens=None):
    """
    Generate default layout.
    """
    assert get_bottom_toolbar_tokens is None or callable(get_bottom_toolbar_tokens)

    # Create processors list.
    if is_password:
        input_processors = [PasswordProcessor(), DefaultPrompt(message)]
    else:
        input_processors = [DefaultPrompt(message)]

    # Create bottom toolbar.
    if get_bottom_toolbar_tokens:
        toolbars = [Window(TokenListControl(get_bottom_toolbar_tokens,
                                            default_char=Char(' ', Token.Toolbar)),
                           height=LayoutDimension.exact(1),
                           filter=~IsDone())]
    else:
        toolbars = []

    def get_height(cli):
        # 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 reserve_space_for_menu and not cli.is_done:
            return LayoutDimension(min=8)
        else:
            return LayoutDimension()

    # Create and return Layout instance.
    return HSplit([
        FloatContainer(
            Window(
                BufferControl(
                    input_processors=input_processors,
                    lexer=lexer),
                get_height=get_height,
            ),
            [
                Float(xcursor=True,
                      ycursor=True,
                      content=CompletionsMenu(max_height=16,
                                              extra_filter=HasFocus('default')))
            ]
        ),
        ValidationToolbar(),
        SystemToolbar(),
    ] + toolbars)
Пример #29
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)
Пример #30
0
    def _extra_prompt_options(self):
        """
        Return the current layout option for the current Terminal InteractiveShell
        """
        def get_message():
            return PygmentsTokens(self.prompts.in_prompt_tokens())

        if self.editing_mode == 'emacs':
            # with emacs mode the prompt is (usually) static, so we call only
            # the function once. With VI mode it can toggle between [ins] and
            # [nor] so we can't precompute.
            # here I'm going to favor the default keybinding which almost
            # everybody uses to decrease CPU usage.
            # if we have issues with users with custom Prompts we can see how to
            # work around this.
            get_message = get_message()

        options = {
            'complete_in_thread':
            False,
            'lexer':
            IPythonPTLexer(),
            'reserve_space_for_menu':
            self.space_for_menu,
            'message':
            get_message,
            'prompt_continuation':
            (lambda width, lineno, is_soft_wrap: PygmentsTokens(
                self.prompts.continuation_prompt_tokens(width))),
            'multiline':
            True,
            'complete_style':
            self.pt_complete_style,

            # Highlight matching brackets, but only when this setting is
            # enabled, and only when the DEFAULT_BUFFER has the focus.
            'input_processors': [
                ConditionalProcessor(
                    processor=HighlightMatchingBracketProcessor(
                        chars='[](){}'),
                    filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()
                    & Condition(lambda: self.highlight_matching_brackets))
            ],
        }
        if not PTK3:
            options['inputhook'] = self.inputhook

        return options