コード例 #1
0
def list_completers():
    """List the active completers"""
    o = "Registered Completer Functions: (NX = Non Exclusive)\n\n"
    non_exclusive = " [NX]"
    _comp = XSH.completers
    ml = max((len(i) for i in _comp), default=0)
    exclusive_len = ml + len(non_exclusive) + 1
    _strs = []
    for c in _comp:
        if _comp[c].__doc__ is None:
            doc = "No description provided"
        else:
            doc = " ".join(_comp[c].__doc__.split())
        doc = justify(doc, 80, exclusive_len + 3)
        if is_exclusive_completer(_comp[c]):
            _strs.append("{: <{}} : {}".format(c, exclusive_len, doc))
        else:
            _strs.append("{: <{}} {} : {}".format(c, ml, non_exclusive, doc))
    return o + "\n".join(_strs) + "\n"
コード例 #2
0
def add_one_completer(name, func, loc="end"):
    new = collections.OrderedDict()
    if loc == "start":
        # Add new completer before the first exclusive one.
        # We don't want new completers to be before the non-exclusive ones,
        # because then they won't be used when this completer is successful.
        # On the other hand, if the new completer is non-exclusive,
        # we want it to be before all other exclusive completers so that is will always work.
        items = list(XSH.completers.items())
        first_exclusive = next(
            (i for i, (_, v) in enumerate(items) if is_exclusive_completer(v)),
            len(items),
        )
        for k, v in items[:first_exclusive]:
            new[k] = v
        new[name] = func
        for k, v in items[first_exclusive:]:
            new[k] = v
    elif loc == "end":
        for (k, v) in XSH.completers.items():
            new[k] = v
        new[name] = func
    else:
        direction, rel = loc[0], loc[1:]
        found = False
        for (k, v) in XSH.completers.items():
            if rel == k and direction == "<":
                new[name] = func
                found = True
            new[k] = v
            if rel == k and direction == ">":
                new[name] = func
                found = True
        if not found:
            new[name] = func
    XSH.completers.clear()
    XSH.completers.update(new)
コード例 #3
0
ファイル: completer.py プロジェクト: Auto-ML/xonsh
    def complete_from_context(self, completion_context, old_completer_args=None):
        lprefix = 0
        completions = set()
        for func in builtins.__xonsh__.completers.values():
            try:
                if is_contextual_completer(func):
                    if completion_context is None:
                        continue
                    out = func(completion_context)
                else:
                    if old_completer_args is None:
                        continue
                    out = func(*old_completer_args)
            except StopIteration:
                # completer requested to stop collecting completions
                break
            except Exception as e:
                print_exception(
                    f"Completer {func.__name__} raises exception when gets "
                    f"old_args={old_completer_args[:-1]} / completion_context={completion_context!r}:\n"
                    f"{e}"
                )
                continue

            completing_contextual_command = (
                is_contextual_completer(func)
                and completion_context is not None
                and completion_context.command is not None
            )
            if isinstance(out, cabc.Sequence):
                res, lprefix = out
                custom_lprefix = True
            else:
                res = out
                custom_lprefix = False
                if completing_contextual_command:
                    lprefix = len(completion_context.command.prefix)
                elif old_completer_args is not None:
                    lprefix = len(old_completer_args[0])
                else:
                    lprefix = 0

            if res is None or len(res) == 0:
                continue

            if (
                completing_contextual_command
                and completion_context.command.is_after_closing_quote
            ):
                """
                The cursor is appending to a closed string literal, i.e. cursor at the end of ``ls "/usr/"``.
                1. The closing quote will be appended to all completions.
                    I.e the completion ``/usr/bin`` will turn into ``/usr/bin"``
                    To prevent this behavior, a completer can return a ``RichCompletion`` with ``append_closing_quote=False``.
                2. If not specified, lprefix will cover the closing prefix.
                    I.e for ``ls "/usr/"``, the default lprefix will be 6 to include the closing quote.
                    To prevent this behavior, a completer can return a different lprefix or specify it inside ``RichCompletion``.
                """
                closing_quote = completion_context.command.closing_quote
                if not custom_lprefix:
                    lprefix += len(closing_quote)

                def append_closing_quote(completion: Completion):
                    if isinstance(completion, RichCompletion):
                        if completion.append_closing_quote:
                            return completion.replace(
                                value=completion.value + closing_quote
                            )
                        return completion
                    return completion + closing_quote

                res = map(append_closing_quote, res)

            completions.update(apply_lprefix(res, lprefix))
            if is_exclusive_completer(func):
                # we got completions for an exclusive completer
                break

        # append spaces AFTER appending closing quote
        def append_space(comp: Completion):
            if (
                isinstance(comp, RichCompletion)
                and comp.append_space
                and not comp.value.endswith(" ")
            ):
                return comp.replace(value=comp.value + " ")
            return comp

        completions = map(append_space, completions)

        def sortkey(s):
            return s.lstrip(''''"''').lower()

        # the last completer's lprefix is returned. other lprefix values are inside the RichCompletions.
        return tuple(sorted(completions, key=sortkey)), lprefix
