def __init__(self, cmdname, cmdtype, repeat, prefix): self.cmdname = cmdname self.cmdtype = cmdtype self.repeat = repeat self.prefix = prefix # Setup a parser for this command. self.parser = ArgumentParser(prog=self.cmdname, description=self.__doc__) self.setup(self.parser) # We need to set the .completer hints in order for # argcomplete to know what to do on types we known. for action in self.parser._actions: if hasattr(action.type, "argcompleter"): action.completer = action.type.argcompleter # And prepare everything for autocompletion. self.completer = argcomplete.CompletionFinder( self.parser, always_complete_options=True) # gdb generates its help from the docstring. # We temporarilly overwrite it with argparse's output. old_doc, self.__doc__ = self.__doc__, self.parser.format_help().strip() # Call gdb's init. This will cause the command to be registerd. super().__init__(cmdname, cmdtype, prefix=prefix) # Restore the docstring so that it is usefull when looking # up help in python or when used for any other puprpose. self.__doc__ = old_doc
def enable_autocomplete(self, parser): if self.cli_ctx.data['completer_active']: argcomplete.autocomplete = argcomplete.CompletionFinder() argcomplete.autocomplete( parser, validator=lambda c, p: c.lower().startswith(p.lower()), default_completer=lambda _: ())
def _execute_complete(commandobj, args): if argcomplete is None: return comp_words, cword_prefix = _container['completion'] parser = commandobj._create_parser(args) finder = argcomplete.CompletionFinder(argument_parser=parser, always_complete_options=False, validator=lambda *_: True) active_parsers = finder._patch_argument_parser() parsed_args = argparse.Namespace() remaining = None finder.completing = True try: with argcomplete.mute_stderr(): parsed_args, remaining = finder._parser.parse_known_args( args, namespace=parsed_args) except BaseException as e: # argcomplete.warn( # 'Exception in parsing args', # e, # traceback.format_exc()) pass finder.completing = False # When the arguments are unmatched (e.g. --optional without a value), # an exception will be thrown and remaining will be None. remaining = remaining or () ##### completer = getattr(commandobj.func, 'completer', None) if completer: func_args, func_kwargs = commandobj.get_args(vars(parsed_args), remaining) func_args = [ arg if arg is not Parameter.empty else None for arg in func_args ] results = completer(*func_args, **func_kwargs) if results is not None: return results return finder.collect_completions(active_parsers=active_parsers, parsed_args=parsed_args, cword_prefix=cword_prefix, debug=argcomplete.debug)
def _make_argparser(self): """Makes a new argument parser.""" self.argparser = ShellArgumentParser(prog='') subparsers = self.argparser.add_subparsers() for name in self.get_names(): if name.startswith('parser_'): parser = subparsers.add_parser(name[7:]) parser.set_defaults(func=getattr(self, 'arg_' + name[7:])) getattr(self, name)(parser) self.argparser_completer = None try: import argcomplete except ImportError: pass else: os.environ.setdefault("_ARGCOMPLETE_COMP_WORDBREAKS", " \t\"'") self.argparser_completer = argcomplete.CompletionFinder(self.argparser)
def enable_autocomplete(parser): argcomplete.autocomplete = argcomplete.CompletionFinder() argcomplete.autocomplete( parser, validator=lambda c, p: c.lower().startswith(p.lower()), default_completer=lambda _: ())
def __init__(self): self.completions = {} for name, func in commands.items(): self.completions[name] = argcomplete.CompletionFinder( func.argparser)
def interactive(self, stream=None): import readline import argcomplete import shlex import time import os import sys def save_history(): if self.interactive_history_file: try: readline.write_history_file( os.path.expanduser(self.interactive_history_file)) except: pass if stream: input_strings = stream.readlines() if not input_strings: return sidx = 0 else: self._i_completer = argcomplete.CompletionFinder( self, default_completer=argcomplete.completers.SuppressCompleter()) readline.set_completer_delims('') readline.set_completer(self.interactive_completer) readline.parse_and_bind('tab: complete') readline.set_history_length(self.interactive_history_length) if self.interactive_history_file: try: readline.read_history_file( os.path.expanduser(self.interactive_history_file)) except: pass while True: try: if stream: try: input_str = input_strings[sidx] except IndexError: return if sidx: print() sidx += 1 else: input_str = input(self.get_interactive_prompt()) try: input_arr = shlex.split(input_str) except: print('invalid input', file=sys.stderr) input_arr = None if not input_arr: continue if input_arr[-1].startswith('|'): repeat = input_arr.pop()[1:] if repeat.startswith('c'): do_repeat = _REPEAT_CONT_CLS repeat = repeat[1:] else: do_repeat = _REPEAT_CONT try: repeat_seconds = float(repeat) except: self.handle_interactive_exception() continue else: do_repeat = _REPEAT_ONCE if ';' in input_arr: size = len(input_arr) idx_list = [ idx + 1 for idx, val in enumerate(input_arr) if val == ';' ] input_val = [ input_arr[i:j] for i, j in zip([0] + idx_list, idx_list + ( [size] if idx_list[-1] != size else [])) ] else: input_val = [input_arr] if do_repeat == _REPEAT_CONT_CLS: input_str = ' '.join(input_arr) self.clear_screen() self.print_repeat_title(input_str, repeat_seconds) while do_repeat: if do_repeat == _REPEAT_ONCE: do_repeat = 0 for pidx, parsed in enumerate(input_val): parsed = parsed.copy() if parsed[-1] == ';': parsed.pop() if not parsed: continue if len(parsed) == 1: if parsed[0] == '/': self.current_section = [] continue elif parsed[0] == '..': try: self.current_section.pop() except IndexError: pass continue elif parsed[0] in self.interactive_help: self.print_global_help() parsed[0] = '-h' elif parsed[0] in self.interactive_quit: if not stream: save_history() print() return # try to jump to section jump_to = [] sect = self.sections if parsed[0] in self.interactive_global_commands: try: self.interactive_global_commands[parsed[0]]( *parsed) except: self.handle_interactive_exception() continue if parsed[0].startswith('/'): root_cmd = True parsed[0] = parsed[0][1:] else: root_cmd = False for i in self.current_section: try: sect = sect[i] except TypeError: break for p in parsed: if sect and p in sect: jump_to.append(p) else: jump_to = None break try: sect = sect[p] except TypeError: sect = None if jump_to: if root_cmd: self.current_section = jump_to else: self.current_section += jump_to continue if not root_cmd and self.current_section: if len(parsed) == 1 and parsed[0] == '-h': args = self.current_section + parsed else: args = [] cs_added = False for p in parsed: if not p.startswith('-') and not cs_added: cs_added = True if not p.startswith('/'): args += self.current_section else: args.append(p[1:]) continue args.append(p) else: args = parsed try: a = self.parse_args(args) except: self.handle_interactive_parser_exception() continue try: if self.send_args_as_dict: self.run(**a.__dict__) else: self.run(a) except: self.handle_interactive_exception() if pidx < len(input_val) - 1: print() if do_repeat: time.sleep(repeat_seconds) if do_repeat == _REPEAT_CONT_CLS: self.clear_screen() self.print_repeat_title(input_str, repeat_seconds) else: print() except KeyboardInterrupt: print() pass except EOFError: if self.current_section: self.current_section.pop() print() continue else: save_history() print() return