Beispiel #1
0
    def _create_default_buffer(self):
        """
        Create and return the default input buffer.
        """
        dyncond = self._dyncond

        # Create buffers list.
        def accept(buff):
            """ Accept the content of the default buffer. This is called when
            the validation succeeds. """
            self.app.exit(result=buff.document.text)

        return Buffer(
            name=DEFAULT_BUFFER,
            # Make sure that complete_while_typing is disabled when
            # enable_history_search is enabled. (First convert to Filter,
            # to avoid doing bitwise operations on bool objects.)
            complete_while_typing=Condition(
                lambda: _true(self.complete_while_typing) and not _true(
                    self.enable_history_search) and not self.complete_style ==
                CompleteStyle.READLINE_LIKE),
            validate_while_typing=dyncond('validate_while_typing'),
            enable_history_search=dyncond('enable_history_search'),
            validator=DynamicValidator(lambda: self.validator),
            completer=DynamicCompleter(
                lambda: ThreadedCompleter(self.completer) if self.
                complete_in_thread and self.completer else self.completer),
            history=self.history,
            auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest),
            accept_handler=accept,
            tempfile_suffix=lambda: self.tempfile_suffix)
Beispiel #2
0
def run_repl():
    global todos
    global selected

    update_todos()

    cooee_completer = CooeeCompleter()
    cooee_validator = CooeeValidator()

    def get_rprompt():
        global selected

        if selected is None:
            return ""

        if "location" in selected:
            url: str = selected["location"]
            parts: ParseResult = urllib.parse.urlparse(url)
            return parts.hostname + parts.path
        elif "message" in selected:
            return selected["message"]

        return f"{selected}"

    def bottom_toolbar():
        update_todos()
        num = len(todos) if todos is not None else 0
        todo_text = f'Todos: ({num})'
        loading_text = f' Loading completions... ' if cooee_completer.loading > 0 else ''
        return todo_text + loading_text

    history_file = os.path.expanduser("~/.cooee/repl.hist")
    session = PromptSession(
        '> ',
        completer=ThreadedCompleter(cooee_completer),
        complete_while_typing=False,
        bottom_toolbar=bottom_toolbar,
        complete_style=CompleteStyle.MULTI_COLUMN,
        history=FileHistory(history_file),
        refresh_interval=5,
        rprompt=get_rprompt,
        validator=ThreadedValidator(cooee_validator),
        validate_while_typing=True,
    )

    while True:
        try:
            text = session.prompt()
            if text != "":
                launch(text)
            else:
                update_todos()
                print_formatted_text("Todos")
                for t in todos:
                    print_formatted_text(todo_string(t))
            selected = {"message": "Todos"}
        except KeyboardInterrupt:
            continue  # Control-C pressed. Try again.
        except EOFError:
            break  # Control-D pressed.
Beispiel #3
0
    def _create_buffer(self) -> Buffer:
        """
        Create the `Buffer` for the Python input.
        """
        python_buffer = Buffer(
            name=DEFAULT_BUFFER,
            complete_while_typing=Condition(
                lambda: self.complete_while_typing),
            enable_history_search=Condition(
                lambda: self.enable_history_search),
            tempfile_suffix=".py",
            history=self.history,
            completer=ThreadedCompleter(self._completer),
            validator=ConditionalValidator(
                self._validator,
                Condition(lambda: self.enable_input_validation)),
            auto_suggest=ConditionalAutoSuggest(
                ThreadedAutoSuggest(AutoSuggestFromHistory()),
                Condition(lambda: self.enable_auto_suggest),
            ),
            accept_handler=self._accept_handler,
            on_text_changed=self._on_input_timeout,
        )

        return python_buffer
Beispiel #4
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
Beispiel #5
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
Beispiel #6
0
    def _create_default_buffer(self):
        """
        Create and return the default input buffer.
        """
        dyncond = self._dyncond

        # Create buffers list.
        def accept(buff):
            if self.current_mode.on_pre_accept:
                self.current_mode.on_pre_accept(self)

            # remember the last working index
            buff.last_working_index = buff.working_index
            """ Accept the content of the default buffer. This is called when
            the validation succeeds. """
            self.app.exit(result=buff.document.text)
            return True  # Keep text, we call 'reset' later on.

        return ModalBuffer(
            name=DEFAULT_BUFFER,
            complete_while_typing=Condition(
                lambda: is_true(self.complete_while_typing) and not self.
                complete_style == CompleteStyle.READLINE_LIKE),
            validate_while_typing=dyncond('validate_while_typing'),
            enable_history_search=dyncond('enable_history_search'),
            validator=DynamicValidator(lambda: self.validator),
            completer=DynamicCompleter(
                lambda: ThreadedCompleter(self.completer) if self.
                complete_in_thread and self.completer else self.completer),
            history=self.history,
            auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest),
            accept_handler=accept,
            tempfile_suffix=lambda: self.tempfile_suffix,
            session_change_mode=self.change_mode,
            session_current_mode=lambda: self.current_mode,
            history_search_no_duplicates=self.history_search_no_duplicates,
            get_add_history=lambda: self.add_history)
