Beispiel #1
0
    def complete(self, text, word):

        # We never want to fallback on readline.
        # Even more so when argcomplete does this by calling bash -c compgen.
        check_output = argcomplete.subprocess.check_output
        argcomplete.subprocess.check_output = lambda *a, **k: b""

        (cword_prequote, cword_prefix, cword_suffix, comp_words, first_colon_pos) = argcomplete.split_line(text)

        comp_words.insert(0, sys.argv[0])

        try:
            completions = self.completer._get_completions(comp_words, cword_prefix, cword_prequote, first_colon_pos)
        except GdbCompleterRequired as e:
            return e.gdbcompleter
        except BaseException as e:
            # This is not expected, but gdb doesn't give us a
            # backtrace in this case, we print it ourself.
            print("\nAn exception occured during auto-completion code.")
            print("%s> %s %s" % (traceback.format_exc(), self.cmdname, text), end="")
            return []
        finally:
            # Don't forget we cheated, fix this and hope no one saw us.
            argcomplete.subprocess.check_output = check_output

        # The characters used by gdb to decide what a 'word' is aren't
        # controled by us. We need to workaround this by ommiting the
        # first part of the actual word...
        # The downside of this trick is we won't see the whole word
        # in gdb's listing, only what he considers the word...
        return [c[len(cword_prefix) - len(word) :].strip() for c in completions]
Beispiel #2
0
    def run_completer(self, parser, completer, command, point=None, **kwargs):
        cword_prequote, cword_prefix, cword_suffix, comp_words, first_colon_pos = split_line(command)

        completions = completer._get_completions(
            comp_words, cword_prefix, cword_prequote, first_colon_pos)

        return completions
Beispiel #3
0
    def run_completer(self, parser, completer, command, point=None, **kwargs):
        cword_prequote, cword_prefix, cword_suffix, comp_words, first_colon_pos = split_line(command)

        completions = completer._get_completions(
            comp_words, cword_prefix, cword_prequote, first_colon_pos)

        return completions
Beispiel #4
0
    def complete(self, text, word):

        # We never want to fallback on readline.
        # Even more so when argcomplete does this by calling bash -c compgen.
        check_output = argcomplete.subprocess.check_output
        argcomplete.subprocess.check_output = lambda *a, **k: b""

        (cword_prequote, cword_prefix, cword_suffix, comp_words,
         first_colon_pos) = argcomplete.split_line(text)

        comp_words.insert(0, sys.argv[0])

        try:
            completions = self.completer._get_completions(
                comp_words, cword_prefix, cword_prequote, first_colon_pos)
        except GdbCompleterRequired as e:
            return e.gdbcompleter
        except BaseException as e:
            # This is not expected, but gdb doesn't give us a
            # backtrace in this case, we print it ourself.
            print("\nAn exception occured during auto-completion code.")
            print("%s> %s %s" % (traceback.format_exc(), self.cmdname, text),
                  end="")
            return []
        finally:
            # Don't forget we cheated, fix this and hope no one saw us.
            argcomplete.subprocess.check_output = check_output

        # The characters used by gdb to decide what a 'word' is aren't
        # controled by us. We need to workaround this by ommiting the
        # first part of the actual word...
        # The downside of this trick is we won't see the whole word
        # in gdb's listing, only what he considers the word...
        return [c[len(cword_prefix) - len(word):].strip() for c in completions]
