def main(): server_address = '127.0.0.1' if len(sys.argv) is 2: server_address = sys.argv[1] else: print('WARNING - Using default Excalibur server address: {}'.format( server_address)) excalibur = ExcaliburCmd(server_address) print('--------------------') print('Welcome to Excalibur') print('--------------------') print('Type "help" for more info, or type "exit" or press CTRL-D to exit') session = PromptSession() while True: try: text = session.prompt(excalibur.prompt_msg, completer=DynamicCompleter( excalibur.meta_completer.get_completer)) excalibur.handle_cmd(text) except KeyboardInterrupt: if excalibur.get_mode() is InterpreterMode.BASE: break else: excalibur.set_mode(InterpreterMode.BASE) except EOFError: break print('Goodbye!')
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 _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 __init__(self, url, runner, completer): self.runner = runner self.completer = completer self.prompt_session = PromptSession( lexer=PygmentsLexer(JsonBareObjectLexer), completer=DynamicCompleter(lambda: self.completer), history=FileHistory(os.path.expanduser("~/.socket-cli.history")), )
def create_modal_prompt(self, options): terminal_width = [None] def process_events(context): while True: if context.input_is_ready(): break api.process_events() app = get_app() output_width = app.output.get_size().columns if terminal_width[0] != output_width: terminal_width[0] = output_width interface.set_option("width", max(terminal_width[0], 20)) time.sleep(1.0 / 30) set_event_loop(create_event_loop(inputhook=process_events)) def get_lexer(): app = get_app(return_none=False) if hasattr(app, "mp"): if app.mp.prompt_mode in ["r", "browse"]: return PygmentsLexer(SLexer) return None def get_completer(): app = get_app(return_none=False) if hasattr(app, "mp"): if app.mp.prompt_mode in ["r", "browse"]: return RCompleter() elif app.mp.prompt_mode == "shell": return SmartPathCompleter() return None def on_render(app): if app.is_aborting and app.mp.prompt_mode not in ["readline"]: app.output.write("\n") mp = ModalPrompt( lexer=DynamicLexer(get_lexer), completer=DynamicCompleter(get_completer), history=self.get_history(options), extra_key_bindings=create_keybindings(), tempfile_suffix=".R", on_render=on_render ) # r mode message is set by RiceApplication.app_initialize() mp.prompt_mode = "r" mp.top_level_modes = ["r", "shell"] mp.auto_width = False mp.add_history = False return mp
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 _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)
def __init__(self, project=None, instance=None, database=None, credentials=None, with_pager=False, inp=None, output=None): # setup environment variables # less option for pager if not os.environ.get(config.EnvironmentVariables.LESS): os.environ[config.EnvironmentVariables.LESS] = config.Constants.LESS_FLAG self.with_pager = with_pager self.logger = logging.getLogger('spanner-cli') self.logger.debug("Staring spanner-cli project=%s, instance=%s, database=%s", project, instance, database) self.project = project with warnings.catch_warnings(record=True) as warns: warnings.simplefilter("always") self.client = spanner.Client( project=self.project, credentials=credentials, client_info=client_info.ClientInfo(user_agent=__name__), ) if len(warns) > 0: for w in warns: self.logger.debug(w) click.echo(message=w.message, err=True, nl=True) self.instance = self.client.instance(instance) self.database = self.instance.database(database) self.prompt_message = self.get_prompt_message() self.completer = SQLCompleter() self.open_history_file() self.rehash() self.session = PromptSession( message=self.prompt_message, lexer=PygmentsLexer(lexer.SpannerLexer), completer=DynamicCompleter(lambda: self.completer), style=style_from_pygments_cls(get_style_by_name(config.get_pygment_style())), history=self.history, auto_suggest=AutoSuggestFromHistory(), input_processors=[ConditionalProcessor( processor=HighlightMatchingBracketProcessor( chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() # pylint: disable=invalid-unary-operand-type )], input=inp, output=output, ) self.formatter = tabular_output.TabularOutputFormatter('ascii')
def __init__(self): InstanceManager.on_instances_update = self._on_instances_update with patch_stdout(raw=True): session = PromptSession() while True: command = session.prompt( lambda: f'[{self.selected_instance if self.selected_instance in InstanceManager.get_all() else None}]> ', completer=DynamicCompleter( lambda: NestedCompleter.from_nested_dict(self. completions)), pre_run=session.default_buffer.start_completion, validator=DynamicValidator(lambda: Validator.from_callable( lambda x: self.get_callable_from_command( x) is not None))) result = self.get_callable_from_command(command)() if isinstance(result, (list, tuple)): logger.output('\n'.join(str(line) for line in result)) elif result is not None: logger.output(str(result))
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 __init__(self, text='', multiline=True, password=False, lexer=None, auto_suggest=None, completer=None, complete_while_typing=True, accept_handler=None, history=None, focusable=True, focus_on_click=False, wrap_lines=True, read_only=False, width=None, height=None, dont_extend_height=False, dont_extend_width=False, line_numbers=False, get_line_prefix=None, scrollbar=False, style='', search_field=None, preview_search=True, prompt='', input_processors=None, max_line_count=1000, initial_text="", align=WindowAlign.LEFT): assert isinstance(text, six.text_type) assert search_field is None or isinstance(search_field, SearchToolbar) if search_field is None: search_control = None elif isinstance(search_field, SearchToolbar): search_control = search_field.control if input_processors is None: input_processors = [] # Writeable attributes. self.completer = completer self.complete_while_typing = complete_while_typing self.lexer = lexer self.auto_suggest = auto_suggest self.read_only = read_only self.wrap_lines = wrap_lines self.max_line_count = max_line_count self.buffer = CustomBuffer( document=Document(text, 0), multiline=multiline, read_only=Condition(lambda: is_true(self.read_only)), completer=DynamicCompleter(lambda: self.completer), complete_while_typing=Condition( lambda: is_true(self.complete_while_typing)), auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest), accept_handler=accept_handler, history=history) self.control = BufferControl( buffer=self.buffer, lexer=DynamicLexer(lambda: self.lexer), input_processors=[ ConditionalProcessor( AppendAutoSuggestion(), has_focus(self.buffer) & ~is_done), ConditionalProcessor( processor=PasswordProcessor(), filter=to_filter(password) ), BeforeInput(prompt, style='class:text-area.prompt'), ] + input_processors, search_buffer_control=search_control, preview_search=preview_search, focusable=focusable, focus_on_click=focus_on_click) if multiline: if scrollbar: right_margins = [ScrollbarMargin(display_arrows=True)] else: right_margins = [] if line_numbers: left_margins = [NumberedMargin()] else: left_margins = [] else: left_margins = [] right_margins = [] style = 'class:text-area ' + style self.window = Window( height=height, width=width, dont_extend_height=dont_extend_height, dont_extend_width=dont_extend_width, content=self.control, style=style, wrap_lines=Condition(lambda: is_true(self.wrap_lines)), left_margins=left_margins, right_margins=right_margins, get_line_prefix=get_line_prefix, align=align) self.log_lines: Deque[str] = deque() self.log(initial_text)
def run_cli(self): iterations = 0 sqlexecute = self.sqlexecute logger = self.logger self.configure_pager() self.refresh_completions() history_file = config_location() + "history" if dir_path_exists(history_file): history = FileHistory(history_file) else: history = None self.echo( 'Error: Unable to open the history file "{}". ' "Your query history will not be saved.".format(history_file), err=True, fg="red", ) key_bindings = cli_bindings(self) if not self.less_chatty: print("Version:", __version__) print("Mail: https://groups.google.com/forum/#!forum/litecli-users") print("GitHub: https://github.com/dbcli/litecli") # print("Home: https://litecli.com") def get_message(): prompt = self.get_prompt(self.prompt_format) if ( self.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 = " " * (width - 1) + " " return [("class:continuation", continuation)] def show_suggestion_tip(): return iterations < 2 def one_iteration(text=None): if text is None: try: text = self.prompt_app.prompt() except KeyboardInterrupt: return special.set_expanded_output(False) try: text = self.handle_editor_command(text) except RuntimeError as e: logger.error("sql: %r, error: %r", text, e) logger.error("traceback: %r", traceback.format_exc()) self.echo(str(e), err=True, fg="red") return if not text.strip(): return if self.destructive_warning: destroy = confirm_destructive_query(text) if destroy is None: pass # Query was not destructive. Nothing to do here. elif destroy is True: self.echo("Your call!") else: self.echo("Wise choice!") return # Keep track of whether or not the query is mutating. In case # of a multi-statement query, the overall query is considered # mutating if any one of the component statements is mutating mutating = False try: logger.debug("sql: %r", text) special.write_tee(self.get_prompt(self.prompt_format) + text) if self.logfile: self.logfile.write("\n# %s\n" % datetime.now()) self.logfile.write(text) self.logfile.write("\n") successful = False start = time() res = sqlexecute.run(text) self.formatter.query = text successful = True result_count = 0 for title, cur, headers, status in res: logger.debug("headers: %r", headers) logger.debug("rows: %r", cur) logger.debug("status: %r", status) threshold = 1000 if is_select(status) and cur and cur.rowcount > threshold: self.echo( "The result set has more than {} rows.".format(threshold), fg="red", ) if not confirm("Do you want to continue?"): self.echo("Aborted!", err=True, fg="red") break if self.auto_vertical_output: max_width = self.prompt_app.output.get_size().columns else: max_width = None formatted = self.format_output( title, cur, headers, special.is_expanded_output(), max_width ) t = time() - start try: if result_count > 0: self.echo("") try: self.output(formatted, status) except KeyboardInterrupt: pass self.echo("Time: %0.03fs" % t) except KeyboardInterrupt: pass start = time() result_count += 1 mutating = mutating or is_mutating(status) special.unset_once_if_written() except EOFError as e: raise e except KeyboardInterrupt: # get last connection id connection_id_to_kill = sqlexecute.connection_id logger.debug("connection id to kill: %r", connection_id_to_kill) # Restart connection to the database sqlexecute.connect() try: for title, cur, headers, status in sqlexecute.run( "kill %s" % connection_id_to_kill ): status_str = str(status).lower() if status_str.find("ok") > -1: logger.debug( "cancelled query, connection id: %r, sql: %r", connection_id_to_kill, text, ) self.echo("cancelled query", err=True, fg="red") except Exception as e: self.echo( "Encountered error while cancelling query: {}".format(e), err=True, fg="red", ) except NotImplementedError: self.echo("Not Yet Implemented.", fg="yellow") except OperationalError as e: logger.debug("Exception: %r", e) if e.args[0] in (2003, 2006, 2013): logger.debug("Attempting to reconnect.") self.echo("Reconnecting...", fg="yellow") try: sqlexecute.connect() logger.debug("Reconnected successfully.") one_iteration(text) return # OK to just return, cuz the recursion call runs to the end. except OperationalError as e: logger.debug("Reconnect failed. e: %r", e) self.echo(str(e), err=True, fg="red") # If reconnection failed, don't proceed further. return else: logger.error("sql: %r, error: %r", text, e) logger.error("traceback: %r", traceback.format_exc()) self.echo(str(e), err=True, fg="red") except Exception as e: logger.error("sql: %r, error: %r", text, e) logger.error("traceback: %r", traceback.format_exc()) self.echo(str(e), err=True, fg="red") else: if is_dropping_database(text, self.sqlexecute.dbname): self.sqlexecute.dbname = None self.sqlexecute.connect() # Refresh the table names and column names if necessary. if need_completion_refresh(text): self.refresh_completions(reset=need_completion_reset(text)) finally: if self.logfile is False: self.echo("Warning: This query was not logged.", err=True, fg="red") query = Query(text, successful, mutating) self.query_history.append(query) get_toolbar_tokens = create_toolbar_tokens_func(self, show_suggestion_tip) if self.wider_completion_menu: complete_style = CompleteStyle.MULTI_COLUMN else: complete_style = CompleteStyle.COLUMN with self._completer_lock: if self.key_bindings == "vi": editing_mode = EditingMode.VI else: editing_mode = EditingMode.EMACS self.prompt_app = PromptSession( lexer=PygmentsLexer(LiteCliLexer), reserve_space_for_menu=self.get_reserved_space(), message=get_message, prompt_continuation=get_continuation, bottom_toolbar=get_toolbar_tokens, complete_style=complete_style, 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, enable_suspend=True, editing_mode=editing_mode, search_ignore_case=True, ) try: while True: one_iteration() iterations += 1 except EOFError: special.close_tee() if not self.less_chatty: self.echo("Goodbye!")
def run_cli(self): iterations = 0 sqlexecute = self.sqlexecute logger = self.logger self.configure_pager() if self.smart_completion: self.refresh_completions() author_file = os.path.join(PACKAGE_ROOT, 'AUTHORS') sponsor_file = os.path.join(PACKAGE_ROOT, 'SPONSORS') history_file = os.path.expanduser( os.environ.get('MYCLI_HISTFILE', '~/.mycli-history')) if dir_path_exists(history_file): history = FileHistory(history_file) else: history = None self.echo( 'Error: Unable to open the history file "{}". ' 'Your query history will not be saved.'.format(history_file), err=True, fg='red') key_bindings = mycli_bindings(self) if not self.less_chatty: print(' '.join(sqlexecute.server_type())) print('mycli', __version__) print('Chat: https://gitter.im/dbcli/mycli') print('Mail: https://groups.google.com/forum/#!forum/mycli-users') print('Home: http://mycli.net') print('Thanks to the contributor -', thanks_picker([author_file, sponsor_file])) def get_message(): prompt = self.get_prompt(self.prompt_format) if self.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 = ' ' * (width - 1) + ' ' return [('class:continuation', continuation)] def show_suggestion_tip(): return iterations < 2 def one_iteration(text=None): if text is None: try: text = self.prompt_app.prompt() except KeyboardInterrupt: return special.set_expanded_output(False) try: text = self.handle_editor_command(text) except RuntimeError as e: logger.error("sql: %r, error: %r", text, e) logger.error("traceback: %r", traceback.format_exc()) self.echo(str(e), err=True, fg='red') return if not text.strip(): return if self.destructive_warning: destroy = confirm_destructive_query(text) if destroy is None: pass # Query was not destructive. Nothing to do here. elif destroy is True: self.echo('Your call!') else: self.echo('Wise choice!') return # Keep track of whether or not the query is mutating. In case # of a multi-statement query, the overall query is considered # mutating if any one of the component statements is mutating mutating = False try: logger.debug('sql: %r', text) special.write_tee(self.get_prompt(self.prompt_format) + text) if self.logfile: self.logfile.write('\n# %s\n' % datetime.now()) self.logfile.write(text) self.logfile.write('\n') successful = False start = time() res = sqlexecute.run(text) self.formatter.query = text successful = True result_count = 0 for title, cur, headers, status in res: logger.debug("headers: %r", headers) logger.debug("rows: %r", cur) logger.debug("status: %r", status) threshold = 1000 if (is_select(status) and cur and cur.rowcount > threshold): self.echo('The result set has more than {} rows.'.format( threshold), fg='red') if not confirm('Do you want to continue?'): self.echo("Aborted!", err=True, fg='red') break if self.auto_vertical_output: max_width = self.prompt_app.output.get_size().columns else: max_width = None formatted = self.format_output( title, cur, headers, special.is_expanded_output(), max_width) t = time() - start try: if result_count > 0: self.echo('') try: self.output(formatted, status) except KeyboardInterrupt: pass if special.is_timing_enabled(): self.echo('Time: %0.03fs' % t) except KeyboardInterrupt: pass start = time() result_count += 1 mutating = mutating or is_mutating(status) special.unset_once_if_written() except EOFError as e: raise e except KeyboardInterrupt: # get last connection id connection_id_to_kill = sqlexecute.connection_id logger.debug("connection id to kill: %r", connection_id_to_kill) # Restart connection to the database sqlexecute.connect() try: for title, cur, headers, status in sqlexecute.run('kill %s' % connection_id_to_kill): status_str = str(status).lower() if status_str.find('ok') > -1: logger.debug("cancelled query, connection id: %r, sql: %r", connection_id_to_kill, text) self.echo("cancelled query", err=True, fg='red') except Exception as e: self.echo('Encountered error while cancelling query: {}'.format(e), err=True, fg='red') except NotImplementedError: self.echo('Not Yet Implemented.', fg="yellow") except OperationalError as e: logger.debug("Exception: %r", e) if (e.args[0] in (2003, 2006, 2013)): logger.debug('Attempting to reconnect.') self.echo('Reconnecting...', fg='yellow') try: sqlexecute.connect() logger.debug('Reconnected successfully.') one_iteration(text) return # OK to just return, cuz the recursion call runs to the end. except OperationalError as e: logger.debug('Reconnect failed. e: %r', e) self.echo(str(e), err=True, fg='red') # If reconnection failed, don't proceed further. return else: logger.error("sql: %r, error: %r", text, e) logger.error("traceback: %r", traceback.format_exc()) self.echo(str(e), err=True, fg='red') except Exception as e: logger.error("sql: %r, error: %r", text, e) logger.error("traceback: %r", traceback.format_exc()) self.echo(str(e), err=True, fg='red') else: if is_dropping_database(text, self.sqlexecute.dbname): self.sqlexecute.dbname = None self.sqlexecute.connect() # Refresh the table names and column names if necessary. if need_completion_refresh(text): self.refresh_completions( reset=need_completion_reset(text)) finally: if self.logfile is False: self.echo("Warning: This query was not logged.", err=True, fg='red') query = Query(text, successful, mutating) self.query_history.append(query) get_toolbar_tokens = create_toolbar_tokens_func( self, show_suggestion_tip) if self.wider_completion_menu: complete_style = CompleteStyle.MULTI_COLUMN else: complete_style = CompleteStyle.COLUMN with self._completer_lock: if self.key_bindings == 'vi': editing_mode = EditingMode.VI else: editing_mode = EditingMode.EMACS self.prompt_app = PromptSession( lexer=PygmentsLexer(MyCliLexer), reserve_space_for_menu=self.get_reserved_space(), message=get_message, prompt_continuation=get_continuation, bottom_toolbar=get_toolbar_tokens, complete_style=complete_style, 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, enable_suspend=True, editing_mode=editing_mode, search_ignore_case=True ) try: while True: one_iteration() iterations += 1 except EOFError: special.close_tee() if not self.less_chatty: self.echo('Goodbye!')
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, text: str = '', multiline: FilterOrBool = True, password: FilterOrBool = False, lexer: Optional[Lexer] = None, auto_suggest: Optional[AutoSuggest] = None, completer: Optional[Completer] = None, complete_while_typing: FilterOrBool = True, accept_handler: Optional[BufferAcceptHandler] = None, history: Optional[History] = None, focusable: FilterOrBool = True, focus_on_click: FilterOrBool = False, wrap_lines: FilterOrBool = True, read_only: FilterOrBool = False, width: AnyDimension = None, height: AnyDimension = None, dont_extend_height: FilterOrBool = False, dont_extend_width: FilterOrBool = False, line_numbers: bool = False, get_line_prefix: Optional[GetLinePrefixCallable] = None, scrollbar: bool = False, style: str = '', search_field: Optional[SearchToolbar] = None, preview_search: FilterOrBool = True, prompt: AnyFormattedText = '', input_processors: Optional[List[Processor]] = None) -> None: if search_field is None: search_control = None elif isinstance(search_field, SearchToolbar): search_control = search_field.control if input_processors is None: input_processors = [] # Writeable attributes. self.completer = completer self.complete_while_typing = complete_while_typing self.lexer = lexer self.auto_suggest = auto_suggest self.read_only = read_only self.wrap_lines = wrap_lines self.buffer = Buffer( document=Document(text, 0), multiline=multiline, read_only=Condition(lambda: is_true(self.read_only)), completer=DynamicCompleter(lambda: self.completer), complete_while_typing=Condition( lambda: is_true(self.complete_while_typing)), auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest), accept_handler=accept_handler, history=history) self.control = BufferControl( buffer=self.buffer, lexer=DynamicLexer(lambda: self.lexer), input_processors=[ ConditionalProcessor(AppendAutoSuggestion(), has_focus(self.buffer) & ~is_done), ConditionalProcessor(processor=PasswordProcessor(), filter=to_filter(password)), BeforeInput(prompt, style='class:text-area.prompt'), ] + input_processors, search_buffer_control=search_control, preview_search=preview_search, focusable=focusable, focus_on_click=focus_on_click) if multiline: if scrollbar: right_margins = [ScrollbarMargin(display_arrows=True)] else: right_margins = [] if line_numbers: left_margins = [NumberedMargin()] else: left_margins = [] else: height = D.exact(1) left_margins = [] right_margins = [] style = 'class:text-area ' + style self.window = Window( height=height, width=width, dont_extend_height=dont_extend_height, dont_extend_width=dont_extend_width, content=self.control, style=style, wrap_lines=Condition(lambda: is_true(self.wrap_lines)), left_margins=left_margins, right_margins=right_margins, get_line_prefix=get_line_prefix)
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 create_layout(self): # 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.formatted_message) default_buffer = ModalBuffer( name=DEFAULT_BUFFER, complete_while_typing=Condition( lambda: self.complete_while_typing), completer=DynamicCompleter(lambda: self.completer), history=self.history, get_tempfile_suffix=lambda: self.tempfile_suffix) search_buffer = Buffer(name=SEARCH_BUFFER) search_toolbar = SearchToolbar(search_buffer) input_processor = merge_processors([ ConditionalProcessor(HighlightSearchProcessor(preview_search=True), has_focus(search_buffer)), HighlightSelectionProcessor(), HighlightMatchingBracketProcessor(), DisplayMultipleCursors() ]) default_buffer_control = BufferControl( buffer=default_buffer, search_buffer_control=search_toolbar.control, input_processor=input_processor, lexer=DynamicLexer(lambda: self.lexer), preview_search=True) def get_default_buffer_control_height(): # 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. space = self.reserve_space_for_menu if space and not get_app().is_done: buff = default_buffer if buff.complete_while_typing( ) or buff.complete_state is not None: return Dimension(min=space) return Dimension() def get_continuation(width): prompt_continuation = self.prompt_continuation if callable(prompt_continuation): prompt_continuation = prompt_continuation(width) return to_formatted_text(prompt_continuation, style='class:prompt-continuation') default_buffer_window = Window( default_buffer_control, height=get_default_buffer_control_height, left_margins=[PromptMargin(get_prompt_text_2, get_continuation)], wrap_lines=True) def get_arg_text(): arg = self.app.key_processor.arg if arg == '-': arg = '-1' return [('class:arg-toolbar', 'Repeat: '), ('class:arg-toolbar.text', arg)] # 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)), default_buffer_window, ]), [ # Completion menus. Float(xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( show_meta=True, extra_filter=has_focus(default_buffer))) ]), ConditionalContainer( Window(FormattedTextControl(get_arg_text), height=1), has_arg), search_toolbar ]) return Layout(layout, default_buffer_window)
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 _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 doexec(self): """Entrance of the client terminal program""" def exec(): try: text = self.xprompt.prompt() except KeyboardInterrupt: return if len(text) < 7 and ''.join(text.lower().split()) in ['quit;', 'exit;']: click.secho('See you again!', fg='green') sys.exit(0) def continuation(width, *_): if self.multi_continuation == '': pmp = '' elif self.multi_continuation: left = width - len(self.multi_continuation) pmp = " " * max((left - 1), 0) + self.multi_continuation + " " else: pmp = "" return [('class:continuation', pmp)] print("") print("Welcome to use xugu database products.") print("Successfully connect to %s:%s %s as %s" %(self.options['host'], self.options['port'], self.options['database'], self.options['user'])) print("%s: %s" %(self.options['name'], self.version)) print('Home: http://www.xugucn.com/') print("") bar = xbottom_toolbar(self) binding = xbottom_binding(self) def xstyle(): elem = [ ('completion-menu.completion.current', 'bg:#ffffff #000000'), ('completion-menu.completion', 'bg:#008888 #ffffff'), ('completion-menu.meta.completion.current', 'bg:#44aaaa #000000'), ('completion-menu.meta.completion', 'bg:#448888 #ffffff'), ('completion-menu.multi-column-meta', 'bg:#aaffff #000000'), ('scrollbar.arrow', 'bg:#003333'), ('scrollbar', 'bg:#00aaaa'), ('selected', '#ffffff bg:#6666aa'), ('search', '#ffffff bg:#4444aa'), ('output.header', '#00ff5f bold'), ('output.odd-row', ''), ('output.even-row', ''), ('output.null', '#808080'), ('search.current', '#ffffff bg:#44aa44'), ('bottom-toolbar', 'bg:#222222 #aaaaaa'), ('bottom-toolbar.off', 'bg:#222222 #888888'), ('bottom-toolbar.on', 'bg:#222222 #ffffff'), ('bottom-toolbar.transaction.valid', 'bg:#222222 #00ff5f bold'), ('bottom-toolbar.transaction.failed', 'bg:#222222 #ff005f bold'), ('search-toolbar', 'noinherit bold'), ('search-toolbar.text', 'nobold'), ('system-toolbar', 'noinherit bold'), ('arg-toolbar', 'noinherit bold')] style = pygments.styles.get_style_by_name('default') override_style = Style([('bottom-toolbar', 'noreverse')]) return merge_styles([style_from_pygments_cls(style), override_style, Style(elem)]) self.xprompt = PromptSession( message = self.xlogin(), lexer = PygmentsLexer(XgCliLexer), completer = DynamicCompleter(lambda: self.completer), bottom_toolbar = bar, style = xstyle(), prompt_continuation = continuation, key_bindings = binding, multiline = cli_multiline(self), complete_while_typing=True, include_default_pygments_style=False, ) try: while True: exec() except EOFError: click.secho('See you again!', fg='green')
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 __init__( self, get_globals: Optional[_GetNamespace] = None, get_locals: Optional[_GetNamespace] = None, history_filename: Optional[str] = None, vi_mode: bool = False, color_depth: Optional[ColorDepth] = None, # Input/output. input: Optional[Input] = None, output: Optional[Output] = None, # For internal use. extra_key_bindings: Optional[KeyBindings] = None, _completer: Optional[Completer] = None, _validator: Optional[Validator] = None, _lexer: Optional[Lexer] = None, _extra_buffer_processors=None, _extra_layout_body=None, _extra_toolbars=None, _input_buffer_height=None, ) -> None: self.get_globals: _GetNamespace = get_globals or (lambda: {}) self.get_locals: _GetNamespace = get_locals or self.get_globals self.completer = _completer or PythonCompleter( self.get_globals, self.get_locals, lambda: self.enable_dictionary_completion, ) self._completer = HidePrivateCompleter( # If fuzzy is enabled, first do fuzzy completion, but always add # the non-fuzzy completions, if somehow the fuzzy completer didn't # find them. (Due to the way the cursor position is moved in the # fuzzy completer, some completions will not always be found by the # fuzzy completer, but will be found with the normal completer.) merge_completers( [ ConditionalCompleter( FuzzyCompleter( DynamicCompleter(lambda: self.completer)), Condition(lambda: self.enable_fuzzy_completion), ), DynamicCompleter(lambda: self.completer), ], deduplicate=True, ), lambda: self.complete_private_attributes, ) self._validator = _validator or PythonValidator( self.get_compiler_flags) self._lexer = PtpythonLexer(_lexer) self.history: History if history_filename: self.history = ThreadedHistory(FileHistory(history_filename)) else: self.history = InMemoryHistory() self._input_buffer_height = _input_buffer_height self._extra_layout_body = _extra_layout_body or [] self._extra_toolbars = _extra_toolbars or [] self._extra_buffer_processors = _extra_buffer_processors or [] self.extra_key_bindings = extra_key_bindings or KeyBindings() # Settings. self.title: AnyFormattedText = "" self.show_signature: bool = False self.show_docstring: bool = False self.show_meta_enter_message: bool = True self.completion_visualisation: CompletionVisualisation = ( CompletionVisualisation.MULTI_COLUMN) self.completion_menu_scroll_offset: int = 1 self.show_line_numbers: bool = False self.show_status_bar: bool = True self.wrap_lines: bool = True self.complete_while_typing: bool = True self.paste_mode: bool = ( False # When True, don't insert whitespace after newline. ) self.confirm_exit: bool = ( True # Ask for confirmation when Control-D is pressed. ) self.accept_input_on_enter: int = 2 # Accept when pressing Enter 'n' times. # 'None' means that meta-enter is always required. self.enable_open_in_editor: bool = True self.enable_system_bindings: bool = True self.enable_input_validation: bool = True self.enable_auto_suggest: bool = False self.enable_mouse_support: bool = False self.enable_history_search: bool = False # When True, like readline, going # back in history will filter the # history on the records starting # with the current input. self.enable_syntax_highlighting: bool = True self.enable_fuzzy_completion: bool = False self.enable_dictionary_completion: bool = False # Also eval-based completion. self.complete_private_attributes: CompletePrivateAttributes = ( CompletePrivateAttributes.ALWAYS) self.swap_light_and_dark: bool = False self.highlight_matching_parenthesis: bool = False self.show_sidebar: bool = False # Currently show the sidebar. # Pager. self.enable_output_formatting: bool = False self.enable_pager: bool = False self.show_locals: bool = True # When the sidebar is visible, also show the help text. self.show_sidebar_help: bool = True # Currently show 'Do you really want to exit?' self.show_exit_confirmation: bool = False # The title to be displayed in the terminal. (None or string.) self.terminal_title: Optional[str] = None self.exit_message: str = "Do you really want to exit?" self.insert_blank_line_after_output: bool = True # (For the REPL.) self.insert_blank_line_after_input: bool = False # (For the REPL.) # The buffers. self.default_buffer = self._create_buffer() self.search_buffer: Buffer = Buffer() self.docstring_buffer: Buffer = Buffer(read_only=True) # Tokens to be shown at the prompt. self.prompt_style: str = "classic" # The currently active style. # Styles selectable from the menu. self.all_prompt_styles: Dict[str, PromptStyle] = { "ipython": IPythonPrompt(self), "classic": ClassicPrompt(), } self.get_input_prompt = lambda: self.all_prompt_styles[ self.prompt_style].in_prompt() self.get_output_prompt = lambda: self.all_prompt_styles[ self.prompt_style].out_prompt() #: Load styles. self.code_styles: Dict[str, BaseStyle] = get_all_code_styles() self.ui_styles = get_all_ui_styles() self._current_code_style_name: str = "default" self._current_ui_style_name: str = "default" if is_windows(): self._current_code_style_name = "win32" self._current_style = self._generate_style() self.color_depth: ColorDepth = color_depth or ColorDepth.default() self.max_brightness: float = 1.0 self.min_brightness: float = 0.0 # Options to be configurable from the sidebar. self.options = self._create_options() self.selected_option_index: int = 0 #: Incremeting integer counting the current statement. self.current_statement_index: int = 1 # Code signatures. (This is set asynchronously after a timeout.) self.signatures: List[Signature] = [] # Boolean indicating whether we have a signatures thread running. # (Never run more than one at the same time.) self._get_signatures_thread_running: bool = False # Get into Vi navigation mode at startup self.vi_start_in_navigation_mode: bool = False # Preserve last used Vi input mode between main loop iterations self.vi_keep_last_used_mode: bool = False self.style_transformation = merge_style_transformations([ ConditionalStyleTransformation( SwapLightAndDarkStyleTransformation(), filter=Condition(lambda: self.swap_light_and_dark), ), AdjustBrightnessStyleTransformation(lambda: self.min_brightness, lambda: self.max_brightness), ]) self.ptpython_layout = PtPythonLayout( self, lexer=DynamicLexer(lambda: self._lexer if self. enable_syntax_highlighting else SimpleLexer()), input_buffer_height=self._input_buffer_height, extra_buffer_processors=self._extra_buffer_processors, extra_body=self._extra_layout_body, extra_toolbars=self._extra_toolbars, ) self.app = self._create_application(input, output) if vi_mode: self.app.editing_mode = EditingMode.VI
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 create_modal_prompt(options, history_file): def get_lexer(): if mp.prompt_mode in ["r", "browse"]: return PygmentsLexer(SLexer) return None def get_completer(): if mp.prompt_mode in ["r", "browse"]: return RCompleter() elif mp.prompt_mode == "shell": return SmartPathCompleter() return None def get_history(): if options.no_history: return ModalInMemoryHistory() elif not options.global_history and os.path.exists(history_file): return ModalFileHistory(os.path.abspath(history_file)) else: return ModalFileHistory(os.path.join(os.path.expanduser("~"), history_file)) def on_render(app): if app.is_aborting and mp.insert_new_line and mp.prompt_mode not in ["readline"]: app.output.write("\n") def accept(buff): buff.last_working_index = buff.working_index app = get_app() if mp.prompt_mode == "browse": if buff.text.strip() in ["n", "s", "f", "c", "cont", "Q", "where", "help"]: mp.add_history = False if mp.prompt_mode in ["r", "browse", "readline"]: app.set_return_value(buff.document.text) app.pre_run_callables.append(buff.reset) elif mp.prompt_mode in ["shell"]: # buffer will be reset to empty, we need to append history at this time point. mp.add_history = True buff.append_to_history() if mp.insert_new_line: sys.stdout.write("\n") shell_cmd.run_shell_command(buff.text) buff.reset() mp = ModalPrompt( lexer=DynamicLexer(get_lexer), completer=DynamicCompleter(get_completer), history=get_history(), extra_key_bindings=create_keybindings(), tempfile_suffix=".R", on_render=on_render, accept=accept ) # r mode message is set by RiceApplication.app_initialize() mp.prompt_mode = "r" mp.top_level_modes = ["r", "shell"] mp.auto_width = False mp.add_history = False return mp