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)
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.
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
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
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
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)
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)
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.")
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
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)
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]))
def completer(self): return ThreadedCompleter(H5PathCompleter(self.context, include_datasets=False))
def completer(self): return ThreadedCompleter( H5PathCompleter(self.context, self._include_groups, self._include_datasets) )
def completer(self): return ThreadedCompleter(H5PathCompleter(self.context))
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)
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
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
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)
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
def __init__(self): self._completer = _CommandCompleter() self._session = PromptSession( completer=ThreadedCompleter(self._completer))