Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add shell completions by shtab #2506

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions pre_commit/_shtab.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from __future__ import annotations

from argparse import ArgumentParser
from typing import Any

FILE = None
DIRECTORY = DIR = None


def add_argument_to(
parser: ArgumentParser, *args: list[Any], **kwargs: dict[Any, Any],
) -> ArgumentParser:
from argparse import Action

Action.complete = None # type: ignore
return parser
28 changes: 25 additions & 3 deletions pre_commit/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,27 @@
from pre_commit.logging_handler import logging_handler
from pre_commit.store import Store

try:
import shtab
except ImportError:
from . import _shtab as shtab


# https://github.com/iterative/shtab/blob/master/examples/customcomplete.py#L11-L22
YAML_FILE = {
'bash': '_shtab_greeter_compgen_yaml_files',
'zsh': "_files -g '*.yaml'",
'tcsh': 'f:*.yaml',
}
PREAMBLE = {
'bash': """
# $1=COMP_WORDS[1]
_shtab_greeter_compgen_yaml_files() {
compgen -d -- $1 # recurse into subdirs
compgen -f -X '!*?.yaml' -- $1
}
""",
}

logger = logging.getLogger('pre_commit')

Expand All @@ -46,7 +67,7 @@ def _add_config_option(parser: argparse.ArgumentParser) -> None:
parser.add_argument(
'-c', '--config', default=C.CONFIG_FILE,
help='Path to alternate config file',
)
).complete = YAML_FILE # type: ignore


def _add_hook_type_option(parser: argparse.ArgumentParser) -> None:
Expand All @@ -67,7 +88,7 @@ def _add_run_options(parser: argparse.ArgumentParser) -> None:
mutex_group.add_argument(
'--files', nargs='*', default=[],
help='Specific filenames to run hooks on.',
)
).complete = shtab.FILE # type: ignore
parser.add_argument(
'--show-diff-on-failure', action='store_true',
help='When hooks fail, run `git diff` directly afterward.',
Expand Down Expand Up @@ -179,6 +200,7 @@ def _adjust_args_and_chdir(args: argparse.Namespace) -> None:
def main(argv: Sequence[str] | None = None) -> int:
argv = argv if argv is not None else sys.argv[1:]
parser = argparse.ArgumentParser(prog='pre-commit')
shtab.add_argument_to(parser, preamble=PREAMBLE)

# https://stackoverflow.com/a/8521644/812183
parser.add_argument(
Expand Down Expand Up @@ -229,7 +251,7 @@ def _add_cmd(name: str, *, help: str) -> argparse.ArgumentParser:
_add_config_option(init_templatedir_parser)
init_templatedir_parser.add_argument(
'directory', help='The directory in which to write the hook script.',
)
).complete = shtab.DIR # type: ignore
init_templatedir_parser.add_argument(
'--no-allow-missing-config',
action='store_false',
Expand Down
4 changes: 4 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ console_scripts =
pre-commit-validate-config = pre_commit.clientlib:validate_config_main
pre-commit-validate-manifest = pre_commit.clientlib:validate_manifest_main

[options.extras_require]
completion =
shtab

[options.package_data]
pre_commit.resources =
*.tar.gz
Expand Down