Beispiel #7
0
def start_interactive_mode(ctx):

    toolbar = BottomToolbar()
    cli_interactive_history = CommandsHistory(
        INTERACTIVE_COMMANDS_HISTORY_FILE_NAME
    )

    # Getting the commands before --cli-auto-prompt, for example if the user execute oci --profile X compute instance --cli-auto-prompt,
    # then the interactive mode will begin with oci --profile X compute instance
    arguments = sys.argv[1:]

    auth_params = []
    for param in AUTHENTICATION_PARAMS:
        if param in arguments:
            param_idx = arguments.index(param)
            auth_params += arguments[param_idx: param_idx + 2]
            del arguments[param_idx: param_idx + 2]

    debug_params = []
    for param in DEBUG_PARAMS:
        if param in arguments:
            param_idx = arguments.index(param)
            debug_params += [arguments[param_idx]]
            del arguments[param_idx]

    command_before_prompt = " ".join(
        [arg for arg in arguments if arg not in AUTO_PROMPT_PARAMS]
    )

    # save the endpoint to be used for the actual command invocation
    endpoint = ctx.obj["endpoint"]
    ctx.obj["endpoint"] = None

    colors_enabled = True
    if OCI_CLI_DISABLE_COLORS_ENV_VAR in os.environ:
        colors_enabled = False

    style = Style.from_dict(styles_dict)
    cli_command = [("class:oci", "> oci ")]

    # Initialize the document with the initial commands typed by the user
    document = Document(command_before_prompt, len(command_before_prompt))
    # Build the config before invoking the prompt session to raise any errors due to incorrect config
    cli_util.create_config_and_signer_based_on_click_context(ctx)
    completer = OciShellCompleter(ctx, colors_enabled, bottom_toolbar=toolbar)
    kb = override_key_binding(completer=completer, toolbar=toolbar)
    multithread_completer = ThreadedCompleter(
        completer
    )  # This is needed for oci resources suggestion to not block the user until the result comes
    os.system("clear")  # Start from the beginning of the terminal window to avoid "window too small" error
    session = PromptSession(
        message=cli_command,
        style=style if colors_enabled else None,
        complete_while_typing=True,
        bottom_toolbar=toolbar.show_toolbar,
        history=cli_interactive_history,
    )
    text = session.prompt(
        completer=multithread_completer, default=document, key_bindings=kb
    )
    endpoint_str = " --endpoint " + endpoint if endpoint else ""
    os.environ[cli_util.OCI_CLI_IN_INTERACTIVE_MODE] = "True"  # This is needed so that the API request adds new user agent for the CLI Interactive
    command = (
        "oci "
        + " ".join(auth_params)
        + " "
        + " ".join(debug_params)
        + endpoint_str
        + " "
        + text if text else ""
    )
    os.system(command)
