def create_lexer(): g = create_ipython_grammar() return GrammarLexer(g, lexers={ 'percent': SimpleLexer('class:pygments.operator'), 'magic': SimpleLexer('class:pygments.keyword'), 'filename': SimpleLexer('class:pygments.name'), 'python': PygmentsLexer(PythonLexer), 'system': PygmentsLexer(BashLexer), })
def create_lexer(): g = create_ipython_grammar() return GrammarLexer(g, lexers={ 'percent': SimpleLexer(Token.Operator), 'magic': SimpleLexer(Token.Keyword), 'filename': SimpleLexer(Token.Name), 'python': PygmentsLexer(PythonLexer), 'system': PygmentsLexer(BashLexer), })
def create_command_lexer(): """ Lexer for highlighting of the command line. """ return GrammarLexer(COMMAND_GRAMMAR, lexers={ 'command': SimpleLexer(Token.CommandLine.Command), 'location': SimpleLexer(Token.CommandLine.Location), 'shell_command': PygmentsLexer(BashLexer), })
def question(message, **kwargs): default = kwargs.pop('default', '') validate_prompt = kwargs.pop('validate', None) if validate_prompt: if inspect.isclass(validate_prompt) and issubclass( validate_prompt, Validator): kwargs['validator'] = validate_prompt() elif callable(validate_prompt): class _InputValidator(Validator): def validate(self, document): verdict = validate_prompt(document.text) if not verdict == True: if verdict == False: verdict = 'invalid input' raise ValidationError(message=verdict, cursor_position=len( document.text)) kwargs['validator'] = _InputValidator() # TODO style defaults on detail level kwargs['style'] = kwargs.pop('style', default_style) qmark = kwargs.pop('qmark', 'Введите') def _get_prompt_tokens(cli): return [(Token.QuestionMark, qmark), (Token.Question, ' %s ' % message)] return create_prompt_application(get_prompt_tokens=_get_prompt_tokens, lexer=SimpleLexer(Token.Answer), default=default, **kwargs)
def question(message, **kwargs): default = kwargs.pop('default', '') eargs = kwargs.pop('eargs', {}) validate_prompt = kwargs.pop('validate', None) if validate_prompt: if issubclass(validate_prompt, Validator): kwargs['validator'] = validate_prompt() elif callable(validate_prompt): class _InputValidator(Validator): def validate(self, document): verdict = validate_prompt(document.text) if not verdict == True: if verdict == False: verdict = 'invalid input' raise ValidationError(message=verdict, cursor_position=len( document.text)) kwargs['validator'] = _InputValidator() for k, v in eargs.items(): if v == "" or v == " ": raise EditorArgumentsError( "Args '{}' value should not be empty".format(k)) editor = eargs.get("editor", None) ext = eargs.get("ext", ".txt") env = eargs.get("env", None) text = default filename = eargs.get("filename", None) multiline = True if not editor else False save = eargs.get("save", None) if editor: _text = edit(editor=editor, extension=ext, text=text, env=env, filename=filename, require_save=save) if filename: default = filename else: default = _text # TODO style defaults on detail level kwargs['style'] = kwargs.pop('style', default_style) qmark = kwargs.pop('qmark', '?') def _get_prompt_tokens(cli): return [(Token.QuestionMark, qmark), (Token.Question, ' %s ' % message)] return create_prompt_application(get_prompt_tokens=_get_prompt_tokens, lexer=SimpleLexer(Token.Answer), default=default, multiline=multiline, **kwargs)
def _prompt(message, default='', path=False, list_=None, required=True, validate=None, allow_invalid=False, password=False, help=None): def _get_prompt_tokens(cli): rv = [ (Token.PROMPT, message), (Token.COLON, ': '), ] if first and help: rv.insert(0, (Token.HELP, wrap_text(help) + '\n')) return rv completer = None if path: completer = PathCompleter(only_directories=True, expanduser=True) elif list_: completer = WordCompleter( sorted(list_), ignore_case=True, sentence=True, meta_dict=(list_ if isinstance(list_, dict) else None)) if validate is None: validate = list_.__contains__ first = True while True: try: rv = prompt(get_prompt_tokens=_get_prompt_tokens, default=default, is_password=password, completer=completer, lexer=SimpleLexer(Token.INPUT), style=PROMPT_TOOLKIT_STYLE) except (EOFError, KeyboardInterrupt): sys.exit(1) # pasting a multiline string works even with multiline disabled :( rv = rv.replace('\n', ' ').strip() if not rv: if not required: break else: if path: rv = os.path.abspath(os.path.expanduser(rv)) if validate is None or validate(rv): break if allow_invalid and _confirm('Keep this value anyway?'): break default = rv first = False return rv
def lexers(self): lexerNames = [ 'send_nym', 'send_get_nym', 'send_attrib', 'send_cred_def', 'send_isr_key', 'add_genesis', 'show_file', 'conn' 'load_file', 'show_link', 'sync_link', 'ping_target' 'show_claim', 'show_claim_req', 'req_claim', 'accept_link_invite', 'set_attr', 'send_claim' ] lexers = {n: SimpleLexer(Token.Keyword) for n in lexerNames} # Add more lexers to base class lexers return {**super().lexers, **lexers}
def start(): g = create_grammar() lexer = GrammarLexer(g, lexers={ 'op_mac': SimpleLexer(Token.Operator), 'op_main': SimpleLexer(Token.Operator), 'op_instance': SimpleLexer(Token.Operator), 'op_configuration': SimpleLexer(Token.Operator), 'op_infrastructure': SimpleLexer(Token.Operator), 'op_parameter': SimpleLexer(Token.Text), }) completer = GrammarCompleter(g, { 'op_main': WordCompleter(op_main), 'op_instance': WordCompleter(op_instance), 'op_configuration': WordCompleter(op_configuration), 'op_infrastructure': WordCompleter(op_infrastructure), }) history = InMemoryHistory() parser = maccli.mac_cli.initialize_parser() show("Start typing 'mac', CTRL+C to exit") user_aborted = False program_running = True while program_running: try: text = prompt('> ', lexer=lexer, completer=completer, style=MacStyle, history=history, auto_suggest=AutoSuggestFromHistory()) argv_raw = shlex.split(text) argv = maccli.mac_cli.patch_help_option(argv_raw) args = parser.parse_args(argv) maccli.mac_cli.dispatch_cmds(args) user_aborted = False except InternalError as e: maccli.logger.debug("Code raised Internal Error", e) pass except EOFError as e: maccli.logger.debug("Code raised EOFError", e) pass except KeyboardInterrupt as e: maccli.logger.debug("Code raised KeyboardInterrupt", e) if user_aborted: program_running = False else: user_aborted = True show("Press CTRL+C again to exit") pass
def _confirm(message, default=False, abort=False, help=None): def _get_prompt_tokens(cli): rv = [ (Token.PROMPT, message), (Token.BRACKET, ' ['), (Token.DEFAULT, 'Y/n' if default else 'y/N'), (Token.BRACKET, ']'), (Token.COLON, ': '), ] if first and help: rv.insert(0, (Token.HELP, wrap_text(help) + '\n')) return rv first = True while True: try: rv = prompt(get_prompt_tokens=_get_prompt_tokens, lexer=SimpleLexer(Token.INPUT), completer=WordCompleter(['yes', 'no'], ignore_case=True, sentence=True), style=PROMPT_TOOLKIT_STYLE) except (EOFError, KeyboardInterrupt): sys.exit(1) first = False rv = rv.replace('\n', ' ').strip().lower() if rv in ('y', 'yes', '1', 'true'): rv = True elif rv in ('n', 'no', '0', 'false'): rv = False elif not rv: rv = default else: _warn('Invalid input, enter Y or N') continue break if abort and not rv: raise click.Abort return rv
def create_layout(python_input, key_bindings_manager, lexer=PythonLexer, extra_body=None, extra_toolbars=None, extra_buffer_processors=None, input_buffer_height=None): D = LayoutDimension extra_body = [extra_body] if extra_body else [] extra_toolbars = extra_toolbars or [] extra_buffer_processors = extra_buffer_processors or [] input_buffer_height = input_buffer_height or D(min=6) def create_python_input_window(): def menu_position(cli): """ When there is no autocompletion menu to be shown, and we have a signature, set the pop-up position at `bracket_start`. """ b = cli.buffers[DEFAULT_BUFFER] if b.complete_state is None and python_input.signatures: row, col = python_input.signatures[0].bracket_start index = b.document.translate_row_col_to_index(row - 1, col) return index return Window( BufferControl( buffer_name=DEFAULT_BUFFER, lexer=lexer, input_processors=[ ConditionalProcessor( processor=HighlightSearchProcessor( preview_search=True), filter=HasFocus(SEARCH_BUFFER), ), HighlightSelectionProcessor(), DisplayMultipleCursors(DEFAULT_BUFFER), # Show matching parentheses, but only while editing. ConditionalProcessor( processor=HighlightMatchingBracketProcessor( chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() & Condition(lambda cli: python_input. highlight_matching_parenthesis)), ConditionalProcessor(processor=AppendAutoSuggestion(), filter=~IsDone()) ] + extra_buffer_processors, menu_position=menu_position, # Make sure that we always see the result of an reverse-i-search: preview_search=True, ), left_margins=[PythonPromptMargin(python_input)], # Scroll offsets. The 1 at the bottom is important to make sure the # cursor is never below the "Press [Meta+Enter]" message which is a float. scroll_offsets=ScrollOffsets(bottom=1, left=4, right=4), # As long as we're editing, prefer a minimal height of 6. get_height=(lambda cli: (None if cli.is_done or python_input. show_exit_confirmation else input_buffer_height)), wrap_lines=Condition(lambda cli: python_input.wrap_lines), ) return HSplit([ VSplit([ HSplit([ FloatContainer( content=HSplit([create_python_input_window()] + extra_body), floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu( scroll_offset=Integer.from_callable( lambda: python_input. completion_menu_scroll_offset), max_height=12, extra_filter=show_completions_menu( python_input))), Float( xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( extra_filter=show_multi_column_completions_menu( python_input))), Float(xcursor=True, ycursor=True, content=signature_toolbar(python_input)), Float(left=2, bottom=1, content=exit_confirmation(python_input)), Float(bottom=0, right=0, height=1, content=meta_enter_message(python_input), hide_when_covering_content=True), Float(bottom=1, left=1, right=0, content=python_sidebar_help(python_input)), ]), ArgToolbar(), SearchToolbar(), SystemToolbar(), ValidationToolbar(), CompletionsToolbar( extra_filter=show_completions_toolbar(python_input)), # Docstring region. ConditionalContainer(content=Window( height=D.exact(1), content=FillControl('\u2500', token=Token.Separator)), filter=HasSignature(python_input) & ShowDocstring(python_input) & ~IsDone()), ConditionalContainer( content=Window( BufferControl( buffer_name='docstring', lexer=SimpleLexer(default_token=Token.Docstring), #lexer=PythonLexer, ), height=D(max=12)), filter=HasSignature(python_input) & ShowDocstring(python_input) & ~IsDone(), ), ]), HSplit([ python_sidebar(python_input), python_sidebar_navigation(python_input), ]) ]), ] + extra_toolbars + [ VSplit([ status_bar(key_bindings_manager, python_input), show_sidebar_button_info(python_input), ]) ])
(\s* (?P<operator2>[a-z]+) \s+ (?P<var1>[0-9.]+) \s*) """) example_style = style_from_dict({ Token.Operator: '#33aa33 bold', Token.Number: '#aa3333 bold', Token.TrailingInput: 'bg:#662222 #ffffff', }) if __name__ == '__main__': g = create_grammar() lexer = GrammarLexer(g, lexers={ 'operator1': SimpleLexer(Token.Operator), 'operator2': SimpleLexer(Token.Operator), 'var1': SimpleLexer(Token.Number), 'var2': SimpleLexer(Token.Number), }) completer = GrammarCompleter( g, { 'operator1': WordCompleter(operators1), 'operator2': WordCompleter(operators2), }) try: # REPL loop. while True: # Read input and parse the result.
def _create_layout(self): """ Generate the main prompt_toolkit layout. """ waits_for_confirmation = WaitsForConfirmation(self.pymux) waits_for_prompt = WaitsForPrompt(self.pymux) in_command_mode = InCommandMode(self.pymux) return FloatContainer( content=HSplit([ # The main window. HighlightBorders(self, self.pymux, FloatContainer( Background(), floats=[ Float(get_width=lambda cli: self.pymux.get_window_size(cli).columns, get_height=lambda cli: self.pymux.get_window_size(cli).rows, content=TraceBodyWritePosition(self.pymux, DynamicBody(self.pymux))) ])), # Status bar. ConditionalContainer( content=VSplit([ # Left. Window( height=D.exact(1), get_width=(lambda cli: D(max=self.pymux.status_left_length)), dont_extend_width=True, content=TokenListControl( self._get_status_left_tokens, default_char=Char(' ', Token.StatusBar))), # List of windows in the middle. Window( height=D.exact(1), content=TokenListControl( self._get_status_tokens, align_right=Condition(self._status_align_right), align_center=Condition(self._status_align_center), default_char=Char(' ', Token.StatusBar))), # Right. Window( height=D.exact(1), get_width=(lambda cli: D(max=self.pymux.status_right_length)), dont_extend_width=True, content=TokenListControl( self._get_status_right_tokens, align_right=True, default_char=Char(' ', Token.StatusBar))) ]), filter=Condition(lambda cli: self.pymux.enable_status), ) ]), floats=[ Float(bottom=1, left=0, content=MessageToolbar(self.pymux)), Float(left=0, right=0, bottom=0, content=HSplit([ # Wait for confirmation toolbar. ConditionalContainer( content=Window( height=D.exact(1), content=ConfirmationToolbar(self.pymux), ), filter=waits_for_confirmation, ), # ':' prompt toolbar. ConditionalContainer( content=Window( height=D(min=1), # Can be more if the command is multiline. dont_extend_height=True, content=BufferControl( buffer_name=COMMAND, default_char=Char(' ', Token.CommandLine), lexer=SimpleLexer(Token.CommandLine), preview_search=True, highlighters=[SelectionHighlighter()], input_processors=[ AppendAutoSuggestion(), DefaultPrompt(lambda cli:[(Token.CommandLine.Prompt, ':')]), ]) ), filter=in_command_mode, ), # Other command-prompt commands toolbar. ConditionalContainer( content=Window( height=D.exact(1), content=BufferControl( buffer_name=PROMPT, default_char=Char(' ', Token.CommandLine), lexer=SimpleLexer(Token.CommandLine), highlighters=[SelectionHighlighter()], input_processors=[ BeforeInput(self._before_prompt_command_tokens), AppendAutoSuggestion(), ]) ), filter=waits_for_prompt, ), ])), Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=12)), ] )
def __init__(self, looper, basedirpath, nodeReg, cliNodeReg, output=None, debug=False, logFileName=None): self.curClientPort = None logging.root.addHandler(CliHandler(self.out)) self.looper = looper self.basedirpath = basedirpath self.nodeReg = nodeReg self.cliNodeReg = cliNodeReg # Used to store created clients self.clients = {} # clientName -> Client # To store the created requests self.requests = {} # To store the nodes created self.nodes = {} self.externalClientKeys = {} # type: Dict[str,str] self.cliCmds = {'status', 'new'} self.nodeCmds = self.cliCmds | {'keyshare'} self.helpablesCommands = self.cliCmds | self.nodeCmds self.simpleCmds = {'status', 'exit', 'quit', 'license'} self.commands = {'list', 'help'} | self.simpleCmds self.cliActions = {'send', 'show'} self.commands.update(self.cliCmds) self.commands.update(self.nodeCmds) self.node_or_cli = ['node', 'client'] self.nodeNames = list(self.nodeReg.keys()) + ["all"] self.debug = debug self.plugins = {} ''' examples: status new node Alpha new node all new client Joe client Joe send <msg> client Joe show 1 ''' psep = re.escape(os.path.sep) self.utilGrams = [ "(\s* (?P<simple>{}) \s*) |".format(self.relist(self.simpleCmds)), "(\s* (?P<load>load) \s+ (?P<file_name>[.a-zA-z0-9{}]+) \s*) |".format(psep), "(\s* (?P<command>help) (\s+ (?P<helpable>[a-zA-Z0-9]+) )? (\s+ (?P<node_or_cli>{}) )?\s*) |".format(self.relist(self.node_or_cli)), "(\s* (?P<command>list) \s*)" ] self.nodeGrams = [ "(\s* (?P<node_command>{}) \s+ (?P<node_or_cli>nodes?) \s+ (?P<node_name>[a-zA-Z0-9]+)\s*) |".format(self.relist(self.nodeCmds)), "(\s* (?P<load_plugins>load\s+plugins\s+from) \s+ (?P<plugin_dir>[a-zA-Z0-9-:{}]+) \s*)".format(psep), ] self.clientGrams = [ "(\s* (?P<client_command>{}) \s+ (?P<node_or_cli>clients?) \s+ (?P<client_name>[a-zA-Z0-9]+) \s*) |".format(self.relist(self.cliCmds)), "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>send) \s+ (?P<msg>\{\s*.*\}) \s*) |", "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>show) \s+ (?P<req_id>[0-9]+) \s*) |", "(\s* (?P<add_key>add\s+key) \s+ (?P<verkey>[a-fA-F0-9]+) \s+ (?P<for_client>for\s+client) \s+ (?P<identifier>[a-zA-Z0-9]+) \s*)", ] self.lexers = { 'node_command': SimpleLexer(Token.Keyword), 'command': SimpleLexer(Token.Keyword), 'helpable': SimpleLexer(Token.Keyword), 'load_plugins': SimpleLexer(Token.Keyword), 'load': SimpleLexer(Token.Keyword), 'node_or_cli': SimpleLexer(Token.Keyword), 'arg1': SimpleLexer(Token.Name), 'node_name': SimpleLexer(Token.Name), 'more_nodes': SimpleLexer(Token.Name), 'simple': SimpleLexer(Token.Keyword), 'client_command': SimpleLexer(Token.Keyword), 'add_key': SimpleLexer(Token.Keyword), 'verkey': SimpleLexer(Token.Literal), 'for_client': SimpleLexer(Token.Keyword), 'identifier': SimpleLexer(Token.Name), } self.clientWC = WordCompleter([]) self.completers = { 'node_command': WordCompleter(self.nodeCmds), 'client_command': WordCompleter(self.cliCmds), 'client': WordCompleter(['client']), 'command': WordCompleter(self.commands), 'node_or_cli': WordCompleter(self.node_or_cli), 'node_name': WordCompleter(self.nodeNames), 'more_nodes': WordCompleter(self.nodeNames), 'helpable': WordCompleter(self.helpablesCommands), 'load_plugins': WordCompleter(['load plugins from']), 'client_name': self.clientWC, 'cli_action': WordCompleter(self.cliActions), 'simple': WordCompleter(self.simpleCmds), 'add_key': WordCompleter(['add key']), 'for_client': WordCompleter(['for client']), } self.initializeGrammar() self.initializeGrammarLexer() self.initializeGrammarCompleter() self.style = PygmentsStyle.from_defaults({ Token.Operator: '#33aa33 bold', Token.Number: '#aa3333 bold', Token.Name: '#ffff00 bold', Token.Heading: 'bold', Token.TrailingInput: 'bg:#662222 #ffffff', Token.BoldGreen: '#33aa33 bold', Token.BoldOrange: '#ff4f2f bold', Token.BoldBlue: '#095cab bold'}) self.functionMappings = self.createFunctionMappings() self.voidMsg = "<none>" # Create an asyncio `EventLoop` object. This is a wrapper around the # asyncio loop that can be passed into prompt_toolkit. eventloop = create_asyncio_eventloop(looper.loop) pers_hist = FileHistory('.{}-cli-history'.format(self.name)) # Create interface. app = create_prompt_application('{}> '.format(self.name), lexer=self.grammarLexer, completer=self.grammarCompleter, style=self.style, history=pers_hist) if output: out = output else: if is_windows(): if is_conemu_ansi(): out = ConEmuOutput(sys.__stdout__) else: out = Win32Output(sys.__stdout__) else: out = CustomOutput.from_pty(sys.__stdout__, true_color=True) self.cli = CommandLineInterface( application=app, eventloop=eventloop, output=out) # Patch stdout in something that will always print *above* the prompt # when something is written to stdout. sys.stdout = self.cli.stdout_proxy() setupLogging(TRACE_LOG_LEVEL, Console.Wordage.mute, filename=logFileName) self.logger = getlogger("cli") self.print("\n{}-CLI (c) 2016 Evernym, Inc.".format(self.properName)) self.print("Node registry loaded.") self.print("None of these are created or running yet.") self.showNodeRegistry() self.print("Type 'help' for more information.")
def __init__(self, pager): self.pager = pager self.dynamic_body = _DynamicBody(pager) # Build an interface. has_colon = HasColon(pager) self.container = FloatContainer(content=HSplit([ Titlebar(pager), self.dynamic_body, SearchToolbar(vi_mode=True), SystemToolbar(), ConditionalContainer(content=VSplit([ Window(height=D.exact(1), content=TokenListControl( self._get_statusbar_left_tokens, default_char=Char(' ', Token.Statusbar))), Window(height=D.exact(1), content=TokenListControl( self._get_statusbar_right_tokens, align_right=True, default_char=Char(' ', Token.Statusbar))), ]), filter=~HasSearch() & ~HasFocus(SYSTEM_BUFFER) & ~has_colon & ~HasFocus('EXAMINE')), ConditionalContainer(content=TokenListToolbar( lambda cli: [(Token.Statusbar, ' :')], default_char=Char(token=Token.Statusbar)), filter=has_colon), ConditionalContainer(content=Window(BufferControl( buffer_name='EXAMINE', default_char=Char(token=Token.Toolbar.Examine), lexer=SimpleLexer(default_token=Token.Toolbar.Examine.Text), input_processors=[ BeforeInput( lambda cli: [(Token.Toolbar.Examine, ' Examine: ')]), ]), height=D.exact(1)), filter=HasFocus('EXAMINE')), ConditionalContainer(content=Window(BufferControl( buffer_name='PATTERN_FILTER', default_char=Char(token=Token.Toolbar.Search), lexer=SimpleLexer(default_token=Token.Toolbar.Search.Text), input_processors=[ BeforeInput(lambda cli: [(Token.Toolbar.Search, '&/')]), ]), height=D.exact(1)), filter=HasFocus('PATTERN_FILTER')), ]), floats=[ Float(right=0, height=1, bottom=1, content=_Arg()), Float(bottom=1, left=0, right=0, height=1, content=MessageToolbarBar( pager)), Float( right=0, height=1, bottom=1, content=ConditionalContainer( content=TokenListToolbar( lambda cli: [ (Token.Loading, ' Loading... ') ], default_char=Char( token=Token. Statusbar)), filter=Condition( lambda cli: pager. waiting_for_input_stream ))), Float( xcursor=True, ycursor=True, content= MultiColumnCompletionsMenu()), ])