# SPDX-FileCopyrightText: 2025 Dennis Fink # # SPDX-License-Identifier: BSD-3-Clause # bash completion for transcode.sh # Install to: # /etc/bash_completion.d/transcode.sh # or source manually: # source transcode.sh.bash-completion.sh # # Each option that takes an argument is supported in all three forms: # short -f list.txt # long space --encode-file list.txt # long equals --encode-file=list.txt function _transcode_sh() { local cur prev _init_completion -n = || return local -r preset_dir="${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/presets" # --------------------------------------------------------------------------- # Helper: collect preset names from the preset directory # --------------------------------------------------------------------------- function _transcode_presets() { local presets=() if [[ -d "$preset_dir" ]]; then local f while IFS= read -r f; do f="${f##*/}" # basename f="${f%.sh}" # strip .sh extension presets+=("$f") done < <(find "$preset_dir" -maxdepth 1 -name '*.sh' -type f 2>/dev/null) fi printf '%s\n' "${presets[@]}" } local codecs='h264 hevc av1 vp8 vp9 mpeg2video mpeg4 mjpeg theora' local nice_vals='0 5 10 15 19' local hwaccel_methods='auto cuda vaapi dxva2 d3d11va videotoolbox qsv' local ffmpeg_loglevels='quiet panic fatal error warning info verbose debug trace' local video_streams='v:0 v:1 v:2 v:3' # --------------------------------------------------------------------------- # Handle --option=VALUE: cur contains the entire "--opt=val" token. # Strip the "opt=" prefix and delegate to the appropriate completer. # This must be checked before the $prev dispatch below. # --------------------------------------------------------------------------- case "$cur" in --config-file=*) cur="${cur#*=}" _filedir return ;; --encode-file=*) cur="${cur#*=}" _filedir return ;; --preset=*) cur="${cur#*=}" COMPREPLY=($(compgen -W "$(_transcode_presets)" -- "$cur")) return ;; --nice=*) cur="${cur#*=}" COMPREPLY=($(compgen -W "$nice_vals" -- "$cur")) return ;; --hwaccel=*) cur="${cur#*=}" COMPREPLY=($(compgen -W "$hwaccel_methods" -- "$cur")) return ;; --video-stream=*) cur="${cur#*=}" COMPREPLY=($(compgen -W "$video_streams" -- "$cur")) return ;; --skip-codec=*) cur="${cur#*=}" COMPREPLY=($(compgen -W "$codecs" -- "$cur")) return ;; --backup-dir=*) cur="${cur#*=}" _filedir -d return ;; --output-dir=*) cur="${cur#*=}" _filedir -d return ;; --size-report-file=*) cur="${cur#*=}" _filedir return ;; --ffmpeg-loglevel=*) cur="${cur#*=}" COMPREPLY=($(compgen -W "$ffmpeg_loglevels" -- "$cur")) return ;; esac # --------------------------------------------------------------------------- # Handle VALUE after short and long space forms. # The dispatch order mirrors the help output where practical. # $prev is the option word, $cur is the value being typed. # --------------------------------------------------------------------------- case "$prev" in --config-file) _filedir return ;; -f | --encode-file) _filedir return ;; -p | --preset) COMPREPLY=($(compgen -W "$(_transcode_presets)" -- "$cur")) return ;; -N | --nice) COMPREPLY=($(compgen -W "$nice_vals" -- "$cur")) return ;; --hwaccel) COMPREPLY=($(compgen -W "$hwaccel_methods" -- "$cur")) return ;; --video-stream) COMPREPLY=($(compgen -W "$video_streams" -- "$cur")) return ;; --ffmpeg-loglevel) COMPREPLY=($(compgen -W "$ffmpeg_loglevels" -- "$cur")) return ;; -S | --skip-codec) COMPREPLY=($(compgen -W "$codecs" -- "$cur")) return ;; --backup-dir) _filedir -d return ;; --output-dir) _filedir -d return ;; --size-report-file) _filedir return ;; esac # --------------------------------------------------------------------------- # Complete option names themselves. # For options that accept an argument we list both the bare long form # (--nice) and the equals form (--nice=) so the user can choose their # preferred style. compopt -o nospace is applied when the sole match # ends with '=' to avoid an unwanted trailing space in that case. # --------------------------------------------------------------------------- case "$cur" in --*) local longopts=' --config-file --config-file= --no-config --encode-file --encode-file= --preset --preset= --nice --nice= --hwaccel --hwaccel= --no-hwaccel --video-stream --video-stream= --skip-codec --skip-codec= --skip-codec-override --dry-run --backup-dir --backup-dir= --output-dir --output-dir= --only-if-smaller --no-only-if-smaller --verify-output --no-verify-output --continue --no-continue --size-report --no-size-report --size-report-file --size-report-file= --ffmpeg-loglevel --ffmpeg-loglevel= --quiet --verbose --color --no-color --help --version --list-presets ' COMPREPLY=($(compgen -W "$longopts" -- "$cur")) # Suppress the trailing space when the only completion ends with '=' [[ ${#COMPREPLY[@]} -eq 1 && "${COMPREPLY[0]}" == *= ]] && compopt -o nospace return ;; -*) local shortopts='-f -p -N -S -n -l -c -s -q -v -h -? --' COMPREPLY=($(compgen -W "$shortopts" -- "$cur")) return ;; esac # --------------------------------------------------------------------------- # Default: complete positional FILE arguments with common media extensions # --------------------------------------------------------------------------- _filedir '@(mkv|mp4|mov|avi|webm|flv|wmv|m4v|ts|mts|m2ts|mpg|mpeg|ogv|3gp|rm|rmvb)' } complete -F _transcode_sh transcode.sh complete -F _transcode_sh transcode