Beispiel #8
0
    def run(self, query, data):
        self.load_config()

        if data or query is not None:
            self.format = self.format_stdin
            self.echo.verbose = False

        if self.echo.verbose:
            show_version()

        if not self.connect():
            return

        if self.client:
            self.client.settings = self.settings
            self.client.cli_settings = {
                'multiline': self.multiline,
                'vi_mode': self.vi_mode,
                'format': self.format,
                'format_stdin': self.format_stdin,
                'show_formatted_query': self.show_formatted_query,
                'highlight': self.highlight,
                'highlight_output': self.highlight_output,
                'refresh_metadata_on_start': self.refresh_metadata_on_start,
                'refresh_metadata_on_query': self.refresh_metadata_on_query,
            }

        if data and query is None:
            # cat stuff.sql | clickhouse-cli
            # clickhouse-cli stuff.sql
            for subdata in data:
                self.handle_input(subdata.read(),
                                  verbose=False,
                                  refresh_metadata=False)

            return

        if not data and query is not None:
            # clickhouse-cli -q 'SELECT 1'
            return self.handle_query(query, stream=False)

        if data and query is not None:
            # cat stuff.csv | clickhouse-cli -q 'INSERT INTO stuff'
            # clickhouse-cli -q 'INSERT INTO stuff' stuff.csv
            for subdata in data:
                compress = 'gzip' if os.path.splitext(
                    subdata.name)[1] == '.gz' else False

                self.handle_query(query,
                                  data=subdata,
                                  stream=True,
                                  compress=compress)

            return

        buffer = CLIBuffer(
            client=self.client,
            multiline=self.multiline,
            metadata=self.metadata,
        )

        root_container = Window(content=BufferControl(buffer=buffer))

        layout = Layout(root_container)
        # layout.focus(root_container)

        # layout = prompt(
        #     lexer=PygmentsLexer(CHLexer) if self.highlight else None,
        #     # get_prompt_tokens=get_prompt_tokens,
        #     # get_continuation_tokens=get_continuation_tokens,
        #     multiline=self.multiline,
        # )

        hist = FileHistory(
            filename=os.path.expanduser('~/.clickhouse-cli_history'))
        self.completer = CHCompleter(self.client, self.metadata)

        self.session = PromptSession(
            style=CHStyle if self.highlight else None,
            lexer=PygmentsLexer(CHLexer) if self.highlight else None,
            message=get_prompt_tokens()[0][1],
            prompt_continuation=get_continuation_tokens()[0][1],
            multiline=is_multiline(self.multiline),
            vi_mode=self.vi_mode,
            history=hist,
            key_bindings=kb,
            complete_while_typing=self.complete_while_typing,
            completer=ThreadedCompleter(
                DynamicCompleter(lambda: self.completer)),
        )

        self.app = Application(layout=layout,
                               # buffer=buffer,
                               )

        #self.cli = CommandLineInterface(application=application, eventloop=eventloop)
        if self.refresh_metadata_on_start:
            self.app.current_buffer.completer.refresh_metadata()

        try:
            while True:
                try:
                    cli_input = self.session.prompt()
                    self.handle_input(cli_input)
                except KeyboardInterrupt:
                    # Attempt to terminate queries
                    for query_id in self.query_ids:
                        self.client.kill_query(query_id)

                    self.echo.error("\nQuery was terminated.")
                finally:
                    self.query_ids = []
        except EOFError:
            self.echo.success("Bye.")
Beispiel #9
0
    def _build_cli(self, history):
        """
            Builds prompt session.
            NOTE: PROMPT-SESSION USES THIS AS DEPENDENCY.
        """
        def get_message():
            prompt = self.get_prompt(self.prompt_format)
            return [(u'class:prompt', prompt)]

        def get_continuation(width, line_number, is_soft_wrap):
            """
                NOTE: updating parameters will cause prompt session to crash.
            """
            # pylint: disable=unused-argument
            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='[](){}'),
                        #pylint: disable=invalid-unary-operand-type
                        filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()),
                    # 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