コード例 #4
0
    def generate_completions(
        completion_context, old_completer_args, trace: bool
    ) -> tp.Iterator[tp.Tuple[Completion, int]]:
        for name, func in XSH.completers.items():
            try:
                if is_contextual_completer(func):
                    if completion_context is None:
                        continue
                    out = func(completion_context)
                else:
                    if old_completer_args is None:
                        continue
                    out = func(*old_completer_args)
            except StopIteration:
                # completer requested to stop collecting completions
                break
            except Exception as e:
                print_exception(
                    f"Completer {func.__name__} raises exception when gets "
                    f"old_args={old_completer_args[:-1]} / completion_context={completion_context!r}:\n"
                    f"{type(e)} - {e}"
                )
                continue

            completing_contextual_command = (
                is_contextual_completer(func)
                and completion_context is not None
                and completion_context.command is not None
            )
            if isinstance(out, cabc.Sequence):
                res, lprefix = out
                custom_lprefix = True
            else:
                res = out
                custom_lprefix = False
                if completing_contextual_command:
                    lprefix = len(completion_context.command.prefix)
                elif old_completer_args is not None:
                    lprefix = len(old_completer_args[0])
                else:
                    lprefix = 0

            if res is None:
                continue

            items = []
            for comp in res:
                comp = Completer._format_completion(
                    comp,
                    completion_context,
                    completing_contextual_command,
                    lprefix or 0,
                    custom_lprefix,
                )
                items.append(comp)
                yield comp

            if not items:  # empty completion
                continue

            if trace:
                print(
                    f"TRACE COMPLETIONS: Got {len(items)} results"
                    f" from {'' if is_exclusive_completer(func) else 'non-'}exclusive completer '{name}':"
                )
                sys.displayhook(items)

            if is_exclusive_completer(func):
                # we got completions for an exclusive completer
                break
コード例 #5
0
ファイル: completer.py プロジェクト: sthagen/xonsh
    def generate_completions(
            completion_context, old_completer_args,
            trace: bool) -> tp.Iterator[tp.Tuple[Completion, int]]:
        filter_func = get_filter_function()

        for name, func in XSH.completers.items():
            try:
                if is_contextual_completer(func):
                    if completion_context is None:
                        continue
                    out = func(completion_context)
                else:
                    if old_completer_args is None:
                        continue
                    out = func(*old_completer_args)
            except StopIteration:
                # completer requested to stop collecting completions
                break
            except Exception as e:
                name = func.__name__ if hasattr(func,
                                                "__name__") else str(func)
                print_exception(
                    f"Completer {name} raises exception when gets "
                    f"old_args={old_completer_args[:-1]} / completion_context={completion_context!r}:\n"
                    f"{type(e)} - {e}")
                continue

            completing_contextual_command = (is_contextual_completer(func)
                                             and completion_context is not None
                                             and completion_context.command
                                             is not None)

            # -- set comp-defaults --

            # the default is that the completer function filters out as necessary
            # we can change that once fuzzy/substring matches are added
            is_filtered = True
            custom_lprefix = False
            prefix = ""
            if completing_contextual_command:
                prefix = completion_context.command.prefix
            elif old_completer_args is not None:
                prefix = old_completer_args[0]
            lprefix = len(prefix)

            if isinstance(out, cabc.Sequence):
                # update comp-defaults from
                res, lprefix_filtered = out
                if isinstance(lprefix_filtered, bool):
                    is_filtered = lprefix_filtered
                else:
                    lprefix = lprefix_filtered
                    custom_lprefix = True
            else:
                res = out

            if res is None:
                continue

            items = []
            for comp in res:
                if (not is_filtered) and (not filter_func(comp, prefix)):
                    continue
                comp = Completer._format_completion(
                    comp,
                    completion_context,
                    completing_contextual_command,
                    lprefix or 0,
                    custom_lprefix,
                )
                items.append(comp)
                yield comp

            if not items:  # empty completion
                continue

            if trace:
                print(
                    f"TRACE COMPLETIONS: Got {len(items)} results"
                    f" from {'' if is_exclusive_completer(func) else 'non-'}exclusive completer '{name}':"
                )
                sys.displayhook(items)

            if is_exclusive_completer(func):
                # we got completions for an exclusive completer
                break