def do_command_completion():
    """ ndt command completion function
    """
    output_stream = os.fdopen(8, "wb")
    ifs = os.environ.get("_ARGCOMPLETE_IFS", "\v")
    if len(ifs) != 1:
        sys.exit(1)
    current = os.environ["COMP_CUR"]
    prev = os.environ["COMP_PREV"]
    comp_line = os.environ["COMP_LINE"]
    comp_point = int(os.environ["COMP_POINT"])

    # Adjust comp_point for wide chars
    if USING_PYTHON2:
        comp_point = len(comp_line[:comp_point].decode(SYS_ENCODING))
    else:
        comp_point = len(
            comp_line.encode(SYS_ENCODING)[:comp_point].decode(SYS_ENCODING))

    comp_line = ensure_str(comp_line)
    comp_words = split_line(comp_line, comp_point)[3]
    if "COMP_CWORD" in os.environ and os.environ["COMP_CWORD"] == "1":
        keys = [
            x for x in list(COMMAND_MAPPINGS.keys()) if x.startswith(current)
        ]
        output_stream.write(ifs.join(keys).encode(SYS_ENCODING))
        output_stream.flush()
        sys.exit(0)
    else:
        command = prev
        if len(comp_words) > 1:
            command = comp_words[1]
        if command not in COMMAND_MAPPINGS:
            sys.exit(1)
        command_type = COMMAND_MAPPINGS[command]
        if command_type == "shell":
            command = command + ".sh"
        if command_type == "ndtshell":
            command = command + ".sh"
        if command_type == "ndtshell" or command_type == "ndtscript":
            command = find_include(command)
        if command_type == "shell" or command_type == "script" or \
           command_type == "ndtshell" or command_type == "ndtscript":
            proc = Popen([command], stderr=PIPE, stdout=PIPE)
            output = proc.communicate()[0]
            if proc.returncode == 0:
                output_stream.write(
                    output.replace("\n", ifs).decode(SYS_ENCODING))
                output_stream.flush()
            else:
                sys.exit(1)
        else:
            line = comp_line[3:].lstrip()
            os.environ['COMP_POINT'] = str(comp_point -
                                           (len(comp_line) - len(line)))
            os.environ['COMP_LINE'] = line
            parts = command_type.split(":")
            getattr(__import__(parts[0], fromlist=[parts[1]]), parts[1])()
        sys.exit(0)
Beispiel #6
0
def get_argcomplete_prefix():
    if "_ARGCOMPLETE_BENCHMARK" in os.environ:
        os.environ["_ARGCOMPLETE_IFS"] = "\n"
        # os.environ["COMP_LINE"] = "cheribuild.py " # return all targets
        os.environ["COMP_LINE"] = "cheribuild.py foo --sq"  # return all options starting with --sq
        # os.environ["COMP_LINE"] = "cheribuild.py foo --no-s"  # return all options
        os.environ["COMP_POINT"] = str(len(os.environ["COMP_LINE"]))
    comp_line = argcomplete.ensure_str(os.environ["COMP_LINE"])
    result = argcomplete.split_line(comp_line, int(os.environ["COMP_POINT"]))[1]
    if "_ARGCOMPLETE_BENCHMARK" in os.environ:
        print("argcomplete_prefix =", result, file=sys.stderr)
    return result
Beispiel #7
0
def argcomplete_args() -> List[str]:
    args: List[str] = []
    # Check if its auto completion
    # is_in_completion = False
    comp_line = os.environ.get("COMP_LINE", None)
    if comp_line is not None:
        # What is this COMP_POINT?
        comp_point = int(os.environ.get("COMP_POINT", 0))
        # is_in_completion = True
        _, _, _, comp_words, _ = argcomplete.split_line(comp_line, comp_point)
        if not args:
            args = comp_words[1:]
    return args