Beispiel #10
0
    def __init__(self, verbose=False):
        try:
            if args.directory:
                os.chdir(args.directory)
        except:
            pass

        self.config = cfg.Config(verbose=verbose, colored=True)
        self.config.load()
        self.config.fallback = {
            "aliases": {},
            "colored": True,
            "prompt": "<base>┏━━(</base><user>${USER}</user> <base>at</base> <user>${DOMAIN}</user><base>)━[</base><path>${PATH}</path><base>]━[</base><style fg='${green-yellow}'>${REPO}</style><base>]━[</base><style fg='yellow'>${TIME}</style><base>]\n┗━</base><pointer>${ROOT}</pointer> ",
            "style": {
                # Default style
                "": "",

                # Specific style
                "base": "#1a8cff",
                "pointer": "#ff4500",
                "path": "aqua",
                "user": "******",

                # Completer
                "completion-menu.completion": "bg:#000000 #ffffff",
                "completion-menu.completion.current": "bg:#00aaaa #000000",
                "scrollbar.background": "bg:#88aaaa",
                "scrollbar.button": "bg:#222222"
            },
            "dialog_style": {
                "dialog": "bg:#88ff88",
                "dialog frame-label": "bg:#ffffff #000000",
                "dialog.body": "bg:#000000 #00ff00",
                "dialog shadow": "bg:#00aa00",
            }
        }
        self.config.colored = self.config["colored"]
        self.style = Style.from_dict(self.config["style"])
        self.dialog_style = Style.from_dict(self.config["dialog_style"])
        self.manager = manager
        self.file = None
        self.mode = None
        self.userInput = None

        if platform.system() == "Windows":
            self.histfile = os.environ["userprofile"] + \
                r"\.voidhistory"  # Rename this
        else:
            # Rename this ... alternative for linux or Unix based systems
            self.histfile = os.path.expanduser("~")+r"/.voidhistory"

        self.history = FileHistory(self.histfile)

        if not args.command:
            function_completer = NestedCompleter.from_nested_dict(
                dict.fromkeys(functions))
            pth_completer = path_completer.PathCompleter(expanduser=True)
            environ_completer = env_completer.EnvCompleter(
                file_filter=filter)
            merged_completers = merge_completers(
                [function_completer, pth_completer, environ_completer])
            self.completer = ThreadedCompleter(merged_completers)
        else:
            self.completer = None

        super().__init__(completer=self.completer,
                         complete_while_typing=False,
                         auto_suggest=AutoSuggestFromHistory(),
                         search_ignore_case=True,
                         refresh_interval=0,
                         color_depth=ColorDepth.TRUE_COLOR,
                         editing_mode=EditingMode.VI,
                         style=self.style,
                         history=self.history)
Beispiel #11
0
    multiline = False

    while True:
        try:
            ps1 = shell_locals['ps1'](
                host=gethostname(),
                user=getuser(),
                cwd=get_dir_str(),
            )
            cmd = prompt(ps1,
                         history=FileHistory(".pysh_history"),
                         auto_suggest=AutoSuggestFromHistory(),
                         multiline=multiline,
                         key_bindings=keys,
                         prompt_continuation=shell_locals['ps2'],
                         completer=ThreadedCompleter(WordCompleter(get_autocomplete_suggestions())))
        except EOFError:
            break
        multiline = False
        if cmd.strip() == "multi":
            multiline = True
            print("Multiline mode active. Press Escape + Enter to terminate input.")
        elif cmd.strip() == "clear":
            print('\n' * (shutil.get_terminal_size()[1] + 5))
        elif cmd.strip().startswith('\\'):
            try:
                exec(compile_pysh(cmd, prelude=False), shell_locals, shell_locals)
                #cmd_list = shlex.split(eval(format_string.format(cmd.strip()[1:]), shell_locals, shell_locals))
                #subprocess.run(cmd_list)
            except FileNotFoundError:
                print("no command `{}` found".format(cmd_list[0]))
Beispiel #12
0
 def completer(self):
     return ThreadedCompleter(H5PathCompleter(self.context, include_datasets=False))
Beispiel #13
0
 def completer(self):
     return ThreadedCompleter(
         H5PathCompleter(self.context, self._include_groups, self._include_datasets)
     )
Beispiel #14
0
 def completer(self):
     return ThreadedCompleter(H5PathCompleter(self.context))
