summaryrefslogtreecommitdiff
path: root/venv/lib/python3.11/site-packages/click/shell_completion.py
diff options
context:
space:
mode:
Diffstat (limited to 'venv/lib/python3.11/site-packages/click/shell_completion.py')
-rw-r--r--venv/lib/python3.11/site-packages/click/shell_completion.py596
1 files changed, 0 insertions, 596 deletions
diff --git a/venv/lib/python3.11/site-packages/click/shell_completion.py b/venv/lib/python3.11/site-packages/click/shell_completion.py
deleted file mode 100644
index dc9e00b..0000000
--- a/venv/lib/python3.11/site-packages/click/shell_completion.py
+++ /dev/null
@@ -1,596 +0,0 @@
-import os
-import re
-import typing as t
-from gettext import gettext as _
-
-from .core import Argument
-from .core import BaseCommand
-from .core import Context
-from .core import MultiCommand
-from .core import Option
-from .core import Parameter
-from .core import ParameterSource
-from .parser import split_arg_string
-from .utils import echo
-
-
-def shell_complete(
- cli: BaseCommand,
- ctx_args: t.MutableMapping[str, t.Any],
- prog_name: str,
- complete_var: str,
- instruction: str,
-) -> int:
- """Perform shell completion for the given CLI program.
-
- :param cli: Command being called.
- :param ctx_args: Extra arguments to pass to
- ``cli.make_context``.
- :param prog_name: Name of the executable in the shell.
- :param complete_var: Name of the environment variable that holds
- the completion instruction.
- :param instruction: Value of ``complete_var`` with the completion
- instruction and shell, in the form ``instruction_shell``.
- :return: Status code to exit with.
- """
- shell, _, instruction = instruction.partition("_")
- comp_cls = get_completion_class(shell)
-
- if comp_cls is None:
- return 1
-
- comp = comp_cls(cli, ctx_args, prog_name, complete_var)
-
- if instruction == "source":
- echo(comp.source())
- return 0
-
- if instruction == "complete":
- echo(comp.complete())
- return 0
-
- return 1
-
-
-class CompletionItem:
- """Represents a completion value and metadata about the value. The
- default metadata is ``type`` to indicate special shell handling,
- and ``help`` if a shell supports showing a help string next to the
- value.
-
- Arbitrary parameters can be passed when creating the object, and
- accessed using ``item.attr``. If an attribute wasn't passed,
- accessing it returns ``None``.
-
- :param value: The completion suggestion.
- :param type: Tells the shell script to provide special completion
- support for the type. Click uses ``"dir"`` and ``"file"``.
- :param help: String shown next to the value if supported.
- :param kwargs: Arbitrary metadata. The built-in implementations
- don't use this, but custom type completions paired with custom
- shell support could use it.
- """
-
- __slots__ = ("value", "type", "help", "_info")
-
- def __init__(
- self,
- value: t.Any,
- type: str = "plain",
- help: t.Optional[str] = None,
- **kwargs: t.Any,
- ) -> None:
- self.value: t.Any = value
- self.type: str = type
- self.help: t.Optional[str] = help
- self._info = kwargs
-
- def __getattr__(self, name: str) -> t.Any:
- return self._info.get(name)
-
-
-# Only Bash >= 4.4 has the nosort option.
-_SOURCE_BASH = """\
-%(complete_func)s() {
- local IFS=$'\\n'
- local response
-
- response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \
-%(complete_var)s=bash_complete $1)
-
- for completion in $response; do
- IFS=',' read type value <<< "$completion"
-
- if [[ $type == 'dir' ]]; then
- COMPREPLY=()
- compopt -o dirnames
- elif [[ $type == 'file' ]]; then
- COMPREPLY=()
- compopt -o default
- elif [[ $type == 'plain' ]]; then
- COMPREPLY+=($value)
- fi
- done
-
- return 0
-}
-
-%(complete_func)s_setup() {
- complete -o nosort -F %(complete_func)s %(prog_name)s
-}
-
-%(complete_func)s_setup;
-"""
-
-_SOURCE_ZSH = """\
-#compdef %(prog_name)s
-
-%(complete_func)s() {
- local -a completions
- local -a completions_with_descriptions
- local -a response
- (( ! $+commands[%(prog_name)s] )) && return 1
-
- response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \
-%(complete_var)s=zsh_complete %(prog_name)s)}")
-
- for type key descr in ${response}; do
- if [[ "$type" == "plain" ]]; then
- if [[ "$descr" == "_" ]]; then
- completions+=("$key")
- else
- completions_with_descriptions+=("$key":"$descr")
- fi
- elif [[ "$type" == "dir" ]]; then
- _path_files -/
- elif [[ "$type" == "file" ]]; then
- _path_files -f
- fi
- done
-
- if [ -n "$completions_with_descriptions" ]; then
- _describe -V unsorted completions_with_descriptions -U
- fi
-
- if [ -n "$completions" ]; then
- compadd -U -V unsorted -a completions
- fi
-}
-
-if [[ $zsh_eval_context[-1] == loadautofunc ]]; then
- # autoload from fpath, call function directly
- %(complete_func)s "$@"
-else
- # eval/source/. command, register function for later
- compdef %(complete_func)s %(prog_name)s
-fi
-"""
-
-_SOURCE_FISH = """\
-function %(complete_func)s;
- set -l response (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \
-COMP_CWORD=(commandline -t) %(prog_name)s);
-
- for completion in $response;
- set -l metadata (string split "," $completion);
-
- if test $metadata[1] = "dir";
- __fish_complete_directories $metadata[2];
- else if test $metadata[1] = "file";
- __fish_complete_path $metadata[2];
- else if test $metadata[1] = "plain";
- echo $metadata[2];
- end;
- end;
-end;
-
-complete --no-files --command %(prog_name)s --arguments \
-"(%(complete_func)s)";
-"""
-
-
-class ShellComplete:
- """Base class for providing shell completion support. A subclass for
- a given shell will override attributes and methods to implement the
- completion instructions (``source`` and ``complete``).
-
- :param cli: Command being called.
- :param prog_name: Name of the executable in the shell.
- :param complete_var: Name of the environment variable that holds
- the completion instruction.
-
- .. versionadded:: 8.0
- """
-
- name: t.ClassVar[str]
- """Name to register the shell as with :func:`add_completion_class`.
- This is used in completion instructions (``{name}_source`` and
- ``{name}_complete``).
- """
-
- source_template: t.ClassVar[str]
- """Completion script template formatted by :meth:`source`. This must
- be provided by subclasses.
- """
-
- def __init__(
- self,
- cli: BaseCommand,
- ctx_args: t.MutableMapping[str, t.Any],
- prog_name: str,
- complete_var: str,
- ) -> None:
- self.cli = cli
- self.ctx_args = ctx_args
- self.prog_name = prog_name
- self.complete_var = complete_var
-
- @property
- def func_name(self) -> str:
- """The name of the shell function defined by the completion
- script.
- """
- safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), flags=re.ASCII)
- return f"_{safe_name}_completion"
-
- def source_vars(self) -> t.Dict[str, t.Any]:
- """Vars for formatting :attr:`source_template`.
-
- By default this provides ``complete_func``, ``complete_var``,
- and ``prog_name``.
- """
- return {
- "complete_func": self.func_name,
- "complete_var": self.complete_var,
- "prog_name": self.prog_name,
- }
-
- def source(self) -> str:
- """Produce the shell script that defines the completion
- function. By default this ``%``-style formats
- :attr:`source_template` with the dict returned by
- :meth:`source_vars`.
- """
- return self.source_template % self.source_vars()
-
- def get_completion_args(self) -> t.Tuple[t.List[str], str]:
- """Use the env vars defined by the shell script to return a
- tuple of ``args, incomplete``. This must be implemented by
- subclasses.
- """
- raise NotImplementedError
-
- def get_completions(
- self, args: t.List[str], incomplete: str
- ) -> t.List[CompletionItem]:
- """Determine the context and last complete command or parameter
- from the complete args. Call that object's ``shell_complete``
- method to get the completions for the incomplete value.
-
- :param args: List of complete args before the incomplete value.
- :param incomplete: Value being completed. May be empty.
- """
- ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args)
- obj, incomplete = _resolve_incomplete(ctx, args, incomplete)
- return obj.shell_complete(ctx, incomplete)
-
- def format_completion(self, item: CompletionItem) -> str:
- """Format a completion item into the form recognized by the
- shell script. This must be implemented by subclasses.
-
- :param item: Completion item to format.
- """
- raise NotImplementedError
-
- def complete(self) -> str:
- """Produce the completion data to send back to the shell.
-
- By default this calls :meth:`get_completion_args`, gets the
- completions, then calls :meth:`format_completion` for each
- completion.
- """
- args, incomplete = self.get_completion_args()
- completions = self.get_completions(args, incomplete)
- out = [self.format_completion(item) for item in completions]
- return "\n".join(out)
-
-
-class BashComplete(ShellComplete):
- """Shell completion for Bash."""
-
- name = "bash"
- source_template = _SOURCE_BASH
-
- @staticmethod
- def _check_version() -> None:
- import subprocess
-
- output = subprocess.run(
- ["bash", "-c", 'echo "${BASH_VERSION}"'], stdout=subprocess.PIPE
- )
- match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode())
-
- if match is not None:
- major, minor = match.groups()
-
- if major < "4" or major == "4" and minor < "4":
- echo(
- _(
- "Shell completion is not supported for Bash"
- " versions older than 4.4."
- ),
- err=True,
- )
- else:
- echo(
- _("Couldn't detect Bash version, shell completion is not supported."),
- err=True,
- )
-
- def source(self) -> str:
- self._check_version()
- return super().source()
-
- def get_completion_args(self) -> t.Tuple[t.List[str], str]:
- cwords = split_arg_string(os.environ["COMP_WORDS"])
- cword = int(os.environ["COMP_CWORD"])
- args = cwords[1:cword]
-
- try:
- incomplete = cwords[cword]
- except IndexError:
- incomplete = ""
-
- return args, incomplete
-
- def format_completion(self, item: CompletionItem) -> str:
- return f"{item.type},{item.value}"
-
-
-class ZshComplete(ShellComplete):
- """Shell completion for Zsh."""
-
- name = "zsh"
- source_template = _SOURCE_ZSH
-
- def get_completion_args(self) -> t.Tuple[t.List[str], str]:
- cwords = split_arg_string(os.environ["COMP_WORDS"])
- cword = int(os.environ["COMP_CWORD"])
- args = cwords[1:cword]
-
- try:
- incomplete = cwords[cword]
- except IndexError:
- incomplete = ""
-
- return args, incomplete
-
- def format_completion(self, item: CompletionItem) -> str:
- return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}"
-
-
-class FishComplete(ShellComplete):
- """Shell completion for Fish."""
-
- name = "fish"
- source_template = _SOURCE_FISH
-
- def get_completion_args(self) -> t.Tuple[t.List[str], str]:
- cwords = split_arg_string(os.environ["COMP_WORDS"])
- incomplete = os.environ["COMP_CWORD"]
- args = cwords[1:]
-
- # Fish stores the partial word in both COMP_WORDS and
- # COMP_CWORD, remove it from complete args.
- if incomplete and args and args[-1] == incomplete:
- args.pop()
-
- return args, incomplete
-
- def format_completion(self, item: CompletionItem) -> str:
- if item.help:
- return f"{item.type},{item.value}\t{item.help}"
-
- return f"{item.type},{item.value}"
-
-
-ShellCompleteType = t.TypeVar("ShellCompleteType", bound=t.Type[ShellComplete])
-
-
-_available_shells: t.Dict[str, t.Type[ShellComplete]] = {
- "bash": BashComplete,
- "fish": FishComplete,
- "zsh": ZshComplete,
-}
-
-
-def add_completion_class(
- cls: ShellCompleteType, name: t.Optional[str] = None
-) -> ShellCompleteType:
- """Register a :class:`ShellComplete` subclass under the given name.
- The name will be provided by the completion instruction environment
- variable during completion.
-
- :param cls: The completion class that will handle completion for the
- shell.
- :param name: Name to register the class under. Defaults to the
- class's ``name`` attribute.
- """
- if name is None:
- name = cls.name
-
- _available_shells[name] = cls
-
- return cls
-
-
-def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]:
- """Look up a registered :class:`ShellComplete` subclass by the name
- provided by the completion instruction environment variable. If the
- name isn't registered, returns ``None``.
-
- :param shell: Name the class is registered under.
- """
- return _available_shells.get(shell)
-
-
-def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool:
- """Determine if the given parameter is an argument that can still
- accept values.
-
- :param ctx: Invocation context for the command represented by the
- parsed complete args.
- :param param: Argument object being checked.
- """
- if not isinstance(param, Argument):
- return False
-
- assert param.name is not None
- # Will be None if expose_value is False.
- value = ctx.params.get(param.name)
- return (
- param.nargs == -1
- or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE
- or (
- param.nargs > 1
- and isinstance(value, (tuple, list))
- and len(value) < param.nargs
- )
- )
-
-
-def _start_of_option(ctx: Context, value: str) -> bool:
- """Check if the value looks like the start of an option."""
- if not value:
- return False
-
- c = value[0]
- return c in ctx._opt_prefixes
-
-
-def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> bool:
- """Determine if the given parameter is an option that needs a value.
-
- :param args: List of complete args before the incomplete value.
- :param param: Option object being checked.
- """
- if not isinstance(param, Option):
- return False
-
- if param.is_flag or param.count:
- return False
-
- last_option = None
-
- for index, arg in enumerate(reversed(args)):
- if index + 1 > param.nargs:
- break
-
- if _start_of_option(ctx, arg):
- last_option = arg
-
- return last_option is not None and last_option in param.opts
-
-
-def _resolve_context(
- cli: BaseCommand,
- ctx_args: t.MutableMapping[str, t.Any],
- prog_name: str,
- args: t.List[str],
-) -> Context:
- """Produce the context hierarchy starting with the command and
- traversing the complete arguments. This only follows the commands,
- it doesn't trigger input prompts or callbacks.
-
- :param cli: Command being called.
- :param prog_name: Name of the executable in the shell.
- :param args: List of complete args before the incomplete value.
- """
- ctx_args["resilient_parsing"] = True
- ctx = cli.make_context(prog_name, args.copy(), **ctx_args)
- args = ctx.protected_args + ctx.args
-
- while args:
- command = ctx.command
-
- if isinstance(command, MultiCommand):
- if not command.chain:
- name, cmd, args = command.resolve_command(ctx, args)
-
- if cmd is None:
- return ctx
-
- ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True)
- args = ctx.protected_args + ctx.args
- else:
- sub_ctx = ctx
-
- while args:
- name, cmd, args = command.resolve_command(ctx, args)
-
- if cmd is None:
- return ctx
-
- sub_ctx = cmd.make_context(
- name,
- args,
- parent=ctx,
- allow_extra_args=True,
- allow_interspersed_args=False,
- resilient_parsing=True,
- )
- args = sub_ctx.args
-
- ctx = sub_ctx
- args = [*sub_ctx.protected_args, *sub_ctx.args]
- else:
- break
-
- return ctx
-
-
-def _resolve_incomplete(
- ctx: Context, args: t.List[str], incomplete: str
-) -> t.Tuple[t.Union[BaseCommand, Parameter], str]:
- """Find the Click object that will handle the completion of the
- incomplete value. Return the object and the incomplete value.
-
- :param ctx: Invocation context for the command represented by
- the parsed complete args.
- :param args: List of complete args before the incomplete value.
- :param incomplete: Value being completed. May be empty.
- """
- # Different shells treat an "=" between a long option name and
- # value differently. Might keep the value joined, return the "="
- # as a separate item, or return the split name and value. Always
- # split and discard the "=" to make completion easier.
- if incomplete == "=":
- incomplete = ""
- elif "=" in incomplete and _start_of_option(ctx, incomplete):
- name, _, incomplete = incomplete.partition("=")
- args.append(name)
-
- # The "--" marker tells Click to stop treating values as options
- # even if they start with the option character. If it hasn't been
- # given and the incomplete arg looks like an option, the current
- # command will provide option name completions.
- if "--" not in args and _start_of_option(ctx, incomplete):
- return ctx.command, incomplete
-
- params = ctx.command.get_params(ctx)
-
- # If the last complete arg is an option name with an incomplete
- # value, the option will provide value completions.
- for param in params:
- if _is_incomplete_option(ctx, args, param):
- return param, incomplete
-
- # It's not an option name or value. The first argument without a
- # parsed value will provide value completions.
- for param in params:
- if _is_incomplete_argument(ctx, param):
- return param, incomplete
-
- # There were no unparsed arguments, the command may be a group that
- # will provide command name completions.
- return ctx.command, incomplete