#!/bin/bash # Completions for borg version 1.1.1 # https://www.borgbackup.org/ # Note: # Listing archives works on password protected repositories only if $BORG_PASSPHRASE is set. # Install: # Copy this file to /usr/share/bash-completion/completions/ or /etc/bash_completion.d/ _borg() { COMPREPLY=() local cur="${COMP_WORDS[COMP_CWORD]}" local prev="${COMP_WORDS[COMP_CWORD-1]}" local prevprev="${COMP_WORDS[COMP_CWORD-2]}" local common_opts="-h --help --version --critical --error --warning --info -v --verbose --debug --debug-topic -p --progress --log-json --lock-wait --show-version --show-rc --umask --remote-path --remote-ratelimit --consider-part-files --debug-profile" local opts="${common_opts}" # Commands if [[ ${COMP_CWORD} == 1 ]] ; then local borg_commands="init create extract check rename list diff delete prune info mount umount key serve upgrade recreate export-tar with-lock break-lock benchmark" COMPREPLY=( $(compgen -W "${borg_commands}" -- ${cur}) ) return 0 fi case "${prev}" in 'key') COMPREPLY=( $(compgen -W "import export change-passphrase" -- ${cur}) ) return 0 ;; 'benchmark') COMPREPLY=( $(compgen -W "crud" -- ${cur}) ) return 0 ;; '--encryption' | '-e') local encryption_modes="none keyfile keyfile-blake2 repokey repokey-blake2 authenticated authenticated-blake2" COMPREPLY=( $(compgen -W "${encryption_modes}" -- ${cur}) ) return 0 ;; '--files-cache') local files_cache_mode="ctime,size,inode mtime,size,inode ctime,size mtime,size rechunk,ctime rechunk,mtime disabled" COMPREPLY=( $(compgen -W "${files_cache_mode}" -- ${cur}) ) return 0 ;; '--compression') local compression_methods="none auto lz4 zlib,1 zlib,2 zlib,3 zlib,4 zlib,5 zlib,6 zlib,7 zlib,8 zlib,9 lzma,0 lzma,1 lzma,2 lzma,3 lzma,4 lzma,5 lzma,6 lzma,7 lzma,8 lzma,9" COMPREPLY=( $(compgen -W "${compression_methods}" -- ${cur}) ) return 0 ;; '--sort-by') local sort_keys="timestamp name id" COMPREPLY=( $(compgen -W "${sort_keys}" -- ${cur}) ) return 0 ;; '-o') local fuse_options="allow_other allow_root" # FIXME there are lot more options, but not all are applicable COMPREPLY=( $(compgen -W "${fuse_options}" -- ${cur}) ) return 0 ;; '--recompress') local recompress_when="if-different always" COMPREPLY=( $(compgen -W "${recompress_when}" -- ${cur}) ) return 0 ;; esac if [[ ${cur} == -* ]] ; then case "${COMP_LINE}" in *' init '*) local opts="-e --encryption --append-only --storage-quota ${common_opts}" ;; *' create '*) local opts="-n --dry-run -s --stats --list --filter --json --no-cache-sync --no-files-cache -e --exclude --exclude-from --pattern --patterns-from --exclude-caches --exclude-if-present --keep-exclude-tags --keep-tag-files --exclude-nodump -x --one-file-system --numeric-owner --noatime --noctime --nobsdflags --ignore-inode --mtime --files-cache --read-special --comment --timestamp -c --checkpoint-interval --chunker-params -C --compression ${common_opts}" ;; *' extract '*) local opts="--list -n --dry-run --numeric-owner --nobsdflags --stdout --sparse -e --exclude --exclude-from --pattern --patterns-from --strip-components ${common_opts}" ;; *' check '*) local opts="--repository-only --archives-only --verify-data --repair --save-space -P --prefix -a --glob-archives --sort-by --first --last ${common_opts}" ;; # rename # no specific options *" list "*) local opts="--short --list-format --format --json --json-lines -P --prefix -a --glob-archives --sort-by --first --last -e --exclude --exclude-from --pattern --patterns-from ${common_opts}" ;; *' diff '*) local opts="--numeric-owner --same-chunker-params --sort -e --exclude --exclude-from --pattern --patterns-from ${common_opts}" ;; *' delete '*) local opts="-s --stats --cache-only --force --save-space -P --prefix -a --glob-archives --sort-by --first --last ${common_opts}" ;; *' prune '*) local opts="-n --dry-run --force -s --stats --list --keep-within --keep-last --keep-secondly --keep-minutely -H --keep-hourly -d --keep-daily -w --keep-weekly -m --keep-monthly -y --keep-yearly --save-space -P --prefix -a --glob-archives ${common_opts}" ;; *' info '*) local opts="--json -P --prefix -a --glob-archives --sort-by --first --last ${common_opts}" ;; *' mount '*) local opts="-f --foreground -o -P --prefix -a --glob-archives --sort-by --first --last ${common_opts}" ;; # umount # no specific options # key change-passphrase # no specific options *' export '*) local opts="--paper --qr-html ${common_opts}" ;; *' import '*) local opts="--paper ${common_opts}" ;; *' upgrade '*) local opts="-n --dry-run --inplace --force --tam --disable-tam ${common_opts}" ;; *' recreate '*) local opts="--list --filter -n dry-run -s stats -e exclude --exclude-from --pattern --patterns-from --exclude-caches --exclude-if-present --keep-exclude-tags --keep-tag-files --target -c checkpoint-interval --comment --timestamp --timestamp -C compression --recompress --chunker-params ${common_opts}" ;; *' export-tar '*) local opts="--tar-filter --list -e exclude --exclude-from --pattern --patterns-from --strip-components ${common_opts}" ;; *' serve '*) local opts="--restrict-to-path --restrict-to-repository --append-only --storage-quota ${common_opts}" ;; # with-lock # no specific options # break-lock # no specific options # benchmark crud # no specific options esac COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 fi # 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 repository_name="" # If set, we'll list the archives local typed_word="" if [[ ${cur} == "::" ]] ; then repository_name=${prev} fi if [[ ${prev} == "::" ]] ; then repository_name=${prevprev} 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 local archive_list=$(borg list --short "${repository_name}" 2>/dev/null) COMPREPLY=( $(compgen -W "${archive_list}" -- "${typed_word}" ) ) return 0 fi COMPREPLY=( $(compgen -f ${cur}) ) return 0 } complete -F _borg borg