Beispiel #15
0
    def __init__(self, my_app: "sqlApp"):
        self.my_app = my_app
        help_text = """
        Press Enter in the input box to page through the table.
        Alternatively, enter a filtering SQL statement and then press Enter
        to page through the results.
        """
        self.formatter = TabularOutputFormatter()
        self.completer = PreviewCompleter(
            my_app=self.my_app,
            completer=MssqlCompleter(
                smart_completion=True,
                get_conn=lambda: self.my_app.selected_object.conn))

        history_file = config_location() + 'preview_history'
        ensure_dir_exists(history_file)
        hist = PreviewHistory(my_app=self.my_app,
                              filename=expanduser(history_file))

        self.input_buffer = PreviewBuffer(
            name="previewbuffer",
            tempfile_suffix=".sql",
            history=ThreadedHistory(hist),
            auto_suggest=ThreadedAutoSuggest(
                PreviewSuggestFromHistory(my_app)),
            completer=ThreadedCompleter(self.completer),
            #                history = hist,
            #                auto_suggest = PreviewSuggestFromHistory(my_app),
            #                completer = self.completer,
            complete_while_typing=Condition(
                lambda: self.my_app.selected_object is not None and self.my_app
                .selected_object.conn.connected()),
            multiline=False)

        input_control = BufferControl(
            buffer=self.input_buffer,
            include_default_input_processors=False,
            input_processors=[AppendAutoSuggestion()],
            preview_search=False)

        self.input_window = Window(input_control)

        search_buffer = Buffer(name="previewsearchbuffer")
        self.search_field = SearchToolbar(search_buffer)
        self.output_field = TextArea(
            style="class:preview-output-field",
            text=help_text,
            height=D(preferred=50),
            search_field=self.search_field,
            wrap_lines=False,
            focusable=True,
            read_only=True,
            preview_search=True,
            input_processors=[
                ConditionalProcessor(
                    processor=HighlightIncrementalSearchProcessor(),
                    filter=has_focus("previewsearchbuffer")
                    | has_focus(self.search_field.control),
                ),
                HighlightSelectionProcessor(),
            ])

        def refresh_results(window_height) -> bool:
            """ This method gets called when the app restarts after
                exiting for execution of preview query.  It populates
                the output buffer with results from the fetch/query.
            """
            sql_conn = self.my_app.selected_object.conn
            if sql_conn.execution_status == executionStatus.FAIL:
                # Let's display the error message to the user
                output = sql_conn.execution_err
            else:
                crsr = sql_conn.cursor
                if crsr.description:
                    cols = [col.name for col in crsr.description]
                else:
                    cols = []
                if len(cols):
                    res = sql_conn.fetch_from_cache(size=window_height - 4,
                                                    wait=True)
                    output = self.formatter.format_output(res,
                                                          cols,
                                                          format_name="psql")
                    output = "\n".join(output)
                else:
                    output = "No rows returned\n"

            # Add text to output buffer.
            self.output_field.buffer.set_document(
                Document(text=output, cursor_position=0), True)

            return True

        def accept(buff: Buffer) -> bool:
            """ This method gets called when the user presses enter/return
                in the filter box.  It is interpreted as either 'execute query'
                or 'fetch next page of results' if filter query hasn't changed.
            """
            obj = self.my_app.selected_object
            sql_conn = obj.conn
            identifier = object_to_identifier(obj)
            query = sql_conn.preview_query(
                name=identifier,
                obj_type=obj.otype,
                filter_query=buff.text,
                limit=self.my_app.preview_limit_rows)
            if query is None:
                return True

            func = partial(refresh_results,
                           window_height=self.output_field.window.render_info.
                           window_height)
            if sql_conn.query != query:
                # Exit the app to execute the query
                self.my_app.application.exit(result=["preview", query])
                self.my_app.application.pre_run_callables.append(func)
            else:
                # No need to exit let's just go and fetch
                func()
            return True  # Keep filter text

        def cancel_handler() -> None:
            sql_conn = self.my_app.selected_object.conn
            sql_conn.close_cursor()
            self.input_buffer.text = ""
            self.output_field.buffer.set_document(
                Document(text=help_text, cursor_position=0), True)
            self.my_app.show_preview = False
            self.my_app.show_sidebar = True
            self.my_app.application.layout.focus(self.input_buffer)
            self.my_app.application.layout.focus("sidebarbuffer")
            return None

        self.input_buffer.accept_handler = accept
        self.cancel_button = Button(text="Done", handler=cancel_handler)
