diff options
author | Frantisek Tobias <frantisek.tobias@nic.cz> | 2024-12-10 08:23:44 +0100 |
---|---|---|
committer | Aleš Mrázek <ales.mrazek@nic.cz> | 2024-12-20 22:24:22 +0100 |
commit | a48d032e8e3e1d66e0c9c050c710a410ea8cec7b (patch) | |
tree | 957527e6c2377bb6151bbb3b3ff8d216256f63b0 | |
parent | python: client: add completion for all config layers (diff) | |
download | knot-resolver-a48d032e8e3e1d66e0c9c050c710a410ea8cec7b.tar.xz knot-resolver-a48d032e8e3e1d66e0c9c050c710a410ea8cec7b.zip |
kresctl: tab-completion: stop appending space after one config layer is completed
-rw-r--r-- | python/knot_resolver/client/command.py | 42 | ||||
-rw-r--r-- | python/knot_resolver/client/commands/config.py | 4 | ||||
-rw-r--r-- | utils/shell-completion/client.bash | 4 |
3 files changed, 47 insertions, 3 deletions
diff --git a/python/knot_resolver/client/command.py b/python/knot_resolver/client/command.py index e4eddf08..79dd9bec 100644 --- a/python/knot_resolver/client/command.py +++ b/python/knot_resolver/client/command.py @@ -1,7 +1,7 @@ import argparse from abc import ABC, abstractmethod # pylint: disable=[no-name-in-module] from pathlib import Path -from typing import Dict, List, Optional, Tuple, Type, TypeVar +from typing import Dict, List, Optional, Set, Tuple, Type, TypeVar from urllib.parse import quote from knot_resolver.constants import API_SOCK_FILE, CONFIG_FILE @@ -16,10 +16,50 @@ CompWords = Dict[str, Optional[str]] COMP_DIRNAMES = "#dirnames#" COMP_FILENAMES = "#filenames#" +COMP_NOSPACE = "#nospace#" _registered_commands: List[Type["Command"]] = [] +def get_mutually_exclusive_commands(parser: argparse.ArgumentParser) -> List[Set[str]]: + command_names: List[Set[str]] = [] + for group in parser._mutually_exclusive_groups: # noqa: SLF001 + command_names.append(set()) + for action in group._group_actions: # noqa: SLF001 + if action.option_strings: + command_names[-1].update(action.option_strings) + return command_names + + +def is_unique_and_new(arg: str, args: Set[str], exclusive: List[Set[str]], last: str) -> bool: + if arg not in args: + for excl in exclusive: + if arg in excl: + for cmd in excl: + if cmd in args: + return False + return True + + return arg == last + + +def get_subparsers_words( + subparser_actions: List[argparse.Action], args: Set[str], exclusive: List[Set[str]], last: str +) -> CompWords: + words: CompWords = {} + for action in subparser_actions: + if isinstance(action, argparse._SubParsersAction) and action.choices: # noqa: SLF001 + for choice, parser in action.choices.items(): + if is_unique_and_new(choice, args, exclusive, last): + words[choice] = parser.description + else: + for opt in action.option_strings: + if is_unique_and_new(opt, args, exclusive, last): + words[opt] = action.help + + return words + + def get_parser_action(name: str, parser_actions: List[argparse.Action]) -> Optional[argparse.Action]: for action in parser_actions: if (action.choices and name in action.choices) or (action.option_strings and name in action.option_strings): diff --git a/python/knot_resolver/client/commands/config.py b/python/knot_resolver/client/commands/config.py index de25f30a..fef3ad79 100644 --- a/python/knot_resolver/client/commands/config.py +++ b/python/knot_resolver/client/commands/config.py @@ -3,7 +3,7 @@ import sys from enum import Enum from typing import List, Literal, Optional, Tuple, Type -from knot_resolver.client.command import Command, CommandArgs, CompWords, comp_get_words, register_command +from knot_resolver.client.command import COMP_NOSPACE, Command, CommandArgs, CompWords, comp_get_words, register_command from knot_resolver.datamodel import KresConfig from knot_resolver.utils.modeling.parsing import DataFormat, parse_json, try_to_parse from knot_resolver.utils.requests import request @@ -124,6 +124,8 @@ class ConfigCommand(Command): if nargs > 1 and args[-2] in ["-p", "--path"]: words: CompWords = {} + words[COMP_NOSPACE] = None + path = args[-1] path_nodes = path.split("/") diff --git a/utils/shell-completion/client.bash b/utils/shell-completion/client.bash index 0df57f31..5cf66723 100644 --- a/utils/shell-completion/client.bash +++ b/utils/shell-completion/client.bash @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#/usr/bin/env bash _kresctl_completion() { @@ -15,6 +15,8 @@ _kresctl_completion() args="$args${args:+ }-d" elif [[ "$opt" == "#filenames#" ]]; then args="$args${args:+ }-f" + elif [[ "$opt" == "#nospace#" ]]; then + compopt -o nospace else words="$words${words:+ }$opt" fi |