1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
import argparse
from enum import Enum
from typing import List, Tuple, Type
from knot_resolver.client.command import (
Command,
CommandArgs,
CompWords,
comp_get_words,
register_command,
)
class Shells(Enum):
BASH = 0
FISH = 1
@register_command
class CompletionCommand(Command):
def __init__(self, namespace: argparse.Namespace) -> None:
super().__init__(namespace)
self.shell: Shells = namespace.shell
self.args: List[str] = namespace.args
if namespace.extra is not None:
self.args.append("--")
@staticmethod
def register_args_subparser(
subparser: "argparse._SubParsersAction[argparse.ArgumentParser]",
) -> Tuple[argparse.ArgumentParser, "Type[Command]"]:
completion = subparser.add_parser(
"completion",
help="commands auto-completion",
)
shells_dest = "shell"
shells = completion.add_mutually_exclusive_group()
shells.add_argument("--bash", action="store_const", dest=shells_dest, const=Shells.BASH, default=Shells.BASH)
shells.add_argument("--fish", action="store_const", dest=shells_dest, const=Shells.FISH)
completion.add_argument("--args", help="arguments to complete", nargs=argparse.REMAINDER, default=[])
return completion, CompletionCommand
@staticmethod
def completion(args: List[str], parser: argparse.ArgumentParser) -> CompWords:
return comp_get_words(args, parser)
def run(self, args: CommandArgs) -> None: # noqa: PLR0912
words: CompWords = {}
parser = args.parser
if parser:
words = comp_get_words(self.args, args.parser)
# print completion words
# based on required bash/fish shell format
if self.shell == Shells.BASH:
print(" ".join(words))
elif self.shell == Shells.FISH:
# TODO: FISH completion implementation
pass
else:
raise ValueError(f"unexpected value of {Shells}: {self.shell}")
|