コード例 #1
0
ファイル: base.py プロジェクト: Auto-ML/xonsh
def complete_base(context: CompletionContext):
    """If the line is empty, complete based on valid commands, python names,
    and paths.  If we are completing the first argument, complete based on
    valid commands and python names.
    """
    out: tp.Set[Completion] = set()
    if context.command is None or context.command.arg_index != 0:
        # don't do unnecessary completions
        return out

    # get and unpack python completions
    python_comps = complete_python(context) or set()
    if isinstance(python_comps, cabc.Sequence):
        python_comps, python_comps_len = python_comps  # type: ignore
        out.update(apply_lprefix(python_comps, python_comps_len))
    else:
        out.update(python_comps)

    # add command completions
    out.update(complete_command(context.command))

    # add paths, if needed
    if not context.command.prefix:
        path_comps, path_comp_len = contextual_complete_path(context.command,
                                                             cdpath=False)
        out.update(apply_lprefix(path_comps, path_comp_len))

    return out
コード例 #2
0
    def _format_completion(
        completion,
        completion_context,
        completing_contextual_command: bool,
        lprefix: int,
        custom_lprefix: bool,
    ) -> tp.Tuple[Completion, int]:
        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)
            if closing_quote:
                if isinstance(completion, RichCompletion):
                    if completion.append_closing_quote:
                        completion = completion.replace(
                            value=completion.value + closing_quote
                        )
                else:
                    completion = completion + closing_quote

        completion = list(apply_lprefix([completion], lprefix))[0]

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

        return completion, lprefix
コード例 #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