Beispiel #8
0
def create_stack():
    """ Create a stack from a template
    """
    parser = argparse.ArgumentParser(description=create_stack.__doc__,
                                     add_help=False)
    _add_default_params(parser)
    parser.add_argument("-h", "--help", action='store_true')
    if "_ARGCOMPLETE" in os.environ:
        ac_args = argcomplete.split_line(os.environ['COMP_LINE'],
                                         os.environ['COMP_POINT'])[3]
        if len(ac_args) >= 2:
            template = ac_args[1]
            template_yaml = load_template(template)
            if template_yaml and "ContextClass" in template_yaml:
                context = load_class(template_yaml["ContextClass"])()
                context.add_context_arguments(parser)
    argcomplete.autocomplete(parser)
    args, _ = parser.parse_known_args()
    if args.template:
        template_yaml = load_template(args.template)
        if "ContextClass" in template_yaml:
            context = load_class(template_yaml["ContextClass"])()
            template_yaml.pop("ContextClass", None)
            parser = argparse.ArgumentParser(description=context.__doc__)
            _add_default_params(parser)
            context.add_context_arguments(parser)
        else:
            parser = argparse.ArgumentParser(description=create_stack.__doc__)
            _add_default_params(parser)
    else:
        parser = argparse.ArgumentParser(description=create_stack.__doc__)
        _add_default_params(parser)
    args = parser.parse_args()
    context.resolve_parameters(args)
    context.set_template(template_yaml)
    if context.write(yes=args.yes):
        subprocess.check_call([
            "ndt", "print-create-instructions", context.component_name,
            context.stack_name
        ])
    return
Beispiel #9
0
 def wordbreak(self, line):
     return split_line(line)[4]
Beispiel #10
0
 def prefix(self, line):
     return split_line(line)[1]
    def __complete(self, line, parser):
        comp_line = line
        comp_point = len(line)
        cword_prequote, cword_prefix, cword_suffix, comp_words, first_colon_pos = argcomplete.split_line(
            comp_line, comp_point)
        # reset display strings for options
        self.option_display_str = []

        # actions already chosen, we don't provide them anymore
        visited_actions = []

        # list of possible completion values
        completions = []

        # is the last action completed ?
        last_action_finished = True

        # are we completing a subcommand ?
        is_sub_command_active = False

        # the active sub command if any.
        sub_command_active = None

        # if the last word starts with a '-', it was an option,
        # we need to check if this option takes an argument
        if comp_words[-1].startswith(parser.prefix_chars):
            last_action_finished = False

        # collect visisted actions
        for action in parser._actions:
            if not isinstance(action, argparse._SubParsersAction):
                for option in action.option_strings:
                    if option in line:
                        visited_actions.append(action)
                        # if last_action_finished is False, the last word was an option
                        # then we check if the current option is this option
                        # if so, we check if the option needs an argument
                        if not last_action_finished and comp_words[
                                -1] in action.option_strings:
                            if action.choices is not None:  # last action was choices action, we return those choices
                                for c in action.choices:
                                    if c.startswith(cword_prefix) or unicode(
                                            c).startswith(cword_prefix):
                                        completions.append(c)
                                return completions
                            elif isinstance(action, _FilePathAction):
                                file_completion_result = self.__data_access_provider.complete(
                                    cword_prefix)
                                # print file_completion_result
                                completions.extend(file_completion_result)
                                return completions
                            if action.type is None:
                                last_action_finished = True
            else:
                for subaction in action._get_subactions():
                    if subaction.dest in line:
                        visited_actions.append(subaction.dest)
                        is_sub_command_active = True
                        sub_command_active = subaction.dest

        if not last_action_finished:
            if action.choices is not None:
                pass
            else:
                return []

        # get options from parser
        if not is_sub_command_active:
            for action in parser._actions:
                if action not in visited_actions:
                    # ensure it is no subparser instance
                    if not isinstance(action, argparse._SubParsersAction):
                        for option in action.option_strings:
                            if option.startswith(cword_prefix):
                                completions.append(option)
                    else:
                        for subaction in action._get_subactions():
                            if subaction.dest.startswith(cword_prefix):
                                completions.append(subaction.dest)
        else:
            subparsers = parser._subparsers
            for action in subparsers._actions:
                if isinstance(action, argparse._SubParsersAction):
                    for choice in action.choices:
                        if choice == sub_command_active:
                            subparser = action.choices[choice]
                            completions += self.__complete(line, subparser)

        return completions
