async def interactive_shell(): """ Like `interactive_shell`, but doing things manual. """ # Create an asyncio `EventLoop` object. This is a wrapper around the # asyncio loop that can be passed into prompt_toolkit. eventloop = create_asyncio_eventloop() # Create interface. cli = CommandLineInterface( application=create_prompt_application('Say something inside the event loop: '), eventloop=eventloop ) # Patch stdout in something that will always print *above* the prompt when # something is written to stdout. sys.stdout = cli.stdout_proxy() # Run echo loop. Read text from stdin, and reply it back. while True: try: result = await cli.run_async() print('You said: "{0}"'.format(result.text)) except (EOFError, KeyboardInterrupt): return
def pt_init(self): def get_prompt_tokens(cli): return [(Token.Prompt, self.prompt)] def patch_stdout(**kwargs): return self.pt_cli.patch_stdout_context(**kwargs) if self._ptcomp is None: compl = IPCompleter( shell=self.shell, namespace={}, global_namespace={}, parent=self.shell, ) self._ptcomp = IPythonPTCompleter(compl, patch_stdout=patch_stdout) kbmanager = KeyBindingManager.for_prompt() supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP')) kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend)(suspend_to_bg) self._pt_app = create_prompt_application( editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()), key_bindings_registry=kbmanager.registry, history=self.shell.debugger_history, completer=self._ptcomp, enable_history_search=True, mouse_support=self.shell.mouse_support, get_prompt_tokens=get_prompt_tokens) self.pt_cli = CommandLineInterface(self._pt_app, eventloop=self.shell._eventloop)
def pt_init(self): def get_prompt_tokens(cli): return [(Token.Prompt, self.prompt)] def patch_stdout(**kwargs): return self.pt_cli.patch_stdout_context(**kwargs) if self._ptcomp is None: compl = IPCompleter( shell=self.shell, namespace={}, global_namespace={}, parent=self.shell, ) self._ptcomp = IPythonPTCompleter(compl, patch_stdout=patch_stdout) self._pt_app = create_prompt_application( editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()), history=self.shell.debugger_history, completer=self._ptcomp, enable_history_search=True, mouse_support=self.shell.mouse_support, get_prompt_tokens=get_prompt_tokens) self.pt_cli = CommandLineInterface(self._pt_app, eventloop=self.shell._eventloop)
def _create_more_application(): """ Create an `Application` instance that displays the "--MORE--". """ from prompt_toolkit.shortcuts import create_prompt_application registry = Registry() @registry.add_binding(' ') @registry.add_binding('y') @registry.add_binding('Y') @registry.add_binding(Keys.ControlJ) @registry.add_binding(Keys.ControlI) # Tab. def _(event): event.cli.set_return_value(True) @registry.add_binding('n') @registry.add_binding('N') @registry.add_binding('q') @registry.add_binding('Q') @registry.add_binding(Keys.ControlC) def _(event): event.cli.set_return_value(False) return create_prompt_application('--MORE--', key_bindings_registry=registry, erase_when_done=True)
def question(message, **kwargs): default = kwargs.pop('default', '') validate_prompt = kwargs.pop('validate', None) if validate_prompt: if inspect.isclass(validate_prompt) and issubclass( validate_prompt, Validator): kwargs['validator'] = validate_prompt() elif callable(validate_prompt): class _InputValidator(Validator): def validate(self, document): verdict = validate_prompt(document.text) if not verdict == True: if verdict == False: verdict = 'invalid input' raise ValidationError(message=verdict, cursor_position=len( document.text)) kwargs['validator'] = _InputValidator() # TODO style defaults on detail level kwargs['style'] = kwargs.pop('style', default_style) qmark = kwargs.pop('qmark', 'Введите') def _get_prompt_tokens(cli): return [(Token.QuestionMark, qmark), (Token.Question, ' %s ' % message)] return create_prompt_application(get_prompt_tokens=_get_prompt_tokens, lexer=SimpleLexer(Token.Answer), default=default, **kwargs)
def interactive_shell(): """ Coroutine that shows the interactive command line. """ # Create an asyncio `EventLoop` object. This is a wrapper around the # asyncio loop that can be passed into prompt_toolkit. eventloop = create_asyncio_eventloop() # Create interface. cli = CommandLineInterface( application=create_prompt_application('Say something inside the event loop: '), eventloop=eventloop) # Patch stdout in something that will always print *above* the prompt when # something is written to stdout. sys.stdout = cli.stdout_proxy() # Run echo loop. Read text from stdin, and reply it back. while True: try: result = yield from cli.run_async() print('You said: "%s"\n' % result.text) except (EOFError, KeyboardInterrupt): loop.stop() print('Qutting event loop. Bye.') return
def __init__(self, host): self.host = host self.socket = None self.cli = CommandLineInterface( application=create_prompt_application('> '), eventloop=create_asyncio_eventloop()) sys.stdout = self.cli.stdout_proxy()
def connected(self): # prompt_toolkit internally checks if it's on windows during output rendering but # we need to force that we use Vt100_Output not Win32_Output from prompt_toolkit import renderer renderer.is_windows = lambda: False def get_size(): return self._size self._cli = CommandLineInterface( application=create_prompt_application(self._shell.prompt), eventloop=UnstoppableEventLoop(create_asyncio_eventloop( self._loop)), input=PatchedStdinInput(sys.stdin), output=Vt100_Output(self, get_size)) self._cb = self._cli.create_eventloop_callbacks() self._inputstream = InputStream(self._cb.feed_key) # Taken from prompt_toolkit telnet server # https://github.com/jonathanslenders/python-prompt-toolkit/blob/99fa7fae61c9b4ed9767ead3b4f9b1318cfa875d/prompt_toolkit/contrib/telnet/server.py#L165 self._cli._is_running = True if self._shell.welcome_message is not None: self.send(self._shell.welcome_message.encode()) self._cli._redraw()
def main(args=sys.argv[1:]): parser, args = parseargs(args) if args.debug: log.setLevel(logging.DEBUG) loop = asyncio.get_event_loop() grbl = SerialGrbl(args.device, args.baudrate, loop) registry = load_key_bindings_for_prompt() history = InMemoryHistory() app_loop = create_asyncio_eventloop(loop=loop) app = create_prompt_application(message='> ', history=history, key_bindings_registry=registry) cli = CommandLineInterface(application=app, eventloop=app_loop) for key, func in key_to_func.items(): func = functools.partial(func, grbl=grbl, loop=loop) registry.add_binding(key, eager=True)(func) try: main_task = asyncio.ensure_future(main_coro(loop, grbl, cli)) return loop.run_until_complete(main_task) except (EOFError, KeyboardInterrupt): main_task.cancel() return 1 except serial.SerialException as error: log.fatal(error) return 1
async def connected(self): # prompt_toolkit internally checks if it's on windows during output rendering but # we need to force that we use Vt100_Output not Win32_Output from prompt_toolkit import renderer renderer.is_windows = lambda: False def get_size(): return self._size self._cli = CommandLineInterface( application=create_prompt_application(self._shell.prompt), eventloop=UnstoppableEventLoop(create_asyncio_eventloop(self._loop)), input=PatchedStdinInput(sys.stdin), output=Vt100_Output(self, get_size)) self._cb = self._cli.create_eventloop_callbacks() self._inputstream = InputStream(self._cb.feed_key) # Taken from prompt_toolkit telnet server # https://github.com/jonathanslenders/python-prompt-toolkit/blob/99fa7fae61c9b4ed9767ead3b4f9b1318cfa875d/prompt_toolkit/contrib/telnet/server.py#L165 self._cli._is_running = True if self._shell.welcome_message is not None: self.send(self._shell.welcome_message.encode()) self._cli._redraw()
def _create_more_application(): """ Create an `Application` instance that displays the "--MORE--". """ from prompt_toolkit.shortcuts import create_prompt_application registry = Registry() @registry.add_binding(' ') @registry.add_binding('y') @registry.add_binding('Y') @registry.add_binding(Keys.ControlJ) @registry.add_binding(Keys.ControlI) # Tab. def _(event): event.cli.set_return_value(True) @registry.add_binding('n') @registry.add_binding('N') @registry.add_binding('q') @registry.add_binding('Q') @registry.add_binding(Keys.ControlC) def _(event): event.cli.set_return_value(False) return create_prompt_application( '--MORE--', key_bindings_registry=registry, erase_when_done=True)
def interactive_shell(): """ Coroutine that shows the interactive command line. """ # Create an asyncio `EventLoop` object. This is a wrapper around the # asyncio loop that can be passed into prompt_toolkit. eventloop = create_asyncio_eventloop() # Create interface. cli = CommandLineInterface(application=create_prompt_application( 'Say something inside the event loop: '), eventloop=eventloop) # Patch stdout in something that will always print *above* the prompt when # something is written to stdout. sys.stdout = cli.stdout_proxy() # Run echo loop. Read text from stdin, and reply it back. while True: try: result = yield from cli.run_async() print('You said: "%s"\n' % result.text) except (EOFError, KeyboardInterrupt): loop.stop() print('Qutting event loop. Bye.') return
def pt_init(self): def get_prompt_tokens(cli): return [(Token.Prompt, self.prompt)] def patch_stdout(**kwargs): return self.pt_cli.patch_stdout_context(**kwargs) if self._ptcomp is None: compl = IPCompleter(shell=self.shell, namespace={}, global_namespace={}, parent=self.shell, ) self._ptcomp = IPythonPTCompleter(compl, patch_stdout=patch_stdout) kbmanager = KeyBindingManager.for_prompt() supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP')) kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend )(suspend_to_bg) self._pt_app = create_prompt_application( editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()), key_bindings_registry=kbmanager.registry, history=self.shell.debugger_history, completer= self._ptcomp, enable_history_search=True, mouse_support=self.shell.mouse_support, get_prompt_tokens=get_prompt_tokens ) self.pt_cli = CommandLineInterface(self._pt_app, eventloop=self.shell._eventloop)
async def td_client_interactive_shell(callback): eventloop = create_asyncio_eventloop() key_bindings_manager = KeyBindingManager.for_prompt() load_td_client_kay_bindings(key_bindings_manager=key_bindings_manager) cli = CommandLineInterface( application=create_prompt_application('待开发指令,just echo: ', key_bindings_registry=key_bindings_manager.registry, get_bottom_toolbar_tokens=get_td_client_bottom_toolbar_tokens, style=get_td_client_styles() ), eventloop=eventloop ) sys.stdout = cli.stdout_proxy() while True: try: result = await cli.run_async() if callback is not None: resp = callback(user_input=result.text) print(resp) else: print('You said: "{0}"'.format(result.text)) except (EOFError, KeyboardInterrupt): return
def init_prompt_toolkit_cli(self): """ Initializes the Prompt Tookkit CLI. """ self.init_lexer() kbmanager = KeyBindingManager.for_prompt() style_overrides = { Token.Prompt: '#aaddaa', Token.OutPrompt: '#ddaaaa', Token.Name.Namespace: '#ddaadd', Token.Name.Function: '#aadddd', } style_cls = get_style_by_name('default') style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls, style_dict=style_overrides) app = create_prompt_application( get_prompt_tokens=self.get_prompt_tokens, key_bindings_registry=kbmanager.registry, completer=self._completer, lexer=self._lexer, style=style, ) self._eventloop = create_eventloop() self.pt_cli = CommandLineInterface( app, eventloop=self._eventloop, output=create_output(true_color=False), )
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 question(message, **kwargs): default = kwargs.pop('default', '') eargs = kwargs.pop('eargs', {}) validate_prompt = kwargs.pop('validate', None) if validate_prompt: if issubclass(validate_prompt, Validator): kwargs['validator'] = validate_prompt() elif callable(validate_prompt): class _InputValidator(Validator): def validate(self, document): verdict = validate_prompt(document.text) if not verdict == True: if verdict == False: verdict = 'invalid input' raise ValidationError(message=verdict, cursor_position=len( document.text)) kwargs['validator'] = _InputValidator() for k, v in eargs.items(): if v == "" or v == " ": raise EditorArgumentsError( "Args '{}' value should not be empty".format(k)) editor = eargs.get("editor", None) ext = eargs.get("ext", ".txt") env = eargs.get("env", None) text = default filename = eargs.get("filename", None) multiline = True if not editor else False save = eargs.get("save", None) if editor: _text = edit(editor=editor, extension=ext, text=text, env=env, filename=filename, require_save=save) if filename: default = filename else: default = _text # TODO style defaults on detail level kwargs['style'] = kwargs.pop('style', default_style) qmark = kwargs.pop('qmark', '?') def _get_prompt_tokens(cli): return [(Token.QuestionMark, qmark), (Token.Question, ' %s ' % message)] return create_prompt_application(get_prompt_tokens=_get_prompt_tokens, lexer=SimpleLexer(Token.Answer), default=default, multiline=multiline, **kwargs)
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 _get_cli(self, loop): global history return CommandLineInterface( application=create_prompt_application( multiline=Condition(lambda: self._multi_line), get_prompt_tokens=self._get_prompt, history=history, wrap_lines=True, ), eventloop=loop, )
def client_connected(self, telnet_connection): # When a client is connected, erase the screen from the client and say # Hello. telnet_connection.erase_screen() telnet_connection.send('Welcome!\n') # Set CommandLineInterface. animal_completer = WordCompleter(['alligator', 'ant']) telnet_connection.set_application( create_prompt_application(message='Say something: ', lexer=HtmlLexer, completer=animal_completer, on_abort=AbortAction.RETRY), self.handle_command)
async def client_talk(loop, coro): usr = await prompt_async("username:"******"password:"******">" contacts = [] history = InMemoryHistory() cli = CommandLineInterface(application=create_prompt_application( cin, history=history, completer=cmd_complete, get_bottom_toolbar_tokens=toolbar_tokens), eventloop=loop) # cli = create_prompt_application( # cin,history=history, # completer=cmd_complete, # get_bottom_toolbar_tokens=toolbar_tokens,patch_stdout=True) sys.stdout = cli.stdout_proxy() client[0].send(Login(usr, pwd)) cin = usr + ">" while True: try: msg = await cli.run_async() sys.stdout.flush() msg = msg.text try: if msg.startswith("/"): msg = msg.split(sep="/") if msg[1] == "bye": client[0].close_conn() elif msg[1] == "contacts": client[0].send(Request("contacts", usr)) elif msg[1] == "send": client[0].send(Sender(msg[2], msg[3])) print("{0:s} [{1:s}]: {2:s}\n".format( tstamp(), usr, msg[3])) else: raise IndexError except IndexError: print("Not understood.") continue except (EOFError, KeyboardInterrupt): return
def run(self): style = style_from_dict({ Token.Prompt: 'bold', Token.Toolbar: '#ccc bg:#333', Token.Name: '#fff bold bg:#333', }) history = InMemoryHistory() eventloop = create_eventloop() app = create_prompt_application( history=history, style=style, get_bottom_toolbar_tokens=self.get_bottom_toolbar_tokens, get_prompt_tokens=self.get_prompt_tokens) self.cli = CommandLineInterface(app, eventloop) with self.cli.patch_stdout_context(raw=True): while True: try: self.cli.run() doc = self.cli.return_value() if doc is None: return cmd = shlex.split(doc.text) app.buffer.reset(append_to_history=True) if not cmd: continue elif cmd[0] in ('exit', 'quit'): self.q.put(Exit()) return elif cmd[0] == 'help': print('Help text forthcoming.') elif cmd[0] == 'skip': self.q.put(Skip()) elif cmd[0] == 'set': self.q.put( Set(cmd[1], ast.literal_eval(' '.join(cmd[2:])))) else: print('Unknown command. Try \'help\'.') except KeyboardInterrupt: continue except EOFError: self.q.put(Exit()) return except Exception as err: print(err) self.q.put(Exit()) return
async def server_console(loop): history = InMemoryHistory() cli = CommandLineInterface( application=create_prompt_application('> ', completer=cmd_complete, history=history, get_bottom_toolbar_tokens=toolbar_tokens), eventloop=loop) sys.stdout = cli.stdout_proxy() # stdout fd is asynchronous, so print messages as they arrive while True: try: result = await cli.run_async() # await a command, "await" is an asyncio-specific thing for client in clients: # Maybe you wanna send everyone a message about something client.send(result.text) except (EOFError, KeyboardInterrupt): return
async def server_console(loop): history = InMemoryHistory() cli = CommandLineInterface(application=create_prompt_application( '> ', completer=cmd_complete, history=history, get_bottom_toolbar_tokens=toolbar_tokens), eventloop=loop) sys.stdout = cli.stdout_proxy() while True: try: result = await cli.run_async() for client in clients: client.send(result.text) except (EOFError, KeyboardInterrupt): return
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 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 select(message, *options): """ Display a confirmation prompt. """ styling = style_from_dict({ Token.Key: 'bold', Token.DefaultKey: 'bold underline', }) def _get_tokens(cli): yield (Token, message + ': ') for i, option in enumerate(options): if i: yield (Token, ', ') if option.default: yield (Token.DefaultKey, option.caption[0].upper()) else: yield (Token.Key, option.caption[0].upper()) yield (Token.Caption, option.caption[1:]) yield (Token, '? ') def _event(option, event): event.cli.buffers[DEFAULT_BUFFER].text = option.output event.cli.set_return_value(option.value) registry = Registry() for option in options: handler = functools.partial(_event, option) for char in option.chars: registry.add_binding(char)(handler) if option.fallback: registry.add_binding(Keys.ControlC)(handler) registry.add_binding(Keys.Escape)(handler) if option.default: registry.add_binding(Keys.Enter)(handler) sys.stdout.flush() return run_application( create_prompt_application( get_prompt_tokens=_get_tokens, style=styling, key_bindings_registry=registry, ))
def pt_init(self): def get_prompt_tokens(cli): return [(Token.Prompt, self.prompt)] def patch_stdout(**kwargs): return self.pt_cli.patch_stdout_context(**kwargs) if self._ptcomp is None: compl = IPCompleter( shell=self.shell, namespace={}, global_namespace={}, use_readline=False, parent=self.shell, ) self._ptcomp = IPythonPTCompleter(compl, patch_stdout=patch_stdout) kbmanager = KeyBindingManager.for_prompt() supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP')) kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend)(suspend_to_bg) if self.shell.display_completions == 'readlinelike': kbmanager.registry.add_binding( Keys.ControlI, filter=(HasFocus(DEFAULT_BUFFER) & ~HasSelection() & ViInsertMode() | EmacsInsertMode() & ~cursor_in_leading_ws ))(display_completions_like_readline) multicolumn = (self.shell.display_completions == 'multicolumn') self._pt_app = create_prompt_application( editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()), key_bindings_registry=kbmanager.registry, history=self.shell.debugger_history, completer=self._ptcomp, enable_history_search=True, mouse_support=self.shell.mouse_support, get_prompt_tokens=get_prompt_tokens, display_completions_in_columns=multicolumn, ) self.pt_cli = CommandLineInterface(self._pt_app, eventloop=self.shell._eventloop)
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 __init__(self, conn, addr, application, server, encoding): assert isinstance(addr, tuple) # (addr, port) tuple assert isinstance(application, TelnetApplication) assert isinstance(server, TelnetServer) assert isinstance(encoding, text_type) # e.g. 'utf-8' self.conn = conn self.addr = addr self.application = application self.closed = False self.handling_command = True self.server = server self.encoding = encoding self.callback = None # Function that handles the CLI result. # Create "Output" object. self.size = Size(rows=40, columns=79) # Initialize. _initialize_telnet(conn) # Create output. def get_size(): return self.size self.stdout = _ConnectionStdout(conn, encoding=encoding) self.vt100_output = Vt100_Output(self.stdout, get_size, write_binary=False) # Create an eventloop (adaptor) for the CommandLineInterface. self.eventloop = _TelnetEventLoopInterface(server) # Set default CommandLineInterface. self.set_application(create_prompt_application()) # Call client_connected application.client_connected(self) # Draw for the first time. self.handling_command = False self.cli._redraw()
def pt_init(self): def get_prompt_tokens(cli): return [(Token.Prompt, self.prompt)] def patch_stdout(**kwargs): return self.pt_cli.patch_stdout_context(**kwargs) if self._ptcomp is None: compl = IPCompleter(shell=self.shell, namespace={}, global_namespace={}, parent=self.shell, ) self._ptcomp = IPythonPTCompleter(compl, patch_stdout=patch_stdout) kbmanager = KeyBindingManager.for_prompt() supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP')) kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend )(suspend_to_bg) if self.shell.display_completions == 'readlinelike': kbmanager.registry.add_binding(Keys.ControlI, filter=(HasFocus(DEFAULT_BUFFER) & ~HasSelection() & ViInsertMode() | EmacsInsertMode() & ~cursor_in_leading_ws ))(display_completions_like_readline) multicolumn = (self.shell.display_completions == 'multicolumn') self._pt_app = create_prompt_application( editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()), key_bindings_registry=kbmanager.registry, history=self.shell.debugger_history, completer= self._ptcomp, enable_history_search=True, mouse_support=self.shell.mouse_support, get_prompt_tokens=get_prompt_tokens, display_completions_in_columns=multicolumn, style=self.shell.style ) self.pt_cli = CommandLineInterface(self._pt_app, eventloop=self.shell._eventloop)
def pt_init(self): def get_prompt_tokens(cli): return [(Token.Prompt, self.prompt)] if self._ptcomp is None: compl = IPCompleter(shell=self.shell, namespace={}, global_namespace={}, parent=self.shell, ) self._ptcomp = IPythonPTCompleter(compl) self._pt_app = create_prompt_application( editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()), history=self.shell.debugger_history, completer= self._ptcomp, enable_history_search=True, mouse_support=self.shell.mouse_support, get_prompt_tokens=get_prompt_tokens ) self.pt_cli = CommandLineInterface(self._pt_app, eventloop=self.shell._eventloop)
def __init__(self, conn, addr, application, server, encoding): assert isinstance(addr, tuple) # (addr, port) tuple assert isinstance(application, TelnetApplication) assert isinstance(server, TelnetServer) assert isinstance(encoding, text_type) # e.g. 'utf-8' self.conn = conn self.addr = addr self.application = application self.closed = False self.handling_command = True self.server = server self.encoding = encoding self.callback = None # Function that handles the CLI result. # Create "Output" object. self.size = Size(rows=40, columns=79) # Initialize. _initialize_telnet(conn) # Create output. def get_size(): return self.size self.stdout = _ConnectionStdout(conn, encoding=encoding) self.vt100_output = Vt100_Output(self.stdout, get_size) # Create an eventloop (adaptor) for the CommandLineInterface. self.eventloop = _TelnetEventLoopInterface(server) # Set default CommandLineInterface. self.set_application(create_prompt_application()) # Call client_connected application.client_connected(self) # Draw for the first time. self.handling_command = False self.cli._redraw()
def __init__(self, repository, eventloop, tests, config, em, runner_class): self.repository = repository self.history = InMemoryHistory() self.tests = tests self.config = config self.displayer = TestDisplayer(self.tests) self.eventloop = eventloop self.runner_class = runner_class self.em = em # Register the callbacks self.em.register(self.displayer.parse_message) self.application = create_prompt_application("> ", history=self.history, completer=completer) self.cli = CommandLineInterface( application=self.application, eventloop=create_asyncio_eventloop(eventloop)) sys.stdout = self.cli.stdout_proxy()
async def interactive_shell(bot): eventloop = create_asyncio_eventloop(bot.loop) cli = CommandLineInterface( application=create_prompt_application(':> ', completer=myCompleter(bot)), eventloop=eventloop, ) sys.stdout = cli.stdout_proxy() while True: try: result = await cli.run_async() if result.text.startswith("#"): parse = total.parseString(result.text[1:], parseAll=True) try: resp = await bot.run_parse(parse, Message(server='SHELL')) for res in resp: print(res.text) except PipeError as e: for loc, err in sorted(e.exs, key=lambda x: x[0]): if isinstance(err, PipeError): for loc2, err2 in sorted(err.exs, key=lambda x: x[0]): try: raise err2 except Exception: # how to print to terminal traceback.print_exc() else: try: raise err except Exception: # how to print to terminal traceback.print_exc() else: try: await aexec(result.text, local={'bot': bot}) except Exception: traceback.print_exc() except (EOFError, KeyboardInterrupt): bot.loop.stop()
def __init__(self, style): self._commands = {} for d in dir(self.__class__): if d.startswith('do_'): name = d[3:] func = getattr(self, d) doc = textwrap.dedent(func.__doc__ or '') self._commands[name] = (func, doc) self._history = InMemoryHistory() self._application = create_prompt_application( get_prompt_tokens=self.get_prompt_tokens, style=style, on_abort=AbortAction.RETURN_NONE, history=self._history) self._cli = CommandLineInterface(application=self._application, output=create_output(true_color=True), eventloop=create_asyncio_eventloop()) self._style = style
async def interactive_shell(): """ Like `interactive_shell`, but doing things manual. """ # Create an asyncio `EventLoop` object. This is a wrapper around the # asyncio loop that can be passed into prompt_toolkit. eventloop = create_asyncio_eventloop() # Create interface. cli = CommandLineInterface(application=create_prompt_application( 'Say something inside the event loop: '), eventloop=eventloop) # Patch stdout in something that will always print *above* the prompt when # something is written to stdout. sys.stdout = cli.stdout_proxy() # Run echo loop. Read text from stdin, and reply it back. while True: try: result = await cli.run_async() print('You said: "{0}"'.format(result.text)) except (EOFError, KeyboardInterrupt): return
def main(): app = create_prompt_application('prompt> ') while True: run_application(app)
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 self.major_minor < (0, 57): kwargs.pop('reserve_space_for_menu', None) if self.major_minor <= (0, 57): kwargs.pop('get_rprompt_tokens', None) kwargs.pop('get_continuation_tokens', None) # VI_Mode handling changed in prompt_toolkit v1.0 if self.major_minor >= (1, 0): from prompt_toolkit.enums import EditingMode if builtins.__xonsh_env__.get('VI_MODE'): editing_mode = EditingMode.VI else: editing_mode = EditingMode.EMACS kwargs['editing_mode'] = editing_mode kwargs['vi_mode'] = builtins.__xonsh_env__.get('VI_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 read(self, prompt_str='λ く'): ''' The main read eval print loop for RIPL. Uses prompt_toolkit: http://python-prompt-toolkit.readthedocs.io/en/stable/ ''' def exit_message(): print('\nThanks for giving RIPL a try!\nさようなら!\n') if not self.global_scope: raise EnvironmentError('Things have gone horribly wrong...') print(' <({[ RIPL -- RIPL Is Pythonic Lisp ]})>\n' ' Ctrl-Space to enter selection mode.\n' ' Ctrl-W/Y to cut/paste to system clipboard.\n' ' Ctrl-D to exit\n') history = InMemoryHistory() completer = WordCompleter(self.completions, ignore_case=True) kbm = KeyBindingManager.for_prompt(enable_system_bindings=True) add_binding = kbm.registry.add_binding @add_binding(Keys.Tab, filter=Tab_to_whitespace()) def _(event): '''Either indent or do completion''' event.cli.current_buffer.insert_text(' ') @add_binding(Keys.ControlJ) def __(event): '''Either enter a newline or accept input based on context''' b = event.current_buffer txt = b.document.text def at_end(b): '''Is the cursor at the end of the buffer?''' text = b.document.text_after_cursor return text == '' or (text.isspace() and '\n' not in text) at_end = at_end(b) has_empty_line = txt.replace(' ', '').endswith('\n') balanced = is_balanced(b.document.text) if (at_end and has_empty_line) or balanced: if b.validate(): b.accept_action.validate_and_handle(event.cli, b) else: newline_and_indent(b) # Show matching parentheses, but only while editing. highlight_parens = ConditionalProcessor( processor=HighlightMatchingBracketProcessor( chars='[](){}'), filter=~IsDone()) while True: repl = create_prompt_application( prompt_str, multiline=True, history=history, style=ripl_style, mouse_support=True, completer=completer, validator=ParenValidator(), enable_history_search=True, complete_while_typing=False, clipboard=PyperclipClipboard(), lexer=PygmentsLexer(RiplLexer), key_bindings_registry=kbm.registry, display_completions_in_columns=True, auto_suggest=AutoSuggestFromHistory(), get_continuation_tokens=self.cont_tokens, extra_input_processors=[highlight_parens]) try: eventloop = create_eventloop() cli = CommandLineInterface( application=repl, eventloop=eventloop, output=create_output(true_color=True)) user_input = cli.run(reset_current_buffer=False) if user_input: if isinstance(user_input, Document): user_input = user_input.text lines = user_input.split('\n') expression = ' '.join([l.strip() for l in lines]) self.eval_and_print(expression) except (EOFError, KeyboardInterrupt): # User hit Ctl+d exit_message() break finally: eventloop.close()
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) def _(event): event.current_buffer.reset() @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=PygmentsLexer(Python3Lexer if PY3 else PythonLexer), 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, ) self.pt_cli = CommandLineInterface(app, eventloop=create_eventloop( self.inputhook))
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() 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 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 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: cc = b.complete_state.current_completion if cc: b.apply_completion(cc) else: b.cancel_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.ControlP, filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER))) def _previous_history_or_previous_completion(event): """ Control-P in vi edit mode on readline is history next, unlike default prompt toolkit. If completer is open this still select previous completion. """ event.current_buffer.auto_up() @kbmanager.registry.add_binding(Keys.ControlN, filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER))) def _next_history_or_next_completion(event): """ Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit. If completer is open this still select next completion. """ event.current_buffer.auto_down() @kbmanager.registry.add_binding(Keys.ControlG, filter=( HasFocus(DEFAULT_BUFFER) & HasCompletions() )) def _dismiss_completion(event): b = event.current_buffer if b.complete_state: b.cancel_completion() @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)) def _reset_buffer(event): b = event.current_buffer if b.complete_state: b.cancel_completion() else: b.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)
async def xmpp_client(): try: with open(os.path.join(os.getenv("HOME"), ".xc.conf"), "r") as config_file: config = json.load(config_file) if "jid" not in config: raise Exception("No JID") except Exception as e: print("Error reading configuration file.\n" + str(e) + "Please create ~/.xc.conf with content like:\n{\"jid\": \"[email protected]\"}") sys.exit(1) async def get_secret(jid, attempt): if attempt > 2: return None try: return await prompt_async("Secret (will not be stored): ", is_password=True) except: return None async def tls_handshake_callback(verifier): print("Warning: blindly accepting TLS certificate from %s" % verifier.transport.get_extra_info("server_hostname")) return True pin_store = PublicKeyPinStore() pin_store.import_from_json(config.get("pkps", {})) my_jid = aioxmpp.JID.fromstr(config["jid"]) security = aioxmpp.make_security_layer(get_secret, pin_store=pin_store, pin_type=PinType.PUBLIC_KEY, post_handshake_deferred_failure=tls_handshake_callback) client = aioxmpp.PresenceManagedClient(my_jid, security) presence = client.summon(aioxmpp.presence.Service) roster = client.summon(aioxmpp.roster.Service) class RosterItemAndCommandCompleter(Completer): def get_completions(self, document, complete_event): text = document.text if not text or " " in text or ":" in text: return if text[0] == "/": part = text[1:] for command in ("roster", "name", "add", "del", "help", "quit"): if command.startswith(part): yield Completion(command + " ", start_position=-len(part), display=command) elif roster is not None: for item in roster.items.values(): if item.name.startswith(text): yield Completion(item.name + ": ", start_position=-len(text), display=item.name) completer = RosterItemAndCommandCompleter() history = InMemoryHistory() next_recipient = None def get_prompt_tokens(_): return ((Token.Prompt, "%s> " % (next_recipient or "")),) cli_app = create_prompt_application(get_prompt_tokens=get_prompt_tokens, completer=completer, reserve_space_for_menu=0, history=history, get_title=lambda: "xc") cli_loop = create_asyncio_eventloop() cli = CommandLineInterface(application=cli_app, eventloop=cli_loop) above_prompt = cli.stdout_proxy() def name_for_jid(jid): try: return roster.items[jid].name except: return str(jid) def peer_available(jid, presence): above_prompt.write("%s is now online\n" % name_for_jid(jid.bare())) presence.on_available.connect(peer_available) def peer_unavailable(jid, presence): above_prompt.write("%s is now offline\n" % name_for_jid(jid.bare())) presence.on_unavailable.connect(peer_unavailable) def message_received(msg): content = " ".join(msg.body.values()) if content: above_prompt.write("%s: %s\n" % (name_for_jid(msg.from_.bare()), content)) client.stream.register_message_callback("chat", None, message_received) try: async with client.connected() as stream: while True: try: document = await cli.run_async() except (KeyboardInterrupt, EOFError): break line = document.text if line.startswith("/"): try: command, *args = line[1:].split(" ") if command == "roster": rows = [(item.name, str(jid), item.subscription) for jid, item in roster.items.items() if jid != my_jid] widths = [max(len(row[i] or "") for row in rows) for i in range(len(rows[0] or ""))] for row in rows: above_prompt.write(" ".join((cell or "").ljust(widths[i]) for i, cell in enumerate(row)) + "\n") elif command == "name": try: jid = args[0] name = args[1] except IndexError: above_prompt.write("usage: /name JID NAME\n") else: jid = aioxmpp.JID.fromstr(jid) await roster.set_entry(jid, name=name) elif command == "add": try: jid = args[0] except IndexError: above_prompt.write("usage: /add JID\n") else: jid = aioxmpp.JID.fromstr(jid) await roster.set_entry(jid) roster.subscribe(jid) roster.approve(jid) elif command == "del": try: jid = args[0] except IndexError: above_prompt.write("usage: /del JID\n") else: jid = aioxmpp.JID.fromstr(jid) await roster.remove_entry(jid) elif command == "quit": break elif command == "help": above_prompt.write("NAME: MESSAGE send MESSAGE to NAME\n" "MESSAGE send MESSAGE to the last correspondent\n" "/roster print the roster\n" "/add JID add JID to the roster\n" "/del JID remove JID from the roster\n" "/name JID NAME set the name of JID to NAME\n" "/quit disconnect and then quit (also ctrl-d, ctrl-c)\n" "/help this help\n") else: above_prompt.write("unrecognised command\n") except Exception as e: above_prompt.write("exception handling command: %s\n" % e) else: try: try: recipient, message = line.split(": ", 1) except ValueError: if next_recipient is not None: recipient = next_recipient message = line else: above_prompt.write("recipient: message\n") continue jid_for_name = lambda r: next((jid for jid, item in roster.items.items() if item.name == r), None) jid = jid_for_name(recipient) if jid is None: if next_recipient is not None and recipient != next_recipient: recipient = next_recipient jid = jid_for_name(recipient) message = line if jid is None: above_prompt.write("unknown recipient: %s\n" % recipient) continue msg = aioxmpp.Message(to=jid, type_="chat") msg.body[None] = message await stream.send_and_wait_for_sent(msg) next_recipient = recipient except Exception as e: above_prompt.write("exception sending message: %s\n" % e) print("Disconnecting…") client.stop() except Exception as e: print("Failed to connect: %s" % e)
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 except Exception: xt.print_exception() # return something to prevent xonsh crash when any # exceptions raise return "" finally: eventloop.close()
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) self._style = self._make_style_from_name(self.highlighting_style) style = DynamicStyle(lambda: self._style) self._app = create_prompt_application( 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.pt_cli = CommandLineInterface(self._app, eventloop=create_eventloop(self.inputhook))
def init_prompt_toolkit_cli(self): if '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 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() # 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', 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 __init__(self, looper, basedirpath, nodeReg, cliNodeReg, output=None, debug=False, logFileName=None): self.curClientPort = None logging.root.addHandler(CliHandler(self.out)) self.looper = looper self.basedirpath = basedirpath self.nodeReg = nodeReg self.cliNodeReg = cliNodeReg # Used to store created clients self.clients = {} # clientName -> Client # To store the created requests self.requests = {} # To store the nodes created self.nodes = {} self.externalClientKeys = {} # type: Dict[str,str] self.cliCmds = {'status', 'new'} self.nodeCmds = self.cliCmds | {'keyshare'} self.helpablesCommands = self.cliCmds | self.nodeCmds self.simpleCmds = {'status', 'exit', 'quit', 'license'} self.commands = {'list', 'help'} | self.simpleCmds self.cliActions = {'send', 'show'} self.commands.update(self.cliCmds) self.commands.update(self.nodeCmds) self.node_or_cli = ['node', 'client'] self.nodeNames = list(self.nodeReg.keys()) + ["all"] self.debug = debug self.plugins = {} ''' examples: status new node Alpha new node all new client Joe client Joe send <msg> client Joe show 1 ''' psep = re.escape(os.path.sep) self.utilGrams = [ "(\s* (?P<simple>{}) \s*) |".format(self.relist(self.simpleCmds)), "(\s* (?P<load>load) \s+ (?P<file_name>[.a-zA-z0-9{}]+) \s*) |".format(psep), "(\s* (?P<command>help) (\s+ (?P<helpable>[a-zA-Z0-9]+) )? (\s+ (?P<node_or_cli>{}) )?\s*) |".format(self.relist(self.node_or_cli)), "(\s* (?P<command>list) \s*)" ] self.nodeGrams = [ "(\s* (?P<node_command>{}) \s+ (?P<node_or_cli>nodes?) \s+ (?P<node_name>[a-zA-Z0-9]+)\s*) |".format(self.relist(self.nodeCmds)), "(\s* (?P<load_plugins>load\s+plugins\s+from) \s+ (?P<plugin_dir>[a-zA-Z0-9-:{}]+) \s*)".format(psep), ] self.clientGrams = [ "(\s* (?P<client_command>{}) \s+ (?P<node_or_cli>clients?) \s+ (?P<client_name>[a-zA-Z0-9]+) \s*) |".format(self.relist(self.cliCmds)), "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>send) \s+ (?P<msg>\{\s*.*\}) \s*) |", "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>show) \s+ (?P<req_id>[0-9]+) \s*) |", "(\s* (?P<add_key>add\s+key) \s+ (?P<verkey>[a-fA-F0-9]+) \s+ (?P<for_client>for\s+client) \s+ (?P<identifier>[a-zA-Z0-9]+) \s*)", ] self.lexers = { 'node_command': SimpleLexer(Token.Keyword), 'command': SimpleLexer(Token.Keyword), 'helpable': SimpleLexer(Token.Keyword), 'load_plugins': SimpleLexer(Token.Keyword), 'load': SimpleLexer(Token.Keyword), 'node_or_cli': SimpleLexer(Token.Keyword), 'arg1': SimpleLexer(Token.Name), 'node_name': SimpleLexer(Token.Name), 'more_nodes': SimpleLexer(Token.Name), 'simple': SimpleLexer(Token.Keyword), 'client_command': SimpleLexer(Token.Keyword), 'add_key': SimpleLexer(Token.Keyword), 'verkey': SimpleLexer(Token.Literal), 'for_client': SimpleLexer(Token.Keyword), 'identifier': SimpleLexer(Token.Name), } self.clientWC = WordCompleter([]) self.completers = { 'node_command': WordCompleter(self.nodeCmds), 'client_command': WordCompleter(self.cliCmds), 'client': WordCompleter(['client']), 'command': WordCompleter(self.commands), 'node_or_cli': WordCompleter(self.node_or_cli), 'node_name': WordCompleter(self.nodeNames), 'more_nodes': WordCompleter(self.nodeNames), 'helpable': WordCompleter(self.helpablesCommands), 'load_plugins': WordCompleter(['load plugins from']), 'client_name': self.clientWC, 'cli_action': WordCompleter(self.cliActions), 'simple': WordCompleter(self.simpleCmds), 'add_key': WordCompleter(['add key']), 'for_client': WordCompleter(['for client']), } self.initializeGrammar() self.initializeGrammarLexer() self.initializeGrammarCompleter() self.style = PygmentsStyle.from_defaults({ Token.Operator: '#33aa33 bold', Token.Number: '#aa3333 bold', Token.Name: '#ffff00 bold', Token.Heading: 'bold', Token.TrailingInput: 'bg:#662222 #ffffff', Token.BoldGreen: '#33aa33 bold', Token.BoldOrange: '#ff4f2f bold', Token.BoldBlue: '#095cab bold'}) self.functionMappings = self.createFunctionMappings() self.voidMsg = "<none>" # Create an asyncio `EventLoop` object. This is a wrapper around the # asyncio loop that can be passed into prompt_toolkit. eventloop = create_asyncio_eventloop(looper.loop) pers_hist = FileHistory('.{}-cli-history'.format(self.name)) # Create interface. app = create_prompt_application('{}> '.format(self.name), lexer=self.grammarLexer, completer=self.grammarCompleter, style=self.style, history=pers_hist) if output: out = output else: if is_windows(): if is_conemu_ansi(): out = ConEmuOutput(sys.__stdout__) else: out = Win32Output(sys.__stdout__) else: out = CustomOutput.from_pty(sys.__stdout__, true_color=True) self.cli = CommandLineInterface( application=app, eventloop=eventloop, output=out) # Patch stdout in something that will always print *above* the prompt # when something is written to stdout. sys.stdout = self.cli.stdout_proxy() setupLogging(TRACE_LOG_LEVEL, Console.Wordage.mute, filename=logFileName) self.logger = getlogger("cli") self.print("\n{}-CLI (c) 2016 Evernym, Inc.".format(self.properName)) self.print("Node registry loaded.") self.print("None of these are created or running yet.") self.showNodeRegistry() self.print("Type 'help' for more information.")
def _process_input(self, reactor): self._print_startup_message() while self._ready.wait(0.5) != True: if not reactor.is_running(): return while True: expression = "" line = "" while len(expression) == 0 or line.endswith("\\"): if not reactor.is_running(): return try: prompt = "[%s]" % self._prompt_string + "-> " if len(expression) == 0 else "... " # We create the prompt manually instead of using get_input, # so we can use the cli in the _on_stop method eventloop = create_eventloop() self._cli = CommandLineInterface( application=create_prompt_application(prompt, history=self._history, completer=self._completer, lexer=JavascriptLexer), eventloop=eventloop, output=create_output()) try: line = None document = self._cli.run() if document: line = document.text finally: eventloop.close() except EOFError: # An extra newline after EOF to exit the REPL cleanly self._print("\nThank you for using Frida!") return except KeyboardInterrupt: line = "" continue if len(line.strip()) > 0: if len(expression) > 0: expression += "\n" expression += line.rstrip("\\") if expression.endswith("?"): try: self._print_help(expression) except JavaScriptError as e: error = e.error self._print(Fore.RED + Style.BRIGHT + error['name'] + Style.RESET_ALL + ": " + error['message']) except frida.InvalidOperationError: return elif expression.startswith("%"): self._do_magic(expression[1:].rstrip()) elif expression in ("exit", "quit", "q"): self._print("Thank you for using Frida!") return elif expression == "help": self._print("Help: #TODO :)") else: self._eval_and_print(expression)
def init_prompt_toolkit_cli(self): if not sys.stdin.isatty(): # Piped input - e.g. for tests. Fall back to plain non-interactive # output. 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) def _(event): event.current_buffer.reset() # 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=PygmentsLexer(Python3Lexer if PY3 else PythonLexer), 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, ) self.pt_cli = CommandLineInterface(app, eventloop=create_eventloop(self.inputhook))
def __init__(self, looper, tmpdir, nodeReg, cliNodeReg, debug=False, logFileName=None): self.curClientPort = None logging.root.addHandler(CliHandler(self.out)) self.looper = looper self.tmpdir = tmpdir self.nodeReg = nodeReg self.cliNodeReg = cliNodeReg # Used to store created clients self.clients = {} # clientId -> Client # To store the created requests self.requests = {} # To store the nodes created self.nodes = {} self.cliCmds = {'status', 'new'} self.nodeCmds = self.cliCmds | {'keyshare'} self.helpablesCommands = self.cliCmds | self.nodeCmds self.simpleCmds = {'status', 'exit', 'quit', 'license'} self.commands = {'list', 'help'} | self.simpleCmds self.cliActions = {'send', 'show'} self.commands.update(self.cliCmds) self.commands.update(self.nodeCmds) self.node_or_cli = ['node', 'client'] self.nodeNames = list(self.nodeReg.keys()) + ["all"] self.debug = debug self.plugins = [] ''' examples: status new node Alpha new node all new client Joe client Joe send <msg> client Joe show 1 ''' def re(seq): return '(' + '|'.join(seq) + ')' grams = [ "(\s* (?P<simple>{}) \s*) |".format(re(self.simpleCmds)), "(\s* (?P<client_command>{}) \s+ (?P<node_or_cli>clients?) \s+ (?P<client_name>[a-zA-Z0-9]+) \s*) |".format(re(self.cliCmds)), "(\s* (?P<node_command>{}) \s+ (?P<node_or_cli>nodes?) \s+ (?P<node_name>[a-zA-Z0-9]+)\s*) |".format(re(self.nodeCmds)), "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>send) \s+ (?P<msg>\{\s*\".*\}) \s*) |", "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>show) \s+ (?P<req_id>[0-9]+) \s*) |", "(\s* (?P<load_plugins>load\s+plugins\s+from) \s+ (?P<plugin_dir>[a-zA-Z0-9-{}]+) \s*) |".format(os.path.sep), "(\s* (?P<load>load) \s+ (?P<file_name>[.a-zA-z0-9{}]+) \s*) |".format(os.path.sep), "(\s* (?P<command>help) (\s+ (?P<helpable>[a-zA-Z0-9]+) )? (\s+ (?P<node_or_cli>{}) )?\s*) |".format(re(self.node_or_cli)), "(\s* (?P<command>list) \s*)".format(re(self.commands)) ] self.grammar = compile("".join(grams)) lexer = GrammarLexer(self.grammar, lexers={ 'node_command': SimpleLexer(Token.Keyword), 'command': SimpleLexer(Token.Keyword), 'helpable': SimpleLexer(Token.Keyword), 'load_plugins': SimpleLexer(Token.Keyword), 'load': SimpleLexer(Token.Keyword), 'node_or_cli': SimpleLexer(Token.Keyword), 'arg1': SimpleLexer(Token.Name), 'node_name': SimpleLexer(Token.Name), 'more_nodes': SimpleLexer(Token.Name), 'simple': SimpleLexer(Token.Keyword), 'client_command': SimpleLexer(Token.Keyword), }) self.clientWC = WordCompleter([]) completer = GrammarCompleter(self.grammar, { 'node_command': WordCompleter(self.nodeCmds), 'client_command': WordCompleter(self.cliCmds), 'client': WordCompleter(['client']), 'command': WordCompleter(self.commands), 'node_or_cli': WordCompleter(self.node_or_cli), 'node_name': WordCompleter(self.nodeNames), 'more_nodes': WordCompleter(self.nodeNames), 'helpable': WordCompleter(self.helpablesCommands), 'load_plugins': WordCompleter(['load plugins from']), 'client_name': self.clientWC, 'cli_action': WordCompleter(self.cliActions), 'simple': WordCompleter(self.simpleCmds) }) self.style = PygmentsStyle.from_defaults({ Token.Operator: '#33aa33 bold', Token.Number: '#aa3333 bold', Token.Name: '#ffff00 bold', Token.Heading: 'bold', Token.TrailingInput: 'bg:#662222 #ffffff', Token.BoldGreen: '#33aa33 bold', Token.BoldOrange: '#ff4f2f bold', Token.BoldBlue: '#095cab bold'}) self.functionMappings = self.createFunctionMappings() self.voidMsg = "<none>" # Create an asyncio `EventLoop` object. This is a wrapper around the # asyncio loop that can be passed into prompt_toolkit. eventloop = create_asyncio_eventloop(looper.loop) pers_hist = FileHistory('.plenum-cli-history') # Create interface. app = create_prompt_application('plenum> ', lexer=lexer, completer=completer, style=self.style, history=pers_hist) self.cli = CommandLineInterface( application=app, eventloop=eventloop, output=CustomOutput.from_pty(sys.__stdout__, true_color=True)) # Patch stdout in something that will always print *above* the prompt # when something is written to stdout. sys.stdout = self.cli.stdout_proxy() setupLogging(TRACE_LOG_LEVEL, Console.Wordage.mute, filename=logFileName) self.logger = getlogger("cli") self.print("\nplenum-CLI (c) 2016 Evernym, Inc.") self.print("Node registry loaded.") self.print("None of these are created or running yet.") self.showNodeRegistry() self.print("Type 'help' for more information.")