def _feed_cli_with_input(text, editing_mode=EditingMode.EMACS, clipboard=None, history=None, multiline=False, check_line_ending=True, key_bindings=None): """ Create a Prompt, feed it with the given user input and return the CLI object. This returns a (result, Application) tuple. """ # If the given text doesn't end with a newline, the interface won't finish. if check_line_ending: assert text.endswith('\r') inp = create_pipe_input() try: inp.send_text(text) session = PromptSession(input=inp, output=DummyOutput(), editing_mode=editing_mode, history=history, multiline=multiline, clipboard=clipboard, key_bindings=key_bindings) result = session.prompt() return session.default_buffer.document, session.app finally: inp.close()
def run_repl(): global todos global selected update_todos() cooee_completer = CooeeCompleter() cooee_validator = CooeeValidator() def get_rprompt(): global selected if selected is None: return "" if "location" in selected: url: str = selected["location"] parts: ParseResult = urllib.parse.urlparse(url) return parts.hostname + parts.path elif "message" in selected: return selected["message"] return f"{selected}" def bottom_toolbar(): update_todos() num = len(todos) if todos is not None else 0 todo_text = f'Todos: ({num})' loading_text = f' Loading completions... ' if cooee_completer.loading > 0 else '' return todo_text + loading_text history_file = os.path.expanduser("~/.cooee/repl.hist") session = PromptSession( '> ', completer=ThreadedCompleter(cooee_completer), complete_while_typing=False, bottom_toolbar=bottom_toolbar, complete_style=CompleteStyle.MULTI_COLUMN, history=FileHistory(history_file), refresh_interval=5, rprompt=get_rprompt, validator=ThreadedValidator(cooee_validator), validate_while_typing=True, ) while True: try: text = session.prompt() if text != "": launch(text) else: update_todos() print_formatted_text("Todos") for t in todos: print_formatted_text(todo_string(t)) selected = {"message": "Todos"} except KeyboardInterrupt: continue # Control-C pressed. Try again. except EOFError: break # Control-D pressed.
def _feed_cli_with_input( text, editing_mode=EditingMode.EMACS, clipboard=None, history=None, multiline=False, check_line_ending=True, key_bindings=None): """ Create a Prompt, feed it with the given user input and return the CLI object. This returns a (result, Application) tuple. """ # If the given text doesn't end with a newline, the interface won't finish. if check_line_ending: assert text.endswith('\r') inp = create_pipe_input() try: inp.send_text(text) session = PromptSession( input=inp, output=DummyOutput(), editing_mode=editing_mode, history=history, multiline=multiline, clipboard=clipboard, key_bindings=key_bindings) result = session.prompt() return session.default_buffer.document, session.app finally: inp.close()
def init_prompt_toolkit_cli(self): if self.simple_prompt: # Fall back to plain non-interactive output for tests. # This is very limited. def prompt(): prompt_text = "".join(x[1] for x in self.prompts.in_prompt_tokens()) lines = [input(prompt_text)] prompt_continuation = "".join( x[1] for x in self.prompts.continuation_prompt_tokens()) while self.check_complete('\n'.join(lines))[0] == 'incomplete': lines.append(input(prompt_continuation)) return '\n'.join(lines) self.prompt_for_code = prompt return # Set up keyboard shortcuts key_bindings = create_ipython_shortcuts(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_string(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()) self.pt_loop = asyncio.new_event_loop() self.pt_app = PromptSession( auto_suggest=self.auto_suggest, editing_mode=editing_mode, key_bindings=key_bindings, history=history, completer=IPythonPTCompleter(shell=self), enable_history_search=self.enable_history_search, style=self.style, include_default_pygments_style=False, mouse_support=self.mouse_support, enable_open_in_editor=self.extra_open_editor_shortcuts, color_depth=self.color_depth, tempfile_suffix=".py", **self._extra_prompt_options())
def test_accept_default(): """ Test `prompt(accept_default=True)`. """ with create_pipe_input() as inp: session = PromptSession(input=inp, output=DummyOutput()) result = session.prompt(default="hello", accept_default=True) assert result == "hello" # Test calling prompt() for a second time. (We had an issue where the # prompt reset between calls happened at the wrong time, breaking this.) result = session.prompt(default="world", accept_default=True) assert result == "world"
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 = input(prompt_text) isp.push(line) prompt_text = prompt_continuation return isp.source_reset() self.prompt_for_code = prompt return # Set up keyboard shortcuts key_bindings = create_ipython_shortcuts(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_string(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()) self.pt_app = PromptSession( editing_mode=editing_mode, key_bindings=key_bindings, history=history, completer=IPythonPTCompleter(shell=self), enable_history_search=self.enable_history_search, style=self.style, include_default_pygments_style=False, mouse_support=self.mouse_support, enable_open_in_editor=self.extra_open_editor_shortcuts, color_depth=(ColorDepth.TRUE_COLOR if self.true_color else None), **self._extra_prompt_options())
def main(type, url): try: backend = backends.load(type, url) except ValueError as ex: print(ex.args[0]) backends.list() return completer = sql.SQLCompleter(tables=backend.get_tables()) bindings = KeyBindings() @bindings.add(" ") def _(event): buffer = event.app.current_buffer word = buffer.document.get_word_before_cursor() if word is not None: for comp in sql.keywords: if Levenshtein.ratio(word.lower(), comp.lower()) >= 0.75: buffer.delete_before_cursor(count=len(word)) buffer.insert_text(comp) break buffer.insert_text(" ") history = FileHistory(".sqlmojo_history") session = PromptSession( ">", lexer=PygmentsLexer(sql.SQLLexer), completer=completer, complete_while_typing=False, history=history, validator=sql.SQLValidator(), validate_while_typing=False, bottom_toolbar=HTML(f"{backend.name}: <b>{url}</b>"), key_bindings=bindings, style=style, ) while True: try: stmt = session.prompt("eSQL> ").rstrip(";") if not stmt.strip(): continue ir_dct = yacc.parse(stmt) ir_dct["raw"] = stmt result = backend.query(ir_dct) render(result) except EOFError: break
def __init__(self, username, client_id, token, channel): self.running = True self.username = username self.client_id = client_id self.token = 'oauth:{}'.format(token) self.channel = channel self.bot = TwitchBot(self.username, self.client_id, self.token, self.channel) self.bot._connect() self.session = PromptSession('ME: ') th1 = Thread(target=self.irc_bot, args=(self, )) th1.start() th2 = Thread(target=self.interactive_shell, args=(self, )) th2.start()
def _create_interruption_dialog() -> PromptSession[InterruptAction]: bindings = KeyBindings() @bindings.add(Keys.Enter) @bindings.add(Keys.Escape) def nothing(event: KeyPressEvent) -> None: event.app.exit(result=InterruptAction.NOTHING) @bindings.add("c-c") @bindings.add("C") @bindings.add("c") def kill(event: KeyPressEvent) -> None: event.app.exit(result=InterruptAction.KILL) @bindings.add("c-d") @bindings.add("D") @bindings.add("d") def detach(event: KeyPressEvent) -> None: event.app.exit(result=InterruptAction.DETACH) @bindings.add(Keys.Any) def _(event: KeyPressEvent) -> None: # Disallow inserting other text. pass message = HTML(" <b>Interrupted</b>. Please choose the action:\n") suffix = HTML("<b>Ctrl-C</b> or <b>C</b> -- Kill\n" "<b>Ctrl-D</b> or <b>D</b> -- Detach \n" "<b>Enter</b> or <b>ESC</b> -- Continue the attached mode") complete_message = merge_formatted_text([message, suffix]) session: PromptSession[InterruptAction] = PromptSession( complete_message, key_bindings=bindings) return session
async def init(self): logger.info("CLI init") session = PromptSession( complete_while_typing=True, completer=self.umbra_completer, style=CLI.umbra_style, auto_suggest=AutoSuggestFromHistory(), ) prompt = ":umbra> " try: while True: try: prompt_text = format_text(prompt, style="prompt") text = await session.prompt_async(prompt_text) except KeyboardInterrupt: continue except EOFError: break try: commands = self.validator(text) except Exception as e: logger.debug(repr(e)) else: if commands: await self.runner.execute(commands) # ack, reply = await self.runner.execute(commands) finally: logger.debug("GoodBye!")
def main(): # Create user interface. hello_world_window() # Enable threading in GTK. (Otherwise, GTK will keep the GIL.) gtk.gdk.threads_init() # Read input from the command line, using an event loop with this hook. # We use `patch_stdout`, because clicking the button will print something; # and that should print nicely 'above' the input line. with patch_stdout(): session = PromptSession('Python >>> ', inputhook=inputhook, lexer=PygmentsLexer(PythonLexer)) result = session.prompt() print('You said: %s' % result)
async def interactive_shell(): """ Like `interactive_shell`, but doing things manual. """ # Create Prompt. def get_toolbar(): return "Bottom toolbar: time=%r" % time.time() session = PromptSession("Say something: ") # Run echo loop. Read text from stdin, and reply it back. while True: try: result = await session.prompt_async(">:", bottom_toolbar=get_toolbar, refresh_interval=0.5) print('You said: "{0}"'.format(result)) if result == 'start': background_task = asyncio.create_task(print_counter()) for task in asyncio.all_tasks(): print(task) except (EOFError, KeyboardInterrupt): print("key") return
def checkbox_prompt( message: str, default: bool, ) -> PromptSession[bool]: """ Create a `PromptSession` object for the 'confirm' function. """ bindings = KeyBindings() check = MiniCheckBoxPrompt(message=message, value=default) @bindings.add(" ") def space(event: "E") -> None: check.value = not check.value # cursor_pos = check.formatMessage().find("[") + 1 # cur_cursor_pos = session.default_buffer.cursor_position # print(f"cur_cursor_pos={cur_cursor_pos}, cursor_pos={cursor_pos}") # session.default_buffer.cursor_position = cursor_pos @bindings.add(Keys.Any) def _(event: "E") -> None: " Disallow inserting other text. " pass complete_message = check session: PromptSession[bool] = PromptSession(complete_message, key_bindings=bindings) session.prompt() return check.value
def __init__(self, name, groups, board=None, learner=False): self.groups_joined = set(groups) if groups is not None else set() self.peers = {} self.directory = {} # peer by name. Should use consensus to maintain self.blocked = set() # set of peers from whom we don't what to hear self.signal = None self.create_node(name) if DISABLE_CONSENSUS: self.consensus = None else: opts = {} opts["stable_storage"] = dbm.open(f"/tmp/{name}-raft.db", "cs") if board == "db": opts["messageBoard"] = DBBoard(prefix=f"/tmp/{name}") role = Learner() if learner else Follower() self.consensus = Raft(ZRENode.GROUP, name, role, self.n, **opts) self.groups = defaultdict(list) self.queue = asyncio.Queue() self.ctx = zmq.asyncio.Context() self.pipe1, self.pipe2 = self.zcreate_pipe(self.ctx) self.session = PromptSession(f"{self.n.name()} {self.GROUP}: ") self.pending_messages = {} self.tasks = [] self.threads = [] t = threading.Thread(target=self.worker, args=[self.pipe2, self.queue]) self.threads.append(t) t.start()
def build_cli(self): # TODO: Optimize index suggestion to serve indices options only at the needed position, such as 'from' indices_list = self.es_executor.indices_list sql_completer = WordCompleter(self.keywords_list + self.functions_list + indices_list, ignore_case=True) # https://stackoverflow.com/a/13726418 denote multiple unused arguments of callback in Python def get_continuation(width, *_): continuation = self.multiline_continuation_char * (width - 1) + " " return [("class:continuation", continuation)] prompt_app = PromptSession( lexer=PygmentsLexer(SqlLexer), completer=sql_completer, complete_while_typing=True, # TODO: add history, refer to pgcli approach # history=history, style=style_factory(self.syntax_style, self.cli_style), prompt_continuation=get_continuation, multiline=es_is_multiline(self), auto_suggest=AutoSuggestFromHistory(), input_processors=[ ConditionalProcessor( processor=HighlightMatchingBracketProcessor( chars="[](){}"), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone(), ) ], tempfile_suffix=".sql", ) return prompt_app
def test_accept_default(): """ Test `prompt(accept_default=True)`. """ inp = create_pipe_input() session = PromptSession(input=inp, output=DummyOutput()) result = session.prompt(default='hello', accept_default=True) assert result == 'hello' # Test calling prompt() for a second time. (We had an issue where the # prompt reset between calls happened at the wrong time, breaking this.) result = session.prompt(default='world', accept_default=True) assert result == 'world' inp.close()
def prompt(session): ''' mec prompt ''' cmd_list = readline_init(session) # cook our completions completion_dict = dict.fromkeys(cmd_list) completion_dict["target"] = dict.fromkeys(os.listdir("./data")) completion_dict["set"] = dict.fromkeys(["auto-update", "proxy-pool"]) completion_dict["set"]["auto-update"] = dict.fromkeys(["True", "False"]) mec_completer = NestedCompleter.from_nested_dict(completion_dict) mec_ps = ANSI(colors.CYAN + colors.BOLD + "\nmec > " + colors.END) cmd_autosuggest = ThreadedAutoSuggest(MecAutoSuggest(completions=cmd_list)) try: mecprompt = PromptSession(message=mec_ps, mouse_support=True, history=FileHistory(HISTFILE), completer=mec_completer, complete_while_typing=True, reserve_space_for_menu=2, auto_suggest=cmd_autosuggest).prompt() except termios.error as err: colors.colored_print(f"[-] Fatal error: {err}", color_code=colors.RED) os.system("mec stop") return mecprompt
def test_run_cli(self, connection, cli, capsys): doc = {"a": "aws"} load_data(connection, doc) # the title is colored by formatter expected = ( "fetched rows / total rows = 1/1" "\n+-----+\n| \x1b[38;5;47;01ma\x1b[39;00m |\n|-----|\n| aws |\n+-----+" ) with mock.patch.object( OpenSearchSqlCli, "echo_via_pager") as mock_pager, mock.patch.object( cli, "build_cli") as mock_prompt: inp = create_pipe_input() inp.send_text(QUERY_WITH_CTRL_D) mock_prompt.return_value = PromptSession( input=inp, multiline=opensearch_is_multiline(cli), style=style_factory(cli.syntax_style, cli.cli_style)) cli.connect(ENDPOINT) cli.run_cli() out, err = capsys.readouterr() inp.close() mock_pager.assert_called_with(expected) assert out.__contains__("Endpoint: %s" % ENDPOINT) assert out.__contains__("See you next search!")
def _build_cli(self, history): def get_message(): prompt = self.context.get_prompt(self.default_prompt) return [('class:prompt', prompt)] prompt_app = PromptSession( message=get_message, complete_style=CompleteStyle.COLUMN, completer=ThreadedCompleter( DynamicCompleter(lambda: self.completer)), complete_while_typing=True, editing_mode=EditingMode.VI, enable_system_prompt=True, enable_suspend=True, history=history, input_processors=[ # Highlight matching brackets while editing. ConditionalProcessor( processor=HighlightMatchingBracketProcessor( chars='[](){}', ), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()), # Render \t as 4 spaces instead of "^I" TabsProcessor(char1=' ', char2=' ') ], key_bindings=get_key_bindings(), search_ignore_case=True, ) return prompt_app
async def UaeDebugger(uaedbg): history = InMemoryHistory() session = PromptSession('(debug) ', history=history) with patch_stdout(): try: lines = await uaedbg.recv() while lines is not None: for line in lines: print(line) try: cmd = '' while not cmd: cmd = await session.prompt_async() cmd.strip() uaedbg.send(cmd) except EOFError: uaedbg.resume() except KeyboardInterrupt: uaedbg.kill() lines = await uaedbg.recv() except asyncio.CancelledError: pass except EOFError: pass except Exception as ex: print('Debugger bug!') print('Quitting...')
def _create_more_session(message: str = '--MORE--') -> 'PromptSession': """ Create a `PromptSession` object for displaying the "--MORE--". """ from prompt_toolkit.shortcuts import PromptSession bindings = KeyBindings() @bindings.add(' ') @bindings.add('y') @bindings.add('Y') @bindings.add(Keys.ControlJ) @bindings.add(Keys.ControlM) @bindings.add(Keys.ControlI) # Tab. def _(event: E) -> None: event.app.exit(result=True) @bindings.add('n') @bindings.add('N') @bindings.add('q') @bindings.add('Q') @bindings.add(Keys.ControlC) def _(event: E) -> None: event.app.exit(result=False) @bindings.add(Keys.Any) def _(event: E) -> None: " Disable inserting of text. " return PromptSession(message, key_bindings=bindings, erase_when_done=True)
def _create_more_session(message: str = "--MORE--") -> "PromptSession": """ Create a `PromptSession` object for displaying the "--MORE--". """ from prompt_toolkit.shortcuts import PromptSession bindings = KeyBindings() @bindings.add(" ") @bindings.add("y") @bindings.add("Y") @bindings.add(Keys.ControlJ) @bindings.add(Keys.ControlM) @bindings.add(Keys.ControlI) # Tab. def _yes(event: E) -> None: event.app.exit(result=True) @bindings.add("n") @bindings.add("N") @bindings.add("q") @bindings.add("Q") @bindings.add(Keys.ControlC) def _no(event: E) -> None: event.app.exit(result=False) @bindings.add(Keys.Any) def _ignore(event: E) -> None: " Disable inserting of text. " return PromptSession(message, key_bindings=bindings, erase_when_done=True)
class TwitchIRC: def __init__(self, username, client_id, token, channel): self.running = True self.username = username self.client_id = client_id self.token = 'oauth:{}'.format(token) self.channel = channel self.bot = TwitchBot(self.username, self.client_id, self.token, self.channel) self.bot._connect() self.session = PromptSession('ME: ') th1 = Thread(target=self.irc_bot, args=(self, )) th1.start() th2 = Thread(target=self.interactive_shell, args=(self, )) th2.start() def irc_bot(self, data): while self.running: self.bot.reactor.process_once(0.2) def interactive_shell(self, data): while self.running: with patch_stdout(): command = self.session.prompt() if command == 'quit()': self.running = False self.bot.reactor.disconnect_all() else: self.bot.connection.privmsg('#{}'.format(self.channel), command)
def main(self): session = PromptSession(message="> ", enable_history_search=True, auto_suggest=AutoCompleter(), history=FileHistory(HISTORY_FILE)) app = session.app textarea = TextArea(text=WELCOME_MSG, read_only=False, scrollbar=True) app.layout.container.height = 1 mainlayout = HSplit([textarea, app.layout.container]) app.layout = Layout(mainlayout, app.layout.current_control) # monkey patch fullscreen mode app.full_screen = True app.renderer.full_screen = True def accept(buf): if buf.text == "exit": app.exit(result="") else: newtext = self.cmd_parser.parse(buf.text) textarea.text = textarea.text + "\n" + newtext textarea.buffer.cursor_position = len(textarea.text) buf.reset(append_to_history=True) session.default_buffer.accept_handler = accept try: app.run() except (KeyboardInterrupt, EOFError): # ctrl+c or ctrl+d pass
def question(message, **kwargs): # TODO need ENTER confirmation default = kwargs.pop('default', True) # TODO style defaults on detail level style = kwargs.pop('style', default_style) status = {'answer': None} qmark = kwargs.pop('qmark', '?') def get_prompt_tokens(): tokens = [] tokens.append(('class:questionmark', qmark)) tokens.append(('class:question', ' %s ' % message)) if isinstance(status['answer'], bool): tokens.append( ('class:answer', ' Yes' if status['answer'] else ' No')) else: if default: instruction = ' (Y/n)' else: instruction = ' (y/N)' tokens.append(('class:instruction', instruction)) return tokens # key bindings kb = KeyBindings() @kb.add('c-q', eager=True) @kb.add('c-c', eager=True) def _(event): event.app.exit(result=None) #raise KeyboardInterrupt() @kb.add('n') @kb.add('N') def key_n(event): status['answer'] = False event.app.exit(result=False) @kb.add('y') @kb.add('Y') def key_y(event): status['answer'] = True event.app.exit(result=True) @kb.add('enter', eager=True) def set_answer(event): status['answer'] = default event.app.exit(result=default) return PromptSession( message=get_prompt_tokens, key_bindings=kb, mouse_support=False, style=style, erase_when_done=False, )
def GatherContractDetails(function_code): print("Please fill out the following contract details:") from neo.bin.prompt import PromptInterface session = PromptSession(completer=PromptInterface.prompt_completer, history=PromptInterface.history) name = session.prompt("[Contract Name] > ") version = session.prompt("[Contract Version] > ") author = session.prompt("[Contract Author] > ") email = session.prompt("[Contract Email] > ") description = session.prompt("[Contract Description] > ") print("Creating smart contract....") print(" Name: %s " % name) print(" Version: %s" % version) print(" Author: %s " % author) print(" Email: %s " % email) print(" Description: %s " % description) print(" Needs Storage: %s " % function_code.HasStorage) print(" Needs Dynamic Invoke: %s " % function_code.HasDynamicInvoke) print(json.dumps(function_code.ToJson(), indent=4)) return generate_deploy_script(function_code.Script, name, version, author, email, description, function_code.ContractProperties, function_code.ReturnTypeBigInteger, function_code.ParameterList)
def CreateSession(self): # self.fPyMode = False # self.fPyMore = False def message(): """Choose correct prompt for current mode.""" if self.fPyMore: return "... > " elif self.fPyMode: return "py>>> " else: return "hdtv> " completer = HDTVCompleter(self.command_tree, self) bindings = KeyBindings() # @bindings.add(':') # def _(event): # if event.app.editing_mode == EditingMode.VI: # event.app.editing_mode = EditingMode.EMACS # else: # event.app.editing_mode = EditingMode.VI @bindings.add("pageup") def _(event): event.current_buffer.enable_history_search = lambda: True event.current_buffer.history_backward(count=event.arg) event.current_buffer.enable_history_search = lambda: False @bindings.add("pagedown") def _(event): event.current_buffer.enable_history_search = lambda: True event.current_buffer.history_forward(count=event.arg) event.current_buffer.enable_history_search = lambda: False self.session = PromptSession( message, history=self.history, completer=completer, complete_while_typing=False, key_bindings=bindings, complete_style=CompleteStyle.MULTI_COLUMN, )
async def prompt(question, validator=None): # Create Prompt. session = PromptSession(question) # Run echo loop. Read text from stdin, and reply it back. while True: try: return await session.prompt_async(validator=validator) except (EOFError, KeyboardInterrupt): return None
def create_pager_prompt( style: BaseStyle, title: AnyFormattedText = "" ) -> PromptSession[PagerResult]: """ Create a "continue" prompt for paginated output. """ bindings = KeyBindings() @bindings.add("enter") @bindings.add("down") def next_line(event: KeyPressEvent) -> None: event.app.exit(result=PagerResult.NEXT_LINE) @bindings.add("space") def next_page(event: KeyPressEvent) -> None: event.app.exit(result=PagerResult.NEXT_PAGE) @bindings.add("a") def print_all(event: KeyPressEvent) -> None: event.app.exit(result=PagerResult.PRINT_ALL) @bindings.add("q") @bindings.add("c-c") @bindings.add("c-d") @bindings.add("escape", eager=True) def no(event: KeyPressEvent) -> None: event.app.exit(result=PagerResult.ABORT) @bindings.add("<any>") def _(event: KeyPressEvent) -> None: "Disallow inserting other text." pass style session: PromptSession[PagerResult] = PromptSession( merge_formatted_text( [ title, HTML( "<status-toolbar>" "<more> -- MORE -- </more> " "<key>[Enter]</key> Scroll " "<key>[Space]</key> Next page " "<key>[a]</key> Print all " "<key>[q]</key> Quit " "</status-toolbar>: " ), ] ), key_bindings=bindings, erase_when_done=True, style=style, ) return session
async def interactive_shell(self) -> None: session = PromptSession() while True: self.prompt_text = self.option_register.get_register('prompt_text') try: data: str = await session.prompt_async(f"{self.prompt_text} > ", style=prompt_style) if not data: continue await self.command_interpreter(data.strip()) except (EOFError, KeyboardInterrupt): return
def user_save_file(filename, force=False): """ Make sure filename is not in use. Offer to backup existing file unless force is True. Returns filename if successful or False if aborted. """ filename = os.path.expanduser(filename) if not force and os.path.exists(filename): hdtv.ui.warning(f"This file already exists: {filename}") bindings = KeyBindings() @bindings.add("y") @bindings.add("Y") def yes(event): session.default_buffer.text = "y" event.app.exit(result=filename) @bindings.add("n") @bindings.add("N") def no(event): session.default_buffer.text = "n" event.app.exit(result=False) @bindings.add("b") @bindings.add("B") @bindings.add(Keys.Enter) def backup(event): session.default_buffer.text = "b" backup_file(filename) event.app.exit(result=filename) @bindings.add(Keys.Any) def _(event): pass session = PromptSession( "Replace [y/n] or backup [B] existing file? ", key_bindings=bindings ) filename = session.prompt() return filename
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 = input(prompt_text) isp.push(line) prompt_text = prompt_continuation return isp.source_reset() self.prompt_for_code = prompt return # Set up keyboard shortcuts key_bindings = create_ipython_shortcuts(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_string(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()) self.pt_app = PromptSession( editing_mode=editing_mode, key_bindings=key_bindings, history=history, completer=IPythonPTCompleter(shell=self), enable_history_search = self.enable_history_search, style=self.style, include_default_pygments_style=False, mouse_support=self.mouse_support, enable_open_in_editor=self.extra_open_editor_shortcuts, color_depth=(ColorDepth.TRUE_COLOR if self.true_color else None), **self._extra_prompt_options())
def __init__(self): """ Constructor __init__(InteractiveCliMixin) :since: v1.0.00 """ self.prompt_session = None """ prompt_toolkit based input prompt session """ self.output_pid = os.getpid() """ PID used for output separation """ self.prompt_session = PromptSession(mouse_support = True)
class InteractiveCliMixin(object): """ This mixin provides methods to handle console input and output. :author: direct Netware Group et al. :copyright: (C) direct Netware Group - All rights reserved :package: dpt :subpackage: interactive_cli :since: v1.0.0 :license: https://www.direct-netware.de/redirect?licenses;mpl2 Mozilla Public License, v. 2.0 """ def __init__(self): """ Constructor __init__(InteractiveCliMixin) :since: v1.0.00 """ self.prompt_session = None """ prompt_toolkit based input prompt session """ self.output_pid = os.getpid() """ PID used for output separation """ self.prompt_session = PromptSession(mouse_support = True) # @property def output_stream(self): """ Returns the current output stream pointer in use. :param prompt: Inline prompt :return: (int) Stream pointer number :since: v1.0.0 """ return get_default_output().fileno() # @output_stream.setter def output_stream(self, pointer): """ Sets the output stream pointer to use. :param pointer: Stream pointer number :since: v1.0.0 """ set_default_output(create_output(pointer)) # def error(self, _exception): """ Prints the stack trace on this error event. :param _exception: Inner exception :since: v1.0.0 """ if (isinstance(_exception, TracedException)): _exception.print_stack_trace(self.output_stream) else: TracedException.print_current_stack_trace(self.output_stream) # def input(self, prompt): """ Reads one line of input. :param prompt: Inline prompt :return: (str) Cli input :since: v1.0.0 """ return self.prompt_session.prompt(prompt) # def output(self, line, *args): """ Outputs the given line. Additional positional arguments are used for string formatting. :param line: Output line :since: v1.0.0 """ output = (line.format(*args) if (len(args) > 0) else line ) print_formatted_text(output) # def output_error(self, line, *args): """ Outputs the given error line. Additional positional arguments are used for string formatting. :param line: Output line :since: v1.0.0 """ line = (line.format(*args) if (len(args) > 0) else line ) self.output_formatted("<small>[{0}({1:d}) {2}]</small> <strong>{3}</strong>", self.__class__.__name__, self.output_pid, ctime(), line ) # def output_formatted(self, line, *args): """ Outputs the given HTML-formatted line. Additional positional arguments are used for string formatting. :param line: Output line :since: v1.0.0 """ output = HTML(line.format(*args) if (len(args) > 0) else line ) print_formatted_text(output) # def output_info(self, line, *args): """ Outputs the given informational line. Additional positional arguments are used for string formatting. :param line: Output line :since: v1.0.0 """ line = (line.format(*args) if (len(args) > 0) else line ) self.output_formatted("<small>[{0}({1:d}) {2}]</small> {3}", self.__class__.__name__, self.output_pid, ctime(), line ) # def secure_input(self, prompt): """ Reads one line of input without showing the user what he typed. :param prompt: Inline prompt :return: (str) Cli input :since: v1.0.0 """ return self.prompt_session.prompt(prompt, is_password = True)
#!/usr/bin/env python """ For testing: test to make sure that everything still works when gevent monkey patches are applied. """ from __future__ import unicode_literals from gevent.monkey import patch_all from prompt_toolkit.shortcuts import PromptSession from prompt_toolkit.eventloop.defaults import create_event_loop if __name__ == '__main__': # Apply patches. patch_all() # There were some issues in the past when the event loop had an input hook. def dummy_inputhook(*a): pass eventloop = create_event_loop(inputhook=dummy_inputhook) # Ask for input. session = PromptSession('Give me some input: ', loop=eventloop) answer = session.prompt() print('You said: %s' % answer)
def main(): session = PromptSession('prompt> ') while True: session.prompt()
class TerminalInteractiveShell(InteractiveShell): space_for_menu = Integer(6, help='Number of line at the bottom of the screen ' 'to reserve for the completion menu' ).tag(config=True) pt_app = None debugger_history = None simple_prompt = Bool(_use_simple_prompt, help="""Use `raw_input` for the REPL, without completion and prompt colors. Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are: IPython own testing machinery, and emacs inferior-shell integration through elpy. This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT` environment variable is set, or the current terminal is not a tty.""" ).tag(config=True) @property def debugger_cls(self): return Pdb if self.simple_prompt else TerminalPdb confirm_exit = Bool(True, help=""" Set to confirm when you try to exit IPython with an EOF (Control-D in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit', you can force a direct exit without any confirmation.""", ).tag(config=True) editing_mode = Unicode('emacs', help="Shortcut style to use at the prompt. 'vi' or 'emacs'.", ).tag(config=True) mouse_support = Bool(False, help="Enable mouse support in the prompt\n(Note: prevents selecting text with the mouse)" ).tag(config=True) # We don't load the list of styles for the help string, because loading # Pygments plugins takes time and can cause unexpected errors. highlighting_style = Union([Unicode('legacy'), Type(klass=Style)], help="""The name or class of a Pygments style to use for syntax highlighting. To see available styles, run `pygmentize -L styles`.""" ).tag(config=True) @validate('editing_mode') def _validate_editing_mode(self, proposal): if proposal['value'].lower() == 'vim': proposal['value']= 'vi' elif proposal['value'].lower() == 'default': proposal['value']= 'emacs' if hasattr(EditingMode, proposal['value'].upper()): return proposal['value'].lower() return self.editing_mode @observe('editing_mode') def _editing_mode(self, change): u_mode = change.new.upper() if self.pt_app: self.pt_app.editing_mode = u_mode @observe('highlighting_style') @observe('colors') def _highlighting_style_changed(self, change): self.refresh_style() def refresh_style(self): self._style = self._make_style_from_name_or_cls(self.highlighting_style) highlighting_style_overrides = Dict( help="Override highlighting format for specific tokens" ).tag(config=True) true_color = Bool(False, help=("Use 24bit colors instead of 256 colors in prompt highlighting. " "If your terminal supports true color, the following command " "should print 'TRUECOLOR' in orange: " "printf \"\\x1b[38;2;255;100;0mTRUECOLOR\\x1b[0m\\n\"") ).tag(config=True) editor = Unicode(get_default_editor(), help="Set the editor used by IPython (default to $EDITOR/vi/notepad)." ).tag(config=True) prompts_class = Type(Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag(config=True) prompts = Instance(Prompts) @default('prompts') def _prompts_default(self): return self.prompts_class(self) # @observe('prompts') # def _(self, change): # self._update_layout() @default('displayhook_class') def _displayhook_class_default(self): return RichPromptDisplayHook term_title = Bool(True, help="Automatically set the terminal title" ).tag(config=True) term_title_format = Unicode("IPython: {cwd}", help="Customize the terminal title format. This is a python format string. " + "Available substitutions are: {cwd}." ).tag(config=True) display_completions = Enum(('column', 'multicolumn','readlinelike'), help= ( "Options for displaying tab completions, 'column', 'multicolumn', and " "'readlinelike'. These options are for `prompt_toolkit`, see " "`prompt_toolkit` documentation for more information." ), default_value='multicolumn').tag(config=True) highlight_matching_brackets = Bool(True, help="Highlight matching brackets.", ).tag(config=True) extra_open_editor_shortcuts = Bool(False, help="Enable vi (v) or Emacs (C-X C-E) shortcuts to open an external editor. " "This is in addition to the F2 binding, which is always enabled." ).tag(config=True) handle_return = Any(None, help="Provide an alternative handler to be called when the user presses " "Return. This is an advanced option intended for debugging, which " "may be changed or removed in later releases." ).tag(config=True) enable_history_search = Bool(True, help="Allows to enable/disable the prompt toolkit history search" ).tag(config=True) prompt_includes_vi_mode = Bool(True, help="Display the current vi mode (when using vi editing mode)." ).tag(config=True) @observe('term_title') def init_term_title(self, change=None): # Enable or disable the terminal title. if self.term_title: toggle_set_term_title(True) set_term_title(self.term_title_format.format(cwd=abbrev_cwd())) else: toggle_set_term_title(False) def init_display_formatter(self): super(TerminalInteractiveShell, self).init_display_formatter() # terminal only supports plain text self.display_formatter.active_types = ['text/plain'] # disable `_ipython_display_` self.display_formatter.ipython_display_formatter.enabled = False def init_prompt_toolkit_cli(self): if self.simple_prompt: # Fall back to plain non-interactive output for tests. # This is very limited. def prompt(): prompt_text = "".join(x[1] for x in self.prompts.in_prompt_tokens()) lines = [input(prompt_text)] prompt_continuation = "".join(x[1] for x in self.prompts.continuation_prompt_tokens()) while self.check_complete('\n'.join(lines))[0] == 'incomplete': lines.append( input(prompt_continuation) ) return '\n'.join(lines) self.prompt_for_code = prompt return # Set up keyboard shortcuts key_bindings = create_ipython_shortcuts(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_string(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()) self.pt_app = PromptSession( editing_mode=editing_mode, key_bindings=key_bindings, history=history, completer=IPythonPTCompleter(shell=self), enable_history_search = self.enable_history_search, style=self.style, include_default_pygments_style=False, mouse_support=self.mouse_support, enable_open_in_editor=self.extra_open_editor_shortcuts, color_depth=self.color_depth, **self._extra_prompt_options()) def _make_style_from_name_or_cls(self, name_or_cls): """ Small wrapper that make an IPython compatible style from a style name We need that to add style for prompt ... etc. """ style_overrides = {} if name_or_cls == 'legacy': legacy = self.colors.lower() if legacy == 'linux': style_cls = get_style_by_name('monokai') style_overrides = _style_overrides_linux elif legacy == 'lightbg': style_overrides = _style_overrides_light_bg style_cls = get_style_by_name('pastie') elif legacy == 'neutral': # 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_cls = get_style_by_name('default') 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', Token.Prompt: '#009900', Token.PromptNum: '#ansibrightgreen bold', Token.OutPrompt: '#990000', Token.OutPromptNum: '#ansibrightred bold', }) # Hack: Due to limited color support on the Windows console # the prompt colors will be wrong without this if os.name == 'nt': style_overrides.update({ Token.Prompt: '#ansidarkgreen', Token.PromptNum: '#ansigreen bold', Token.OutPrompt: '#ansidarkred', Token.OutPromptNum: '#ansired bold', }) elif legacy =='nocolor': style_cls=_NoStyle style_overrides = {} else : raise ValueError('Got unknown colors: ', legacy) else : if isinstance(name_or_cls, str): style_cls = get_style_by_name(name_or_cls) else: style_cls = name_or_cls style_overrides = { Token.Prompt: '#009900', Token.PromptNum: '#ansibrightgreen bold', Token.OutPrompt: '#990000', Token.OutPromptNum: '#ansibrightred bold', } style_overrides.update(self.highlighting_style_overrides) style = merge_styles([ style_from_pygments_cls(style_cls), style_from_pygments_dict(style_overrides), ]) return style @property def pt_complete_style(self): return { 'multicolumn': CompleteStyle.MULTI_COLUMN, 'column': CompleteStyle.COLUMN, 'readlinelike': CompleteStyle.READLINE_LIKE, }[self.display_completions] @property def color_depth(self): return (ColorDepth.TRUE_COLOR if self.true_color else None) def _extra_prompt_options(self): """ Return the current layout option for the current Terminal InteractiveShell """ def get_message(): return PygmentsTokens(self.prompts.in_prompt_tokens()) return { 'complete_in_thread': False, 'lexer':IPythonPTLexer(), 'reserve_space_for_menu':self.space_for_menu, 'message': get_message, 'prompt_continuation': ( lambda width, lineno, is_soft_wrap: PygmentsTokens(self.prompts.continuation_prompt_tokens(width))), 'multiline': True, 'complete_style': self.pt_complete_style, # Highlight matching brackets, but only when this setting is # enabled, and only when the DEFAULT_BUFFER has the focus. 'input_processors': [ConditionalProcessor( processor=HighlightMatchingBracketProcessor(chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() & Condition(lambda: self.highlight_matching_brackets))], 'inputhook': self.inputhook, } def prompt_for_code(self): if self.rl_next_input: default = self.rl_next_input self.rl_next_input = None else: default = '' with patch_stdout(raw=True): text = self.pt_app.prompt( default=default, # pre_run=self.pre_prompt,# reset_current_buffer=True, **self._extra_prompt_options()) return text def enable_win_unicode_console(self): if sys.version_info >= (3, 6): # Since PEP 528, Python uses the unicode APIs for the Windows # console by default, so WUC shouldn't be needed. return import win_unicode_console win_unicode_console.enable() def init_io(self): if sys.platform not in {'win32', 'cli'}: return self.enable_win_unicode_console() import colorama colorama.init() # For some reason we make these wrappers around stdout/stderr. # For now, we need to reset them so all output gets coloured. # https://github.com/ipython/ipython/issues/8669 # io.std* are deprecated, but don't show our own deprecation warnings # during initialization of the deprecated API. with warnings.catch_warnings(): warnings.simplefilter('ignore', DeprecationWarning) io.stdout = io.IOStream(sys.stdout) io.stderr = io.IOStream(sys.stderr) def init_magics(self): super(TerminalInteractiveShell, self).init_magics() self.register_magics(TerminalMagics) def init_alias(self): # The parent class defines aliases that can be safely used with any # frontend. super(TerminalInteractiveShell, self).init_alias() # Now define aliases that only make sense on the terminal, because they # need direct access to the console in a way that we can't emulate in # GUI or web frontend if os.name == 'posix': for cmd in ('clear', 'more', 'less', 'man'): self.alias_manager.soft_define_alias(cmd, cmd) def __init__(self, *args, **kwargs): super(TerminalInteractiveShell, self).__init__(*args, **kwargs) self.init_prompt_toolkit_cli() self.init_term_title() self.keep_running = True self.debugger_history = InMemoryHistory() def ask_exit(self): self.keep_running = False rl_next_input = None def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED): if display_banner is not DISPLAY_BANNER_DEPRECATED: warn('interact `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2) self.keep_running = True while self.keep_running: print(self.separate_in, end='') try: code = self.prompt_for_code() except EOFError: if (not self.confirm_exit) \ or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'): self.ask_exit() else: if code: self.run_cell(code, store_history=True) def mainloop(self, display_banner=DISPLAY_BANNER_DEPRECATED): # An extra layer of protection in case someone mashing Ctrl-C breaks # out of our internal code. if display_banner is not DISPLAY_BANNER_DEPRECATED: warn('mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2) while True: try: self.interact() break except KeyboardInterrupt as e: print("\n%s escaped interact()\n" % type(e).__name__) finally: # An interrupt during the eventloop will mess up the # internal state of the prompt_toolkit library. # Stopping the eventloop fixes this, see # https://github.com/ipython/ipython/pull/9867 if hasattr(self, '_eventloop'): self._eventloop.stop() _inputhook = None def inputhook(self, context): if self._inputhook is not None: self._inputhook(context) active_eventloop = None def enable_gui(self, gui=None): if gui: self.active_eventloop, self._inputhook =\ get_inputhook_name_and_func(gui) else: self.active_eventloop = self._inputhook = None # Run !system commands directly, not through pipes, so terminal programs # work correctly. system = InteractiveShell.system_raw def auto_rewrite_input(self, cmd): """Overridden from the parent class to use fancy rewriting prompt""" if not self.show_rewritten_input: return tokens = self.prompts.rewrite_prompt_tokens() if self.pt_app: print_formatted_text(PygmentsTokens(tokens), end='', style=self.pt_app.app.style) print(cmd) else: prompt = ''.join(s for t, s in tokens) print(prompt, cmd, sep='') _prompts_before = None def switch_doctest_mode(self, mode): """Switch prompts to classic for %doctest_mode""" if mode: self._prompts_before = self.prompts self.prompts = ClassicPrompts(self) elif self._prompts_before: self.prompts = self._prompts_before self._prompts_before = None