def create_default_layout(message='', lexer=None, is_password=False, reserve_space_for_menu=False, get_bottom_toolbar_tokens=None): """ Generate default layout. """ assert get_bottom_toolbar_tokens is None or callable(get_bottom_toolbar_tokens) # Create processors list. input_processors = [HighlightSearchProcessor(), HighlightSelectionProcessor()] if is_password: input_processors.extend([PasswordProcessor(), DefaultPrompt(message)]) else: input_processors.append(DefaultPrompt(message)) # Create bottom toolbar. if get_bottom_toolbar_tokens: toolbars = [Window(TokenListControl(get_bottom_toolbar_tokens, default_char=Char(' ', Token.Toolbar)), height=LayoutDimension.exact(1), filter=~IsDone())] else: toolbars = [] def get_height(cli): # If there is an autocompletion menu to be shown, make sure that our # layout has at least a minimal height in order to display it. if reserve_space_for_menu and not cli.is_done: return LayoutDimension(min=8) else: return LayoutDimension() # Create and return Layout instance. return HSplit([ FloatContainer( Window( BufferControl( input_processors=input_processors, lexer=lexer, # Enable preview_search, we want to have immediate feedback # in reverse-i-search mode. preview_search=Always()), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, extra_filter=HasFocus(DEFAULT_BUFFER))) ] ), ValidationToolbar(), SystemToolbar(), ] + toolbars)
def create_default_layout(message='', lexer=None, is_password=False, reserve_space_for_menu=False, get_bottom_toolbar_tokens=None): """ Generate default layout. """ assert get_bottom_toolbar_tokens is None or callable(get_bottom_toolbar_tokens) # Create processors list. if is_password: input_processors = [PasswordProcessor(), DefaultPrompt(message)] else: input_processors = [DefaultPrompt(message)] # Create bottom toolbar. if get_bottom_toolbar_tokens: toolbars = [Window(TokenListControl(get_bottom_toolbar_tokens, default_char=Char(' ', Token.Toolbar)), height=LayoutDimension.exact(1), filter=~IsDone())] else: toolbars = [] def get_height(cli): # If there is an autocompletion menu to be shown, make sure that our # layout has at least a minimal height in order to display it. if reserve_space_for_menu and not cli.is_done: return LayoutDimension(min=8) else: return LayoutDimension() # Create and return Layout instance. return HSplit([ FloatContainer( Window( BufferControl( input_processors=input_processors, lexer=lexer), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, extra_filter=HasFocus('default'))) ] ), ValidationToolbar(), SystemToolbar(), ] + toolbars)
def main(): layout = Layout(left_margin=LeftMarginWithLineNumbers(), before_input=DefaultPrompt(text='Before input >> '), after_input=Prompt(' << after input'), top_toolbars=[ TextToolbar('This is a top toolbar', token=Token.TopToolbar1), TextToolbar('This is another top toolbar', token=Token.TopToolbar2), ], bottom_toolbars=[ ArgToolbar(), SearchToolbar(), CompletionsToolbar(), TextToolbar('This is a bottom toolbar', token=Token.BottomToolbar1), TextToolbar('This is another bottom toolbar', token=Token.BottomToolbar2), ], show_tildes=True, menus=[CompletionsMenu()]) cli = CommandLineInterface(layout=layout, style=TestStyle, line=Line(is_multiline=True, completer=TestCompleter())) code_obj = cli.read_input(initial_value=lipsum) print('You said: ' + code_obj.text)
def main(): cli = CommandLineInterface( style=AnimalStyle, layout=Layout(before_input=DefaultPrompt('Give some animals: '), menus=[CompletionsMenu()]), line=Line(completer=AnimalCompleter()), create_async_autocompleters=True, ) print('Press tab to complete') code_obj = cli.read_input() print('You said: ' + code_obj.text)
def create_layout(self, exam_lex, toolbar_lex): """ creates the layout """ lexer, exam_lex, toolbar_lex = get_lexers(self.shell_ctx.lexer, exam_lex, toolbar_lex) if not any( isinstance(processor, DefaultPrompt) for processor in self.input_processors): self.input_processors.append(DefaultPrompt(self.get_prompt_tokens)) layout_lower = ConditionalContainer(HSplit([ get_anyhline(self.shell_ctx.config), get_descriptions(self.shell_ctx.config, exam_lex, lexer), get_examplehline(self.shell_ctx.config), get_example(self.shell_ctx.config, exam_lex), ConditionalContainer(get_hline(), filter=self.show_default | self.show_symbol), ConditionalContainer(Window(content=BufferControl( buffer_name='default_values', lexer=lexer)), filter=self.show_default), ConditionalContainer(get_hline(), filter=self.show_default & self.show_symbol), ConditionalContainer(Window( content=BufferControl(buffer_name='symbols', lexer=exam_lex)), filter=self.show_symbol), ConditionalContainer(Window( content=BufferControl(buffer_name='progress', lexer=lexer)), filter=self.show_progress), Window(content=BufferControl(buffer_name='bottom_toolbar', lexer=toolbar_lex), ), ]), filter=~IsDone() & RendererHeightIsKnown()) layout_full = HSplit([ FloatContainer( Window( BufferControl(input_processors=self.input_processors, lexer=lexer, preview_search=Always()), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=MAX_COMPLETION, scroll_offset=1, extra_filter=(HasFocus(DEFAULT_BUFFER)))) ]), layout_lower ]) return layout_full
def main(database): connection = sqlite3.connect(database) layout = Layout(before_input=DefaultPrompt('> '), lexer=SqlLexer, menus=[CompletionsMenu()]) line = Line(completer=SqlCompleter()) cli = CommandLineInterface(style=DocumentStyle, layout=layout, line=line) try: while True: document = cli.read_input(on_exit=AbortAction.RAISE_EXCEPTION) with connection: messages = connection.execute(document.text) for message in messages: print message except Exit: print 'GoodBye!'
def create_layout(lex, exam_lex, toolbar_lex): """ creates the layout """ config = azclishell.configuration.CONFIGURATION lexer, exam_lex, toolbar_lex = get_lexers(lex, exam_lex, toolbar_lex) input_processors.append(DefaultPrompt(get_prompt_tokens)) layout_lower = ConditionalContainer(HSplit([ get_anyhline(config), get_descriptions(config, exam_lex, lexer), get_examplehline(config), get_example(config, exam_lex), ConditionalContainer(get_hline(), filter=ShowDefault() | ShowSymbol()), ConditionalContainer(Window( content=BufferControl(buffer_name='default_values', lexer=lexer)), filter=ShowDefault()), ConditionalContainer(get_hline(), filter=ShowDefault() & ShowSymbol()), ConditionalContainer(Window( content=BufferControl(buffer_name='symbols', lexer=exam_lex)), filter=ShowSymbol()), ConditionalContainer( Window(content=BufferControl(buffer_name='progress', lexer=lexer)), filter=ShowProgress()), Window(content=BufferControl(buffer_name='bottom_toolbar', lexer=toolbar_lex), ), ]), filter=~IsDone() & RendererHeightIsKnown()) layout_full = HSplit([ FloatContainer( Window( BufferControl(input_processors=input_processors, lexer=lexer, preview_search=Always()), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=MAX_COMPLETION, scroll_offset=1, extra_filter=(HasFocus(DEFAULT_BUFFER)))) ]), layout_lower ]) return layout_full
def main(): layout = Layout(before_input=DefaultPrompt('> '), menus=[CompletionMenu()]) line = Line(RESTCompleter()) cli = CommandLineInterface(style=DocumentStyle, layout=layout, line=line) try: while True: document = cli.read_input(on_exit=AbortAction.RAISE_EXCEPTION) input_args = document.text.split(' ') if len(input_args) < 2: raise AssertionError( "Must provide at least a method and a url") response = process_request(input_args) print 'Response:', response.json() except Exit: print 'GoodBye!'
def cli(database, user, password, host, port): from pgcli import __file__ as package_root package_root = os.path.dirname(package_root) default_config = os.path.join(package_root, 'pgclirc') # Write default config. write_default_config(default_config, '~/.pgclirc') # Load config. config = load_config('~/.pgclirc') # Connect to the database. try: pgexecute = PGExecute(database, user, password, host, port) except Exception as e: click.secho(e.message, err=True, fg='red') exit(1) layout = Layout(before_input=DefaultPrompt('%s> ' % database), menus=[CompletionsMenu()], lexer=SqlLexer) completer = PGCompleter(config.getboolean('main', 'smart_completion')) completer.extend_special_commands(pgexecute.special_commands.keys()) completer.extend_table_names(pgexecute.tables()) completer.extend_column_names(pgexecute.all_columns()) line = Line(completer=completer, history=FileHistory(os.path.expanduser('~/.pgcli-history'))) cli = CommandLineInterface(style=PGStyle, layout=layout, line=line) try: while True: document = cli.read_input(on_exit=AbortAction.RAISE_EXCEPTION) try: rows, headers, status = pgexecute.run(document.text) if rows: print(tabulate(rows, headers, tablefmt='psql')) print(status) except Exception as e: click.secho(e.message, err=True, fg='red') except Exit: print ('GoodBye!')
def run_cli(self): pgexecute = self.pgexecute prompt = '%s> ' % pgexecute.dbname logger = self.logger original_less_opts = self.adjust_less_opts() completer = self.completer self.refresh_completions() key_binding_manager = pgcli_bindings(self.vi_mode) print('Version:', __version__) print('Chat: https://gitter.im/amjith/pgcli') print('Mail: https://groups.google.com/forum/#!forum/pgcli') print('Home: http://pgcli.com') layout = Layout(before_input=DefaultPrompt(prompt), menus=[CompletionsMenu(max_height=10)], lexer=PostgresLexer, bottom_toolbars=[PGToolbar(key_binding_manager)]) buf = PGBuffer(always_multiline=self.multi_line, completer=completer, history=FileHistory( os.path.expanduser('~/.pgcli-history'))) cli = CommandLineInterface( style=style_factory(self.syntax_style), layout=layout, buffer=buf, key_bindings_registry=key_binding_manager.registry) try: while True: cli.layout.before_input = DefaultPrompt(prompt) document = cli.read_input(on_exit=AbortAction.RAISE_EXCEPTION) # The reason we check here instead of inside the pgexecute is # because we want to raise the Exit exception which will be # caught by the try/except block that wraps the pgexecute.run() # statement. if quit_command(document.text): raise Exit # 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', document.text) successful = False # Initialized to [] because res might never get initialized # if an exception occurs in pgexecute.run(). Which causes # finally clause to fail. res = [] start = time() # Run the query. res = pgexecute.run(document.text) duration = time() - start successful = True output = [] total = 0 for title, cur, headers, status in res: logger.debug("headers: %r", headers) logger.debug("rows: %r", cur) logger.debug("status: %r", status) start = time() threshold = 1000 if (is_select(status) and cur and cur.rowcount > threshold): click.secho( 'The result set has more than %s rows.' % threshold, fg='red') if not click.confirm('Do you want to continue?'): click.secho("Aborted!", err=True, fg='red') break output.extend( format_output(title, cur, headers, status, self.table_format)) end = time() total += end - start mutating = mutating or is_mutating(status) except KeyboardInterrupt: # Restart connection to the database pgexecute.connect() logger.debug("cancelled query, sql: %r", document.text) click.secho("cancelled query", err=True, fg='red') except Exception as e: logger.error("sql: %r, error: %r", document.text, e) logger.error("traceback: %r", traceback.format_exc()) click.secho(str(e), err=True, fg='red') else: click.echo_via_pager('\n'.join(output)) if pgspecial.TIMING_ENABLED: print('Command Time:', duration) print('Format Time:', total) finally: for cur, _, _ in res: if hasattr(cur, 'close'): cur.close() # Refresh the table names and column names if necessary. if need_completion_refresh(document.text): prompt = '%s> ' % pgexecute.dbname self.refresh_completions() # Refresh search_path to set default schema. if need_search_path_refresh(document.text): logger.debug('Refreshing search path') completer.set_search_path(pgexecute.search_path()) logger.debug('Search path: %r', completer.search_path) query = Query(document.text, successful, mutating) self.query_history.append(query) except Exit: print('Goodbye!') finally: # Reset the less opts back to original. logger.debug('Restoring env var LESS to %r.', original_less_opts) os.environ['LESS'] = original_less_opts
def main(): manager = KeyBindingManager(enable_system_bindings=Always()) D = LayoutDimension layout = HSplit([ VSplit([ Window(width=D(min=15, max=30, preferred=30), content=FillControl('a', token=Token.A)), Window(width=D.exact(1), content=FillControl('|', token=Token.Line)), Window(content=TokenListControl.static([(Token.HelloWorld, lipsum)])), Window(width=D.exact(1), content=FillControl('|', token=Token.Line)), Window(content=BufferControl( lexer=PygmentsLexer(PythonLexer), margin=NumberredMargin(), input_processors=[ DefaultPrompt.from_message('python> '), AfterInput.static(' <python', token=Token.AfterInput), ]), ), Window(width=D.exact(1), content=FillControl('|', token=Token.Line)), HSplit([ Window(width=D(max=40), height=D.exact(4), content=FillControl('b', token=Token.B)), Window(width=D(max=40), content=FillControl('f', token=Token.F)), Window(width=D.exact(30), height=D.exact(2), content=FillControl('c', token=Token.C)), ]), #CompletionsMenu(), ]), Window(height=D.exact(1), content=FillControl('-', token=Token.Line)), Window(height=D.exact(3), content=FillControl('d', token=Token.D)), SystemToolbar(), ArgToolbar(), CompletionsToolbar(), SearchToolbar(), ]) layout = FloatContainer(content=layout, floats=[ Float(xcursor=True, ycursor=True, content=VSplit([ Window(width=D.exact(5), content=FillControl( 'f', token=Token.F)), CompletionsMenu(), ])), ]) eventloop = create_eventloop() application = Application(layout=layout, style=TestStyle, key_bindings_registry=manager.registry, buffer=Buffer(is_multiline=Always(), completer=TestCompleter())) cli = CommandLineInterface(application=application, eventloop=eventloop) cli.run() eventloop.close()
def main(): manager = KeyBindingManager(enable_system_prompt=True) D = LayoutDimension layout = HSplit([ VSplit([ Window(width=D(min=15, max=30, preferred=30), content=FillControl('a', token=Token.A)), Window(width=D.exact(1), content=FillControl('|', token=Token.Line)), Window(content=TokenListControl.static([(Token.HelloWorld, lipsum)])), Window(width=D.exact(1), content=FillControl('|', token=Token.Line)), Window(content=BufferControl(lexer=PythonLexer, show_line_numbers=Always(), input_processors=[ DefaultPrompt.from_message('python> '), AfterInput.static(' <python', token=Token.AfterInput), ]), ), Window(width=D.exact(1), content=FillControl('|', token=Token.Line)), HSplit([ Window(width=D(max=40), height=D.exact(4), content=FillControl('b', token=Token.B)), Window(width=D(max=40), content=FillControl('f', token=Token.F)), Window(width=D.exact(30), height=D.exact(2), content=FillControl('c', token=Token.C)), ]), #CompletionsMenu(), ]), Window(height=D.exact(1), content=FillControl('-', token=Token.Line)), Window(height=D.exact(3), content=FillControl('d', token=Token.D)), SystemToolbar(), ArgToolbar(), CompletionsToolbar(), SearchToolbar(), ]) layout = FloatContainer( content=layout, floats=[ Float(xcursor=True, ycursor=True, content=VSplit([ Window(width=D.exact(5), content=FillControl('f', token=Token.F)), CompletionsMenu(), ]) ), ] ) eventloop = create_eventloop() application = Application(layout=layout, style=TestStyle, key_bindings_registry=manager.registry, buffer=Buffer(is_multiline=Always(), completer=TestCompleter())) cli = CommandLineInterface(application=application, eventloop=eventloop) cli.run() eventloop.close()
Name: '#008800', Token.Literal.String: '#440000', Comment: '#0000dd', Error: '#000000 bg:#ff8888', # Completion Menu Token.Menu.Completions.Completion.Current: 'bg:#00aaaa #000000', Token.Menu.Completions.Completion: 'bg:#008888 #ffffff', Token.Menu.Completions.ProgressButton: 'bg:#003333', Token.Menu.Completions.ProgressBar: 'bg:#00aaaa', } if __name__ == '__main__': cli = CommandLineInterface(layout=Layout( before_input=DefaultPrompt('(pdb) '), after_input=CompletionHint(grammar), menus=[CompletionsMenu()]), line=Line(completer=ShellCompleter(grammar)), style=PdbStyle) try: while True: document = cli.read_input(on_exit=AbortAction.RAISE_EXCEPTION) try: parse_info = get_parse_info(grammar, document) except InvalidCommandException: print('Invalid command\n') continue else:
def _create_layout(self): """ Generate the main prompt_toolkit layout. """ waits_for_confirmation = WaitsForConfirmation(self.pymux) waits_for_prompt = WaitsForPrompt(self.pymux) in_command_mode = InCommandMode(self.pymux) return FloatContainer( content=HSplit([ # The main window. HighlightBorders(self, self.pymux, FloatContainer( Background(), floats=[ Float(get_width=lambda cli: self.pymux.get_window_size(cli).columns, get_height=lambda cli: self.pymux.get_window_size(cli).rows, content=TraceBodyWritePosition(self.pymux, DynamicBody(self.pymux))) ])), # Status bar. ConditionalContainer( content=VSplit([ # Left. Window( height=D.exact(1), get_width=(lambda cli: D(max=self.pymux.status_left_length)), dont_extend_width=True, content=TokenListControl( self._get_status_left_tokens, default_char=Char(' ', Token.StatusBar))), # List of windows in the middle. Window( height=D.exact(1), content=TokenListControl( self._get_status_tokens, align_right=Condition(self._status_align_right), align_center=Condition(self._status_align_center), default_char=Char(' ', Token.StatusBar))), # Right. Window( height=D.exact(1), get_width=(lambda cli: D(max=self.pymux.status_right_length)), dont_extend_width=True, content=TokenListControl( self._get_status_right_tokens, align_right=True, default_char=Char(' ', Token.StatusBar))) ]), filter=Condition(lambda cli: self.pymux.enable_status), ) ]), floats=[ Float(bottom=1, left=0, content=MessageToolbar(self.pymux)), Float(left=0, right=0, bottom=0, content=HSplit([ # Wait for confirmation toolbar. ConditionalContainer( content=Window( height=D.exact(1), content=ConfirmationToolbar(self.pymux), ), filter=waits_for_confirmation, ), # ':' prompt toolbar. ConditionalContainer( content=Window( height=D(min=1), # Can be more if the command is multiline. dont_extend_height=True, content=BufferControl( buffer_name=COMMAND, default_char=Char(' ', Token.CommandLine), lexer=SimpleLexer(Token.CommandLine), preview_search=True, highlighters=[SelectionHighlighter()], input_processors=[ AppendAutoSuggestion(), DefaultPrompt(lambda cli:[(Token.CommandLine.Prompt, ':')]), ]) ), filter=in_command_mode, ), # Other command-prompt commands toolbar. ConditionalContainer( content=Window( height=D.exact(1), content=BufferControl( buffer_name=PROMPT, default_char=Char(' ', Token.CommandLine), lexer=SimpleLexer(Token.CommandLine), highlighters=[SelectionHighlighter()], input_processors=[ BeforeInput(self._before_prompt_command_tokens), AppendAutoSuggestion(), ]) ), filter=waits_for_prompt, ), ])), Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=12)), ] )
# Match found stack.pop() else: # No match for closing bracket. tokens[index] = (self.error_token, text) # Highlight unclosed tags that are still on the stack. for index in stack: tokens[index] = (self.error_token, tokens[index][1]) return tokens cli = CommandLineInterface( layout=Layout(input_processors=[BracketsMismatchProcessor()], before_input=DefaultPrompt(u'ϛ '), menus=[], lexer=VauLexer), style=VauStyle, buffer=Buffer(completer=vau_completer), create_async_autocompleters=True, ) def start_repl(): """The vau read-evau-print loop""" try: while True: code_obj = cli.read_input(on_exit=AbortAction.RAISE_EXCEPTION) try: val = evau(parse(code_obj.text, evau))
def _create_layout(self, message='', lexer=None, is_password=False, reserve_space_for_menu=8, get_prompt_tokens=None, get_continuation_tokens=None, get_rprompt_tokens=None, get_bottom_toolbar_tokens=None, get_url_tokens=None, display_completions_in_columns=False, extra_input_processors=None, multiline=False, wrap_lines=True): """ Create a :class:`.Container` instance for a prompt. :param message: Text to be used as prompt. :param lexer: :class:`~prompt_toolkit.layout.lexers.Lexer` to be used for the highlighting. :param is_password: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. When True, display input as '*'. :param reserve_space_for_menu: Space to be reserved for the menu. When >0, make sure that a minimal height is allocated in the terminal, in order to display the completion menu. :param get_prompt_tokens: An optional callable that returns the tokens to be shown in the menu. (To be used instead of a `message`.) :param get_continuation_tokens: An optional callable that takes a CommandLineInterface and width as input and returns a list of (Token, text) tuples to be used for the continuation. :param get_bottom_toolbar_tokens: An optional callable that returns the tokens for a toolbar at the bottom. :param display_completions_in_columns: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. Display the completions in multiple columns. :param multiline: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. When True, prefer a layout that is more adapted for multiline input. Text after newlines is automatically indented, and search/arg input is shown below the input, instead of replacing the prompt. :param wrap_lines: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. When True (the default), automatically wrap long lines instead of scrolling horizontally. """ assert get_bottom_toolbar_tokens is None or callable( get_bottom_toolbar_tokens) assert get_prompt_tokens is None or callable(get_prompt_tokens) assert get_rprompt_tokens is None or callable(get_rprompt_tokens) assert not (message and get_prompt_tokens) display_completions_in_columns = to_cli_filter( display_completions_in_columns) multiline = to_cli_filter(multiline) if get_prompt_tokens is None: get_prompt_tokens = lambda _: [(Token.Prompt, message)] has_before_tokens, get_prompt_tokens_1, get_prompt_tokens_2 = \ _split_multiline_prompt(get_prompt_tokens) # `lexer` is supposed to be a `Lexer` instance. But if a Pygments lexer # class is given, turn it into a PygmentsLexer. (Important for # backwards-compatibility.) try: if pygments_Lexer and issubclass(lexer, pygments_Lexer): lexer = PygmentsLexer(lexer, sync_from_start=True) except TypeError: # Happens when lexer is `None` or an instance of something else. pass # Create processors list. input_processors = [ ConditionalProcessor( # By default, only highlight search when the search # input has the focus. (Note that this doesn't mean # there is no search: the Vi 'n' binding for instance # still allows to jump to the next match in # navigation mode.) HighlightSearchProcessor(preview_search=True), HasFocus(SEARCH_BUFFER)), HighlightSelectionProcessor(), ConditionalProcessor(AppendAutoSuggestion(), HasFocus(DEFAULT_BUFFER) & ~IsDone()), ConditionalProcessor(PasswordProcessor(), is_password), DisplayMultipleCursors(DEFAULT_BUFFER), ] if extra_input_processors: input_processors.extend(extra_input_processors) # Show the prompt before the input (using the DefaultPrompt processor. # This also replaces it with reverse-i-search and 'arg' when required. # (Only for single line mode.) # (DefaultPrompt should always be at the end of the processors.) input_processors.append( ConditionalProcessor(DefaultPrompt(get_prompt_tokens_2), ~multiline)) # Create bottom toolbar. if get_bottom_toolbar_tokens: toolbars = [ ConditionalContainer(VSplit([ Window(TokenListControl(get_url_tokens, default_char=Char( ' ', Token.Toolbar)), height=LayoutDimension.exact(1)), Window(TokenListControl(get_bottom_toolbar_tokens, default_char=Char( ' ', Token.Toolbar), align_right=True), height=LayoutDimension.exact(1)) ]), filter=~IsDone() & RendererHeightIsKnown()) ] else: toolbars = [] def get_height(cli): # If there is an autocompletion menu to be shown, make sure that our # layout has at least a minimal height in order to display it. if reserve_space_for_menu and not cli.is_done: buff = cli.current_buffer # Reserve the space, either when there are completions, or when # `complete_while_typing` is true and we expect completions very # soon. if buff.complete_while_typing( ) or buff.complete_state is not None: return LayoutDimension(min=reserve_space_for_menu) return LayoutDimension() # Create and return Container instance. return HSplit([ # The main input, with completion menus floating on top of it. FloatContainer( HSplit([ ConditionalContainer( Window(TokenListControl(get_prompt_tokens_1), dont_extend_height=True), Condition(has_before_tokens)), Window( BufferControl( input_processors=input_processors, lexer=lexer, # Enable preview_search, we want to have immediate feedback # in reverse-i-search mode. preview_search=True), get_height=get_height, left_margins=[ # In multiline mode, use the window margin to display # the prompt and continuation tokens. ConditionalMargin(PromptMargin( get_prompt_tokens_2, get_continuation_tokens), filter=multiline) ], wrap_lines=wrap_lines, ), ]), [ # Completion menus. Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=16, scroll_offset=1, extra_filter=HasFocus(DEFAULT_BUFFER) & ~display_completions_in_columns)), Float(xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( extra_filter=HasFocus(DEFAULT_BUFFER) & display_completions_in_columns, show_meta=True)), # The right prompt. Float(right=0, top=0, hide_when_covering_content=True, content=_RPrompt(get_rprompt_tokens)), ]), ValidationToolbar(), SystemToolbar(), # In multiline mode, we use two toolbars for 'arg' and 'search'. ConditionalContainer(ArgToolbar(), multiline), ConditionalContainer(SearchToolbar(), multiline), ] + toolbars)
def create_prompt_layout(self, message='', lexer=None, is_password=False, reserve_space_for_menu=8, get_prompt_tokens=None, get_bottom_toolbar_tokens=None, display_completions_in_columns=False, extra_input_processors=None, multiline=False, wrap_lines=True): """Create a Container instance for a prompt. Parameters ---------- message : Text to be used as prompt. lexer : ~prompt_toolkit.layout.lexers.Lexer to be used for the highlighting. is_password : bool or ~prompt_toolkit.filters.CLIFilter. When True, display input as '*'. reserve_space_for_menu : Space to be reserved for the menu. When >0, make sure that a minimal height is allocated in the terminal, in order to display the completion menu. get_prompt_tokens : An optional callable that returns the tokens to be shown in the menu. (To be used instead of a `message`.) get_bottom_toolbar_tokens : An optional callable that returns the tokens for a toolbar at the bottom. display_completions_in_columns : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. Display the completions in multiple columns. multiline : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. When True, prefer a layout that is more adapted for multiline input. Text after newlines is automatically indented, and search/arg input is shown below the input, instead of replacing the prompt. wrap_lines : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. When True (the default), automatically wrap long lines instead of scrolling horizontally. Notes ----- This method was forked from the mainline prompt-toolkit repo. Copyright (c) 2014, Jonathan Slenders, All rights reserved. WARNING; This method is due for removal once prompt-toolkit >v0.54 is released. """ assert isinstance(message, str) assert get_bottom_toolbar_tokens is None or callable( get_bottom_toolbar_tokens) assert get_prompt_tokens is None or callable(get_prompt_tokens) assert not (message and get_prompt_tokens) display_completions_in_columns = to_cli_filter( display_completions_in_columns) multiline = to_cli_filter(multiline) if get_prompt_tokens is None: get_prompt_tokens = lambda _: [(Token.Prompt, message)] get_prompt_tokens_1, get_prompt_tokens_2 = _split_multiline_prompt( get_prompt_tokens) # `lexer` is supposed to be a `Lexer` instance. But if a Pygments lexer # class is given, turn it into a PygmentsLexer. (Important for # backwards-compatibility.) try: if issubclass(lexer, pygments.lexer.Lexer): lexer = PygmentsLexer(lexer) except TypeError: # Happens when lexer is `None` or an instance of something else. pass # Create highlighters and processors list. if ConditionalHighlighter is None: highlighters = None highlighters_kwargs = {} else: highlighters = [ ConditionalHighlighter( # 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.) SearchHighlighter(preview_search=True), HasFocus(SEARCH_BUFFER)), SelectionHighlighter() ] highlighters_kwargs = {'highlighters': highlighters} input_processors = [ ConditionalProcessor(AppendAutoSuggestion(), HasFocus(DEFAULT_BUFFER) & ~IsDone()), ConditionalProcessor(PasswordProcessor(), is_password) ] if extra_input_processors: input_processors.extend(extra_input_processors) # Show the prompt before the input (using the DefaultPrompt processor. # This also replaces it with reverse-i-search and 'arg' when required. # (Only for single line mode.) # (DefaultPrompt should always be at the end of the processors.) input_processors.append( ConditionalProcessor(DefaultPrompt(get_prompt_tokens), ~multiline)) # Create bottom toolbar. if get_bottom_toolbar_tokens: toolbars = [ ConditionalContainer( Window(TokenListControl(get_bottom_toolbar_tokens, default_char=Char( ' ', Token.Toolbar)), height=LayoutDimension.exact(1)), filter=~IsDone() & RendererHeightIsKnown()) ] else: toolbars = [] def get_height(cli): # If there is an autocompletion menu to be shown, make sure that our # layout has at least a minimal height in order to display it. if reserve_space_for_menu and not cli.is_done: return LayoutDimension(min=reserve_space_for_menu) else: return LayoutDimension() # Create and return Container instance. return HSplit([ ConditionalContainer( Window(TokenListControl(get_prompt_tokens_1), dont_extend_height=True), filter=multiline, ), VSplit([ # In multiline mode, the prompt is displayed in a left pane. ConditionalContainer( Window( TokenListControl(get_prompt_tokens_2), dont_extend_width=True, ), filter=multiline, ), # The main input, with completion menus floating on top of it. FloatContainer( Window( BufferControl( input_processors=input_processors, lexer=lexer, wrap_lines=wrap_lines, # Enable preview_search, we want to have immediate feedback # in reverse-i-search mode. preview_search=True, **highlighters_kwargs), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=16, scroll_offset=1, extra_filter=HasFocus(DEFAULT_BUFFER) & ~display_completions_in_columns)), Float(xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( extra_filter=HasFocus(DEFAULT_BUFFER) & display_completions_in_columns, show_meta=True)) ]), ]), ValidationToolbar(), SystemToolbar(), # In multiline mode, we use two toolbars for 'arg' and 'search'. ConditionalContainer(ArgToolbar(), multiline), ConditionalContainer(SearchToolbar(), multiline), ] + toolbars)
styles = { Token.Placeholder: "#888888", Token.Placeholder.Variable: "#888888", Token.Placeholder.Bracket: "bold #ff7777", Token.Placeholder.Separator: "#ee7777", Token.Aborted: '#aaaaaa', Token.Menu.Completions.Completion.Current: 'bg:#00aaaa #000000', Token.Menu.Completions.Completion: 'bg:#008888 #ffffff', Token.Menu.Completions.ProgressButton: 'bg:#003333', Token.Menu.Completions.ProgressBar: 'bg:#00aaaa', } if __name__ == '__main__': cli = CommandLineInterface(layout=Layout( before_input=DefaultPrompt('Calculate: '), after_input=CompletionHint(grammar), menus=[CompletionsMenu()]), line=Line(completer=ShellCompleter(grammar)), style=ExampleStyle) try: # REPL loop. while True: # Read input and parse the result. try: document = cli.read_input(on_exit=AbortAction.RAISE_EXCEPTION) parse_info = get_parse_info(grammar, document) except InvalidCommandException: print('Invalid command\n') continue
def create_default_layout(app, message='', lexer=None, is_password=False, reserve_space_for_menu=False, get_prompt_tokens=None, get_bottom_toolbar_tokens=None, display_completions_in_columns=False, extra_input_processors=None, multiline=False): """ Generate default layout. Returns a ``Layout`` instance. :param message: Text to be used as prompt. :param lexer: Lexer to be used for the highlighting. :param is_password: `bool` or `CLIFilter`. When True, display input as '*'. :param reserve_space_for_menu: When True, make sure that a minimal height is allocated in the terminal, in order to display the completion menu. :param get_prompt_tokens: An optional callable that returns the tokens to be shown in the menu. (To be used instead of a `message`.) :param get_bottom_toolbar_tokens: An optional callable that returns the tokens for a toolbar at the bottom. :param display_completions_in_columns: `bool` or `CLIFilter`. Display the completions in multiple columns. :param multiline: `bool` or `CLIFilter`. When True, prefer a layout that is more adapted for multiline input. Text after newlines is automatically indented, and search/arg input is shown below the input, instead of replacing the prompt. """ assert isinstance(message, text_type) assert (get_bottom_toolbar_tokens is None or callable(get_bottom_toolbar_tokens)) assert get_prompt_tokens is None or callable(get_prompt_tokens) assert not (message and get_prompt_tokens) display_completions_in_columns = to_cli_filter( display_completions_in_columns) multiline = to_cli_filter(multiline) if get_prompt_tokens is None: get_prompt_tokens = lambda _: [(Token.Prompt, message)] get_prompt_tokens_1, get_prompt_tokens_2 = _split_multiline_prompt( get_prompt_tokens) # `lexer` is supposed to be a `Lexer` instance. But if a Pygments lexer # class is given, turn it into a PygmentsLexer. (Important for # backwards-compatibility.) try: if issubclass(lexer, Lexer): lexer = PygmentsLexer(lexer) except TypeError: # Happens when lexer is `None` or an instance of something else. pass # Create processors list. # (DefaultPrompt should always be at the end.) input_processors = [ ConditionalProcessor( # By default, only highlight search when the search # input has the focus. (Note that this doesn't mean # there is no search: the Vi 'n' binding for instance # still allows to jump to the next match in # navigation mode.) HighlightSearchProcessor(preview_search=Always()), HasFocus(SEARCH_BUFFER)), HighlightSelectionProcessor(), ConditionalProcessor(AppendAutoSuggestion(), HasFocus(DEFAULT_BUFFER) & ~IsDone()), ConditionalProcessor(PasswordProcessor(), is_password) ] if extra_input_processors: input_processors.extend(extra_input_processors) # Show the prompt before the input (using the DefaultPrompt processor. # This also replaces it with reverse-i-search and 'arg' when required. # (Only for single line mode.) input_processors.append( ConditionalProcessor(DefaultPrompt(get_prompt_tokens), ~multiline)) # Create bottom toolbar. if get_bottom_toolbar_tokens: toolbars = [ ConditionalContainer(Window(TokenListControl( get_bottom_toolbar_tokens, default_char=Char(' ', Token.Toolbar)), height=LayoutDimension.exact(1)), filter=~IsDone() & RendererHeightIsKnown()) ] else: toolbars = [] def get_height(cli): # If there is an autocompletion menu to be shown, make sure that our # layout has at least a minimal height in order to display it. if reserve_space_for_menu and not cli.is_done: return LayoutDimension(min=8) else: return LayoutDimension() def separator(): return ConditionalContainer(content=Window( height=LayoutDimension.exact(1), content=FillControl(u'\u2500', token=Token.Separator)), filter=HasDocumentation(app) & ~IsDone()) # Create and return Layout instance. return HSplit([ ConditionalContainer( Window(TokenListControl(get_prompt_tokens_1), dont_extend_height=True), filter=multiline, ), VSplit([ # In multiline mode, the prompt is displayed in a left pane. ConditionalContainer( Window( TokenListControl(get_prompt_tokens_2), dont_extend_width=True, ), filter=multiline, ), # The main input, with completion menus floating on top of it. FloatContainer( Window( BufferControl( input_processors=input_processors, lexer=lexer, # Enable preview_search, we want to have immediate # feedback in reverse-i-search mode. preview_search=Always(), focus_on_click=True, ), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=16, scroll_offset=1, extra_filter=(HasFocus(DEFAULT_BUFFER) & ~display_completions_in_columns ))), # noqa E501 Float(xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( extra_filter=(HasFocus(DEFAULT_BUFFER) & display_completions_in_columns), show_meta=Always())) ]), ]), separator(), ConditionalContainer( content=Window(BufferControl( focus_on_click=True, buffer_name=u'clidocs', ), height=LayoutDimension(max=15)), filter=HasDocumentation(app) & ~IsDone(), ), separator(), ValidationToolbar(), SystemToolbar(), # In multiline mode, we use two toolbars for 'arg' and 'search'. ConditionalContainer(ArgToolbar(), multiline), ConditionalContainer(SearchToolbar(), multiline), ] + toolbars)
class StatusToolbar(Toolbar): """ Status toolbar showing the current location. """ def __init__(self): super(StatusToolbar, self).__init__(Token.StatusBar) def get_tokens(self, cli, width): return [(self.token, ' '), (self.token, os.getcwd())] if __name__ == '__main__': cli = CommandLineInterface( layout=Layout( before_input=DefaultPrompt('Shell> '), #after_input=CompletionHint(grammar), menus=[CompletionsMenu()], bottom_toolbars=[StatusToolbar()]), line=Line(completer=ShellCompleter(grammar)), style=ExampleStyle) try: while True: try: document = cli.read_input(on_exit=AbortAction.RAISE_EXCEPTION) parse_info = get_parse_info(grammar, document) except InvalidCommandException: os.system(document.text) continue else:
def create_default_layout(message='', lexer=None, is_password=False, reserve_space_for_menu=False, get_prompt_tokens=None, get_bottom_toolbar_tokens=None, extra_input_processors=None): """ Generate default layout. Returns a ``Layout`` instance. :param message: Text to be used as prompt. :param lexer: Pygments lexer to be used for the highlighting. :param is_password: When True, display input as '*'. :param reserve_space_for_menu: When True, make sure that a minimal height is allocated in the terminal, in order to display the completion menu. :param get_prompt_tokens: An optional callable that returns the tokens to be shown in the menu. (To be used instead of a `message`.) :param get_bottom_toolbar_tokens: An optional callable that returns the tokens for a toolbar at the bottom. """ assert isinstance(message, text_type) assert get_bottom_toolbar_tokens is None or callable(get_bottom_toolbar_tokens) assert get_prompt_tokens is None or callable(get_prompt_tokens) assert not (message and get_prompt_tokens) # Create processors list. # (DefaultPrompt should always be at the end.) input_processors = [HighlightSearchProcessor(preview_search=Always()), HighlightSelectionProcessor()] if is_password: input_processors.append(PasswordProcessor()) if extra_input_processors: input_processors.extend(extra_input_processors) if get_prompt_tokens is None: input_processors.append(DefaultPrompt.from_message(message)) else: input_processors.append(DefaultPrompt(get_prompt_tokens)) # Create bottom toolbar. if get_bottom_toolbar_tokens: toolbars = [Window(TokenListControl(get_bottom_toolbar_tokens, default_char=Char(' ', Token.Toolbar)), height=LayoutDimension.exact(1), filter=~IsDone() & RendererHeightIsKnown())] else: toolbars = [] def get_height(cli): # If there is an autocompletion menu to be shown, make sure that our # layout has at least a minimal height in order to display it. if reserve_space_for_menu and not cli.is_done: return LayoutDimension(min=8) else: return LayoutDimension() # Create and return Layout instance. return HSplit([ FloatContainer( Window( BufferControl( input_processors=input_processors, lexer=lexer, # Enable preview_search, we want to have immediate feedback # in reverse-i-search mode. preview_search=Always()), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, extra_filter=HasFocus(DEFAULT_BUFFER))) ] ), ValidationToolbar(), SystemToolbar(), ] + toolbars)
def CreatePromptLayout(message='', lexer=None, is_password=False, reserve_space_for_menu=5, get_prompt_tokens=None, get_continuation_tokens=None, get_bottom_toolbar_tokens=None, display_completions_in_columns=False, extra_input_processors=None, multiline=False, wrap_lines=True, get_help_tokens=None, show_help=True): """Create a container instance for the prompt.""" assert isinstance(message, unicode), 'Please provide a unicode string.' assert get_bottom_toolbar_tokens is None or callable( get_bottom_toolbar_tokens) assert get_prompt_tokens is None or callable(get_prompt_tokens) assert not (message and get_prompt_tokens) display_completions_in_columns = filters.to_cli_filter( display_completions_in_columns) multiline = filters.to_cli_filter(multiline) if get_prompt_tokens is None: get_prompt_tokens = lambda _: [(Token.Prompt, message)] has_before_tokens, get_prompt_tokens_1, get_prompt_tokens_2 = ( shortcuts._split_multiline_prompt(get_prompt_tokens)) # pylint: disable=protected-access # TODO(b/35347840): reimplement _split_multiline_prompt to remove # protected-access. # Create processors list. input_processors = [ processors.ConditionalProcessor( # By default, only highlight search when the search # input has the focus. (Note that this doesn't mean # there is no search: the Vi 'n' binding for instance # still allows to jump to the next match in # navigation mode.) processors.HighlightSearchProcessor(preview_search=True), filters.HasFocus(enums.SEARCH_BUFFER)), processors.HighlightSelectionProcessor(), processors.ConditionalProcessor(processors.AppendAutoSuggestion(), filters.HasFocus(enums.DEFAULT_BUFFER) & ~filters.IsDone()), processors.ConditionalProcessor(processors.PasswordProcessor(), is_password), ] if extra_input_processors: input_processors.extend(extra_input_processors) # Show the prompt before the input (using the DefaultPrompt processor. # This also replaces it with reverse-i-search and 'arg' when required. # (Only for single line mode.) # (DefaultPrompt should always be at the end of the processors.) input_processors.append( processors.ConditionalProcessor( DefaultPrompt(get_prompt_tokens_2), ~multiline)) # Create toolbars toolbars = [] if get_help_tokens: toolbars.append( containers.ConditionalContainer( layout.HSplit([ layout.Window( controls.FillControl(char=Char('-', Token.HSep)), height=LayoutDimension.exact(1)), layout.Window( controls.TokenListControl( get_help_tokens, default_char=Char(' ', Token.Toolbar)), height=LayoutDimension(preferred=10, max=10)), ]), filter=(show_help & UserTypingFilter & ~filters.IsDone() & filters.RendererHeightIsKnown()))) if get_bottom_toolbar_tokens: toolbars.append( containers.ConditionalContainer( layout.HSplit([ layout.Window( controls.FillControl(char=Char('-', Token.HSep)), height=LayoutDimension.exact(1)), layout.Window( controls.TokenListControl( get_bottom_toolbar_tokens, default_char=Char(' ', Token.Toolbar)), height=LayoutDimension.exact(1)), ]), filter=~filters.IsDone() & filters.RendererHeightIsKnown())) def GetHeight(cli): """Determine the height for the input buffer.""" # If there is an autocompletion menu to be shown, make sure that our # layout has at least a minimal height in order to display it. if reserve_space_for_menu and not cli.is_done: buff = cli.current_buffer # Reserve the space, either when there are completions, or when # `complete_while_typing` is true and we expect completions very # soon. if UserTypingFilter(cli) or buff.complete_state is not None: return LayoutDimension(min=reserve_space_for_menu) return LayoutDimension() # Create and return Container instance. return layout.HSplit([ # The main input, with completion menus floating on top of it. containers.FloatContainer( layout.HSplit([ containers.ConditionalContainer( layout.Window( controls.TokenListControl(get_prompt_tokens_1), dont_extend_height=True), filters.Condition(has_before_tokens)), layout.Window( controls.BufferControl( input_processors=input_processors, lexer=lexer, # Enable preview_search, we want to have immediate # feedback in reverse-i-search mode. preview_search=True), get_height=GetHeight, left_margins=[ # In multiline mode, use the window margin to display # the prompt and continuation tokens. margins.ConditionalMargin( margins.PromptMargin(get_prompt_tokens_2, get_continuation_tokens), filter=multiline) ], wrap_lines=wrap_lines,), ]), [ # Completion menus. layout.Float( xcursor=True, ycursor=True, content=menus.CompletionsMenu( max_height=16, scroll_offset=1, extra_filter=filters.HasFocus(enums.DEFAULT_BUFFER) & ~display_completions_in_columns)), layout.Float( xcursor=True, ycursor=True, content=menus.MultiColumnCompletionsMenu( extra_filter=filters.HasFocus(enums.DEFAULT_BUFFER) & display_completions_in_columns, show_meta=True)), ]), pt_toolbars.ValidationToolbar(), pt_toolbars.SystemToolbar(), # In multiline mode, we use two toolbars for 'arg' and 'search'. containers.ConditionalContainer(pt_toolbars.ArgToolbar(), multiline), containers.ConditionalContainer(pt_toolbars.SearchToolbar(), multiline), ] + toolbars)
def create_default_layout(message='', lexer=None, is_password=False, reserve_space_for_menu=False, get_prompt_tokens=None, get_bottom_toolbar_tokens=None, extra_input_processors=None): """ Generate default layout. Returns a ``Layout`` instance. :param message: Text to be used as prompt. :param lexer: Pygments lexer to be used for the highlighting. :param is_password: When True, display input as '*'. :param reserve_space_for_menu: When True, make sure that a minimal height is allocated in the terminal, in order to display the completion menu. :param get_prompt_tokens: An optional callable that returns the tokens to be shown in the menu. (To be used instead of a `message`.) :param get_bottom_toolbar_tokens: An optional callable that returns the tokens for a toolbar at the bottom. """ assert isinstance(message, text_type) assert get_bottom_toolbar_tokens is None or callable( get_bottom_toolbar_tokens) assert get_prompt_tokens is None or callable(get_prompt_tokens) assert not (message and get_prompt_tokens) # Create processors list. # (DefaultPrompt should always be at the end.) input_processors = [ HighlightSearchProcessor(preview_search=Always()), HighlightSelectionProcessor() ] if is_password: input_processors.append(PasswordProcessor()) if extra_input_processors: input_processors.extend(extra_input_processors) if message: input_processors.append(DefaultPrompt.from_message(message)) else: input_processors.append(DefaultPrompt(get_prompt_tokens)) # Create bottom toolbar. if get_bottom_toolbar_tokens: toolbars = [ Window(TokenListControl(get_bottom_toolbar_tokens, default_char=Char(' ', Token.Toolbar)), height=LayoutDimension.exact(1), filter=~IsDone() & RendererHeightIsKnown()) ] else: toolbars = [] def get_height(cli): # If there is an autocompletion menu to be shown, make sure that our # layout has at least a minimal height in order to display it. if reserve_space_for_menu and not cli.is_done: return LayoutDimension(min=8) else: return LayoutDimension() # Create and return Layout instance. return HSplit([ FloatContainer( Window( BufferControl( input_processors=input_processors, lexer=lexer, # Enable preview_search, we want to have immediate feedback # in reverse-i-search mode. preview_search=Always()), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, extra_filter=HasFocus( DEFAULT_BUFFER))) ]), ValidationToolbar(), SystemToolbar(), ] + toolbars)
def main(): cli = CommandLineInterface(layout=Layout( before_input=DefaultPrompt('Enter HTML: '), lexer=HtmlLexer)) html_code_obj = cli.read_input() print('You said: ' + html_code_obj.text)
""" Simple example of the layout options. """ from __future__ import unicode_literals from prompt_toolkit import CommandLineInterface from prompt_toolkit.layout import Layout from prompt_toolkit.layout.prompt import DefaultPrompt from prompt_toolkit.layout.toolbars import ValidationToolbar from prompt_toolkit.validation import Validator, ValidationError from prompt_toolkit.line import Line from pygments.token import Token from pygments.style import Style layout = Layout(before_input=DefaultPrompt(text='Give an e-mail address: '), bottom_toolbars=[ValidationToolbar()]) class EmailValidator(Validator): def validate(self, document): if not '@' in document.text: raise ValidationError(message='Not a valid e-mail address') class TestLine(Line): is_multiline = True class TestStyle(Style): styles = {
def cli(database, user, password, host, port): if password: passwd = click.prompt('Password', hide_input=True, show_default=False, type=str) else: passwd = '' from pgcli import __file__ as package_root package_root = os.path.dirname(package_root) default_config = os.path.join(package_root, 'pgclirc') write_default_config(default_config, '~/.pgclirc') # Load config. config = load_config('~/.pgclirc', default_config) smart_completion = config.getboolean('main', 'smart_completion') multi_line = config.getboolean('main', 'multi_line') log_file = config.get('main', 'log_file') log_level = config.get('main', 'log_level') initialize_logging(log_file, log_level) original_less_opts = adjust_less_opts() _logger.debug('Launch Params: \n' '\tdatabase: %r' '\tuser: %r' '\tpassword: %r' '\thost: %r' '\tport: %r', database, user, passwd, host, port) # Connect to the database. try: pgexecute = PGExecute(database, user, passwd, host, port) except Exception as e: # Connecting to a database could fail. _logger.debug('Database connection failed: %r.', e.message) click.secho(e.message, err=True, fg='red') exit(1) layout = Layout(before_input=DefaultPrompt('%s> ' % pgexecute.dbname), menus=[CompletionsMenu(max_height=10)], lexer=SqlLexer, bottom_toolbars=[ PGToolbar()]) completer = PGCompleter(smart_completion) completer.extend_special_commands(CASE_SENSITIVE_COMMANDS.keys()) completer.extend_special_commands(NON_CASE_SENSITIVE_COMMANDS.keys()) refresh_completions(pgexecute, completer) line = PGLine(always_multiline=multi_line, completer=completer, history=FileHistory(os.path.expanduser('~/.pgcli-history'))) cli = CommandLineInterface(style=PGStyle, layout=layout, line=line, key_binding_factories=[emacs_bindings, pgcli_bindings]) try: while True: cli.layout.before_input = DefaultPrompt('%s> ' % pgexecute.dbname) document = cli.read_input(on_exit=AbortAction.RAISE_EXCEPTION) # The reason we check here instead of inside the pgexecute is # because we want to raise the Exit exception which will be caught # by the try/except block that wraps the pgexecute.run() statement. if quit_command(document.text): raise Exit try: _logger.debug('sql: %r', document.text) res = pgexecute.run(document.text) output = [] for rows, headers, status in res: _logger.debug("headers: %r", headers) _logger.debug("rows: %r", rows) if rows: output.append(tabulate(rows, headers, tablefmt='psql')) if status: # Only print the status if it's not None. output.append(status) _logger.debug("status: %r", status) click.echo_via_pager('\n'.join(output)) except Exception as e: _logger.debug("sql: %r, error: %r", document.text, e.message) click.secho(e.message, err=True, fg='red') # Refresh the table names and column names if necessary. if need_completion_refresh(document.text): completer.reset_completions() refresh_completions(pgexecute, completer) except Exit: print ('GoodBye!') finally: # Reset the less opts back to original. _logger.debug('Restoring env var LESS to %r.', original_less_opts) os.environ['LESS'] = original_less_opts