From 4346c4e85b05be47df64405c90ec4353320d96f7 Mon Sep 17 00:00:00 2001 From: SanskritFritz Date: Tue, 26 Jan 2021 22:43:05 +0100 Subject: [PATCH 1/2] Tab completion support for additional archives for 'borg delete' Bash and Fish tab completions now too support more than just one archive provided for 'borg delete'. --- scripts/shell_completions/bash/borg | 30 ++++++++++++++---------- scripts/shell_completions/fish/borg.fish | 17 +++++++++----- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/scripts/shell_completions/bash/borg b/scripts/shell_completions/bash/borg index 9d4303e3d..0bca21b5e 100644 --- a/scripts/shell_completions/bash/borg +++ b/scripts/shell_completions/bash/borg @@ -143,32 +143,36 @@ _borg() return 0 fi + # Get the repository name if available + # If there is a space before the "::" it means that no repository name was typed, + # so probably $BORG_REPO was set and we can still list the archives. + local repository_name=`expr match "${COMP_LINE}" "\(.*\)::"` + repository_name=${repository_name##* } + # Listing archives. - # Since "::" is treated as separate word in bash, + # Since "::" is treated as separate word in Bash, # it is $cur when the cursor is right behind it # and $prev if the user has started to type an archive name. - local repository_name="" # If set, we'll list the archives local typed_word="" + local please_list_the_archives=false if [[ ${cur} == "::" ]] ; then - repository_name=${prev} + please_list_the_archives=true fi if [[ ${prev} == "::" ]] ; then - repository_name=${prevprev} + please_list_the_archives=true typed_word=${cur} fi # Second archive listing for borg diff if [[ ${COMP_LINE} =~ ^.*\ diff\ .*::[^\ ]+\ ${cur}$ ]] ; then - repository_name=`expr match "${COMP_LINE}" "\(.*\)::"` - repository_name=${repository_name##* } + please_list_the_archives=true typed_word=${cur} fi - if [[ ${repository_name} != "" ]] ; then - if [[ ${COMP_LINE} == *" ::"* ]] ; then - # There is a space before the "::" - # which means that no repository name was typed, - # so probably $BORG_REPO is set. - repository_name="" - fi + # Additional archive listing for borg delete + if [[ ${COMP_LINE} =~ ^.*\ delete\ .*::[^\ ]+.*${cur}$ ]] ; then + please_list_the_archives=true + typed_word=${cur} + fi + if [[ $please_list_the_archives = true ]] ; then local archive_list=$(borg list --short "${repository_name}" 2>/dev/null) COMPREPLY=( $(compgen -W "${archive_list}" -- "${typed_word}" ) ) return 0 diff --git a/scripts/shell_completions/fish/borg.fish b/scripts/shell_completions/fish/borg.fish index 89d76c750..6ba7df3ef 100644 --- a/scripts/shell_completions/fish/borg.fish +++ b/scripts/shell_completions/fish/borg.fish @@ -360,7 +360,7 @@ function __fish_borg_list_repos_or_archives if string match --quiet --regex '.*::' '"'(commandline --current-token)'"' # If the current token contains "::" then list the archives: set -l repository_name (string replace --regex '::.*' '' (commandline --current-token)) - borg list --format="$repository_name::{archive}{NEWLINE}" "$repository_name" ^/dev/null + borg list --format="$repository_name::{archive}{TAB}{comment}{NEWLINE}" "$repository_name" ^/dev/null else # Otherwise list the repositories, directories and user@host entries: set -l directories (commandline --cut-at-cursor --current-token)*/ @@ -378,15 +378,20 @@ end complete -c borg -f -n "__fish_borg_is_argument_n 2" -a '(__fish_borg_list_repos_or_archives)' -# Second archive listing for borg diff +# Additional archive listings function __fish_borg_is_diff_second_archive return (string match --quiet --regex ' diff .*::[^ ]+ '(commandline --current-token)'$' (commandline)) end -function __fish_borg_list_diff_archives - set -l repo_matches (string match --regex '([^ ]*)::' (commandline)) - borg list --format="{archive}{NEWLINE}" "$repo_matches[2]" ^/dev/null +function __fish_borg_is_delete_additional_archive + return (string match --quiet --regex ' delete .*::[^ ]+ ' (commandline)) end -complete -c borg -f -n __fish_borg_is_diff_second_archive -a '(__fish_borg_list_diff_archives)' +function __fish_borg_list_only_archives + set -l repo_matches (string match --regex '([^ ]*)::' (commandline)) + borg list --format="{archive}{TAB}{comment}{NEWLINE}" "$repo_matches[2]" ^/dev/null +end + +complete -c borg -f -n __fish_borg_is_diff_second_archive -a '(__fish_borg_list_only_archives)' +complete -c borg -f -n __fish_borg_is_delete_additional_archive -a '(__fish_borg_list_only_archives)' From 426fb9e8ec2348908d0523b829bc14c2b2504bd4 Mon Sep 17 00:00:00 2001 From: SanskritFritz Date: Sat, 30 Jan 2021 13:16:27 +0100 Subject: [PATCH 2/2] Efficiency fixes thanks to @oxiedi --- scripts/shell_completions/bash/borg | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/scripts/shell_completions/bash/borg b/scripts/shell_completions/bash/borg index 0bca21b5e..1262f2e1a 100644 --- a/scripts/shell_completions/bash/borg +++ b/scripts/shell_completions/bash/borg @@ -146,35 +146,33 @@ _borg() # Get the repository name if available # If there is a space before the "::" it means that no repository name was typed, # so probably $BORG_REPO was set and we can still list the archives. - local repository_name=`expr match "${COMP_LINE}" "\(.*\)::"` + local repository_name="${COMP_LINE%%::*}" repository_name=${repository_name##* } # Listing archives. # Since "::" is treated as separate word in Bash, # it is $cur when the cursor is right behind it # and $prev if the user has started to type an archive name. - local typed_word="" - local please_list_the_archives=false + local typed_word=${cur} + local -i list_archives=0 if [[ ${cur} == "::" ]] ; then - please_list_the_archives=true + list_archives=1 + typed_word="" fi if [[ ${prev} == "::" ]] ; then - please_list_the_archives=true - typed_word=${cur} + list_archives=1 fi # Second archive listing for borg diff if [[ ${COMP_LINE} =~ ^.*\ diff\ .*::[^\ ]+\ ${cur}$ ]] ; then - please_list_the_archives=true - typed_word=${cur} + list_archives=1 fi # Additional archive listing for borg delete if [[ ${COMP_LINE} =~ ^.*\ delete\ .*::[^\ ]+.*${cur}$ ]] ; then - please_list_the_archives=true - typed_word=${cur} + list_archives=1 fi - if [[ $please_list_the_archives = true ]] ; then - local archive_list=$(borg list --short "${repository_name}" 2>/dev/null) - COMPREPLY=( $(compgen -W "${archive_list}" -- "${typed_word}" ) ) + if (( $list_archives )) ; then + local archives=$(borg list --short "${repository_name}" 2>/dev/null) + COMPREPLY=( $(compgen -W "${archives}" -- "${typed_word}" ) ) return 0 fi