Beispiel #12
0
def add_subparsers_on_demand(parser,
                             cli_name,
                             dest,
                             group_name,
                             hide_extensions=None,
                             required=True,
                             argv=None):
    """
    Create argparse subparser for each extension on demand.

    The ``cli_name`` is used for the title and description of the
    ``add_subparsers`` function call.

    For each extension a subparser is created is necessary.
    If no extension has been selected by command line arguments all first level
    extension must be loaded and instantiated.
    If a specific extension has been selected by command line arguments the
    sibling extension can be skipped and only that one extension (as well as
    potentially its recursive extensions) are loaded and instantiated.
    If the extension has an ``add_arguments`` method it is being called.

    :param parser: the parent argument parser
    :type parser: :py:class:`argparse.ArgumentParser`
    :param str cli_name: name of the command line command to which the
      subparsers are being added
    :param str dest: name of the attribute under which the selected extension
      will be stored
    :param str group_name: the name of the ``entry_point`` group identifying
      the extensions to be added
    :param list hide_extensions: an optional list of extension names which
      should be skipped
    :param bool required: a flag if the command is a required argument
    :param list argv: the list of command line arguments (default:
      ``sys.argv``)
    """
    # add subparser without a description for now
    mutable_description = MutableString()
    subparser = parser.add_subparsers(
        title='Commands',
        description=mutable_description,
        metavar=f'Call `{cli_name} <command> -h` for more detailed usage.')
    # use a name which doesn't collide with any argument
    # but is readable when shown as part of the the usage information
    subparser.dest = ' ' + dest.lstrip('_')
    subparser.required = required

    # add entry point specific sub-parsers but without a description and
    # arguments for now
    entry_points = get_entry_points(group_name)
    command_parsers = {}
    for name in sorted(entry_points.keys()):
        command_parser = subparser.add_parser(
            name, formatter_class=argparse.RawDescriptionHelpFormatter)
        command_parsers[name] = command_parser

    # temporarily attach root parser to each command parser
    # in order to parse known args
    root_parser = getattr(parser, '_root_parser', parser)
    with SuppressUsageOutput({parser} | set(command_parsers.values())):
        args = argv
        # for completion use the arguments provided by the argcomplete env var
        if _is_completion_requested():
            from argcomplete import split_line
            _, _, _, comp_words, _ = split_line(os.environ['COMP_LINE'])
            args = comp_words[1:]
        try:
            known_args, _ = root_parser.parse_known_args(args=args)
        except SystemExit:
            if not _is_completion_requested():
                raise
            # if the partial arguments can't be parsed use no known args
            known_args = argparse.Namespace(**{subparser.dest: None})

    # check if a specific subparser is selected
    name = getattr(known_args, subparser.dest)
    if name is None:
        # add description for all command extensions to the root parser
        command_extensions = get_command_extensions(group_name)
        if command_extensions:
            description = ''
            max_length = max(
                len(name) for name in command_extensions.keys()
                if hide_extensions is None or name not in hide_extensions)
            for name in sorted(command_extensions.keys()):
                if hide_extensions is not None and name in hide_extensions:
                    continue
                extension = command_extensions[name]
                description += '%s  %s\n' % (name.ljust(max_length),
                                             get_first_line_doc(extension))
                command_parser = command_parsers[name]
                command_parser.set_defaults(**{dest: extension})
            mutable_description.value = description
    else:
        # add description for the selected command extension to the subparser
        command_extensions = get_command_extensions(
            group_name, exclude_names=set(entry_points.keys() - {name}))
        extension = command_extensions[name]
        command_parser = command_parsers[name]
        command_parser.set_defaults(**{dest: extension})
        command_parser.description = get_first_line_doc(extension)

        # add the arguments for the requested extension
        if hasattr(extension, 'add_arguments'):
            command_parser = command_parsers[name]
            command_parser._root_parser = root_parser
            signature = inspect.signature(extension.add_arguments)
            kwargs = {}
            if 'argv' in signature.parameters:
                kwargs['argv'] = argv
            extension.add_arguments(command_parser, f'{cli_name} {name}',
                                    **kwargs)
            del command_parser._root_parser

    return subparser
Beispiel #13
0
 def prefix(self, line):
     return split_line(line)[1]