Exemple #1
0
    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
Exemple #2
0
 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 _: ())
Exemple #3
0
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)
Exemple #4
0
    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)
Exemple #5
0
def enable_autocomplete(parser):
    argcomplete.autocomplete = argcomplete.CompletionFinder()
    argcomplete.autocomplete(
        parser,
        validator=lambda c, p: c.lower().startswith(p.lower()),
        default_completer=lambda _: ())
Exemple #6
0
 def __init__(self):
     self.completions = {}
     for name, func in commands.items():
         self.completions[name] = argcomplete.CompletionFinder(
             func.argparser)
Exemple #7
0
    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