Beispiel #16
0
    def _create_application(self, editing_mode, erase_when_done):
        def dyncond(attr_name):
            """
            Dynamically take this setting from this 'Prompt' class.
            `attr_name` represents an attribute name of this class. Its value
            can either be a boolean or a `Filter`.

            This returns something that can be used as either a `Filter`
            or `Filter`.
            """
            @Condition
            def dynamic():
                value = getattr(self, attr_name)
                return to_filter(value)()

            return dynamic

        # Create functions that will dynamically split the prompt. (If we have
        # a multiline prompt.)
        has_before_fragments, get_prompt_text_1, get_prompt_text_2 = \
            _split_multiline_prompt(self._get_prompt)

        # Create buffers list.
        def accept(buff):
            """ Accept the content of the default buffer. This is called when
            the validation succeeds. """
            self.app.set_result(buff.document.text)

            # Reset content before running again.
            self.app.pre_run_callables.append(buff.reset)

        default_buffer = Buffer(
            name=DEFAULT_BUFFER,
            # Make sure that complete_while_typing is disabled when
            # enable_history_search is enabled. (First convert to Filter,
            # to avoid doing bitwise operations on bool objects.)
            complete_while_typing=Condition(
                lambda: _true(self.complete_while_typing) and not _true(
                    self.enable_history_search) and not self.complete_style ==
                CompleteStyle.READLINE_LIKE),
            validate_while_typing=dyncond('validate_while_typing'),
            enable_history_search=dyncond('enable_history_search'),
            validator=DynamicValidator(lambda: self.validator),
            completer=ThreadedCompleter(
                completer=DynamicCompleter(lambda: self.completer),
                in_thread=dyncond('complete_in_thread'),
            ),
            history=DynamicHistory(lambda: self.history),
            auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest),
            accept_handler=accept,
            get_tempfile_suffix=lambda: self.tempfile_suffix)

        search_buffer = Buffer(name=SEARCH_BUFFER)

        # Create processors list.
        input_processor = merge_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=True),
                has_focus(search_buffer)),
            HighlightSelectionProcessor(),
            ConditionalProcessor(AppendAutoSuggestion(),
                                 has_focus(default_buffer) & ~is_done),
            ConditionalProcessor(PasswordProcessor(), dyncond('is_password')),
            DisplayMultipleCursors(),

            # Users can insert processors here.
            DynamicProcessor(lambda: self.extra_input_processor),

            # For single line mode, show the prompt before the input.
            ConditionalProcessor(
                merge_processors([
                    BeforeInput(get_prompt_text_2),
                    ShowArg(),
                ]), ~dyncond('multiline'))
        ])

        # Create bottom toolbars.
        bottom_toolbar = ConditionalContainer(
            Window(FormattedTextControl(lambda: self.bottom_toolbar,
                                        style='class:bottom-toolbar.text'),
                   style='class:bottom-toolbar',
                   dont_extend_height=True,
                   height=Dimension(min=1)),
            filter=~is_done & renderer_height_is_known
            & Condition(lambda: self.bottom_toolbar is not None))

        search_toolbar = SearchToolbar(
            search_buffer,
            get_search_state=lambda: default_buffer_control.get_search_state())
        search_buffer_control = BufferControl(buffer=search_buffer,
                                              input_processor=merge_processors(
                                                  [
                                                      ReverseSearchProcessor(),
                                                      ShowArg(),
                                                  ]))

        system_toolbar = SystemToolbar()

        def get_search_buffer_control():
            " Return the UIControl to be focused when searching start. "
            if _true(self.multiline):
                return search_toolbar.control
            else:
                return search_buffer_control

        default_buffer_control = BufferControl(
            buffer=default_buffer,
            get_search_buffer_control=get_search_buffer_control,
            input_processor=input_processor,
            lexer=DynamicLexer(lambda: self.lexer),
            preview_search=True)

        default_buffer_window = Window(
            default_buffer_control,
            height=self._get_default_buffer_control_height,
            left_margins=[
                # In multiline mode, use the window margin to display
                # the prompt and continuation fragments.
                ConditionalMargin(
                    PromptMargin(get_prompt_text_2, self._get_continuation),
                    filter=dyncond('multiline'),
                )
            ],
            wrap_lines=dyncond('wrap_lines'))

        @Condition
        def multi_column_complete_style():
            return self.complete_style == CompleteStyle.MULTI_COLUMN

        # Build the layout.
        layout = HSplit([
            # The main input, with completion menus floating on top of it.
            FloatContainer(
                HSplit([
                    ConditionalContainer(
                        Window(FormattedTextControl(get_prompt_text_1),
                               dont_extend_height=True),
                        Condition(has_before_fragments)),
                    ConditionalContainer(
                        default_buffer_window,
                        Condition(lambda: get_app().layout.current_control !=
                                  search_buffer_control),
                    ),
                    ConditionalContainer(
                        Window(search_buffer_control),
                        Condition(lambda: get_app().layout.current_control ==
                                  search_buffer_control),
                    ),
                ]),
                [
                    # Completion menus.
                    Float(xcursor=True,
                          ycursor=True,
                          content=CompletionsMenu(
                              max_height=16,
                              scroll_offset=1,
                              extra_filter=has_focus(default_buffer)
                              & ~multi_column_complete_style)),
                    Float(xcursor=True,
                          ycursor=True,
                          content=MultiColumnCompletionsMenu(
                              show_meta=True,
                              extra_filter=has_focus(default_buffer)
                              & multi_column_complete_style)),
                    # The right prompt.
                    Float(right=0,
                          top=0,
                          hide_when_covering_content=True,
                          content=_RPrompt(lambda: self.rprompt)),
                ]),
            ConditionalContainer(ValidationToolbar(), filter=~is_done),
            ConditionalContainer(system_toolbar,
                                 dyncond('enable_system_prompt') & ~is_done),

            # In multiline mode, we use two toolbars for 'arg' and 'search'.
            ConditionalContainer(
                Window(FormattedTextControl(self._get_arg_text), height=1),
                dyncond('multiline') & has_arg),
            ConditionalContainer(search_toolbar,
                                 dyncond('multiline') & ~is_done),
            bottom_toolbar,
        ])

        # Default key bindings.
        auto_suggest_bindings = load_auto_suggest_bindings()
        open_in_editor_bindings = load_open_in_editor_bindings()
        prompt_bindings = self._create_prompt_bindings()

        # Create application
        application = Application(
            layout=Layout(layout, default_buffer_window),
            style=DynamicStyle(lambda: self.style),
            include_default_pygments_style=dyncond(
                'include_default_pygments_style'),
            clipboard=DynamicClipboard(lambda: self.clipboard),
            key_bindings=merge_key_bindings([
                merge_key_bindings([
                    auto_suggest_bindings,
                    ConditionalKeyBindings(
                        open_in_editor_bindings,
                        dyncond('enable_open_in_editor')
                        & has_focus(DEFAULT_BUFFER)), prompt_bindings
                ]),
                ConditionalKeyBindings(
                    system_toolbar.get_global_key_bindings(),
                    dyncond('enable_system_prompt')),
                DynamicKeyBindings(lambda: self.extra_key_bindings),
            ]),
            mouse_support=dyncond('mouse_support'),
            editing_mode=editing_mode,
            erase_when_done=erase_when_done,
            reverse_vi_search_direction=True,

            # I/O.
            input=self.input,
            output=self.output)

        # During render time, make sure that we focus the right search control
        # (if we are searching). - This could be useful if people make the
        # 'multiline' property dynamic.
        '''
        def on_render(app):
            multiline = _true(self.multiline)
            current_control = app.layout.current_control

            if multiline:
                if current_control == search_buffer_control:
                    app.layout.current_control = search_toolbar.control
                    app.invalidate()
            else:
                if current_control == search_toolbar.control:
                    app.layout.current_control = search_buffer_control
                    app.invalidate()

        app.on_render += on_render
        '''

        return application, default_buffer, default_buffer_control
