def __init__(self, *a, **kw): vi_mode = kw.pop('vi_mode', False) history_filename = kw.pop('history_filename', None) configure = kw.pop('configure', None) title = kw.pop('title', None) super(InteractiveShellEmbed, self).__init__(*a, **kw) def get_globals(): return self.user_ns self._eventloop = create_eventloop() ipython_input = IPythonInput( self, get_globals=get_globals, vi_mode=vi_mode, history_filename=history_filename) if title: ipython_input.terminal_title = title if configure: configure(ipython_input) self._cli = CommandLineInterface( application=ipython_input.create_application(), eventloop=self._eventloop)
def main(): eventloop = create_eventloop() done = [False] # Non local def on_read_start(cli): """ This function is called when we start reading at the input. (Actually the start of the read-input event loop.) """ # Following function should be run in the background. # We do it by using an executor thread from the `CommandLineInterface` # instance. def run(): # Send every second a redraw request. while not done[0]: time.sleep(1) cli.request_redraw() cli.eventloop.run_in_executor(run) def on_read_end(cli): done[0] = True app = Application( layout=Window(BufferControl(input_processors=[ClockPrompt()])), on_start=Callback(on_read_start), on_stop=Callback(on_read_end)) cli = CommandLineInterface(application=app, eventloop=eventloop) code_obj = cli.run() print('You said: %s' % code_obj.text) eventloop.close()
def get_user_input(get_prompt_tokens, history=None, lexer=None, key_bindings_registry=None, completer=None): """Customized function that mostly mimics promp_toolkit's get_input. Main difference between this and prompt_toolkit's get_input() is that it allows to pass get_tokens() function instead of text prompt. """ eventloop = create_eventloop() cli = create_cli( eventloop, lexer=lexer, completer=completer, history=history, get_prompt_tokens=get_prompt_tokens, key_bindings_registry=key_bindings_registry) try: document = cli.read_input() if document: return document.text finally: eventloop.close()
def _create_cli(self): """Create the prompt_toolkit's CommandLineInterface.""" history = FileHistory(os.path.expanduser('~/.haxornewshistory')) toolbar = Toolbar(lambda: self.paginate_comments) layout = create_default_layout( message=u'haxor> ', reserve_space_for_menu=True, get_bottom_toolbar_tokens=toolbar.handler, ) cli_buffer = Buffer( history=history, auto_suggest=AutoSuggestFromHistory(), enable_history_search=True, completer=self.completer, complete_while_typing=Always(), accept_action=AcceptAction.RETURN_DOCUMENT) self.key_manager = self._create_key_manager() style_factory = StyleFactory(self.theme) application = Application( mouse_support=False, style=style_factory.style, layout=layout, buffer=cli_buffer, key_bindings_registry=self.key_manager.manager.registry, on_exit=AbortAction.RAISE_EXCEPTION, on_abort=AbortAction.RETRY, ignore_case=True) eventloop = create_eventloop() self.cli = CommandLineInterface( application=application, eventloop=eventloop)
def create_cli_interface(self, display_completions_in_columns): # A CommandLineInterface from prompt_toolkit # accepts two things: an application and an # event loop. loop = create_eventloop() app = self.create_application(self.completer, self.file_history, display_completions_in_columns) cli = CommandLineInterface(application=app, eventloop=loop) return cli
def eventloop(): # Allow to keep gevent greenlets running # while waiting for some input on the cli def inputhook(context): while not context.input_is_ready(): gevent.sleep(0.1) return create_eventloop(inputhook=inputhook)
def __init__(self, config_directory='~/.pyvim'): # Vi options. self.show_line_numbers = True self.highlight_search = True self.paste_mode = False self.show_ruler = True self.show_wildmenu = True self.expand_tab = True # Insect spaces instead of tab characters. self.tabstop = 4 # Number of spaces that a tab character represents. self.incsearch = True # Show matches while typing search string. self.ignore_case = False # Ignore case while searching. self.display_unprintable_characters = True # ':set list' self.enable_jedi = True # ':set jedi', for Python Jedi completion. self.scroll_offset = 0 # ':set scrolloff' # Ensure config directory exists. self.config_directory = os.path.abspath(os.path.expanduser(config_directory)) if not os.path.exists(self.config_directory): os.mkdir(self.config_directory) self._reporters_running_for_buffer_names = set() self.window_arrangement = WindowArrangement(self) self.message = None # Load styles. (Mapping from name to Style class.) self.styles = generate_built_in_styles() self.current_style = get_editor_style_by_name('default') # I/O backends. self.io_backends = [ DirectoryIO(), HttpIO(), GZipFileIO(), # Should come before FileIO. FileIO(), ] # Create eventloop. self.eventloop = create_eventloop() # Create key bindings manager self.key_bindings_manager = create_key_bindings(self) # Create layout and CommandLineInterface instance. self.editor_layout = EditorLayout( self, self.key_bindings_manager, self.window_arrangement) self.application = self._create_application() self.cli = CommandLineInterface( eventloop=self.eventloop, application=self.application) # Hide message when a key is pressed. def key_pressed(): self.message = None self.cli.input_processor.beforeKeyPress += key_pressed # Command line previewer. self.previewer = CommandPreviewer(self)
def run(app): eventloop = shortcuts.create_eventloop() try: cli = interface.CommandLineInterface(application=app, eventloop=eventloop) cli.run(reset_current_buffer=False) finally: eventloop.close()
def main(): eventloop = create_eventloop() try: cli = PythonCommandLineInterface(eventloop) code_obj = cli.run() print('You said: ' + code_obj.text) finally: eventloop.close()
def run(self): neo4j = Neo4j(self.host, self.port, self.username, self.password) try: labels = neo4j.labels() relationship_types = neo4j.relationship_types() properties = neo4j.properties() except Unauthorized: print("Unauthorized. See cycli --help for authorization instructions.") return except SocketError: print("Connection refused. Is Neo4j turned on?") return completer = CypherCompleter(labels, relationship_types, properties) layout = create_default_layout( lexer=CypherLexer, get_prompt_tokens=get_tokens, reserve_space_for_menu=True ) buff = CypherBuffer( history=History(), completer=completer, complete_while_typing=Always() ) application = Application( style=CypherStyle, buffer=buff, layout=layout, on_exit=AbortAction.RAISE_EXCEPTION ) cli = CommandLineInterface(application=application, eventloop=create_eventloop()) try: while True: document = cli.run() query = document.text if query in ["quit", "exit"]: raise Exception elif query == "help": print(help_text()) else: results = neo4j.cypher(query) print(results) except Exception: print("Goodbye!")
def init_prompt_toolkit_cli(self): if self.simple_prompt: # Fall back to plain non-interactive output for tests. # This is very limited, and only accepts a single line. def prompt(): isp = self.input_splitter prompt_text = "".join(x[1] for x in self.prompts.in_prompt_tokens()) prompt_continuation = "".join(x[1] for x in self.prompts.continuation_prompt_tokens()) while isp.push_accepts_more(): line = cast_unicode_py2(input(prompt_text)) isp.push(line) prompt_text = prompt_continuation return isp.source_reset() self.prompt_for_code = prompt return # Set up keyboard shortcuts kbmanager = KeyBindingManager.for_prompt( enable_open_in_editor=self.extra_open_editor_shortcuts, ) register_ipython_shortcuts(kbmanager.registry, self) # Pre-populate history from IPython's history database history = InMemoryHistory() last_cell = u"" for __, ___, cell in self.history_manager.get_tail(self.history_load_length, include_latest=True): # Ignore blank lines and consecutive duplicates cell = cell.rstrip() if cell and (cell != last_cell): history.append(cell) last_cell = cell self._style = self._make_style_from_name_or_cls(self.highlighting_style) self.style = DynamicStyle(lambda: self._style) editing_mode = getattr(EditingMode, self.editing_mode.upper()) def patch_stdout(**kwargs): return self.pt_cli.patch_stdout_context(**kwargs) self._pt_app = create_prompt_application( editing_mode=editing_mode, key_bindings_registry=kbmanager.registry, history=history, completer=IPythonPTCompleter(shell=self, patch_stdout=patch_stdout), enable_history_search=True, style=self.style, mouse_support=self.mouse_support, **self._layout_options() ) self._eventloop = create_eventloop(self.inputhook) self.pt_cli = CommandLineInterface( self._pt_app, eventloop=self._eventloop, output=create_output(true_color=self.true_color))
def __init__(self, conn_args): self.connection = None self.eventloop = pt_shortcuts.create_eventloop() self.aioloop = None self.cli = None self.conn_args = conn_args self.cur_db = None self.graphql = False self.commands = type(self)._command.__kwdefaults__['_all_commands']
def create_cli(self): """Creates the prompt_toolkit's CommandLineInterface. Long description. Args: * None. Returns: None. """ history = FileHistory(os.path.expanduser('~/.saws-history')) toolbar = Toolbar(self.get_color, self.get_fuzzy_match, self.get_shortcut_match) layout = create_default_layout( message='saws> ', reserve_space_for_menu=True, lexer=CommandLexer, get_bottom_toolbar_tokens=toolbar.handler, extra_input_processors=[ ConditionalProcessor( processor=HighlightMatchingBracketProcessor( chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()) ] ) cli_buffer = Buffer( history=history, completer=self.completer, complete_while_typing=Always(), accept_action=AcceptAction.RETURN_DOCUMENT) self.key_manager = KeyManager( self.set_color, self.get_color, self.set_fuzzy_match, self.get_fuzzy_match, self.set_shortcut_match, self.get_shortcut_match, self.refresh_resources, self.handle_docs) style_factory = StyleFactory(self.theme) application = Application( mouse_support=False, style=style_factory.style, layout=layout, buffer=cli_buffer, key_bindings_registry=self.key_manager.manager.registry, on_exit=AbortAction.RAISE_EXCEPTION, on_abort=AbortAction.RETRY, ignore_case=True) eventloop = create_eventloop() self.aws_cli = CommandLineInterface( application=application, eventloop=eventloop)
def loop(cmd, history_file): key_binding_manager = KeyBindingManager( enable_search=True, enable_abort_and_exit_bindings=True ) layout = create_prompt_layout( message=u'cr> ', multiline=True, lexer=SqlLexer, extra_input_processors=[ ConditionalProcessor( processor=HighlightMatchingBracketProcessor(chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()) ] ) buffer = CrashBuffer( history=TruncatedFileHistory(history_file, max_length=MAX_HISTORY_LENGTH), accept_action=AcceptAction.RETURN_DOCUMENT, completer=SQLCompleter(cmd) ) buffer.complete_while_typing = lambda cli=None: cmd.should_autocomplete() application = Application( layout=layout, buffer=buffer, style=PygmentsStyle.from_defaults(pygments_style_cls=CrateStyle), key_bindings_registry=key_binding_manager.registry, editing_mode=_get_editing_mode(), on_exit=AbortAction.RAISE_EXCEPTION, on_abort=AbortAction.RETRY, ) eventloop = create_eventloop() output = create_output() cli = CommandLineInterface( application=application, eventloop=eventloop, output=output ) def get_num_columns_override(): return output.get_size().columns cmd.get_num_columns = get_num_columns_override while True: try: doc = cli.run(reset_current_buffer=True) if doc: cmd.process(doc.text) except KeyboardInterrupt: cmd.logger.warn("Query not cancelled. Run KILL <jobId> to cancel it") except EOFError: cmd.logger.warn(u'Bye!') return
def __init__(self, force_passwd_prompt=False, never_passwd_prompt=False, pgexecute=None, pgclirc_file=None, row_limit=None): self.force_passwd_prompt = force_passwd_prompt self.never_passwd_prompt = never_passwd_prompt self.pgexecute = pgexecute # Load config. c = self.config = get_config(pgclirc_file) self.logger = logging.getLogger(__name__) self.initialize_logging() self.set_default_pager(c) self.output_file = None self.pgspecial = PGSpecial() self.multi_line = c['main'].as_bool('multi_line') self.vi_mode = c['main'].as_bool('vi') self.pgspecial.timing_enabled = c['main'].as_bool('timing') if row_limit is not None: self.row_limit = row_limit else: self.row_limit = c['main'].as_int('row_limit') self.table_format = c['main']['table_format'] self.syntax_style = c['main']['syntax_style'] self.cli_style = c['colors'] self.wider_completion_menu = c['main'].as_bool('wider_completion_menu') self.less_chatty = c['main'].as_bool('less_chatty') self.null_string = c['main'].get('null_string', '<null>') self.prompt_format = c['main'].get('prompt', self.default_prompt) self.on_error = c['main']['on_error'].upper() self.completion_refresher = CompletionRefresher() self.query_history = [] # Initialize completer smart_completion = c['main'].as_bool('smart_completion') self.settings = {'casing_file': get_casing_file(c), 'generate_casing_file': c['main'].as_bool('generate_casing_file'), 'generate_aliases': c['main'].as_bool('generate_aliases'), 'asterisk_column_order': c['main']['asterisk_column_order']} completer = PGCompleter(smart_completion, pgspecial=self.pgspecial, settings=self.settings) self.completer = completer self._completer_lock = threading.Lock() self.register_special_commands() self.eventloop = create_eventloop() self.cli = None
def __init__(self): pdb.Pdb.__init__(self) # Cache for the grammar. self._grammar_cache = None # (current_pdb_commands, grammar) tuple. self._cli_history = FileHistory(os.path.expanduser('~/.ptpdb_history')) self.completer = None self.validator = None self.python_input = PythonInput( get_locals=lambda: self.curframe.f_locals, get_globals=lambda: self.curframe.f_globals, _completer=DynamicCompleter(lambda: self.completer), _validator=DynamicValidator(lambda: self.validator), _python_prompt_control=PdbLeftMargin(self._get_current_pdb_commands()), _extra_buffers={'source_code': Buffer()}, _extra_buffer_processors=[CompletionHint()], _extra_sidebars=[ HSplit([ FileLocationToolbar(weakref.ref(self)), ConditionalContainer( Window( BufferControl( buffer_name='source_code', lexer=PythonLexer, ), ), filter=~IsDone()), PdbShortcutsToolbar(weakref.ref(self)), ]), ], ) # Set UI styles. self.python_input.ui_styles = { 'ptpdb': get_ui_style(), } self.python_input.use_ui_colorscheme('ptpdb') # Set autocompletion style. (Multi-column works nicer.) self.python_input.completion_visualisation = CompletionVisualisation.MULTI_COLUMN self.python_input.complete_while_typing = False # Load additional key bindings. load_custom_pdb_key_bindings(self.python_input.key_bindings_registry) self.cli = CommandLineInterface( eventloop=create_eventloop(), application=self.python_input.create_application())
def __init__(self): pdb.Pdb.__init__(self) # Cache for the grammar. self._grammar_cache = None # (current_pdb_commands, grammar) tuple. self._cli_history = FileHistory(os.path.expanduser('~/.ptpdb_history')) self.python_cli_settings = PythonCLISettings() self.completer = None self.validator = None # def is_multiline(document): # if (self.python_cli_settings.paste_mode or # self.python_cli_settings.currently_multiline): # return True # match = g.match_prefix(document.text) # if match: # for v in match.variables().getall('python_code'): # if document_is_multiline_python(Document(v)): # return True # return False self.cli = PythonCommandLineInterface( eventloop=create_eventloop(), style=PdbStyle, get_locals=lambda: self.curframe.f_locals, get_globals=lambda: self.curframe.f_globals, _completer=DynamicCompleter(lambda: self.completer), _validator=DynamicValidator(lambda: self.validator), _python_prompt_control=PdbLeftMargin(self.python_cli_settings, self._get_current_pdb_commands()), _extra_buffers={'source_code': Buffer()}, _extra_buffer_processors=[CompletionHint()], _extra_sidebars=[ HSplit([ FileLocationToolbar(weakref.ref(self)), Window( BufferControl( buffer_name='source_code', lexer=PythonLexer, ), filter=~IsDone(), ), PdbShortcutsToolbar(weakref.ref(self)), ]), ], )
def _build_cli(self): def set_vi_mode(value): self.vi_mode = value key_binding_manager = pgcli_bindings( get_vi_mode_enabled=lambda: self.vi_mode, set_vi_mode_enabled=set_vi_mode) def prompt_tokens(_): return [(Token.Prompt, '%s> ' % self.pgexecute.dbname)] get_toolbar_tokens = create_toolbar_tokens_func( lambda: self.vi_mode, self.completion_refresher.is_refreshing) layout = create_default_layout( lexer=PostgresLexer, reserve_space_for_menu=True, get_prompt_tokens=prompt_tokens, get_bottom_toolbar_tokens=get_toolbar_tokens, display_completions_in_columns=self.wider_completion_menu, multiline=True, extra_input_processors=[ # Highlight matching brackets while editing. ConditionalProcessor( processor=HighlightMatchingBracketProcessor(chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()), ]) history_file = self.config['main']['history_file'] with self._completer_lock: buf = PGBuffer( always_multiline=self.multi_line, completer=self.completer, history=FileHistory(os.path.expanduser(history_file)), complete_while_typing=Always()) application = Application( style=style_factory(self.syntax_style, self.cli_style), layout=layout, buffer=buf, key_bindings_registry=key_binding_manager.registry, on_exit=AbortAction.RAISE_EXCEPTION, ignore_case=True) cli = CommandLineInterface( application=application, eventloop=create_eventloop()) return cli
def __init__(self, force_passwd_prompt=False, never_passwd_prompt=False, pgexecute=None, pgclirc_file=None): self.force_passwd_prompt = force_passwd_prompt self.never_passwd_prompt = never_passwd_prompt self.pgexecute = pgexecute from pgcli import __file__ as package_root package_root = os.path.dirname(package_root) pgclirc_file = pgclirc_file or '%sconfig' % config_location() default_config = os.path.join(package_root, 'pgclirc') write_default_config(default_config, pgclirc_file) # Load config. c = self.config = load_config(pgclirc_file, default_config) self.logger = logging.getLogger(__name__) self.initialize_logging() self.set_default_pager(c) self.output_file = None self.pgspecial = PGSpecial() self.multi_line = c['main'].as_bool('multi_line') self.vi_mode = c['main'].as_bool('vi') self.pgspecial.timing_enabled = c['main'].as_bool('timing') self.table_format = c['main']['table_format'] self.syntax_style = c['main']['syntax_style'] self.cli_style = c['colors'] self.wider_completion_menu = c['main'].as_bool('wider_completion_menu') self.on_error = c['main']['on_error'].upper() self.completion_refresher = CompletionRefresher() self.query_history = [] # Initialize completer smart_completion = c['main'].as_bool('smart_completion') completer = PGCompleter(smart_completion, pgspecial=self.pgspecial) self.completer = completer self._completer_lock = threading.Lock() self.register_special_commands() self.eventloop = create_eventloop() self.cli = None
def __init__(self, *a, **kw): vi_mode = kw.pop('vi_mode', False) history_filename = kw.pop('history_filename', None) super(InteractiveShellEmbed, self).__init__(*a, **kw) def get_globals(): return self.user_ns self._eventloop = create_eventloop() self._cli = IPythonCommandLineInterface( self, eventloop=self._eventloop, get_globals=get_globals, vi_mode=vi_mode, history_filename=history_filename)
def main(): # Create user interface. hello_world_window() # Enable threading in GTK. (Otherwise, GTK will keep the GIL.) gtk.gdk.threads_init() # Read input from the command line, using an event loop with this hook. # We say `patch_stdout=True`, because clicking the button will print # something; and that should print nicely 'above' the input line. result = prompt('Python >>> ', eventloop=create_eventloop(inputhook=inputhook), lexer=PythonLexer, patch_stdout=True) print('You said: %s' % result)
def main(): hy_repl = HyREPL() eventloop = create_eventloop() validator = HyValidator() history = FileHistory(expanduser("~/.pthy_history")) def src_is_multiline(): if app and app.buffer: text = app.buffer.document.text if '\n' in text: return True return False app = create_default_application("λ: ", validator=validator, multiline=Condition(src_is_multiline), lexer=HyLexer, style=HyStyle, history=history, completer=HyCompleter(hy_repl), display_completions_in_columns=True, extra_input_processors=[ ConditionalProcessor( processor=HighlightMatchingBracketProcessor(), filter=~IsDone()) ]) # Somewhat ugly trick to add a margin to the multiline input # without needing to define a custom layout app.layout.children[0].children[1].content.content.margin = ConditionalMargin( NumberredMargin(), filter=IsMultiline()) cli = CommandLineInterface(application=app, eventloop=eventloop) load_modified_bindings(app.key_bindings_registry) hy_repl.cli = cli try: while True: try: code_obj = cli.run() hy_repl.evaluate(code_obj.text) except KeyboardInterrupt: pass except EOFError: pass finally: eventloop.close()
def __init__(self, parser, engine, options=None): self.parser = parser self.engine = engine self.options = options if options is not None else {} util.ensure_data_dir_exists() application = create_prompt_application( message='> ', lexer=PygmentsLexer(SqlLexer), history=FileHistory(os.path.expanduser('~/.aq/history')), completer=AqCompleter(schemas=engine.available_schemas, tables=engine.available_tables), auto_suggest=AutoSuggestFromHistory(), validator=QueryValidator(parser), on_abort=AbortAction.RETRY, ) loop = create_eventloop() self.cli = CommandLineInterface(application=application, eventloop=loop) self.patch_context = self.cli.patch_stdout_context()
def embed(globals=None, locals=None, vi_mode=False, history_filename=None, no_colors=False, startup_paths=None, patch_stdout=False, return_asyncio_coroutine=False): """ Call this to embed Python shell at the current point in your program. It's similar to `IPython.embed` and `bpython.embed`. :: from prompt_toolkit.contrib.repl import embed embed(globals(), locals(), vi_mode=False) :param vi_mode: Boolean. Use Vi instead of Emacs key bindings. """ globals = globals or {} locals = locals or globals def get_globals(): return globals def get_locals(): return locals # Create eventloop. if return_asyncio_coroutine: eventloop = create_asyncio_eventloop() else: eventloop = create_eventloop() # Create REPL. repl = PythonRepl(eventloop, get_globals, get_locals, vi_mode=vi_mode, history_filename=history_filename, style=(None if no_colors else PythonStyle)) # Start repl. patch_context = repl.cli.patch_stdout_context() if patch_stdout else DummyContext() if return_asyncio_coroutine: def coroutine(): with patch_context: for future in repl.asyncio_start_repl(): yield future return coroutine() else: with patch_context: repl.start_repl(startup_paths=startup_paths)
def init_prompt_toolkit_cli(self): if self.simple_prompt: # Fall back to plain non-interactive output for tests. # This is very limited, and only accepts a single line. def prompt(): return cast_unicode_py2(input('In [%d]: ' % self.execution_count)) self.prompt_for_code = prompt return # Set up keyboard shortcuts kbmanager = KeyBindingManager.for_prompt() register_ipython_shortcuts(kbmanager.registry, self) # Pre-populate history from IPython's history database history = InMemoryHistory() last_cell = u"" for __, ___, cell in self.history_manager.get_tail(self.history_load_length, include_latest=True): # Ignore blank lines and consecutive duplicates cell = cell.rstrip() if cell and (cell != last_cell): history.append(cell) last_cell = cell self._style = self._make_style_from_name_or_cls(self.highlighting_style) style = DynamicStyle(lambda: self._style) editing_mode = getattr(EditingMode, self.editing_mode.upper()) self._pt_app = create_prompt_application( editing_mode=editing_mode, key_bindings_registry=kbmanager.registry, history=history, completer=IPythonPTCompleter(shell=self), enable_history_search=True, style=style, mouse_support=self.mouse_support, **self._layout_options() ) self._eventloop = create_eventloop(self.inputhook) self.pt_cli = CommandLineInterface( self._pt_app, eventloop=self._eventloop, output=create_output(true_color=self.true_color))
def run_cli(self): """ Run the main loop """ print(u'Version:', __version__) print(u'Home: https://github.com/glasslion/saltcli') history = FileHistory(os.path.expanduser('~/.saltcli-history')) layout = create_prompt_layout( message=u'saltcli> ', ) application = Application( layout=layout ) eventloop = create_eventloop() self.cli = CommandLineInterface( application=application, eventloop=eventloop) while True: try: document = self.cli.run() if quit_command(document.text): raise EOFError except KeyboardInterrupt: # user pressed Ctrl + C click.echo('') except EOFError: break except Exception as ex: self.logger.debug('Exception: %r.', ex) self.logger.error("traceback: %r", traceback.format_exc()) click.secho("{0}".format(ex), fg='red') break print('Goodbye!')
def instapipe(runner, init_cmd, instant=False, input_lines=1, input_deco=''): layout = HSplit([ Window(content=BufferControl(buffer_name=DEFAULT_BUFFER), height=D.exact(1)), Window(content=FillControl('-', token=Token.Line), height=D.exact(1)), Window(content=BufferControl(buffer_name='OUTPUT')) ]) buffers, keybinds = _setup_buffers(runner, layout.children[-1], instant) app = Application(layout=layout, buffers=buffers, mouse_support=True, key_bindings_registry=keybinds, use_alternate_screen=True) eventloop = create_eventloop() final_cmd = '' try: final_cmd = CommandLineInterface(application=app, eventloop=eventloop).run() except: print_exc() finally: eventloop.close() return final_cmd
def RunApplication(app): """Run a prompt_toolkit Application.""" eventloop = shortcuts.create_eventloop() # Create CommandLineInterface. cli = interface.CommandLineInterface( application=app, eventloop=eventloop, output=shortcuts.create_output()) # Note: We pass `reset_current_buffer=False`, because that way it's easy to # give DEFAULT_BUFFER a default value, without it getting erased. We # don't have to reset anyway, because this is the first and only time # that this CommandLineInterface will run. try: result = cli.run(reset_current_buffer=False) if isinstance(result, document.Document): # Backwards-compatibility. return result.text return result finally: eventloop.close()
def example_repl(self, text, example, start_index, continue_flag): """ REPL for interactive tutorials """ from prompt_toolkit.interface import CommandLineInterface if start_index: start_index = start_index + 1 cmd = ' '.join(text.split()[:start_index]) example_cli = CommandLineInterface( application=self.create_application( full_layout=False), eventloop=create_eventloop()) example_cli.buffers['example_line'].reset( initial_document=Document(u'{}\n'.format( add_new_lines(example))) ) while start_index < len(text.split()): if self.default_command: cmd = cmd.replace(self.default_command + ' ', '') example_cli.buffers[DEFAULT_BUFFER].reset( initial_document=Document( u'{}'.format(cmd), cursor_position=len(cmd))) example_cli.request_redraw() answer = example_cli.run() if not answer: return "", True answer = answer.text if answer.strip('\n') == cmd.strip('\n'): continue else: if len(answer.split()) > 1: start_index += 1 cmd += " " + answer.split()[-1] + " " +\ u' '.join(text.split()[start_index:start_index + 1]) example_cli.exit() del example_cli else: cmd = text return cmd, continue_flag
def CreateCli(gcloud_py_dir): """Creates the CLI application. Args: gcloud_py_dir: str, path to completion lookup table Returns: cli, a cli instance """ completer = ShellCliCompleter(gcloud_py_dir) in_memory_history = history.InMemoryHistory() auto_suggest_from_history = auto_suggest.AutoSuggestFromHistory() key_manager = _KeyBindings() layout = shortcuts.create_prompt_layout( lexer=shell.BashLexer, get_bottom_toolbar_tokens=GetBottomToolbarTokens, message=u'Cloud SDK {0}> '.format(config.CLOUD_SDK_VERSION)) cli_buffer = ptkbuffer.Buffer( history=in_memory_history, auto_suggest=auto_suggest_from_history, complete_while_typing=True, completer=completer, accept_action=interface.AcceptAction.RETURN_DOCUMENT) application = Application( style=GetDocumentStyle(), buffer=cli_buffer, layout=layout, key_bindings_registry=key_manager.registry, mouse_support=True) cli = interface.CommandLineInterface( application=application, eventloop=shortcuts.create_eventloop()) return cli
def __init__(self, options): # Load config. c = self.config = get_config(options.mssqlclirc_file) self.initialize_logging() self.logger = logging.getLogger(u'mssqlcli.main') self.set_default_pager(c) self.output_file = None self.multi_line = c['main'].as_bool('multi_line') self.multiline_mode = c['main'].get('multi_line_mode', 'tsql') self.vi_mode = c['main'].as_bool('vi') self.auto_expand = options.auto_vertical_output or c['main'][ 'expand'] == 'auto' self.expanded_output = c['main']['expand'] == 'always' self.prompt_format = options.prompt or c['main'].get( 'prompt', self.default_prompt) if options.row_limit is not None: self.row_limit = options.row_limit else: self.row_limit = c['main'].as_int('row_limit') self.min_num_menu_lines = c['main'].as_int('min_num_menu_lines') self.multiline_continuation_char = c['main'][ 'multiline_continuation_char'] self.table_format = c['main']['table_format'] self.syntax_style = c['main']['syntax_style'] self.cli_style = c['colors'] self.wider_completion_menu = c['main'].as_bool('wider_completion_menu') self.less_chatty = bool( options.less_chatty) or c['main'].as_bool('less_chatty') self.null_string = c['main'].get('null_string', '<null>') self.on_error = c['main']['on_error'].upper() self.decimal_format = c['data_formats']['decimal'] self.float_format = c['data_formats']['float'] self.now = dt.datetime.today() self.completion_refresher = CompletionRefresher() self.query_history = [] # Initialize completer smart_completion = True if c['main'].get('smart_completion', 'True') == 'True' else False keyword_casing = c['main']['keyword_casing'] self.settings = { 'casing_file': get_casing_file(c), 'generate_casing_file': c['main'].as_bool('generate_casing_file'), 'generate_aliases': c['main'].as_bool('generate_aliases'), 'asterisk_column_order': c['main']['asterisk_column_order'], 'qualify_columns': c['main']['qualify_columns'], 'case_column_headers': c['main'].as_bool('case_column_headers'), 'search_path_filter': c['main'].as_bool('search_path_filter'), 'single_connection': False, 'less_chatty': options.less_chatty, 'keyword_casing': keyword_casing, } self.completer = MssqlCompleter(smart_completion=smart_completion, settings=self.settings) self._completer_lock = threading.Lock() self.eventloop = create_eventloop() self.cli = None self.integrated_auth = options.integrated_auth self.sqltoolsclient = SqlToolsClient( enable_logging=options.enable_sqltoolsservice_logging) self.mssqlcliclient_main = MssqlCliClient(options, self.sqltoolsclient)
def __init__(self, force_passwd_prompt=False, never_passwd_prompt=False, pgexecute=None, pgclirc_file=None, row_limit=None, single_connection=False, prompt=None): self.force_passwd_prompt = force_passwd_prompt self.never_passwd_prompt = never_passwd_prompt self.pgexecute = pgexecute # Load config. c = self.config = get_config(pgclirc_file) self.logger = logging.getLogger(__name__) self.initialize_logging() self.set_default_pager(c) self.output_file = None self.pgspecial = PGSpecial() self.multi_line = c['main'].as_bool('multi_line') self.multiline_mode = c['main'].get('multi_line_mode', 'psql') self.vi_mode = c['main'].as_bool('vi') self.pgspecial.timing_enabled = c['main'].as_bool('timing') if row_limit is not None: self.row_limit = row_limit else: self.row_limit = c['main'].as_int('row_limit') self.table_format = c['main']['table_format'] self.syntax_style = c['main']['syntax_style'] self.cli_style = c['colors'] self.wider_completion_menu = c['main'].as_bool('wider_completion_menu') self.less_chatty = c['main'].as_bool('less_chatty') self.null_string = c['main'].get('null_string', '<null>') self.prompt_format = prompt if prompt is not None else c['main'].get( 'prompt', self.default_prompt) self.on_error = c['main']['on_error'].upper() self.decimal_format = c['data_formats']['decimal'] self.float_format = c['data_formats']['float'] self.completion_refresher = CompletionRefresher() self.query_history = [] # Initialize completer smart_completion = c['main'].as_bool('smart_completion') keyword_casing = c['main']['keyword_casing'] self.settings = { 'casing_file': get_casing_file(c), 'generate_casing_file': c['main'].as_bool('generate_casing_file'), 'generate_aliases': c['main'].as_bool('generate_aliases'), 'asterisk_column_order': c['main']['asterisk_column_order'], 'single_connection': single_connection, 'keyword_casing': keyword_casing, } completer = PGCompleter(smart_completion, pgspecial=self.pgspecial, settings=self.settings) self.completer = completer self._completer_lock = threading.Lock() self.register_special_commands() self.eventloop = create_eventloop() self.cli = None
def __init__(self, cosh=None, args=None, config=None): self.args = args self.coshell = cosh self.config = config self.key_bindings = bindings.KeyBindings( edit_mode=self.coshell.edit_mode == 'emacs') # Load the default CLI trees. On startup we ignore out of date trees. The # alternative is to regenerate them before the first prompt. This could be # a noticeable delay for users that accrue a lot of trees. Although ignored # at startup, the regen will happen on demand as the individual commands # are typed. self.root = generate_cli_trees.LoadAll(ignore_out_of_date=True, warn_on_exceptions=True) # Add the exit command completer node to the CLI tree. self.root[parser.LOOKUP_COMMANDS]['exit'] = cli_tree.Node( command='exit', description='Exit the interactive shell.', positionals=[ { 'default': '0', 'description': 'The exit status.', 'name': 'status', 'nargs': '?', 'required': False, 'value': 'STATUS', }, ], ) # Create the parser and completer. interactive_parser = parser.Parser(self.root, context=config.context, hidden=config.hidden) interactive_completer = completer.InteractiveCliCompleter( interactive_parser=interactive_parser, args=args, cosh=self.coshell, hidden=config.hidden, manpage_generator=config.manpage_generator) # Make sure that complete_while_typing is disabled when # enable_history_search is enabled. (First convert to SimpleFilter, to # avoid doing bitwise operations on bool objects.) complete_while_typing = shortcuts.to_simple_filter(True) enable_history_search = shortcuts.to_simple_filter(False) complete_while_typing &= ~enable_history_search history_file = os.path.join(core_config.Paths().global_config_dir, 'shell_history') multiline = shortcuts.to_simple_filter(False) # Create the default buffer. self.default_buffer = pt_buffer.Buffer( enable_history_search=enable_history_search, complete_while_typing=complete_while_typing, is_multiline=multiline, history=pt_history.FileHistory(history_file), validator=None, completer=interactive_completer, auto_suggest=(auto_suggest.AutoSuggestFromHistory() if config.suggest else None), accept_action=pt_buffer.AcceptAction.RETURN_DOCUMENT, ) # Create the CLI. self.cli = CLI( config=config, cosh=cosh, root=self.root, interactive_parser=interactive_parser, application=self._CreatePromptApplication(config=config, multiline=multiline), eventloop=shortcuts.create_eventloop(), output=shortcuts.create_output(), ) self.key_bindings.Initialize(self.cli)
#!/usr/bin/env python """ For testing: test to make sure that everything still works when gevent monkey patches are applied. """ from __future__ import unicode_literals from gevent.monkey import patch_all from prompt_toolkit.shortcuts import prompt, create_eventloop if __name__ == '__main__': # Apply patches. patch_all() # There were some issues in the past when the event loop had an input hook. def dummy_inputhook(*a): pass eventloop = create_eventloop(inputhook=dummy_inputhook) # Ask for input. answer = prompt('Give me some input: ', eventloop=eventloop) print('You said: %s' % answer)
def run_cli(self): sqlexecute = self.sqlexecute logger = self.logger original_less_opts = self.adjust_less_opts() self.set_pager_from_config() self.initialize_completions() completer = self.completer def set_key_bindings(value): if value not in ('emacs', 'vi'): value = 'emacs' self.key_bindings = value project_root = os.path.dirname(PACKAGE_ROOT) author_file = os.path.join(project_root, 'AUTHORS') sponsor_file = os.path.join(project_root, 'SPONSORS') key_binding_manager = mycli_bindings(get_key_bindings=lambda: self.key_bindings, set_key_bindings=set_key_bindings) print('Version:', __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 prompt_tokens(cli): return [(Token.Prompt, self.get_prompt(self.prompt_format))] get_toolbar_tokens = create_toolbar_tokens_func(lambda: self.key_bindings) layout = create_default_layout(lexer=MyCliLexer, reserve_space_for_menu=True, multiline=True, get_prompt_tokens=prompt_tokens, get_bottom_toolbar_tokens=get_toolbar_tokens, display_completions_in_columns=self.wider_completion_menu, extra_input_processors=[ ConditionalProcessor( processor=HighlightMatchingBracketProcessor(chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()), ]) buf = CLIBuffer(always_multiline=self.multi_line, completer=completer, history=FileHistory(os.path.expanduser('~/.mycli-history')), complete_while_typing=Always()) application = Application(style=style_factory(self.syntax_style, self.cli_style), layout=layout, buffer=buf, key_bindings_registry=key_binding_manager.registry, on_exit=AbortAction.RAISE_EXCEPTION, ignore_case=True) cli = CommandLineInterface(application=application, eventloop=create_eventloop()) try: while True: document = cli.run() special.set_expanded_output(False) # The reason we check here instead of inside the sqlexecute is # because we want to raise the Exit exception which will be # caught by the try/except block that wraps the # sqlexecute.run() statement. if quit_command(document.text): raise EOFError try: document = self.handle_editor_command(cli, document) except RuntimeError as e: logger.error("sql: %r, error: %r", document.text, e) logger.error("traceback: %r", traceback.format_exc()) self.output(str(e), err=True, fg='red') continue if self.destructive_warning: destroy = confirm_destructive_query(document.text) if destroy is None: pass # Query was not destructive. Nothing to do here. elif destroy is True: self.output('Your call!') else: self.output('Wise choice!') continue # 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) if self.logfile: self.logfile.write('\n# %s\n' % datetime.now()) self.logfile.write(document.text) self.logfile.write('\n') successful = False start = time() res = sqlexecute.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): self.output('The result set has more than %s rows.' % threshold, fg='red') if not click.confirm('Do you want to continue?'): self.output("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 sqlexecute.connect() logger.debug("cancelled query, sql: %r", document.text) self.output("cancelled query", err=True, fg='red') except NotImplementedError: self.output('Not Yet Implemented.', fg="yellow") except OperationalError as e: logger.debug("Exception: %r", e) reconnect = True if (e.args[0] in (2003, 2006, 2013)): reconnect = click.prompt('Connection reset. Reconnect (Y/n)', show_default=False, type=bool, default=True) if reconnect: logger.debug('Attempting to reconnect.') try: sqlexecute.connect() logger.debug('Reconnected successfully.') self.output('Reconnected!\nTry the command again.', fg='green') except OperationalError as e: logger.debug('Reconnect failed. e: %r', e) self.output(str(e), err=True, fg='red') continue # If reconnection failed, don't proceed further. else: # If user chooses not to reconnect, don't proceed further. continue else: logger.error("sql: %r, error: %r", document.text, e) logger.error("traceback: %r", traceback.format_exc()) self.output(str(e), err=True, fg='red') except Exception as e: logger.error("sql: %r, error: %r", document.text, e) logger.error("traceback: %r", traceback.format_exc()) self.output(str(e), err=True, fg='red') else: try: self.output_via_pager('\n'.join(output)) except KeyboardInterrupt: pass if special.is_timing_enabled(): self.output('Command Time: %0.03fs' % duration) self.output('Format Time: %0.03fs' % total) # Refresh the table names and column names if necessary. if need_completion_refresh(document.text): self.refresh_dynamic_completions() query = Query(document.text, successful, mutating) self.query_history.append(query) except EOFError: self.output('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 os.environ['PAGER'] = special.get_original_pager()
def init_prompt_toolkit_cli(self): if self.simple_prompt or ('JUPYTER_CONSOLE_TEST' in os.environ): # Simple restricted interface for tests so we can find prompts with # pexpect. Multi-line input not supported. def prompt(): return cast_unicode_py2( input('In [%d]: ' % self.execution_count)) self.prompt_for_code = prompt self.print_out_prompt = \ lambda: print('Out[%d]: ' % self.execution_count, end='') return kbmanager = KeyBindingManager.for_prompt() insert_mode = ViInsertMode() | EmacsInsertMode() # Ctrl+J == Enter, seemingly @kbmanager.registry.add_binding(Keys.ControlJ, filter=(HasFocus(DEFAULT_BUFFER) & ~HasSelection() & insert_mode)) def _(event): b = event.current_buffer d = b.document if not (d.on_last_line or d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end()): b.newline() return # Pressing enter flushes any pending display. This also ensures # the displayed execution_count is correct. self.handle_iopub() more, indent = self.check_complete(d.text) if (not more) and b.accept_action.is_returnable: b.accept_action.validate_and_handle(event.cli, b) else: b.insert_text('\n' + indent) @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)) def _(event): event.current_buffer.reset() @kbmanager.registry.add_binding(Keys.ControlBackslash, filter=HasFocus(DEFAULT_BUFFER)) def _(event): raise EOFError # Pre-populate history from IPython's history database history = InMemoryHistory() last_cell = u"" for _, _, cell in self.history_manager.get_tail( self.history_load_length, include_latest=True): # Ignore blank lines and consecutive duplicates cell = cast_unicode_py2(cell.rstrip()) if cell and (cell != last_cell): history.append(cell) style_overrides = { Token.Prompt: '#009900', Token.PromptNum: '#00ff00 bold', Token.OutPrompt: '#ff2200', Token.OutPromptNum: '#ff0000 bold', } if self.highlighting_style: style_cls = get_style_by_name(self.highlighting_style) else: style_cls = get_style_by_name('default') # The default theme needs to be visible on both a dark background # and a light background, because we can't tell what the terminal # looks like. These tweaks to the default theme help with that. style_overrides.update({ Token.Number: '#007700', Token.Operator: 'noinherit', Token.String: '#BB6622', Token.Name.Function: '#2080D0', Token.Name.Class: 'bold #2080D0', Token.Name.Namespace: 'bold #2080D0', }) style_overrides.update(self.highlighting_style_overrides) style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls, style_dict=style_overrides) editing_mode = getattr(EditingMode, self.editing_mode.upper()) langinfo = self.kernel_info.get('language_info', {}) lexer = langinfo.get('pygments_lexer', langinfo.get('name', 'text')) app = create_prompt_application( multiline=True, editing_mode=editing_mode, lexer=PygmentsLexer(get_pygments_lexer(lexer)), get_prompt_tokens=self.get_prompt_tokens, get_continuation_tokens=self.get_continuation_tokens, key_bindings_registry=kbmanager.registry, history=history, completer=JupyterPTCompleter(self.Completer), enable_history_search=True, style=style, ) self._eventloop = create_eventloop() self.pt_cli = CommandLineInterface( app, eventloop=self._eventloop, output=create_output(true_color=self.true_color), )
def prompt(self, message='', **kwargs): """Get input from the user and return it. This is a wrapper around a lot of prompt_toolkit functionality and can be a replacement for raw_input. (or GNU readline.) If you want to keep your history across several calls, create one `~prompt_toolkit.history.History instance and pass it every time. This function accepts many keyword arguments. Except for the following. they are a proxy to the arguments of create_prompt_application(). Parameters ---------- patch_stdout : file-like, optional Replace ``sys.stdout`` by a proxy that ensures that print statements from other threads won't destroy the prompt. (They will be printed above the prompt instead.) return_asyncio_coroutine : bool, optional When True, return a asyncio coroutine. (Python >3.3) Notes ----- This method was forked from the mainline prompt-toolkit repo. Copyright (c) 2014, Jonathan Slenders, All rights reserved. """ patch_stdout = kwargs.pop('patch_stdout', False) return_asyncio_coroutine = kwargs.pop('return_asyncio_coroutine', False) if return_asyncio_coroutine: eventloop = create_asyncio_eventloop() else: eventloop = kwargs.pop('eventloop', None) or create_eventloop() # Create CommandLineInterface. if self.cli is None: if builtins.__xonsh_env__.get('VI_MODE'): editing_mode = EditingMode.VI else: editing_mode = EditingMode.EMACS kwargs['editing_mode'] = editing_mode cli = CommandLineInterface(application=create_prompt_application( message, **kwargs), eventloop=eventloop, output=create_output()) self.cli = cli else: cli = self.cli # Replace stdout. patch_context = cli.patch_stdout_context( ) if patch_stdout else DummyContext() # Read input and return it. if return_asyncio_coroutine: # Create an asyncio coroutine and call it. exec_context = {'patch_context': patch_context, 'cli': cli} exec( textwrap.dedent(''' import asyncio @asyncio.coroutine def prompt_coro(): with patch_context: document = yield from cli.run_async(reset_current_buffer=False) if document: return document.text '''), exec_context) return exec_context['prompt_coro']() else: # Note: We pass `reset_current_buffer=False`, because that way # it's easy to give DEFAULT_BUFFER a default value, without it # getting erased. We don't have to reset anyway, because this is # the first and only time that this CommandLineInterface will run. try: with patch_context: document = cli.run(reset_current_buffer=False) if document: return document.text finally: eventloop.close()
def init_prompt_toolkit_cli(self): self._app = None if self.simple_prompt: # Fall back to plain non-interactive output for tests. # This is very limited, and only accepts a single line. def prompt(): return cast_unicode_py2( input('In [%d]: ' % self.execution_count)) self.prompt_for_code = prompt return kbmanager = KeyBindingManager.for_prompt() insert_mode = ViInsertMode() | EmacsInsertMode() # Ctrl+J == Enter, seemingly @kbmanager.registry.add_binding(Keys.ControlJ, filter=(HasFocus(DEFAULT_BUFFER) & ~HasSelection() & insert_mode)) def _(event): b = event.current_buffer d = b.document if b.complete_state: cs = b.complete_state b.apply_completion(cs.current_completion) return if not (d.on_last_line or d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end()): b.newline() return status, indent = self.input_splitter.check_complete(d.text) if (status != 'incomplete') and b.accept_action.is_returnable: b.accept_action.validate_and_handle(event.cli, b) else: b.insert_text('\n' + (' ' * (indent or 0))) @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)) def _reset_buffer(event): event.current_buffer.reset() @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER)) def _reset_search_buffer(event): if event.current_buffer.document.text: event.current_buffer.reset() else: event.cli.push_focus(DEFAULT_BUFFER) supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP')) @kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend) def _suspend_to_bg(event): event.cli.suspend_to_background() @Condition def cursor_in_leading_ws(cli): before = cli.application.buffer.document.current_line_before_cursor return (not before) or before.isspace() # Ctrl+I == Tab @kbmanager.registry.add_binding(Keys.ControlI, filter=(HasFocus(DEFAULT_BUFFER) & ~HasSelection() & insert_mode & cursor_in_leading_ws)) def _indent_buffer(event): event.current_buffer.insert_text(' ' * 4) # Pre-populate history from IPython's history database history = InMemoryHistory() last_cell = u"" for __, ___, cell in self.history_manager.get_tail( self.history_load_length, include_latest=True): # Ignore blank lines and consecutive duplicates cell = cell.rstrip() if cell and (cell != last_cell): history.append(cell) self._style = self._make_style_from_name(self.highlighting_style) style = DynamicStyle(lambda: self._style) editing_mode = getattr(EditingMode, self.editing_mode.upper()) self._app = create_prompt_application( editing_mode=editing_mode, key_bindings_registry=kbmanager.registry, history=history, completer=IPythonPTCompleter(self.Completer), enable_history_search=True, style=style, mouse_support=self.mouse_support, **self._layout_options()) self._eventloop = create_eventloop(self.inputhook) self.pt_cli = CommandLineInterface(self._app, eventloop=self._eventloop)
def create_interface(self): """ instantiates the intereface """ return CommandLineInterface(application=self.create_application(), eventloop=create_eventloop())
def __init__(self, force_passwd_prompt=False, mssqlclirc_file=None, row_limit=None, single_connection=False, less_chatty=None, auto_vertical_output=False, sql_tools_client=None, integrated_auth=False): self.force_passwd_prompt = force_passwd_prompt # Load config. c = self.config = get_config(mssqlclirc_file) self.logger = logging.getLogger(u'mssqlcli.main') self.initialize_logging() self.set_default_pager(c) self.output_file = None self.multi_line = c['main'].as_bool('multi_line') self.multiline_mode = c['main'].get('multi_line_mode', 'tsql') self.vi_mode = c['main'].as_bool('vi') self.auto_expand = auto_vertical_output or c['main']['expand'] == 'auto' self.expanded_output = c['main']['expand'] == 'always' if row_limit is not None: self.row_limit = row_limit else: self.row_limit = c['main'].as_int('row_limit') self.min_num_menu_lines = c['main'].as_int('min_num_menu_lines') self.multiline_continuation_char = c['main'][ 'multiline_continuation_char'] self.table_format = c['main']['table_format'] self.syntax_style = c['main']['syntax_style'] self.cli_style = c['colors'] self.wider_completion_menu = c['main'].as_bool('wider_completion_menu') self.less_chatty = bool(less_chatty) or c['main'].as_bool( 'less_chatty') self.null_string = c['main'].get('null_string', '<null>') self.on_error = c['main']['on_error'].upper() self.decimal_format = c['data_formats']['decimal'] self.float_format = c['data_formats']['float'] self.now = dt.datetime.today() self.completion_refresher = CompletionRefresher() self.query_history = [] # Initialize completer # Smart completion is not-supported in Public Preview. Tracked by # GitHub issue number 47. smart_completion = False keyword_casing = c['main']['keyword_casing'] self.settings = { 'casing_file': get_casing_file(c), 'generate_casing_file': c['main'].as_bool('generate_casing_file'), 'generate_aliases': c['main'].as_bool('generate_aliases'), 'asterisk_column_order': c['main']['asterisk_column_order'], 'qualify_columns': c['main']['qualify_columns'], 'case_column_headers': c['main'].as_bool('case_column_headers'), 'search_path_filter': c['main'].as_bool('search_path_filter'), 'single_connection': single_connection, 'less_chatty': less_chatty, 'keyword_casing': keyword_casing, } completer = MssqlCompleter(smart_completion, settings=self.settings) self.completer = completer self._completer_lock = threading.Lock() self.eventloop = create_eventloop() self.cli = None # mssql-cli self.sqltoolsclient = sql_tools_client if sql_tools_client else SqlToolsClient( ) self.mssqlcliclient_query_execution = None self.integrated_auth = integrated_auth
def __init__(self, config_directory='~/.pyvim'): # Vi options. self.show_line_numbers = True self.highlight_search = True self.paste_mode = False self.show_ruler = True self.show_wildmenu = True self.expand_tab = True # Insect spaces instead of tab characters. self.tabstop = 4 # Number of spaces that a tab character represents. self.incsearch = True # Show matches while typing search string. self.ignore_case = False # Ignore case while searching. self.enable_mouse_support = True self.display_unprintable_characters = True # ':set list' self.enable_jedi = True # ':set jedi', for Python Jedi completion. self.scroll_offset = 0 # ':set scrolloff' self.relative_number = False # ':set relativenumber' self.wrap_lines = True # ':set wrap' self.cursorline = False # ':set cursorline' self.cursorcolumn = False # ':set cursorcolumn' self.colorcolumn = [] # ':set colorcolumn'. List of integers. # Ensure config directory exists. self.config_directory = os.path.abspath( os.path.expanduser(config_directory)) if not os.path.exists(self.config_directory): os.mkdir(self.config_directory) self._reporters_running_for_buffer_names = set() self.window_arrangement = WindowArrangement(self) self.message = None # Load styles. (Mapping from name to Style class.) self.styles = generate_built_in_styles() self.current_style = get_editor_style_by_name('default') # I/O backends. self.io_backends = [ DirectoryIO(), HttpIO(), GZipFileIO(), # Should come before FileIO. FileIO(), ] # Create eventloop. self.eventloop = create_eventloop() # Create key bindings manager self.key_bindings_manager = create_key_bindings(self) # Create layout and CommandLineInterface instance. self.editor_layout = EditorLayout(self, self.key_bindings_manager, self.window_arrangement) self.application = self._create_application() self.cli = CommandLineInterface(eventloop=self.eventloop, application=self.application) # Hide message when a key is pressed. def key_pressed(_): self.message = None self.cli.input_processor.beforeKeyPress += key_pressed # Command line previewer. self.previewer = CommandPreviewer(self)
def create_interface(self): """ instantiates the interface """ from prompt_toolkit.interface import CommandLineInterface return CommandLineInterface(application=self.create_application(), eventloop=create_eventloop())
def run_cli(self): pgexecute = self.pgexecute logger = self.logger original_less_opts = self.adjust_less_opts() completer = self.completer self.refresh_completions() def set_vi_mode(value): self.vi_mode = value key_binding_manager = pgcli_bindings( get_vi_mode_enabled=lambda: self.vi_mode, set_vi_mode_enabled=set_vi_mode) print('Version:', __version__) print('Chat: https://gitter.im/dbcli/pgcli') print('Mail: https://groups.google.com/forum/#!forum/pgcli') print('Home: http://pgcli.com') def prompt_tokens(cli): return [(Token.Prompt, '%s> ' % pgexecute.dbname)] get_toolbar_tokens = create_toolbar_tokens_func(lambda: self.vi_mode) layout = create_default_layout(lexer=PostgresLexer, reserve_space_for_menu=True, get_prompt_tokens=prompt_tokens, get_bottom_toolbar_tokens=get_toolbar_tokens, extra_input_processors=[ # Highlight matching brackets while editing. ConditionalProcessor( processor=HighlightMatchingBracketProcessor(chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()), ]) buf = PGBuffer(always_multiline=self.multi_line, completer=completer, history=FileHistory(os.path.expanduser('~/.pgcli-history')), complete_while_typing=Always()) application = Application(style=style_factory(self.syntax_style), layout=layout, buffer=buf, key_bindings_registry=key_binding_manager.registry, on_exit=AbortAction.RAISE_EXCEPTION) cli = CommandLineInterface(application=application, eventloop=create_eventloop()) try: while True: document = cli.run() # 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 EOFError try: document = self.handle_editor_command(cli, document) except RuntimeError 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') continue # 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, self.pgspecial) 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 formatted = format_output(title, cur, headers, status, self.table_format, self.pgspecial.expanded_output) output.extend(formatted) 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 NotImplementedError: click.secho('Not Yet Implemented.', fg="yellow") except OperationalError as e: reconnect = True if ('server closed the connection' in utf8tounicode(e.args[0])): reconnect = click.prompt('Connection reset. Reconnect (Y/n)', show_default=False, type=bool, default=True) if reconnect: try: pgexecute.connect() click.secho('Reconnected!\nTry the command again.', fg='green') except OperationalError as e: click.secho(str(e), err=True, fg='red') else: logger.error("sql: %r, error: %r", document.text, e) logger.error("traceback: %r", traceback.format_exc()) click.secho(str(e), 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 self.pgspecial.timing_enabled: print('Command Time: %0.03fs' % duration) print('Format Time: %0.03fs' % total) # Refresh the table names and column names if necessary. if need_completion_refresh(document.text): 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 EOFError: 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 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, '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 layout = create_prompt_layout( lexer=PygmentsLexer(CHLexer) if self.highlight else None, get_prompt_tokens=get_prompt_tokens, get_continuation_tokens=get_continuation_tokens, multiline=self.multiline, ) buffer = CLIBuffer( client=self.client, multiline=self.multiline, metadata=self.metadata, ) application = Application( layout=layout, buffer=buffer, style=CHStyle if self.highlight else None, key_bindings_registry=KeyBinder.registry, ) eventloop = create_eventloop() self.cli = CommandLineInterface(application=application, eventloop=eventloop) if self.refresh_metadata_on_start: self.cli.application.buffer.completer.refresh_metadata() try: while True: try: cli_input = self.cli.run(reset_current_buffer=True) self.handle_input( cli_input.text, refresh_metadata=self.refresh_metadata_on_query) except KeyboardInterrupt: # Attempt to terminate queries for query_id in self.query_ids: self.client.kill_query(query_id) self.echo.error("\nQuery was terminated.") finally: self.query_ids = [] except EOFError: self.echo.success("Bye.")
def _build_cli(self, history): key_binding_manager = cli_bindings() def prompt_tokens(cli): prompt = self.get_prompt(self.prompt) if len(prompt) > self.MAX_LEN_PROMPT: prompt = self.get_prompt('\\d> ') return [(Token.Prompt, prompt)] def get_continuation_tokens(cli, width): prompt = self.get_prompt(self.prompt_continuation) token = (Token.Continuation, ' ' * (width - len(prompt)) + prompt) return [token] def show_suggestion_tip(): return self.iterations < 2 get_toolbar_tokens = create_toolbar_tokens_func( self.completion_refresher.is_refreshing, show_suggestion_tip) layout = create_prompt_layout( lexer=Lexer, multiline=True, get_prompt_tokens=prompt_tokens, get_continuation_tokens=get_continuation_tokens, get_bottom_toolbar_tokens=get_toolbar_tokens, display_completions_in_columns=self.config['main'].as_bool( 'wider_completion_menu'), extra_input_processors=[ ConditionalProcessor( processor=HighlightMatchingBracketProcessor( chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()) ], reserve_space_for_menu=self.get_reserved_space()) with self._completer_lock: buf = CLIBuffer(always_multiline=self.multi_line, completer=self.completer, history=history, auto_suggest=AutoSuggestFromHistory(), complete_while_typing=Always(), accept_action=AcceptAction.RETURN_DOCUMENT) if self.key_bindings == 'vi': editing_mode = EditingMode.VI else: editing_mode = EditingMode.EMACS application = Application( style=style_from_pygments(style_cls=self.output_style), layout=layout, buffer=buf, key_bindings_registry=key_binding_manager.registry, on_exit=AbortAction.RAISE_EXCEPTION, on_abort=AbortAction.RETRY, editing_mode=editing_mode, ignore_case=True) cli = CommandLineInterface(application=application, eventloop=create_eventloop()) return cli
def run_cli(self): 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') key_binding_manager = mycli_bindings() if not self.less_chatty: print('Version:', __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 prompt_tokens(cli): 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 [(Token.Prompt, prompt)] def get_continuation_tokens(cli, width): continuation_prompt = self.get_prompt(self.prompt_continuation_format) return [(Token.Continuation, ' ' * (width - len(continuation_prompt)) + continuation_prompt)] def one_iteration(document=None): if document is None: document = self.cli.run() special.set_expanded_output(False) # The reason we check here instead of inside the sqlexecute is # because we want to raise the Exit exception which will be # caught by the try/except block that wraps the # sqlexecute.run() statement. if quit_command(document.text): raise EOFError try: document = self.handle_editor_command(self.cli, document) except RuntimeError as e: logger.error("sql: %r, error: %r", document.text, e) logger.error("traceback: %r", traceback.format_exc()) self.output(str(e), err=True, fg='red') return if self.destructive_warning: destroy = confirm_destructive_query(document.text) if destroy is None: pass # Query was not destructive. Nothing to do here. elif destroy is True: self.output('Your call!') else: self.output('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', document.text) special.write_tee(self.get_prompt(self.prompt_format) + document.text) if self.logfile: self.logfile.write('\n# %s\n' % datetime.now()) self.logfile.write(document.text) self.logfile.write('\n') successful = False start = time() res = sqlexecute.run(document.text) 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) threshold = 1000 if (is_select(status) and cur and cur.rowcount > threshold): self.output('The result set has more than %s rows.' % threshold, fg='red') if not click.confirm('Do you want to continue?'): self.output("Aborted!", err=True, fg='red') break if self.auto_vertical_output: max_width = self.cli.output.get_size().columns else: max_width = None formatted = self.format_output(title, cur, headers, status, special.is_expanded_output(), max_width) output.extend(formatted) total = time() - start mutating = mutating or is_mutating(status) 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, document.text) self.output("cancelled query", err=True, fg='red') except Exception as e: self.output('Encountered error while cancelling query: %s' % str(e), err=True, fg='red') except NotImplementedError: self.output('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.output('Reconnecting...', fg='yellow') try: sqlexecute.connect() logger.debug('Reconnected successfully.') one_iteration(document) 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.output(str(e), err=True, fg='red') return # If reconnection failed, don't proceed further. else: logger.error("sql: %r, error: %r", document.text, e) logger.error("traceback: %r", traceback.format_exc()) self.output(str(e), err=True, fg='red') except Exception as e: logger.error("sql: %r, error: %r", document.text, e) logger.error("traceback: %r", traceback.format_exc()) self.output(str(e), err=True, fg='red') else: try: special.write_tee('\n'.join(output)) if special.is_pager_enabled(): self.output_via_pager('\n'.join(output)) else: self.output('\n'.join(output)) except KeyboardInterrupt: pass if special.is_timing_enabled(): self.output('Time: %0.03fs' % total) # Refresh the table names and column names if necessary. if need_completion_refresh(document.text): self.refresh_completions( reset=need_completion_reset(document.text)) finally: if self.logfile is False: self.output("Warning: This query was not logged.", err=True, fg='red') query = Query(document.text, successful, mutating) self.query_history.append(query) get_toolbar_tokens = create_toolbar_tokens_func(self.completion_refresher.is_refreshing) layout = create_prompt_layout( lexer=MyCliLexer, multiline=True, get_prompt_tokens=prompt_tokens, get_continuation_tokens=get_continuation_tokens, get_bottom_toolbar_tokens=get_toolbar_tokens, display_completions_in_columns=self.wider_completion_menu, extra_input_processors=[ConditionalProcessor( processor=HighlightMatchingBracketProcessor(chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() )], reserve_space_for_menu=self.get_reserved_space() ) with self._completer_lock: buf = CLIBuffer(always_multiline=self.multi_line, completer=self.completer, history=FileHistory(os.path.expanduser(os.environ.get('MYCLI_HISTFILE', '~/.mycli-history'))), complete_while_typing=Always(), accept_action=AcceptAction.RETURN_DOCUMENT) if self.key_bindings == 'vi': editing_mode = EditingMode.VI else: editing_mode = EditingMode.EMACS application = Application(style=style_factory(self.syntax_style, self.cli_style), layout=layout, buffer=buf, key_bindings_registry=key_binding_manager.registry, on_exit=AbortAction.RAISE_EXCEPTION, on_abort=AbortAction.RETRY, editing_mode=editing_mode, ignore_case=True) self.cli = CommandLineInterface(application=application, eventloop=create_eventloop()) try: while True: one_iteration() except EOFError: special.close_tee() if not self.less_chatty: self.output('Goodbye!')
def __init__(self, force_passwd_prompt=False, never_passwd_prompt=False, pgexecute=None, pgclirc_file=None, row_limit=None, single_connection=False, less_chatty=None, prompt=None, prompt_dsn=None, auto_vertical_output=False): self.force_passwd_prompt = force_passwd_prompt self.never_passwd_prompt = never_passwd_prompt self.pgexecute = pgexecute self.dsn_alias = None # Load config. c = self.config = get_config(pgclirc_file) self.logger = logging.getLogger(__name__) self.initialize_logging() self.set_default_pager(c) self.output_file = None self.pgspecial = PGSpecial() self.multi_line = c['main'].as_bool('multi_line') self.multiline_mode = c['main'].get('multi_line_mode', 'psql') self.vi_mode = c['main'].as_bool('vi') self.auto_expand = auto_vertical_output or c['main'].as_bool( 'auto_expand') self.expanded_output = c['main'].as_bool('expand') self.pgspecial.timing_enabled = c['main'].as_bool('timing') if row_limit is not None: self.row_limit = row_limit else: self.row_limit = c['main'].as_int('row_limit') self.min_num_menu_lines = c['main'].as_int('min_num_menu_lines') self.multiline_continuation_char = c['main'][ 'multiline_continuation_char'] self.table_format = c['main']['table_format'] self.syntax_style = c['main']['syntax_style'] self.cli_style = c['colors'] self.wider_completion_menu = c['main'].as_bool('wider_completion_menu') self.less_chatty = bool(less_chatty) or c['main'].as_bool( 'less_chatty') self.null_string = c['main'].get('null_string', '<null>') self.prompt_format = prompt if prompt is not None else c['main'].get( 'prompt', self.default_prompt) self.prompt_dsn_format = prompt_dsn self.on_error = c['main']['on_error'].upper() self.decimal_format = c['data_formats']['decimal'] self.float_format = c['data_formats']['float'] self.pgspecial.pset_pager( self.config['main'].as_bool('enable_pager') and "on" or "off") self.style_output = style_factory_output(self.syntax_style, c['colors']) self.now = dt.datetime.today() self.completion_refresher = CompletionRefresher() self.query_history = [] # Initialize completer smart_completion = c['main'].as_bool('smart_completion') keyword_casing = c['main']['keyword_casing'] self.settings = { 'casing_file': get_casing_file(c), 'generate_casing_file': c['main'].as_bool('generate_casing_file'), 'generate_aliases': c['main'].as_bool('generate_aliases'), 'asterisk_column_order': c['main']['asterisk_column_order'], 'qualify_columns': c['main']['qualify_columns'], 'case_column_headers': c['main'].as_bool('case_column_headers'), 'search_path_filter': c['main'].as_bool('search_path_filter'), 'single_connection': single_connection, 'less_chatty': less_chatty, 'keyword_casing': keyword_casing, } completer = PGCompleter(smart_completion, pgspecial=self.pgspecial, settings=self.settings) self.completer = completer self._completer_lock = threading.Lock() self.register_special_commands() self.eventloop = create_eventloop() self.cli = None
def init_prompt_toolkit_cli(self): if ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or not sys.stdin.isatty(): # Fall back to plain non-interactive output for tests. # This is very limited, and only accepts a single line. def prompt(): return cast_unicode_py2( input('In [%d]: ' % self.execution_count)) self.prompt_for_code = prompt return kbmanager = KeyBindingManager.for_prompt(enable_vi_mode=self.vi_mode) insert_mode = ViStateFilter(kbmanager.get_vi_state, InputMode.INSERT) # Ctrl+J == Enter, seemingly @kbmanager.registry.add_binding(Keys.ControlJ, filter=(HasFocus(DEFAULT_BUFFER) & ~HasSelection() & insert_mode)) def _(event): b = event.current_buffer d = b.document if not (d.on_last_line or d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end()): b.newline() return status, indent = self.input_splitter.check_complete(d.text) if (status != 'incomplete') and b.accept_action.is_returnable: b.accept_action.validate_and_handle(event.cli, b) else: b.insert_text('\n' + (' ' * (indent or 0))) @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)) def _(event): event.current_buffer.reset() @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER)) def _(event): if event.current_buffer.document.text: event.current_buffer.reset() else: event.cli.push_focus(DEFAULT_BUFFER) supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP')) @kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend) def _(event): event.cli.suspend_to_background() @Condition def cursor_in_leading_ws(cli): before = cli.application.buffer.document.current_line_before_cursor return (not before) or before.isspace() # Ctrl+I == Tab @kbmanager.registry.add_binding(Keys.ControlI, filter=(HasFocus(DEFAULT_BUFFER) & ~HasSelection() & insert_mode & cursor_in_leading_ws)) def _(event): event.current_buffer.insert_text(' ' * 4) # Pre-populate history from IPython's history database history = InMemoryHistory() last_cell = u"" for _, _, cell in self.history_manager.get_tail( self.history_load_length, include_latest=True): # Ignore blank lines and consecutive duplicates cell = cell.rstrip() if cell and (cell != last_cell): history.append(cell) style_overrides = { Token.Prompt: '#009900', Token.PromptNum: '#00ff00 bold', } if self.highlighting_style: style_cls = get_style_by_name(self.highlighting_style) else: style_cls = get_style_by_name('default') # The default theme needs to be visible on both a dark background # and a light background, because we can't tell what the terminal # looks like. These tweaks to the default theme help with that. style_overrides.update({ Token.Number: '#007700', Token.Operator: 'noinherit', Token.String: '#BB6622', Token.Name.Function: '#2080D0', Token.Name.Class: 'bold #2080D0', Token.Name.Namespace: 'bold #2080D0', }) style_overrides.update(self.highlighting_style_overrides) style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls, style_dict=style_overrides) app = create_prompt_application( multiline=True, lexer=IPythonPTLexer(), get_prompt_tokens=self.get_prompt_tokens, get_continuation_tokens=self.get_continuation_tokens, key_bindings_registry=kbmanager.registry, history=history, completer=IPythonPTCompleter(self.Completer), enable_history_search=True, style=style, mouse_support=self.mouse_support, reserve_space_for_menu=6, ) self.pt_cli = CommandLineInterface(app, eventloop=create_eventloop( self.inputhook))