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 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 main(): # We start with a `KeyBindingManager` instance, because this will already # nicely load all the default key bindings. key_bindings_manager = KeyBindingManager() # We add a custom key binding to space. @key_bindings_manager.registry.add_binding(' ') def _(event): """ When space is pressed, we check the word before the cursor, and autocorrect that. """ b = event.cli.current_buffer w = b.document.get_word_before_cursor() if w is not None: if w in corrections: b.delete_before_cursor(count=len(w)) b.insert_text(corrections[w]) b.insert_text(' ') # Read input. print('Say something') text = get_input(key_bindings_registry=key_bindings_manager.registry) print('You said: %s' % text)
def __init__(self, prompt=None, histfile=None, eventloop=None): cmd.Cmd.__init__(self) self.title = u"mailnex" self.completer = Completer(self) # ttyBusy tracks times when printing is a Bad Idea self.ttyBusy = False # lexerEnabled is a marker for the lexer to check before doing # interpretations. Currently, this just turns it off when the prompt # isn't for the command line but for composing messages. self.lexerEnabled = True if histfile: self.history = prompt_toolkit.history.FileHistory(histfile) else: self.history = prompt_toolkit.history.InMemoryHistory() if prompt is None: prompt = "> " self.prompt = prompt def gpt(cli): return [ (Token, self.prompt), ] self.ptkevloop = ptk_pyuv_wrapper(eventloop) registry = KeyBindingManager.for_prompt().registry @registry.add_binding(Keys.ControlZ) def _(event): """Support backrounding ourselves.""" # I'm surprised this isn't part of the default maps. # # Ideally, we shouldn't actually have to handle this ourselves; the # terminal should handle it for us. However, we are putting the # terminal into raw mode, so it won't. The next best thing would be # to try to get the actual background character the terminal would # use and use that. It is controlZ by default on every Unix system # I've used, but it is adjustable, with the 'stty' utility for # example. # TODO: Figure out how to use an appropriate key here, or allow it # to be customized. event.cli.suspend_to_background() self.cli = prompt_toolkit.interface.CommandLineInterface( application = prompt_toolkit.shortcuts.create_prompt_application( u"", #multiline = True, get_prompt_tokens = gpt, style = prompt_style, lexer = PygmentsLexer(PromptLexerFactory(self)), completer = self.completer, history = self.history, auto_suggest = prompt_toolkit.auto_suggest.AutoSuggestFromHistory(), get_title = self.get_title, get_bottom_toolbar_tokens=self.toolbar, key_bindings_registry=registry, ), eventloop = self.ptkevloop, output = prompt_toolkit.shortcuts.create_output(true_color = False), ) # ui_lines is the number of lines occupied by the UI. # For example, 1 line for command prompt, 7 lines for completion menu, # 1 line for toolbar. self.ui_lines = 9 self.status = {'unread': None}
def set_key_binding(cntrllr): manager = KeyBindingManager.for_prompt() registry = manager.registry @registry.add_binding(Keys.ControlQ, eager=True) @registry.add_binding(Keys.ControlC, eager=True) def _(event): event.cli.set_return_value(None) @registry.add_binding(Keys.Down, eager=True) @registry.add_binding(Keys.ControlN, eager=True) def move_cursor_down(event): cntrllr.selected_option_index = ((cntrllr.selected_option_index + 1) % cntrllr.choice_count) @registry.add_binding(Keys.Up, eager=True) @registry.add_binding(Keys.ControlP, eager=True) def move_cursor_up(event): cntrllr.selected_option_index = ((cntrllr.selected_option_index - 1) % cntrllr.choice_count) @registry.add_binding(Keys.Enter, eager=True) def set_answer(event): cntrllr.answered = True event.cli.set_return_value(None) return registry
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__(self, **kwargs): super().__init__(**kwargs) self.history = setup_history() self.pt_completer = PromptToolkitCompleter(self.completer, self.ctx) self.key_bindings_manager = KeyBindingManager( enable_search=True, enable_abort_and_exit_bindings=True) load_xonsh_bindings(self.key_bindings_manager)
def create_cli(message='', multiline=False, is_password=False, vi_mode=False, lexer=None, enable_system_prompt=False, enable_open_in_editor=False, validator=None, completer=None, style=None, history=None, get_bottom_toolbar_tokens=None): # Create history instance. if history is None: history = History() # Load all key bindings. manager = KeyBindingManager(enable_vi_mode=vi_mode, enable_system_prompt=enable_system_prompt, enable_open_in_editor=enable_open_in_editor) # Create interface. return CommandLineInterface( layout=create_default_layout(message=message, lexer=lexer, is_password=is_password, reserve_space_for_menu=(completer is not None), get_bottom_toolbar_tokens=get_bottom_toolbar_tokens), buffer=Buffer( is_multiline=multiline, history=history, validator=validator, completer=completer, ), key_bindings_registry=manager.registry, style=style)
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 _feed_cli_with_input(text, editing_mode=EditingMode.EMACS, clipboard=None, history=None): """ Create a CommandLineInterface, feed it with the given user input and return the CLI object. This returns a (result, CLI) tuple. """ # If the given text doesn't end with a newline, the interface won't finish. assert text.endswith('\n') loop = PosixEventLoop() try: inp = PipeInput() inp.send_text(text) cli = CommandLineInterface( application=Application( buffer=Buffer(accept_action=AcceptAction.RETURN_DOCUMENT, history=history), editing_mode=editing_mode, clipboard=clipboard or InMemoryClipboard(), key_bindings_registry=KeyBindingManager.for_prompt().registry, ), eventloop=loop, input=inp, output=DummyOutput()) result = cli.run() return result, cli finally: loop.close() inp.close()
def main(): # We start with a `KeyBindingManager` instance, because this will already # nicely load all the default key bindings. key_bindings_manager = KeyBindingManager() # Add our own key binding to the registry of the key bindings manager. @key_bindings_manager.registry.add_binding(Keys.F4) def _(event): """ When F4 has been pressed. Insert "hello world" as text. """ event.cli.current_buffer.insert_text('hello world') @key_bindings_manager.registry.add_binding('x', 'y') def _(event): """ (Useless, but for demoing.) Typing 'xy' will insert 'z'. Note that when you type for instance 'xa', the insertion of 'x' is postponed until the 'a' is typed. because we don't know earlier whether or not a 'y' will follow. """ event.cli.current_buffer.insert_text('z') # Read input. print('Press F4 to insert "hello world", type "xy" to insert "z":') text = get_input(key_bindings_registry=key_bindings_manager.registry) print('You said: %s' % text)
def run(): # Create a set of key bindings that have Vi mode enabled if the # ``vi_mode_enabled`` is True.. manager = KeyBindingManager.for_prompt() # Add an additional key binding for toggling this flag. @manager.registry.add_binding(Keys.F4) def _(event): " Toggle between Emacs and Vi mode. " if event.cli.editing_mode == EditingMode.VI: event.cli.editing_mode = EditingMode.EMACS else: event.cli.editing_mode = EditingMode.VI # Add a bottom toolbar to display the status. style = style_from_dict({ Token.Toolbar: 'reverse', }) def get_bottom_toolbar_tokens(cli): " Display the current input mode. " text = 'Vi' if cli.editing_mode == EditingMode.VI else 'Emacs' return [(Token.Toolbar, ' [F4] %s ' % text)] prompt('> ', key_bindings_registry=manager.registry, get_bottom_toolbar_tokens=get_bottom_toolbar_tokens, style=style)
def _feed_cli_with_input(text, editing_mode=EditingMode.EMACS, clipboard=None, history=None): """ Create a CommandLineInterface, feed it with the given user input and return the CLI object. This returns a (result, CLI) tuple. """ # If the given text doesn't end with a newline, the interface won't finish. assert text.endswith('\n') from prompt_toolkit.eventloop.posix import PosixEventLoop as EventLoop loop = EventLoop() try: inp = PipeInput() inp.send_text(text) cli = CommandLineInterface(application=Application( buffer=Buffer(accept_action=AcceptAction.RETURN_DOCUMENT, history=history), editing_mode=editing_mode, clipboard=clipboard or InMemoryClipboard(), key_bindings_registry=KeyBindingManager.for_prompt().registry, ), eventloop=loop, input=inp, output=DummyOutput()) result = cli.run() return result, cli finally: loop.close() inp.close()
def _build_cli(self): layout = create_prompt_layout( message='{0}> '.format(self.args['username']), lexer=PygmentsLexer(SqlLexer), ) buf = Buffer(completer=self.completer, history=self.history, complete_while_typing=Always(), accept_action=AcceptAction.RETURN_DOCUMENT) key_binding_manager = KeyBindingManager( enable_abort_and_exit_bindings=True, ) application = Application( layout=layout, buffer=buf, key_bindings_registry=key_binding_manager.registry, on_exit=AbortAction.RAISE_EXCEPTION, on_abort=AbortAction.RETRY, ignore_case=True) cli = CommandLineInterface(application=application, eventloop=self.eventloop) return cli
def run(): vi_mode_enabled = False # Create a set of key bindings that have Vi mode enabled if the # ``vi_mode_enabled`` is True.. manager = KeyBindingManager.for_prompt( enable_vi_mode=Condition(lambda cli: vi_mode_enabled)) # Add an additional key binding for toggling this flag. @manager.registry.add_binding(Keys.F4) def _(event): " Toggle between Emacs and Vi mode. " nonlocal vi_mode_enabled vi_mode_enabled = not vi_mode_enabled # Add a bottom toolbar to display the status. style = style_from_dict({ Token.Toolbar: 'reverse', }) def get_bottom_toolbar_tokens(cli): " Display the current input mode. " text = 'Vi' if vi_mode_enabled else 'Emacs' return [(Token.Toolbar, ' [F4] %s ' % text)] prompt('> ', key_bindings_registry=manager.registry, get_bottom_toolbar_tokens=get_bottom_toolbar_tokens, style=style)
class KeyHandlers(object): """Contains all handlers registered with key bindings """ __single_instance = None __key_binding_manager = KeyBindingManager( enable_abort_and_exit_bindings=bool(egc.KB_ABORT_EXIT_BIND), enable_system_bindings=bool(egc.KB_SYSTEM_BIND), enable_search=bool(egc.KB_SEARCH), enable_open_in_editor=bool(egc.KB_OPEN_IN_EDITOR), enable_extra_page_navigation=bool(egc.KB_PAGE_SCROLL), enable_auto_suggest_bindings=bool(egc.KB_AUTO_SUGGEST) ) registry = __key_binding_manager.registry def __new__(cls): """docstring for __new__""" if cls != type(cls.__single_instance): cls.__single_instance = object.__new__(cls) return cls.__single_instance def get_key_binding_manager(self): """docstring for get_key_binding_manager""" return KeyHandlers.__key_binding_manager def get_key_binding_registry(self): """docstring for get_key_binding_registry""" return KeyHandlers.registry
def run(): vi_mode_enabled = False # Create a set of key bindings that have Vi mode enabled if the # ``vi_mode_enabled`` is True.. manager = KeyBindingManager.for_prompt( enable_vi_mode=Condition(lambda cli: vi_mode_enabled)) # Add an additional key binding for toggling this flag. @manager.registry.add_binding(Keys.F4) def _(event): " Toggle between Emacs and Vi mode. " nonlocal vi_mode_enabled vi_mode_enabled = not vi_mode_enabled # Add a bottom toolbar to display the status. style = style_from_dict({ Token.Toolbar: 'reverse', }) def get_bottom_toolbar_tokens(cli): " Display the current input mode. " text = 'Vi' if vi_mode_enabled else 'Emacs' return [ (Token.Toolbar, ' [F4] %s ' % text) ] prompt('> ', key_bindings_registry=manager.registry, get_bottom_toolbar_tokens=get_bottom_toolbar_tokens, style=style)
def get_key_manager(set_long_options, get_long_options, set_fuzzy_match, get_fuzzy_match): """ Create and initialize keybinding manager :return: KeyBindingManager """ assert callable(set_long_options) assert callable(get_long_options) assert callable(set_fuzzy_match) assert callable(get_fuzzy_match) manager = KeyBindingManager(enable_system_bindings=True) @manager.registry.add_binding(Keys.F2) def _(event): """ When F2 has been pressed, fill in the "help" command. """ event.cli.current_buffer.insert_text("help") @manager.registry.add_binding(Keys.F3) def _(_): """ Enable/Disable long option name suggestion. """ set_long_options(not get_long_options()) @manager.registry.add_binding(Keys.F4) def _(_): """ Enable/Disable fuzzy matching. """ set_fuzzy_match(not get_fuzzy_match()) @manager.registry.add_binding(Keys.F10) def _(event): """ When F10 has been pressed, quit. """ # Unused parameters for linter. raise EOFError @manager.registry.add_binding(Keys.ControlSpace) def _(event): """ Initialize autocompletion at cursor. If the autocompletion menu is not showing, display it with the appropriate completions for the context. If the menu is showing, select the next completion. """ b = event.cli.current_buffer if b.complete_state: b.complete_next() else: event.cli.start_completion(select_first=False) return manager
def run(): # Create a set of key bindings that have Vi mode enabled if the # ``vi_mode_enabled`` is True.. manager = KeyBindingManager.for_prompt() # Add an additional key binding for toggling this flag. @manager.registry.add_binding(Keys.F4) def _(event): " Toggle between Emacs and Vi mode. " if event.cli.editing_mode == EditingMode.VI: event.cli.editing_mode = EditingMode.EMACS else: event.cli.editing_mode = EditingMode.VI # Add a bottom toolbar to display the status. style = style_from_dict({ Token.Toolbar: 'reverse', }) def get_bottom_toolbar_tokens(cli): " Display the current input mode. " text = 'Vi' if cli.editing_mode == EditingMode.VI else 'Emacs' return [ (Token.Toolbar, ' [F4] %s ' % text) ] prompt('> ', key_bindings_registry=manager.registry, get_bottom_toolbar_tokens=get_bottom_toolbar_tokens, style=style)
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, graphuri, *args, **kwargs): super(GraphCLI, self).__init__(*args, **kwargs) self.graph = GraphMiddleware.get_middleware_by_uri(graphuri) self.kbmgr = KeyBindingManager.for_prompt() self.histmgr = HistoryManager() self.register_shortcuts()
def create_cli(eventloop, message='', multiline=False, is_password=False, vi_mode=False, lexer=None, enable_system_prompt=False, enable_open_in_editor=False, validator=None, completer=None, style=None, history=None, get_prompt_tokens=None, get_bottom_toolbar_tokens=None, extra_input_processors=None, key_bindings_registry=None, output=None, on_abort=AbortAction.RAISE_EXCEPTION, on_exit=AbortAction.RAISE_EXCEPTION, on_accept=AcceptAction.RETURN_DOCUMENT): """ Create a `CommandLineInterface` instance. """ assert isinstance(eventloop, EventLoop) # Create history instance. if history is None: history = History() # Use default registry from KeyBindingManager if none was given. if key_bindings_registry is None: key_bindings_registry = KeyBindingManager( enable_vi_mode=vi_mode, enable_system_prompt=enable_system_prompt, enable_open_in_editor=enable_open_in_editor).registry # Create interface. return CommandLineInterface( eventloop=eventloop, layout=create_default_layout( message=message, lexer=lexer, is_password=is_password, reserve_space_for_menu=(completer is not None), get_prompt_tokens=get_prompt_tokens, get_bottom_toolbar_tokens=get_bottom_toolbar_tokens, extra_input_processors=extra_input_processors), buffer=Buffer( is_multiline=(Always() if multiline else Never()), history=history, validator=validator, completer=completer, ), key_bindings_registry=key_bindings_registry, style=style, output=output, on_abort=on_abort, on_exit=on_exit)
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 test_bindings(self): mngr = KeyBindingManager(enable_search=True, enable_abort_and_exit_bindings=True, enable_system_bindings=True, enable_open_in_editor=True) bind_keys(mngr.registry) self.assertTrue( 'on_backspace' in handlers_for_key(mngr, Keys.Backspace)) self.assertTrue('on_tab' in handlers_for_key(mngr, Keys.Tab))
def __init__(self, **kwargs): super().__init__(**kwargs) self.history = setup_history() self.pt_completer = PromptToolkitCompleter(self.completer, self.ctx) self.key_bindings_manager = KeyBindingManager( enable_auto_suggest_bindings=True, enable_search=True, enable_abort_and_exit_bindings=True, enable_vi_mode=Condition(lambda cli: builtins.__xonsh_env__.get('VI_MODE')), enable_open_in_editor=True) load_xonsh_bindings(self.key_bindings_manager)
def __init__(self, **kwargs): super().__init__(**kwargs) self.prompter = Prompter() self.history = PromptToolkitHistory() self.pt_completer = PromptToolkitCompleter(self.completer, self.ctx) key_bindings_manager_args = { 'enable_auto_suggest_bindings': True, 'enable_search': True, 'enable_abort_and_exit_bindings': True, } self.key_bindings_manager = KeyBindingManager(**key_bindings_manager_args) load_xonsh_bindings(self.key_bindings_manager)
def create_cli(self): ## KeyBindings configuration key_binding = KeyBindingManager(enable_search=True, enable_abort_and_exit_bindings=True, enable_system_bindings=True, enable_auto_suggest_bindings=True, enable_open_in_editor=False) ## Buffer configuration default_buffer = Buffer(history=self.file_history, auto_suggest=AutoSuggestFromHistory(), enable_history_search=True, completer=self.completer, complete_while_typing=Always(), accept_action=AcceptAction.RETURN_DOCUMENT) ## Style configuration try: style = get_style_by_name(self._config.highlighter_style) except ClassNotFound: style = get_style_by_name('native') styles = {} styles.update(style.styles) styles.update(default_style_extensions) styles.update({ Token.Menu.Completions.Completion: 'bg:#003fff #ffffff', Token.Menu.Completions.Completion.Current: 'bg:#5ab300 #000000', Token.Menu.Completions.Meta.Current: 'bg:#5ab300 #ffffff', Token.Menu.Completions.Meta: 'bg:#ffffff #000000', Token.Scrollbar: 'bg:#003fff', Token.Scrollbar.Button: 'bg:#003333', }) prompt_style = style_from_dict(styles) ## Application application = Application( layout=self.create_cli_layout(), mouse_support=False, style=prompt_style, buffer=default_buffer, on_abort=AbortAction.RETRY, on_exit=AbortAction.RAISE_EXCEPTION, on_input_timeout=self.on_input_timeout, key_bindings_registry=key_binding.registry, ) cli = CommandLineInterface(application=application, eventloop=create_eventloop()) return cli
def main(): hidden = [True] # Nonlocal key_bindings_manager = KeyBindingManager() @key_bindings_manager.registry.add_binding(Keys.ControlT) def _(event): ' When ControlT has been pressed, toggle visibility. ' hidden[0] = not hidden[0] print('Type Control-T to toggle password visible.') password = get_input('Password: '******'You said: %s' % password)
def repl(self): history = InMemoryHistory() auto_suggest = AutoSuggestFromHistory() manager = KeyBindingManager.for_prompt() @manager.registry.add_binding(Keys.ControlT) def _(event): def update_multiline(): multiline = self.toggle_multiline() if multiline: event.cli.current_buffer.is_multiline = Always() else: event.cli.current_buffer.is_multiline = Never() print('Set multiline', multiline and 'ON' or 'off') event.cli.run_in_terminal(update_multiline) def get_bottom_toolbar_tokens(cli): msg = ' Connected as {0} to {1}'.format(self.username, self.url) ml = ' Multiline is {0}'.format(self.multiline and 'ON' or 'off') return [(Token.Toolbar.Connection, msg), (Token.Toolbar.Multiline, ml)] style = style_from_dict({ Token.Toolbar.Connection: '#ffffff bg:#009900', Token.Toolbar.Multiline: '#ffffff bg:#ee0000', }) ppt = partial(prompt, history=history, auto_suggest=auto_suggest, get_bottom_toolbar_tokens=get_bottom_toolbar_tokens, key_bindings_registry=manager.registry, style=style) try: prompt_msg = self.get_prompt() except Exception as e: print("ERROR: {}".format(e)) return while True: try: cmd_line = ppt(prompt_msg, multiline=self.multiline) self.rep(cmd_line) except (EOFError, KeyboardInterrupt): print('\nCtrl-C pressed. Bailing out!') break except: sys.excepthook(*sys.exc_info())
def main(): # We start with a `KeyBindingManager` instance, because this will already # nicely load all the default key bindings. key_bindings_manager = KeyBindingManager.for_prompt() # Add our own key binding to the registry of the key bindings manager. @key_bindings_manager.registry.add_binding(Keys.F4) def _(event): """ When F4 has been pressed. Insert "hello world" as text. """ event.cli.current_buffer.insert_text('hello world') @key_bindings_manager.registry.add_binding('x', 'y') def _(event): """ (Useless, but for demoing.) Typing 'xy' will insert 'z'. Note that when you type for instance 'xa', the insertion of 'x' is postponed until the 'a' is typed. because we don't know earlier whether or not a 'y' will follow. However, prompt-toolkit should already give some visual feedback of the typed character. """ event.cli.current_buffer.insert_text('z') @key_bindings_manager.registry.add_binding('a', 'b', 'c') def _(event): " Typing 'abc' should insert 'd'. " event.cli.current_buffer.insert_text('d') @key_bindings_manager.registry.add_binding(Keys.ControlT) def _(event): """ Print 'hello world' in the terminal when ControlT is pressed. We use ``run_in_terminal``, because that ensures that the prompt is hidden right before ``print_hello`` gets executed and it's drawn again after it. (Otherwise this would destroy the output.) """ def print_hello(): print('hello world') event.cli.run_in_terminal(print_hello) # Read input. print('Press F4 to insert "hello world", type "xy" to insert "z":') text = prompt('> ', key_bindings_registry=key_bindings_manager.registry) print('You said: %s' % text)
def get_bindings(): key_bindings_manager = KeyBindingManager.for_prompt() def insert_pair(l_symb, r_symb): @key_bindings_manager.registry.add_binding(l_symb) def _(event): buf = event.cli.current_buffer buf.insert_text(l_symb + r_symb) buf.cursor_left(count=1) def insert_spaced_pair(l_symb, r_symb): @key_bindings_manager.registry.add_binding(l_symb, ' ') def _(event): buf = event.cli.current_buffer buf.insert_text(l_symb + ' ' + r_symb) buf.cursor_left(count=2) def undo_add_pair(l_symb, r_symb): @key_bindings_manager.registry.add_binding(l_symb, Keys.Backspace) def _(event): return def pass_closing_pair(l_symb, r_symb): @key_bindings_manager.registry.add_binding(r_symb) def _(event): buf = event.cli.current_buffer text = buf.text[buf.cursor_position:] if text.lstrip().startswith(r_symb): symb_ix = text.find(r_symb) + 1 buf.cursor_right(count=symb_ix) else: buf.insert_text(r_symb) buf.cursor_right(count=1) parens = [('(', ')'), ('[', ']'), ('{', '}')] for pair in parens: insert_pair(*pair) insert_spaced_pair(*pair) undo_add_pair(*pair) pass_closing_pair(*pair) @key_bindings_manager.registry.add_binding(Keys.F4) def _(event): buf = event.cli.current_buffer buf.insert_text('dump') buf.newline() return key_bindings_manager
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, **kwargs): super().__init__(**kwargs) self.prompter = Prompter() self.history = PromptToolkitHistory() self.pt_completer = PromptToolkitCompleter(self.completer, self.ctx) key_bindings_manager_args = { 'enable_auto_suggest_bindings': True, 'enable_search': True, 'enable_abort_and_exit_bindings': True, } self.key_bindings_manager = KeyBindingManager( **key_bindings_manager_args) load_xonsh_bindings(self.key_bindings_manager) # This assumes that PromptToolkitShell is a singleton events.on_ptk_create.fire(self.prompter, self.history, self.pt_completer, self.key_bindings_manager)
def main(): if len(sys.argv) > 1: logout() else: studentID = raw_input("Please Input Your Student ID:") hidden = [True] # Nonlocal key_bindings_manager = KeyBindingManager() @key_bindings_manager.registry.add_binding(Keys.ControlT) def _(event): hidden[0] = not hidden[0] passwd = prompt('Password: ', is_password=Condition(lambda cli: hidden[0]), key_bindings_registry=key_bindings_manager.registry) login(studentID, passwd)
def get_key_bindings(tosh): global_registry = KeyBindingManager.for_prompt(enable_all=Condition(_in_prompt_tab)).registry mouse_registry = ConditionalRegistry(load_mouse_bindings(), Condition(_in_interactive_tab)) prompt_registry = ConditionalRegistry(filter=Condition(_in_prompt_tab)) interactive_registry = ConditionalRegistry(filter=Condition(_in_interactive_tab)) @global_registry.add_binding(Keys.BracketedPaste) def _paste(event): tosh.window.active_tab().paste(event) @prompt_registry.add_binding(Keys.ControlW) @interactive_registry.add_binding(Keys.ControlB, 'w') def _close_tab(event): tosh.window.active_tab().close() @prompt_registry.add_binding(Keys.ControlT) @interactive_registry.add_binding(Keys.ControlB, 't') def _new_prompt_tab(event): from .tosh_tab import ToshTab tosh.window.add_tab(ToshTab(tosh)) @interactive_registry.add_binding(Keys.Any) def _forward_to_session(event): tosh.window.active_tab().write_to_ssh(prompt_toolkit_key_to_vt100_key(event.key_sequence[0].key, True)) @global_registry.add_binding(Keys.ControlB, '1') @global_registry.add_binding(Keys.ControlB, '2') @global_registry.add_binding(Keys.ControlB, '3') @global_registry.add_binding(Keys.ControlB, '4') @global_registry.add_binding(Keys.ControlB, '5') @global_registry.add_binding(Keys.ControlB, '6') @global_registry.add_binding(Keys.ControlB, '7') @global_registry.add_binding(Keys.ControlB, '8') @global_registry.add_binding(Keys.ControlB, '9') def _change_tab(event): tosh.window.switch_tab(int(event.key_sequence[-1].key) - 1) @global_registry.add_binding(Keys.ControlB, Keys.Left) def _prev_tab(_): tosh.window.prev_tab() @global_registry.add_binding(Keys.ControlB, Keys.Right) def _next_tab(_): tosh.window.next_tab() return MergedRegistry([global_registry, prompt_registry, interactive_registry, mouse_registry])
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, opt_ns, srv_c, inst_xml): manager = KeyBindingManager() # Start with the `KeyBindingManager`. self.srv_text = ServiceOutput(opt_ns, srv_c, inst_xml) layout = HSplit( [ # One window that holds the BufferControl with the default buffer on the # left. Window( height=D.exact(1), content=TokenListControl( self.get_title_line, default_char=Char(" ", token=Token.String.ICSW.Header) ) ), Window( height=D.exact(1), content=FillControl('-', token=Token.Line) ), # Display the text 'Hello world' on the right. Window( content=TokenListControl( self.get_icsw_output, ) ), ] ) self._updating = False @manager.registry.add_binding(Keys.ControlC, eager=True) @manager.registry.add_binding("q", eager=True) def _handler_data(event): event.cli.set_return_value(0) our_style = style_from_dict(logging_tools.get_icsw_prompt_styles()) application = Application( layout=layout, use_alternate_screen=True, style=our_style, on_input_timeout=self.input_timeout, key_bindings_registry=manager.registry, ) event_loop = create_eventloop() self.application = application self.event_loop = event_loop
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 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 __init__(self, username, fs, starting_path=None, prompt_style=DEFAULT_PROMPT_STYLE): # TODO: Consider rewriting to pass in a fake host/IP self.host = gethostname() # TODO: Uhhh....wat self.ip = gethostbyname(self.host) homedir = '/home/%s' % username starting_path = starting_path if starting_path else homedir self.env = Env( SHELL=SHELL_PATH, USER=username, PWD=starting_path, HOME=homedir ) self.fs = fs self.manager = KeyBindingManager.for_prompt() self.manager.registry.add_binding(Keys.ControlC)(self.on_ctrlc) self.prompt_style = prompt_style # TODO: Use on-disk history file self.history = InMemoryHistory() self.is_running = True self.last_exit_code = 0 self.status = 'Welcome back, %s' % username
from __future__ import print_function from __future__ import unicode_literals from prompt_toolkit.completion import Completer, Completion from prompt_toolkit import prompt from prompt_toolkit.styles import PygmentsStyle from pygments.token import Token from prompt_toolkit.key_binding.manager import KeyBindingManager from prompt_toolkit.keys import Keys from datetime import datetime import os import subprocess import random import sys manager = KeyBindingManager.for_prompt() toolbar_style = PygmentsStyle.from_defaults({ Token.Toolbar: '#ffffff bg:#333333', Token.SCM: '#FF1A00 bg:#333333', Token.QUIT: '#ffffff bg:#ff0000' }) # GIT COMMANDS GIT_STATUS = ['git', 'status', '--porcelain'] GIT_BRANCH = ['git', 'rev-parse', '--abbrev-ref', 'HEAD'] GIT_MODIFICATIONS = ['git', '--no-pager', 'diff', '--numstat', 'HEAD'] GIT_AUTHORS = ["git", "log", "--format=%aN"] @manager.registry.add_binding(Keys.ControlC)
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)
def __init__(self, get_globals=None, get_locals=None, history_filename=None, vi_mode=False, # For internal use. _completer=None, _validator=None, _lexer=None, _extra_buffers=None, _extra_buffer_processors=None, _on_start=None, _extra_layout_body=None, _extra_toolbars=None, _input_buffer_height=None, _accept_action=AcceptAction.RETURN_DOCUMENT, _on_exit=AbortAction.RAISE_EXCEPTION): self.get_globals = get_globals or (lambda: {}) self.get_locals = get_locals or self.get_globals self._completer = _completer or PythonCompleter(self.get_globals, self.get_locals) self._validator = _validator or PythonValidator(self.get_compiler_flags) self.history = FileHistory(history_filename) if history_filename else InMemoryHistory() self._lexer = _lexer or PygmentsLexer(PythonLexer) self._extra_buffers = _extra_buffers self._accept_action = _accept_action self._on_exit = _on_exit self._on_start = _on_start self._input_buffer_height = _input_buffer_height self._extra_layout_body = _extra_layout_body or [] self._extra_toolbars = _extra_toolbars or [] self._extra_buffer_processors = _extra_buffer_processors or [] # Settings. self.settings = Settings({ 'show_signature': True, 'show_docstring': False, 'show_meta_enter_message': True, 'completion_visualisation': 'CompletionVisualisation.MULTI_COLUMN', 'completion_menu_scroll_offset': 1, 'show_line_numbers': False, 'show_status_bar': True, 'wrap_lines': True, 'complete_while_typing': True, 'vi_mode': vi_mode, 'paste_mode': False, # When True, don't insert whitespace after newline. 'confirm_exit': True, # Ask for confirmation when Control-D is pressed. 'accept_input_on_enter': 2, # Accept when pressing Enter 'n' times. # 'None' means that meta-enter is always required. 'enable_open_in_editor': True, 'enable_system_bindings': True, 'enable_input_validation': True, 'enable_auto_suggest': False, 'enable_mouse_support': False, 'enable_history_search': False, # When True, like readline, going # back in history will filter the # history on the records starting # with the current input. 'highlight_matching_parenthesis': True, 'show_sidebar': False, # Currently show the sidebar. 'show_sidebar_help': True, # When the sidebar is visible, also show the help text. 'terminal_title': None, # The title to be displayed in the terminal. (None or string.) 'exit_message': 'Do you really want to exit?', # Tokens to be shown at the prompt. 'prompt_style': 'classic' # The currently active style. }) self.show_exit_confirmation = False self.all_prompt_styles = { # Styles selectable from the menu. 'ipython': IPythonPrompt(self), 'classic': ClassicPrompt(), } self.get_input_prompt_tokens = lambda cli: \ self.all_prompt_styles[self.settings.prompt_style].in_tokens(cli) self.get_output_prompt_tokens = lambda cli: \ self.all_prompt_styles[self.settings.prompt_style].out_tokens(cli) #: Load styles. self.code_styles = get_all_code_styles() self.ui_styles = get_all_ui_styles() self._current_code_style_name = 'default' self._current_ui_style_name = 'default' if is_windows(): self._current_code_style_name = 'win32' self._current_style = self._generate_style() # Options to be configurable from the sidebar. self.options = self._create_options() self.selected_option_index = 0 #: Incremeting integer counting the current statement. self.current_statement_index = 1 # Code signatures. (This is set asynchronously after a timeout.) self.signatures = [] # Use a KeyBindingManager for loading the key bindings. self.key_bindings_manager = KeyBindingManager( enable_abort_and_exit_bindings=True, enable_search=True, enable_vi_mode=Condition(lambda cli: self.settings.vi_mode), enable_open_in_editor=Condition(lambda cli: self.settings.enable_open_in_editor), enable_system_bindings=Condition(lambda cli: self.settings.enable_system_bindings), enable_auto_suggest_bindings=Condition(lambda cli: self.settings.enable_auto_suggest), # Disable all default key bindings when the sidebar or the exit confirmation # are shown. enable_all=Condition(lambda cli: not (self.settings.show_sidebar or self.show_exit_confirmation))) load_python_bindings(self.key_bindings_manager, self) load_sidebar_bindings(self.key_bindings_manager, self) load_confirm_exit_bindings(self.key_bindings_manager, self) # Boolean indicating whether we have a signatures thread running. # (Never run more than one at the same time.) self._get_signatures_thread_running = False
def run_shell(): ppm_password = require_pwd() account_manager = new_account_manager(ppm_password) shell_history = FileHistory(ppm_shell_history) key_bindings_manager = KeyBindingManager.for_prompt() g = create_grammar() lexer = GrammarLexer(g, lexers={ 'command': SimpleLexer(Token.Command), 'value': SimpleLexer(Token.Value), 'accountName': SimpleLexer(Token.Value), 'force': SimpleLexer(Token.Option), 'option': SimpleLexer(Token.Option), 'updateOption': SimpleLexer(Token.Option), 'updateValue': SimpleLexer(Token.OptionValue), 'keyword': SimpleLexer(Token.Value), 'path': SimpleLexer(Token.Value), }) @key_bindings_manager.registry.add_binding('c', 't') def _(event): if len(event.cli.current_buffer.text) == 0: event.cli.current_buffer.insert_text('create') @key_bindings_manager.registry.add_binding('l', 's') def _(event): if len(event.cli.current_buffer.text) == 0: event.cli.current_buffer.insert_text('list') @key_bindings_manager.registry.add_binding('e', 't') def _(event): if len(event.cli.current_buffer.text) == 0: event.cli.current_buffer.insert_text('exit') @key_bindings_manager.registry.add_binding('r', 'm') def _(event): if len(event.cli.current_buffer.text) == 0: event.cli.current_buffer.insert_text('remove') @key_bindings_manager.registry.add_binding('p', 'w') def _(event): if len(event.cli.current_buffer.text) == 0: event.cli.current_buffer.insert_text('password') @key_bindings_manager.registry.add_binding('s', 't') def _(event): if len(event.cli.current_buffer.text) == 0: event.cli.current_buffer.insert_text('switch') @key_bindings_manager.registry.add_binding('w', 'e') def _(event): if len(event.cli.current_buffer.text) == 0: event.cli.current_buffer.insert_text('where') @key_bindings_manager.registry.add_binding('u', 'd') def _(event): if len(event.cli.current_buffer.text) == 0: event.cli.current_buffer.insert_text('update') @key_bindings_manager.registry.add_binding('s', 'h') def _(event): if len(event.cli.current_buffer.text) == 0: event.cli.current_buffer.insert_text('search') @key_bindings_manager.registry.add_binding('h', 'p') def _(event): if len(event.cli.current_buffer.text) == 0: event.cli.current_buffer.insert_text('help') while True: completer = GrammarCompleter(g, { 'command': WordCompleter(shell_commands), 'accountName': WordCompleter(account_manager.get_all_name()), 'force': WordCompleter(['-f']), 'updateOption': WordCompleter(update_options), 'path': PathCompleter(), }) text = prompt(">> ", history=shell_history, key_bindings_registry=key_bindings_manager.registry, lexer=lexer, completer=completer, style=PygmentsStyle(CommandStyle), on_abort=AbortAction.RETRY) m = g.match(text) if m: _vars = m.variables() command = _vars.get('command') if command == 'list': target = _vars.get('accountName') do_list(account_manager, target=target) elif command == 'create': do_create(account_manager) elif command == 'remove': target = _vars.get('accountName') force_option = _vars.get('force') do_remove(account_manager, target=target, force=force_option) elif command == 'update': target = _vars.get('accountName') update_option = _vars.get('updateOption') force_option = _vars.get('force') do_update(account_manager, target=target, field=update_option, force=force_option) elif command == 'search': keyword = _vars.get('keyword') do_search(account_manager, keyword=keyword) elif command == 'password': store_path = _vars.get('path') if not store_path: store_path = default_store_path account_manager = do_password(account_manager, store_path=store_path) elif command == 'switch': store_path = _vars.get('path') try: account_manager = do_switch(store_path) except Exception, e: print "ERROR: Wrong password!" elif command == 'where': print account_manager.get_store_path() elif command == 'exit': sys.exit(0) elif command == 'help': do_help() else: print 'ERROR: Command error!'
"leopard", "lion", "mouse", "rabbit", "rat", "snake", "spider", "turkey", "turtle", ], ignore_case=True, ) # Create key bindings registry with a custom binding for the Tab key that # displays completions like GNU readline. key_bindings_manager = KeyBindingManager.for_prompt() key_bindings_manager.registry.add_binding(Keys.ControlI)(display_completions_like_readline) def main(): text = prompt( "Give some animals: ", completer=animal_completer, key_bindings_registry=key_bindings_manager.registry, # Important: for this to work: `complete_while_typing` needs # to be False. complete_while_typing=False, ) print("You said: %s" % text)
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 create_prompt_application(self, message='', multiline=False, wrap_lines=True, is_password=False, vi_mode=False, complete_while_typing=True, enable_history_search=False, lexer=None, enable_system_bindings=False, enable_open_in_editor=False, validator=None, completer=None, reserve_space_for_menu=8, auto_suggest=None, style=None, history=None, clipboard=None, get_prompt_tokens=None, get_bottom_toolbar_tokens=None, display_completions_in_columns=False, get_title=None, mouse_support=False, extra_input_processors=None, key_bindings_registry=None, on_abort=AbortAction.RAISE_EXCEPTION, on_exit=AbortAction.RAISE_EXCEPTION, accept_action=AcceptAction.RETURN_DOCUMENT, default=''): """Create an :class:`~Application` instance for a prompt. (It is meant to cover 90% of the prompt use cases, where no extreme customization is required. For more complex input, it is required to create a custom :class:`~Application` instance.) message : Text to be shown before the prompt. mulitiline : Allow multiline input. Pressing enter will insert a newline. (This requires Meta+Enter to accept the input.) wrap_lines : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. When True (the default), automatically wrap long lines instead of scrolling horizontally. is_password : Show asterisks instead of the actual typed characters. vi_mode : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. If True, use Vi key bindings. complete_while_typing : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. Enable autocompletion while typing. enable_history_search : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. Enable up-arrow parting string matching. lexer : :class:`~prompt_toolkit.layout.lexers.Lexer` to be used for the syntax highlighting. validator : :class:`~prompt_toolkit.validation.Validator` instance for input validation. completer : :class:`~prompt_toolkit.completion.Completer` instance for input completion. reserve_space_for_menu : Space to be reserved for displaying the menu. (0 means that no space needs to be reserved.) auto_suggest : :class:`~prompt_toolkit.auto_suggest.AutoSuggest` instance for input suggestions. style : Pygments style class for the color scheme. enable_system_bindings : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. Pressing Meta+'!' will show a system prompt. enable_open_in_editor : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. Pressing 'v' in Vi mode or C-X C-E in emacs mode will open an external editor. history : :class:`~prompt_toolkit.history.History` instance. clipboard : :class:`~prompt_toolkit.clipboard.base.Clipboard` instance. (e.g. :class:`~prompt_toolkit.clipboard.in_memory.InMemoryClipboard`) get_bottom_toolbar_tokens : Optional callable which takes a :class:`~prompt_toolkit.interface.CommandLineInterface` and returns a list of tokens for the bottom toolbar. display_completions_in_columns : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. Display the completions in multiple columns. get_title : Callable that returns the title to be displayed in the terminal. mouse_support : `bool` or :class:`~prompt_toolkit.filters.CLIFilter` to enable mouse support. default : The default text to be shown in the input buffer. (This can be edited by the user.) Notes ----- This method was forked from the mainline prompt-toolkit repo. Copyright (c) 2014, Jonathan Slenders, All rights reserved. WARNING; This method is due for removal once prompt-toolkit >v0.54 is released. """ if key_bindings_registry is None: key_bindings_registry = KeyBindingManager.for_prompt( enable_vi_mode=vi_mode, enable_system_bindings=enable_system_bindings, enable_open_in_editor=enable_open_in_editor).registry # 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 = to_simple_filter(complete_while_typing) enable_history_search = to_simple_filter(enable_history_search) multiline = to_simple_filter(multiline) complete_while_typing = complete_while_typing & ~enable_history_search # Accept Pygments styles as well for backwards compatibility. try: if issubclass(style, pygments.style.Style): style = PygmentsStyle(style) except TypeError: # Happens when style is `None` or an instance of something else. pass # Create application return Application( layout=self.create_prompt_layout( message=message, lexer=lexer, is_password=is_password, reserve_space_for_menu=(reserve_space_for_menu if completer is not None else 0), multiline=Condition(lambda cli: multiline()), get_prompt_tokens=get_prompt_tokens, get_bottom_toolbar_tokens=get_bottom_toolbar_tokens, display_completions_in_columns=display_completions_in_columns, extra_input_processors=extra_input_processors, wrap_lines=wrap_lines), buffer=Buffer( enable_history_search=enable_history_search, complete_while_typing=complete_while_typing, is_multiline=multiline, history=(history or InMemoryHistory()), validator=validator, completer=completer, auto_suggest=auto_suggest, accept_action=accept_action, initial_document=Document(default), ), style=style or DEFAULT_STYLE, clipboard=clipboard, key_bindings_registry=key_bindings_registry, get_title=get_title, mouse_support=mouse_support, on_abort=on_abort, on_exit=on_exit)
class PythonInput(object): """ Prompt for reading Python input. :: python_input = PythonInput(...) application = python_input.create_application() cli = CommandLineInterface(application=application) python_code = cli.run() """ def __init__(self, get_globals=None, get_locals=None, history_filename=None, vi_mode=False, # For internal use. _completer=None, _validator=None, _python_prompt_control=None, _lexer=None, _extra_buffers=None, _extra_buffer_processors=None, _on_start=None, _extra_sidebars=None, _accept_action=AcceptAction.RETURN_DOCUMENT, _on_exit=AbortAction.RAISE_EXCEPTION): self.get_globals = get_globals or (lambda: {}) self.get_locals = get_locals or self.get_globals self._completer = _completer or PythonCompleter(self.get_globals, self.get_locals) self._validator = _validator or PythonValidator() self._history = FileHistory(history_filename) if history_filename else History() self._lexer = _lexer or PythonLexer self._extra_buffers = _extra_buffers self._accept_action = _accept_action self._on_exit = _on_exit self._on_start = _on_start self._extra_sidebars = _extra_sidebars or [] self._extra_buffer_processors = _extra_buffer_processors or [] self._python_prompt_control = _python_prompt_control or PythonPrompt(self) # Settings. self.show_signature = True self.show_docstring = False self.show_completions_toolbar = False self.show_completions_menu = True self.show_line_numbers = True self.show_status_bar = True self.complete_while_typing = True self.vi_mode = vi_mode self.paste_mode = False # When True, don't insert whitespace after newline. self.confirm_exit = True # Ask for confirmation when Control-D is pressed. self.enable_open_in_editor = True self.enable_system_bindings = True self.enable_history_search = False # When True, like readline, going # back in history will filter the # history on the records starting # with the current input. self.show_sidebar = False # Currently show the sidebar. self.show_exit_confirmation = False # Currently show 'Do you really want to exit?' #: Load styles. self.code_styles = get_all_code_styles() self.ui_styles = get_all_ui_styles() self._current_code_style_name = 'default' self._current_ui_style_name = 'default' self._current_style = self._generate_style() # Options to be configurable from the sidebar. def handler(enable=None, disable=None): " Handler for an '_Option'. " def handler(): if enable: for o in enable: setattr(self, o, True) if disable: for o in disable: setattr(self, o, False) return handler def simple_option(description, field_name, values=None): " Create Simple on/of option. " values = values or ['off', 'on'] def current_value(): return values[bool(getattr(self, field_name))] return _Option(description, lambda: { values[1]: handler(enable=[field_name]), values[0]: handler(disable=[field_name]), }, current_value) def get_completion_menu_value(): " Return active value for the 'completion menu' option. " if self.show_completions_menu: return 'pop-up' elif self.show_completions_toolbar: return 'toolbar' else: return 'off' self.options = [ simple_option('Input mode', 'vi_mode', values=['emacs', 'vi']), simple_option('Paste mode', 'paste_mode'), _Option('Completion menu', lambda: { 'off': handler(disable=['show_completions_menu', 'show_completions_toolbar']), 'pop-up': handler(enable=['show_completions_menu'], disable=['show_completions_toolbar']), 'toolbar': handler(enable=['show_completions_toolbar'], disable=['show_completions_menu']) }, get_completion_menu_value), _Option('Complete while typing', lambda: { 'on': handler(enable=['complete_while_typing'], disable=['enable_history_search']), 'off': handler(disable=['complete_while_typing']), }, lambda: ['off', 'on'][self.complete_while_typing]), simple_option('Show signature', 'show_signature'), simple_option('Show docstring', 'show_docstring'), simple_option('Show line numbers', 'show_line_numbers'), simple_option('Show status bar', 'show_status_bar'), _Option('History search', lambda: { 'on': handler(enable=['enable_history_search'], disable=['complete_while_typing']), 'off': handler(disable=['enable_history_search']), }, lambda: ['off', 'on'][self.enable_history_search]), _Option('Color scheme (code)', lambda: { name: partial(self.use_code_colorscheme, name) for name in self.code_styles }, lambda: self._current_code_style_name), _Option('Color scheme (UI)', lambda: { name: partial(self.use_ui_colorscheme, name) for name in self.ui_styles }, lambda: self._current_ui_style_name), simple_option('Confirm on exit', 'confirm_exit'), ] self.selected_option = 0 #: Incremeting integer counting the current statement. self.current_statement_index = 1 # Code signatures. (This is set asynchronously after a timeout.) self.signatures = [] # Use a KeyBindingManager for loading the key bindings. self.key_bindings_manager = KeyBindingManager( enable_vi_mode=Condition(lambda cli: self.vi_mode), enable_open_in_editor=Condition(lambda cli: self.enable_open_in_editor), enable_system_bindings=Condition(lambda cli: self.enable_system_bindings), # Disable all default key bindings when the sidebar or the exit confirmation # are shown. enable_all=Condition(lambda cli: not (self.show_sidebar or self.show_exit_confirmation))) load_python_bindings(self.key_bindings_manager, self) load_sidebar_bindings(self.key_bindings_manager, self) load_confirm_exit_bindings(self.key_bindings_manager, self) # Boolean indicating whether we have a signatures thread running. # (Never run more than one at the same time.) self._get_signatures_thread_running = False @property def key_bindings_registry(self): return self.key_bindings_manager.registry @property def add_key_binding(self): """ Shortcut for adding new key bindings. (Mostly useful for a .ptpython/config.py file, that receives a PythonInput/Repl instance as input.) :: @python_input.add_key_binding(Keys.ControlX, filter=...) def handler(event): ... """ # Extra key bindings should not be active when the sidebar is visible. sidebar_visible = Condition(lambda cli: self.show_sidebar) def add_binding_decorator(*keys, **kw): # Pop default filter keyword argument. filter = kw.pop('filter', Always()) assert not kw return self.key_bindings_registry.add_binding(*keys, filter=filter & ~sidebar_visible) return add_binding_decorator def install_code_colorscheme(self, name, style_dict): """ Install a new code color scheme. """ assert isinstance(name, six.text_type) assert isinstance(style_dict, dict) self.code_styles[name] = style_dict def use_code_colorscheme(self, name): """ Apply new colorscheme. (By name.) """ assert name in self.code_styles self._current_code_style_name = name self._current_style = self._generate_style() def install_ui_colorscheme(self, name, style_dict): """ Install a new UI color scheme. """ assert isinstance(name, six.text_type) assert isinstance(style_dict, dict) self.ui_styles[name] = style_dict def use_ui_colorscheme(self, name): """ Apply new colorscheme. (By name.) """ assert name in self.ui_styles self._current_ui_style_name = name self._current_style = self._generate_style() def _generate_style(self): """ Create new Style instance. (We don't want to do this on every key press, because each time the renderer receives a new style class, he will redraw everything.) """ return generate_style(self.code_styles[self._current_code_style_name], self.ui_styles[self._current_ui_style_name]) def create_application(self): """ Create an `Application` instance for use in a `CommandLineInterface`. """ buffers = { 'docstring': Buffer(), # XXX: make docstring read only. } buffers.update(self._extra_buffers or {}) return Application( layout=create_layout( self, self.key_bindings_manager, self._python_prompt_control, lexer=self._lexer, extra_buffer_processors=self._extra_buffer_processors, extra_sidebars=self._extra_sidebars), buffer=self._create_buffer(), buffers=buffers, key_bindings_registry=self.key_bindings_registry, paste_mode=Condition(lambda cli: self.paste_mode), on_abort=AbortAction.RETRY, on_exit=self._on_exit, get_style=lambda: self._current_style, on_start=self._on_start, on_input_timeout=Callback(self._on_input_timeout)) def _create_buffer(self): """ Create the `Buffer` for the Python input. """ def is_buffer_multiline(): return (self.paste_mode or document_is_multiline_python(python_buffer.document)) python_buffer = Buffer( is_multiline=Condition(is_buffer_multiline), complete_while_typing=Condition(lambda: self.complete_while_typing), enable_history_search=Condition(lambda: self.enable_history_search), tempfile_suffix='.py', history=self._history, completer=self._completer, validator=self._validator, accept_action=self._accept_action) return python_buffer def _on_input_timeout(self, cli): """ When there is no input activity, in another thread, get the signature of the current code. """ if cli.focus_stack.current != DEFAULT_BUFFER: return # Never run multiple get-signature threads. if self._get_signatures_thread_running: return self._get_signatures_thread_running = True buffer = cli.current_buffer document = buffer.document def run(): script = get_jedi_script_from_document(document, self.get_locals(), self.get_globals()) # Show signatures in help text. if script: try: signatures = script.call_signatures() except ValueError: # e.g. in case of an invalid \\x escape. signatures = [] except Exception: # Sometimes we still get an exception (TypeError), because # of probably bugs in jedi. We can silence them. # See: https://github.com/davidhalter/jedi/issues/492 signatures = [] else: signatures = [] self._get_signatures_thread_running = False # Set signatures and redraw if the text didn't change in the # meantime. Otherwise request new signatures. if buffer.text == document.text: self.signatures = signatures # Set docstring in docstring buffer. if signatures: string = signatures[0].docstring() if not isinstance(string, six.text_type): string = string.decode('utf-8') cli.buffers['docstring'].reset( initial_document=Document(string, cursor_position=0)) else: cli.buffers['docstring'].reset() cli.request_redraw() else: self._on_input_timeout(cli) cli.eventloop.run_in_executor(run) def on_reset(self, cli): self.key_bindings_manager.reset() self.signatures = []
def get_prompt_args(): key_bindings_manager = KeyBindingManager.for_prompt() @key_bindings_manager.registry.add_binding(Keys.Escape) def h1(event): """ When ESC has been pressed, clear the input text. """ event.cli.current_buffer.cursor_right(999) event.cli.current_buffer.delete_before_cursor(999) @key_bindings_manager.registry.add_binding(Keys.ControlV) def h2(event): """ When Ctrl-V has been pressed, insert clipboard text to the cursor. """ from hlutils import get_clipboard_text text = get_clipboard_text(True) event.cli.current_buffer.insert_text(text) @key_bindings_manager.registry.add_binding(Keys.ControlO) def h3(event): """ When Ctrl-O has been pressed, open a Vim process to select a history command. """ import subprocess as sp import random rcfile = os.path.dirname(__file__) + "\\history.vim" randval = random.randint(1000000, 9999999) histfile = os.path.expandvars("$TMP/cmdex_%d.hist" % randval) selectfile = os.path.expandvars("$TMP/cmdex_%d.sel" % randval) with open(histfile, "w") as f: for cmd in hist_obj.strings: print >> f, cmd.encode("utf-8") os.system("vim.exe -R --noplugin + -u %s -- %s" % (rcfile, histfile)) os.remove(histfile) global default_input if os.path.exists(selectfile): text = open(selectfile).read().strip() default_input = text.decode("utf-8", "ignore") os.remove(selectfile) event.cli.current_buffer.cursor_right(999) event.cli.current_buffer.delete_before_cursor(999) event.cli.set_return_value(Document("")) args = { "style": style_from_dict({ Token.PATH: "#80C0FF", Token.HOST: "#00FF00", Token.TIP: "#FF0000", }), "get_prompt_tokens": lambda cli: [ (Token.HOST, "%s@%s " % (os.getenv("USERNAME", ""), os.getenv("COMPUTERNAME", ""))), (Token.PATH, "%s\n" % os.getcwdu().replace("\\", "/")), (Token.TIP, "$ "), ], "completer": CmdExCompleter(), "display_completions_in_columns": True, "history": hist_obj, "key_bindings_registry": key_bindings_manager.registry, } return args
def __init__(self, eventloop, get_globals=None, get_locals=None, stdin=None, stdout=None, vi_mode=False, history_filename=None, style=PythonStyle, # For internal use. _completer=None, _validator=None, _lexer=None, _python_prompt_control=None, _extra_buffers=None, _extra_buffer_processors=None, _extra_sidebars=None): self.settings = PythonCLISettings() self.get_globals = get_globals or (lambda: {}) self.get_locals = get_locals or self.get_globals self.completer = _completer or PythonCompleter(self.get_globals, self.get_locals) self.validator = _validator or PythonValidator() self.history = FileHistory(history_filename) if history_filename else History() self.python_prompt_control = _python_prompt_control or PythonPrompt(self.settings) self._extra_sidebars = _extra_sidebars or [] self._extra_buffer_processors = _extra_buffer_processors or [] self._lexer = _lexer or PythonLexer # Use a KeyBindingManager for loading the key bindings. self.key_bindings_manager = KeyBindingManager(enable_vi_mode=vi_mode, enable_open_in_editor=True, enable_system_prompt=True) load_python_bindings(self.key_bindings_manager, self.settings) self.get_signatures_thread_running = False buffers = { 'default': self._create_python_buffer(), 'docstring': Buffer(), # XXX: make docstring read only. } buffers.update(_extra_buffers or {}) self.cli = CommandLineInterface( eventloop=eventloop, style=style, key_bindings_registry=self.key_bindings_manager.registry, buffers=buffers, paste_mode=Condition(lambda cli: self.settings.paste_mode), layout=self._create_layout(), on_abort=AbortAction.RETRY, on_exit=AbortAction.RAISE_EXCEPTION) def on_input_timeout(): """ When there is no input activity, in another thread, get the signature of the current code. """ if self.cli.focus_stack.current != 'default': return # Never run multiple get-signature threads. if self.get_signatures_thread_running: return self.get_signatures_thread_running = True buffer = self.cli.current_buffer document = buffer.document def run(): script = get_jedi_script_from_document(document, self.get_locals(), self.get_globals()) # Show signatures in help text. if script: try: signatures = script.call_signatures() except ValueError: # e.g. in case of an invalid \\x escape. signatures = [] except Exception: # Sometimes we still get an exception (TypeError), because # of probably bugs in jedi. We can silence them. # See: https://github.com/davidhalter/jedi/issues/492 signatures = [] else: signatures = [] self.get_signatures_thread_running = False # Set signatures and redraw if the text didn't change in the # meantime. Otherwise request new signatures. if buffer.text == document.text: self.settings.signatures = signatures # Set docstring in docstring buffer. if signatures: string = signatures[0].docstring() if not isinstance(string, six.text_type): string = string.decode('utf-8') self.cli.buffers['docstring'].reset( initial_document=Document(string, cursor_position=0)) else: self.cli.buffers['docstring'].reset() self.cli.request_redraw() else: on_input_timeout() self.cli.eventloop.run_in_executor(run) def reset(): self.key_bindings_manager.reset() self.settings.signatures = [] self.cli.onReset += reset self.cli.onInputTimeout += on_input_timeout
def __init__(self, get_globals=None, get_locals=None, history_filename=None, vi_mode=False, # For internal use. _completer=None, _validator=None, _python_prompt_control=None, _lexer=None, _extra_buffers=None, _extra_buffer_processors=None, _on_start=None, _extra_layout_body=None, _extra_toolbars=None, _input_buffer_height=None, _accept_action=AcceptAction.RETURN_DOCUMENT, _on_exit=AbortAction.RAISE_EXCEPTION): self.get_globals = get_globals or (lambda: {}) self.get_locals = get_locals or self.get_globals self._completer = _completer or PythonCompleter(self.get_globals, self.get_locals) self._validator = _validator or PythonValidator(self.get_compiler_flags) self._history = FileHistory(history_filename) if history_filename else InMemoryHistory() self._lexer = _lexer or PygmentsLexer(PythonLexer) self._extra_buffers = _extra_buffers self._accept_action = _accept_action self._on_exit = _on_exit self._on_start = _on_start self._input_buffer_height = _input_buffer_height self._extra_layout_body = _extra_layout_body or [] self._extra_toolbars = _extra_toolbars or [] self._extra_buffer_processors = _extra_buffer_processors or [] self._python_prompt_control = _python_prompt_control or PythonPrompt(self) # Settings. self.show_signature = True self.show_docstring = False self.completion_visualisation = CompletionVisualisation.MULTI_COLUMN self.completion_menu_scroll_offset = 1 self.show_line_numbers = True self.show_status_bar = True self.complete_while_typing = True self.vi_mode = vi_mode self.paste_mode = False # When True, don't insert whitespace after newline. self.confirm_exit = True # Ask for confirmation when Control-D is pressed. self.accept_input_on_enter = 2 # Accept when pressing Enter 'n' times. # 'None' means that meta-enter is always required. self.enable_open_in_editor = True self.enable_system_bindings = True self.enable_input_validation = True self.enable_history_search = False # When True, like readline, going # back in history will filter the # history on the records starting # with the current input. self.show_sidebar = False # Currently show the sidebar. self.show_sidebar_help = True # When the sidebar is visible, also show the help text. self.show_exit_confirmation = False # Currently show 'Do you really want to exit?' self.terminal_title = None # The title to be displayed in the terminal. (None or string.) self.exit_message = 'Do you really want to exit?' #: Load styles. self.code_styles = get_all_code_styles() self.ui_styles = get_all_ui_styles() self._current_code_style_name = 'default' self._current_ui_style_name = 'default' if is_windows(): self._current_code_style_name = 'win32' self._current_style = self._generate_style() # Options to be configurable from the sidebar. self.options = self._create_options() self.selected_option_index = 0 #: Incremeting integer counting the current statement. self.current_statement_index = 1 # Code signatures. (This is set asynchronously after a timeout.) self.signatures = [] # Use a KeyBindingManager for loading the key bindings. self.key_bindings_manager = KeyBindingManager( enable_vi_mode=Condition(lambda cli: self.vi_mode), enable_open_in_editor=Condition(lambda cli: self.enable_open_in_editor), enable_system_bindings=Condition(lambda cli: self.enable_system_bindings), # Disable all default key bindings when the sidebar or the exit confirmation # are shown. enable_all=Condition(lambda cli: not (self.show_sidebar or self.show_exit_confirmation))) load_python_bindings(self.key_bindings_manager, self) load_sidebar_bindings(self.key_bindings_manager, self) load_confirm_exit_bindings(self.key_bindings_manager, self) # Boolean indicating whether we have a signatures thread running. # (Never run more than one at the same time.) self._get_signatures_thread_running = False
class PythonInput(object): """ Prompt for reading Python input. :: python_input = PythonInput(...) application = python_input.create_application() cli = CommandLineInterface(application=application) python_code = cli.run() """ def __init__(self, get_globals=None, get_locals=None, history_filename=None, vi_mode=False, # For internal use. _completer=None, _validator=None, _python_prompt_control=None, _lexer=None, _extra_buffers=None, _extra_buffer_processors=None, _on_start=None, _extra_layout_body=None, _extra_toolbars=None, _input_buffer_height=None, _accept_action=AcceptAction.RETURN_DOCUMENT, _on_exit=AbortAction.RAISE_EXCEPTION): self.get_globals = get_globals or (lambda: {}) self.get_locals = get_locals or self.get_globals self._completer = _completer or PythonCompleter(self.get_globals, self.get_locals) self._validator = _validator or PythonValidator(self.get_compiler_flags) self._history = FileHistory(history_filename) if history_filename else InMemoryHistory() self._lexer = _lexer or PygmentsLexer(PythonLexer) self._extra_buffers = _extra_buffers self._accept_action = _accept_action self._on_exit = _on_exit self._on_start = _on_start self._input_buffer_height = _input_buffer_height self._extra_layout_body = _extra_layout_body or [] self._extra_toolbars = _extra_toolbars or [] self._extra_buffer_processors = _extra_buffer_processors or [] self._python_prompt_control = _python_prompt_control or PythonPrompt(self) # Settings. self.show_signature = True self.show_docstring = False self.completion_visualisation = CompletionVisualisation.MULTI_COLUMN self.completion_menu_scroll_offset = 1 self.show_line_numbers = True self.show_status_bar = True self.complete_while_typing = True self.vi_mode = vi_mode self.paste_mode = False # When True, don't insert whitespace after newline. self.confirm_exit = True # Ask for confirmation when Control-D is pressed. self.accept_input_on_enter = 2 # Accept when pressing Enter 'n' times. # 'None' means that meta-enter is always required. self.enable_open_in_editor = True self.enable_system_bindings = True self.enable_input_validation = True self.enable_history_search = False # When True, like readline, going # back in history will filter the # history on the records starting # with the current input. self.show_sidebar = False # Currently show the sidebar. self.show_sidebar_help = True # When the sidebar is visible, also show the help text. self.show_exit_confirmation = False # Currently show 'Do you really want to exit?' self.terminal_title = None # The title to be displayed in the terminal. (None or string.) self.exit_message = 'Do you really want to exit?' #: Load styles. self.code_styles = get_all_code_styles() self.ui_styles = get_all_ui_styles() self._current_code_style_name = 'default' self._current_ui_style_name = 'default' if is_windows(): self._current_code_style_name = 'win32' self._current_style = self._generate_style() # Options to be configurable from the sidebar. self.options = self._create_options() self.selected_option_index = 0 #: Incremeting integer counting the current statement. self.current_statement_index = 1 # Code signatures. (This is set asynchronously after a timeout.) self.signatures = [] # Use a KeyBindingManager for loading the key bindings. self.key_bindings_manager = KeyBindingManager( enable_vi_mode=Condition(lambda cli: self.vi_mode), enable_open_in_editor=Condition(lambda cli: self.enable_open_in_editor), enable_system_bindings=Condition(lambda cli: self.enable_system_bindings), # Disable all default key bindings when the sidebar or the exit confirmation # are shown. enable_all=Condition(lambda cli: not (self.show_sidebar or self.show_exit_confirmation))) load_python_bindings(self.key_bindings_manager, self) load_sidebar_bindings(self.key_bindings_manager, self) load_confirm_exit_bindings(self.key_bindings_manager, self) # Boolean indicating whether we have a signatures thread running. # (Never run more than one at the same time.) self._get_signatures_thread_running = False @property def option_count(self): " Return the total amount of options. (In all categories together.) " return sum(len(category.options) for category in self.options) @property def selected_option(self): " Return the currently selected option. " i = 0 for category in self.options: for o in category.options: if i == self.selected_option_index: return o else: i += 1 def get_compiler_flags(self): """ Give the current compiler flags by looking for _Feature instances in the globals. """ flags = 0 for value in self.get_globals().values(): if isinstance(value, __future__._Feature): flags |= value.compiler_flag return flags @property def key_bindings_registry(self): return self.key_bindings_manager.registry @property def add_key_binding(self): """ Shortcut for adding new key bindings. (Mostly useful for a .ptpython/config.py file, that receives a PythonInput/Repl instance as input.) :: @python_input.add_key_binding(Keys.ControlX, filter=...) def handler(event): ... """ # Extra key bindings should not be active when the sidebar is visible. sidebar_visible = Condition(lambda cli: self.show_sidebar) def add_binding_decorator(*keys, **kw): # Pop default filter keyword argument. filter = kw.pop('filter', Always()) assert not kw return self.key_bindings_registry.add_binding(*keys, filter=filter & ~sidebar_visible) return add_binding_decorator def install_code_colorscheme(self, name, style_dict): """ Install a new code color scheme. """ assert isinstance(name, six.text_type) assert isinstance(style_dict, dict) self.code_styles[name] = style_dict def use_code_colorscheme(self, name): """ Apply new colorscheme. (By name.) """ assert name in self.code_styles self._current_code_style_name = name self._current_style = self._generate_style() def install_ui_colorscheme(self, name, style_dict): """ Install a new UI color scheme. """ assert isinstance(name, six.text_type) assert isinstance(style_dict, dict) self.ui_styles[name] = style_dict def use_ui_colorscheme(self, name): """ Apply new colorscheme. (By name.) """ assert name in self.ui_styles self._current_ui_style_name = name self._current_style = self._generate_style() def _generate_style(self): """ Create new Style instance. (We don't want to do this on every key press, because each time the renderer receives a new style class, he will redraw everything.) """ return generate_style(self.code_styles[self._current_code_style_name], self.ui_styles[self._current_ui_style_name]) def _create_options(self): """ Create a list of `Option` instances for the options sidebar. """ def enable(attribute, value=True): setattr(self, attribute, value) # Return `True`, to be able to chain this in the lambdas below. return True def disable(attribute): setattr(self, attribute, False) return True def simple_option(title, description, field_name, values=None): " Create Simple on/of option. " values = values or ['off', 'on'] def get_current_value(): return values[bool(getattr(self, field_name))] def get_values(): return { values[1]: lambda: enable(field_name), values[0]: lambda: disable(field_name), } return Option(title=title, description=description, get_values=get_values, get_current_value=get_current_value) return [ OptionCategory('Input', [ simple_option(title='Input mode', description='Vi or emacs key bindings.', field_name='vi_mode', values=['emacs', 'vi']), simple_option(title='Paste mode', description="When enabled, don't indent automatically.", field_name='paste_mode'), Option(title='Complete while typing', description="Generate autocompletions automatically while typing. " 'Don\'t require pressing TAB. (Not compatible with "History search".)', get_current_value=lambda: ['off', 'on'][self.complete_while_typing], get_values=lambda: { 'on': lambda: enable('complete_while_typing') and disable('enable_history_search'), 'off': lambda: disable('complete_while_typing'), }), Option(title='History search', description='When pressing the up-arrow, filter the history on input starting ' 'with the current text. (Not compatible with "Complete while typing".)', get_current_value=lambda: ['off', 'on'][self.enable_history_search], get_values=lambda: { 'on': lambda: enable('enable_history_search') and disable('complete_while_typing'), 'off': lambda: disable('enable_history_search'), }), simple_option(title='Confirm on exit', description='Require confirmation when exiting.', field_name='confirm_exit'), simple_option(title='Input validation', description='In case of syntax errors, move the cursor to the error ' 'instead of showing a traceback of a SyntaxError.', field_name='enable_input_validation'), Option(title='Accept input on enter', description='Amount of ENTER presses required to execute input when the cursor ' 'is at the end of the input. (Note that META+ENTER will always execute.)', get_current_value=lambda: str(self.accept_input_on_enter or 'meta-enter'), get_values=lambda: { '2': lambda: enable('accept_input_on_enter', 2), '3': lambda: enable('accept_input_on_enter', 3), '4': lambda: enable('accept_input_on_enter', 4), 'meta-enter': lambda: enable('accept_input_on_enter', None), }), ]), OptionCategory('Display', [ Option(title='Completions', description='Visualisation to use for displaying the completions. (Multiple columns, one column, a toolbar or nothing.)', get_current_value=lambda: self.completion_visualisation, get_values=lambda: { CompletionVisualisation.NONE: lambda: enable('completion_visualisation', CompletionVisualisation.NONE), CompletionVisualisation.POP_UP: lambda: enable('completion_visualisation', CompletionVisualisation.POP_UP), CompletionVisualisation.MULTI_COLUMN: lambda: enable('completion_visualisation', CompletionVisualisation.MULTI_COLUMN), CompletionVisualisation.TOOLBAR: lambda: enable('completion_visualisation', CompletionVisualisation.TOOLBAR), }), simple_option(title='Show signature', description='Display function signatures.', field_name='show_signature'), simple_option(title='Show docstring', description='Display function docstrings.', field_name='show_docstring'), simple_option(title='Show line numbers', description='Show line numbers when the input consists of multiple lines.', field_name='show_line_numbers'), simple_option(title='Show status bar', description='Show the status bar at the bottom of the terminal.', field_name='show_status_bar'), simple_option(title='Show sidebar help', description='When the sidebar is visible, also show this help text.', field_name='show_sidebar_help'), ]), OptionCategory('Colors', [ Option(title='Code', description='Color scheme to use for the Python code.', get_current_value=lambda: self._current_code_style_name, get_values=lambda: dict( (name, partial(self.use_code_colorscheme, name)) for name in self.code_styles) ), Option(title='User interface', description='Color scheme to use for the user interface.', get_current_value=lambda: self._current_ui_style_name, get_values=lambda: dict( (name, partial(self.use_ui_colorscheme, name)) for name in self.ui_styles) ), ]), ] def create_application(self): """ Create an `Application` instance for use in a `CommandLineInterface`. """ buffers = { 'docstring': Buffer(read_only=True), } buffers.update(self._extra_buffers or {}) return Application( layout=create_layout( self, self.key_bindings_manager, self._python_prompt_control, lexer=self._lexer, input_buffer_height=self._input_buffer_height, extra_buffer_processors=self._extra_buffer_processors, extra_body=self._extra_layout_body, extra_toolbars=self._extra_toolbars), buffer=self._create_buffer(), buffers=buffers, key_bindings_registry=self.key_bindings_registry, paste_mode=Condition(lambda cli: self.paste_mode), on_abort=AbortAction.RETRY, on_exit=self._on_exit, get_style=lambda: self._current_style, get_title=lambda: self.terminal_title, on_start=self._on_start, on_input_timeout=Callback(self._on_input_timeout)) def _create_buffer(self): """ Create the `Buffer` for the Python input. """ def is_buffer_multiline(): return (self.paste_mode or document_is_multiline_python(python_buffer.document)) python_buffer = Buffer( is_multiline=Condition(is_buffer_multiline), complete_while_typing=Condition(lambda: self.complete_while_typing), enable_history_search=Condition(lambda: self.enable_history_search), tempfile_suffix='.py', history=self._history, completer=self._completer, validator=SwitchableValidator( self._validator, Condition(lambda: self.enable_input_validation)), accept_action=self._accept_action) return python_buffer def _on_input_timeout(self, cli): """ When there is no input activity, in another thread, get the signature of the current code. """ if cli.focus_stack.current != DEFAULT_BUFFER: return # Never run multiple get-signature threads. if self._get_signatures_thread_running: return self._get_signatures_thread_running = True buffer = cli.current_buffer document = buffer.document def run(): script = get_jedi_script_from_document(document, self.get_locals(), self.get_globals()) # Show signatures in help text. if script: try: signatures = script.call_signatures() except ValueError: # e.g. in case of an invalid \\x escape. signatures = [] except Exception: # Sometimes we still get an exception (TypeError), because # of probably bugs in jedi. We can silence them. # See: https://github.com/davidhalter/jedi/issues/492 signatures = [] else: # Try to access the params attribute just once. For Jedi # signatures containing the keyword-only argument star, # this will crash when retrieving it the first time with # AttributeError. Every following time it works. # See: https://github.com/jonathanslenders/ptpython/issues/47 # https://github.com/davidhalter/jedi/issues/598 try: if signatures: signatures[0].params except AttributeError: pass else: signatures = [] self._get_signatures_thread_running = False # Set signatures and redraw if the text didn't change in the # meantime. Otherwise request new signatures. if buffer.text == document.text: self.signatures = signatures # Set docstring in docstring buffer. if signatures: string = signatures[0].docstring() if not isinstance(string, six.text_type): string = string.decode('utf-8') cli.buffers['docstring'].reset( initial_document=Document(string, cursor_position=0)) else: cli.buffers['docstring'].reset() cli.request_redraw() else: self._on_input_timeout(cli) cli.eventloop.run_in_executor(run) def on_reset(self, cli): self.key_bindings_manager.reset() self.signatures = []
def __call__(self): def get_prompt_tokens(cli): return [ (Token.Username, Context().session.user or ''), (Token.At, '@' if Context().session.user else ''), (Token.Host, Context().session.host), (Token.Colon, ':'), (Token.Path, text_type(Context().shell.current_path)), (Token.Pound, '> ') ] key_bindings_registry = KeyBindingManager.for_prompt().registry manager = CommandManager() manager.load_namespace('contrail_api_cli.shell_command') completer = ShellCompleter() history = FileHistory(os.path.join(CONFIG_DIR, 'history')) cmd_aliases = ShellAliases() for cmd_name, cmd in manager.list: map(cmd_aliases.set, cmd.aliases) # load home resources to have them in cache # also build shortcut list for resource types # typing vmi/ will be expanded to virtual-machine-interface/ # automagically res_aliases = ShellAliases() try: for c in RootCollection(fetch=True): short_name = "".join([p if p == "ip" else p[0].lower() for p in c.type.split('-')]) res_aliases.set("%s = %s" % (short_name, c.type)) except HTTPClientError as e: return text_type(e) def _(event, aliases, char): b = event.cli.current_buffer w = b.document.get_word_before_cursor() if w is not None: if not w == aliases.get(w): b.delete_before_cursor(count=len(w)) b.insert_text(aliases.get(w)) b.insert_text(char) @key_bindings_registry.add_binding(' ') def _sa(event): _(event, cmd_aliases, ' ') @key_bindings_registry.add_binding('/') def _ra(event): _(event, res_aliases, '/') while True: try: action = prompt(get_prompt_tokens=get_prompt_tokens, history=history, completer=completer, style=default_style, eventloop=eventloop(), key_bindings_registry=key_bindings_registry) action = cmd_aliases.apply(action) except (EOFError, KeyboardInterrupt): break try: action = action.split('|') pipe_cmds = action[1:] action = shlex.split(action[0]) cmd = manager.get(action[0]) args = action[1:] if pipe_cmds: p = pipes.Template() for pipe_cmd in pipe_cmds: p.append(str(pipe_cmd.strip()), '--') cmd.is_piped = True else: cmd.is_piped = False except IndexError: continue except CommandNotFound as e: printo(text_type(e)) continue try: result = cmd.parse_and_call(*args) except (HttpError, HTTPClientError, CommandError, SchemaError, NotFound, Exists) as e: printo(text_type(e)) continue except KeyboardInterrupt: continue except EOFError: break else: if not result: continue elif pipe_cmds: t = tempfile.NamedTemporaryFile('r') with p.open(t.name, 'w') as f: f.write(result) printo(t.read().strip()) else: printo(result)
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, get_globals=None, get_locals=None, history_filename=None, vi_mode=False, # For internal use. _completer=None, _validator=None, _python_prompt_control=None, _lexer=None, _extra_buffers=None, _extra_buffer_processors=None, _on_start=None, _extra_sidebars=None, _accept_action=AcceptAction.RETURN_DOCUMENT, _on_exit=AbortAction.RAISE_EXCEPTION): self.get_globals = get_globals or (lambda: {}) self.get_locals = get_locals or self.get_globals self._completer = _completer or PythonCompleter(self.get_globals, self.get_locals) self._validator = _validator or PythonValidator() self._history = FileHistory(history_filename) if history_filename else History() self._lexer = _lexer or PythonLexer self._extra_buffers = _extra_buffers self._accept_action = _accept_action self._on_exit = _on_exit self._on_start = _on_start self._extra_sidebars = _extra_sidebars or [] self._extra_buffer_processors = _extra_buffer_processors or [] self._python_prompt_control = _python_prompt_control or PythonPrompt(self) # Settings. self.show_signature = True self.show_docstring = False self.show_completions_toolbar = False self.show_completions_menu = True self.show_line_numbers = True self.show_status_bar = True self.complete_while_typing = True self.vi_mode = vi_mode self.paste_mode = False # When True, don't insert whitespace after newline. self.confirm_exit = True # Ask for confirmation when Control-D is pressed. self.enable_open_in_editor = True self.enable_system_bindings = True self.enable_history_search = False # When True, like readline, going # back in history will filter the # history on the records starting # with the current input. self.show_sidebar = False # Currently show the sidebar. self.show_exit_confirmation = False # Currently show 'Do you really want to exit?' #: Load styles. self.code_styles = get_all_code_styles() self.ui_styles = get_all_ui_styles() self._current_code_style_name = 'default' self._current_ui_style_name = 'default' self._current_style = self._generate_style() # Options to be configurable from the sidebar. def handler(enable=None, disable=None): " Handler for an '_Option'. " def handler(): if enable: for o in enable: setattr(self, o, True) if disable: for o in disable: setattr(self, o, False) return handler def simple_option(description, field_name, values=None): " Create Simple on/of option. " values = values or ['off', 'on'] def current_value(): return values[bool(getattr(self, field_name))] return _Option(description, lambda: { values[1]: handler(enable=[field_name]), values[0]: handler(disable=[field_name]), }, current_value) def get_completion_menu_value(): " Return active value for the 'completion menu' option. " if self.show_completions_menu: return 'pop-up' elif self.show_completions_toolbar: return 'toolbar' else: return 'off' self.options = [ simple_option('Input mode', 'vi_mode', values=['emacs', 'vi']), simple_option('Paste mode', 'paste_mode'), _Option('Completion menu', lambda: { 'off': handler(disable=['show_completions_menu', 'show_completions_toolbar']), 'pop-up': handler(enable=['show_completions_menu'], disable=['show_completions_toolbar']), 'toolbar': handler(enable=['show_completions_toolbar'], disable=['show_completions_menu']) }, get_completion_menu_value), _Option('Complete while typing', lambda: { 'on': handler(enable=['complete_while_typing'], disable=['enable_history_search']), 'off': handler(disable=['complete_while_typing']), }, lambda: ['off', 'on'][self.complete_while_typing]), simple_option('Show signature', 'show_signature'), simple_option('Show docstring', 'show_docstring'), simple_option('Show line numbers', 'show_line_numbers'), simple_option('Show status bar', 'show_status_bar'), _Option('History search', lambda: { 'on': handler(enable=['enable_history_search'], disable=['complete_while_typing']), 'off': handler(disable=['enable_history_search']), }, lambda: ['off', 'on'][self.enable_history_search]), _Option('Color scheme (code)', lambda: { name: partial(self.use_code_colorscheme, name) for name in self.code_styles }, lambda: self._current_code_style_name), _Option('Color scheme (UI)', lambda: { name: partial(self.use_ui_colorscheme, name) for name in self.ui_styles }, lambda: self._current_ui_style_name), simple_option('Confirm on exit', 'confirm_exit'), ] self.selected_option = 0 #: Incremeting integer counting the current statement. self.current_statement_index = 1 # Code signatures. (This is set asynchronously after a timeout.) self.signatures = [] # Use a KeyBindingManager for loading the key bindings. self.key_bindings_manager = KeyBindingManager( enable_vi_mode=Condition(lambda cli: self.vi_mode), enable_open_in_editor=Condition(lambda cli: self.enable_open_in_editor), enable_system_bindings=Condition(lambda cli: self.enable_system_bindings), # Disable all default key bindings when the sidebar or the exit confirmation # are shown. enable_all=Condition(lambda cli: not (self.show_sidebar or self.show_exit_confirmation))) load_python_bindings(self.key_bindings_manager, self) load_sidebar_bindings(self.key_bindings_manager, self) load_confirm_exit_bindings(self.key_bindings_manager, self) # Boolean indicating whether we have a signatures thread running. # (Never run more than one at the same time.) self._get_signatures_thread_running = False
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 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 main(tenant, host, port, verbose): """Leapsight Semantic Dataspace Command Line Tool""" # Create a set of key bindings that have Vi mode enabled if the # ``vi_mode_enabled`` is True. if verbose: format = '[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d] %(message)s' logging.basicConfig(level=logging.DEBUG, format=format) # try to connect to lsd try: shell_ctx['lsd_api'] = Lsd(tenant, host, port) except Exception as e: click.echo(colorize('ERROR: connection refused {0}:{1}({2})'.format( host, port, tenant), rgb=0xE11500)) logging.debug(e) exit(1) manager = KeyBindingManager.for_prompt( enable_vi_mode=Condition(lambda cli: shell_ctx['vi_mode_enabled'])) # add an additional key binding for toggling this flag. @manager.registry.add_binding(Keys.F4) def _f4(_event): """ Toggle between Emacs and Vi mode. """ shell_ctx['vi_mode_enabled'] = not shell_ctx['vi_mode_enabled'] # add an additional key binding for toggling this flag. @manager.registry.add_binding(Keys.F5) def _f5(_event): """ Toggle between Json and Tabular mode. """ shell_ctx['json_mode_enabled'] = not shell_ctx['json_mode_enabled'] click.clear() click.echo(colorize(""" Welcome to _/ _/_/_/_/ _/_/_/ _/ _/ _/ _/ _/ _/_/_/_/ _/ _/ _/ _/ _/ _/ _/_/_/_/ _/_/_/_/ _/_/_/ command line interface! """ , rgb=0x2cb9d0)) ll_completer = WordCompleter( ['@prefix prefix: <uri>.', '@include <uri>.', '++().', '--().', '+().', '-().', '?().', 'import(filename)', 'export(filename)', 'h()', 'e()']) # load init file ~/lsd-cli.rc try: _load_context(shell_ctx, cli_rc) except: pass while True: input = prompt('lsd> ', history=history, auto_suggest=auto_suggest, get_bottom_toolbar_tokens=get_bottom_toolbar_tokens, style=style, vi_mode=shell_ctx['vi_mode_enabled'], key_bindings_registry=manager.registry, get_title=get_title, completer=ll_completer) try: if input: process_input(shell_ctx, input.strip()) except Exception as e: click.echo(colorize(e, rgb=0xE11500)) logging.debug(traceback.print_exc())