Beispiel #17
0
    def _build_cli(self, history):
        key_bindings = pgcli_bindings(self)

        def get_message():
            if self.dsn_alias and self.prompt_dsn_format is not None:
                prompt_format = self.prompt_dsn_format
            else:
                prompt_format = self.prompt_format

            prompt = self.get_prompt(prompt_format)

            if (
                prompt_format == self.default_prompt
                and len(prompt) > self.max_len_prompt
            ):
                prompt = self.get_prompt("\\d> ")

            prompt = prompt.replace("\\x1b", "\x1b")
            return ANSI(prompt)

        def get_continuation(width, line_number, is_soft_wrap):
            continuation = self.multiline_continuation_char * (width - 1) + " "
            return [("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:
            prompt_app = PromptSession(
                lexer=PygmentsLexer(PostgresLexer),
                reserve_space_for_menu=self.min_num_menu_lines,
                message=get_message,
                prompt_continuation=get_continuation,
                bottom_toolbar=get_toolbar_tokens,
                complete_style=complete_style,
                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=" "),
                ],
                auto_suggest=AutoSuggestFromHistory(),
                tempfile_suffix=".sql",
                # N.b. pgcli's multi-line mode controls submit-on-Enter (which
                # overrides the default behaviour of prompt_toolkit) and is
                # distinct from prompt_toolkit's multiline mode here, which
                # controls layout/display of the prompt/buffer
                multiline=True,
                history=history,
                completer=ThreadedCompleter(DynamicCompleter(lambda: self.completer)),
                complete_while_typing=True,
                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,
                enable_suspend=True,
                editing_mode=EditingMode.VI if self.vi_mode else EditingMode.EMACS,
                search_ignore_case=True,
            )

            return prompt_app
