From 562a08dda1c86af6795cc7cb9435c7eba18f52b7 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 19 Nov 2025 02:22:07 +0100 Subject: [PATCH] completion: support CompressionSpec --- src/borg/archiver/completion_cmd.py | 47 +++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/borg/archiver/completion_cmd.py b/src/borg/archiver/completion_cmd.py index dbc80bc3e..4765eb3a9 100644 --- a/src/borg/archiver/completion_cmd.py +++ b/src/borg/archiver/completion_cmd.py @@ -5,6 +5,7 @@ import shtab from ._common import process_epilog from ..constants import * # NOQA from ..helpers import archivename_validator, SortBySpec, FilesCacheMode +from ..compress import CompressionSpec from ..helpers.parseformat import partial_format from ..manifest import AI_HUMAN_SORT_KEYS @@ -33,6 +34,10 @@ SORTBY_ZSH_FN_NAME = "_borg_complete_sortby" FCM_BASH_FN_NAME = "_borg_complete_filescachemode" FCM_ZSH_FN_NAME = "_borg_complete_filescachemode" +# Name of the helper function inserted for completing CompressionSpec options +COMP_SPEC_BASH_FN_NAME = "_borg_complete_compression_spec" +COMP_SPEC_ZSH_FN_NAME = "_borg_complete_compression_spec" + # Global bash preamble that is prepended to the generated completion script. # It aggregates only what we need: # - wordbreak fixes for ':' and '=' so tokens like 'aid:' and '--repo=/path' stay intact @@ -86,6 +91,13 @@ _borg_complete_aid() { return 0 } +# Complete compression spec options +_borg_complete_compression_spec() { + local choices="{COMP_SPEC_CHOICES}" + local IFS=$' \t\n' + compgen -W "${choices}" -- "$1" +} + # Complete comma-separated sort keys for any option with type=SortBySpec. # Keys are validated against Borg's AI_HUMAN_SORT_KEYS. _borg_complete_sortby() { @@ -258,6 +270,13 @@ _borg_complete_aid() { return 0 } +# Complete compression spec options +_borg_complete_compression_spec() { + local choices=({COMP_SPEC_CHOICES}) + # use compadd -V to preserve order (do not sort) + compadd -V 'compression algorithms' -Q -a choices +} + # Complete comma-separated sort keys for any option with type=SortBySpec. _borg_complete_sortby() { local cur @@ -414,6 +433,20 @@ def _attach_filescachemode_completion(parser: argparse.ArgumentParser): action.complete = {"bash": FCM_BASH_FN_NAME, "zsh": FCM_ZSH_FN_NAME} # type: ignore[attr-defined] +def _attach_compression_spec_completion(parser: argparse.ArgumentParser): + """Tag all arguments with type CompressionSpec with compression-spec completion.""" + + for action in parser._actions: + # Recurse into subparsers + if isinstance(action, argparse._SubParsersAction): + for sub in action.choices.values(): + _attach_compression_spec_completion(sub) + continue + + if action.type is CompressionSpec: + action.complete = {"bash": COMP_SPEC_BASH_FN_NAME, "zsh": COMP_SPEC_ZSH_FN_NAME} # type: ignore[attr-defined] + + def _attach_help_completion(parser: argparse.ArgumentParser, completion_dict: dict): """Tag the 'topic' argument of the 'help' command with static completion choices.""" for action in parser._actions: @@ -437,6 +470,7 @@ class CompletionMixIn: _attach_aid_completion(parser) _attach_sortby_completion(parser) _attach_filescachemode_completion(parser) + _attach_compression_spec_completion(parser) # Collect all commands and help topics for "borg help" completion help_choices = list(self.helptext.keys()) @@ -454,9 +488,22 @@ class CompletionMixIn: # Help completion templates help_choices = " ".join(sorted(help_choices)) + # Compression spec choices (static list) + comp_spec_choices = [ + "lz4", + "zstd,3", + "auto,zstd,10", + "zlib,6", + "lzma,6", + "obfuscate,250,lz4", + "none", + ] + comp_spec_choices_str = " ".join(comp_spec_choices) + mapping = { "SORT_KEYS": sort_keys, "FCM_KEYS": fcm_keys, + "COMP_SPEC_CHOICES": comp_spec_choices_str, "HELP_CHOICES": help_choices, } bash_preamble = partial_format(BASH_PREAMBLE_TMPL, mapping)