Beispiel #18
0
    def __init__(self, my_app: "sqlApp") -> None:

        self.my_app = my_app
        self.search_field = SearchToolbar()
        history_file = config_location() + 'history'
        ensure_dir_exists(history_file)
        hist = ThreadedHistory(FileHistory(expanduser(history_file)))
        self.input_buffer = Buffer(
            name="defaultbuffer",
            tempfile_suffix=".py",
            multiline=MultilineFilter(self.my_app),
            history=hist,
            completer=DynamicCompleter(
                lambda: ThreadedCompleter(self.my_app.completer)),
            #                    lambda: self.my_app.completer),
            auto_suggest=ThreadedAutoSuggest(AutoSuggestFromHistory()),
            complete_while_typing=Condition(
                lambda: self.my_app.active_conn is not None))
        main_win_control = BufferControl(
            buffer=self.input_buffer,
            lexer=PygmentsLexer(SqlLexer),
            search_buffer_control=self.search_field.control,
            include_default_input_processors=False,
            input_processors=[AppendAutoSuggestion()],
            preview_search=True)

        self.main_win = Window(
            main_win_control,
            height=(
                lambda:
                (None if get_app().is_done else
                 (Dimension(min=self.my_app.min_num_menu_lines)
                  if not self.my_app.show_preview else Dimension(
                      min=self.my_app.min_num_menu_lines, preferred=180)))),
            get_line_prefix=partial(sql_line_prefix, my_app=self.my_app),
            scroll_offsets=ScrollOffsets(bottom=1, left=4, right=4))

        self.lprompt = login_prompt(self.my_app)
        self.preview = preview_element(self.my_app)
        self.disconnect_dialog = disconnect_dialog(self.my_app)
        container = HSplit([
            VSplit([
                FloatContainer(
                    content=HSplit([
                        self.main_win,
                        self.search_field,
                    ]),
                    floats=[
                        Float(
                            bottom=1,
                            left=1,
                            right=0,
                            content=sql_sidebar_help(self.my_app),
                        ),
                        Float(content=self.lprompt),
                        Float(content=self.preview, ),
                        Float(content=self.disconnect_dialog, ),
                        Float(left=2,
                              bottom=1,
                              content=exit_confirmation(self.my_app)),
                        Float(xcursor=True,
                              ycursor=True,
                              transparent=True,
                              content=CompletionsMenu(scroll_offset=1,
                                                      max_height=16,
                                                      extra_filter=has_focus(
                                                          self.input_buffer)))
                    ]),
                ConditionalContainer(
                    content=sql_sidebar(self.my_app),
                    filter=ShowSidebar(self.my_app) & ~is_done,
                )
            ]),
            VSplit([
                status_bar(self.my_app),
                show_sidebar_button_info(self.my_app)
            ])
        ])

        def accept(buff):
            app = get_app()
            app.exit(result=["non-preview", buff.text])
            app.pre_run_callables.append(buff.reset)
            return True

        self.input_buffer.accept_handler = accept
        self.layout = Layout(container, focused_element=self.main_win)
Beispiel #19
0
    def _build_cli(self, history):
        key_bindings = pgcli_bindings(self)

        def get_message():
            if self.dsn_alias and self.prompt_dsn_format is not None:
                prompt_format = self.prompt_dsn_format
            else:
                prompt_format = self.prompt_format

            prompt = self.get_prompt(prompt_format)

            if (prompt_format == self.default_prompt and
                    len(prompt) > self.max_len_prompt):
                prompt = self.get_prompt('\\d> ')

            return [('class:prompt', prompt)]

        def get_continuation(width, line_number, is_soft_wrap):
            continuation = self.multiline_continuation_char * (width - 1) + ' '
            return [('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:
            prompt_app = PromptSession(
                lexer=PygmentsLexer(PostgresLexer),
                reserve_space_for_menu=self.min_num_menu_lines,
                message=get_message,
                prompt_continuation=get_continuation,
                bottom_toolbar=get_toolbar_tokens,
                complete_style=complete_style,
                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=' ')],
                auto_suggest=AutoSuggestFromHistory(),
                tempfile_suffix='.sql',
                multiline=pg_is_multiline(self),
                history=history,
                completer=ThreadedCompleter(
                    DynamicCompleter(lambda: self.completer)),
                complete_while_typing=True,
                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,
                enable_suspend=True,
                editing_mode=EditingMode.VI if self.vi_mode else EditingMode.EMACS,
                search_ignore_case=True)

            return prompt_app
Beispiel #20
0
    def __init__(self):
        self._completer = _CommandCompleter()

        self._session = PromptSession(
            completer=ThreadedCompleter(self._completer))