From 309e74e2c33470c4771a5c4bf22e1b5a853e4aef Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Wed, 20 Aug 2025 13:30:41 +0100 Subject: [PATCH] Add bash completions Assisted-by: Cursor --- Makefile.am | 27 ++- bash-completion-patchutils | 434 +++++++++++++++++++++++++++++++++++++ 2 files changed, 460 insertions(+), 1 deletion(-) create mode 100644 bash-completion-patchutils diff --git a/Makefile.am b/Makefile.am index d4fa70d7..09a88870 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,6 +19,10 @@ dist_bin_SCRIPTS = \ patchview/svndiff \ patchview/svndiffview +# Bash completion files +bashcompletiondir = $(datadir)/bash-completion/completions +dist_bashcompletion_DATA = bash-completion-patchutils + AM_CFLAGS = -I$(srcdir)/src -I$(top_builddir)/lib -I$(top_srcdir)/lib src_interdiff_SOURCES = src/interdiff.c src/util.c src/util.h src/diff.c \ src/diff.h @@ -68,12 +72,32 @@ install-exec-hook: ln -sf "`echo filterdiff|sed '$(transform)'`" $(DESTDIR)$(bindir)/"`echo grepdiff|sed '$(transform)'`" ln -sf "`echo filterdiff|sed '$(transform)'`" $(DESTDIR)$(bindir)/"`echo patchview|sed '$(transform)'`" +install-data-hook: + if [ -d "$(DESTDIR)$(bashcompletiondir)" ]; then \ + cd "$(DESTDIR)$(bashcompletiondir)" && \ + mv bash-completion-patchutils patchutils && \ + for cmd in filterdiff lsdiff grepdiff interdiff combinediff flipdiff rediff \ + splitdiff recountdiff unwrapdiff dehtmldiff editdiff espdiff \ + fixcvsdiff patchview gitdiff svndiff gitdiffview svndiffview; do \ + ln -sf patchutils "$$cmd" || true; \ + done; \ + fi + uninstall-hook: rm -f $(DESTDIR)$(bindir)/"`echo combinediff|sed '$(transform)'`" rm -f $(DESTDIR)$(bindir)/"`echo flipdiff|sed '$(transform)'`" rm -f $(DESTDIR)$(bindir)/"`echo lsdiff|sed '$(transform)'`" rm -f $(DESTDIR)$(bindir)/"`echo grepdiff|sed '$(transform)'`" rm -f $(DESTDIR)$(bindir)/"`echo patchview|sed '$(transform)'`" + if [ -d "$(DESTDIR)$(bashcompletiondir)" ]; then \ + cd "$(DESTDIR)$(bashcompletiondir)" && \ + for cmd in filterdiff lsdiff grepdiff interdiff combinediff flipdiff rediff \ + splitdiff recountdiff unwrapdiff dehtmldiff editdiff espdiff \ + fixcvsdiff patchview gitdiff svndiff gitdiffview svndiffview; do \ + rm -f "$$cmd"; \ + done; \ + rm -f patchutils; \ + fi CLEANFILES=src/combinediff src/flipdiff src/lsdiff src/grepdiff src/patchview MAINTAINERCLEANFILES=$(man_MANS) @@ -291,7 +315,8 @@ EXTRA_DIST = $(man_MANS) \ doc/patchutils.xml \ patchview/README.patchview \ scripts/move-to-front \ - m4/gnulib-cache.m4 + m4/gnulib-cache.m4 \ + bash-completion-patchutils tag: cvs tag -c `echo V@VERSION@ | tr . _` diff --git a/bash-completion-patchutils b/bash-completion-patchutils new file mode 100644 index 00000000..73e32aed --- /dev/null +++ b/bash-completion-patchutils @@ -0,0 +1,434 @@ +# Bash completion for patchutils commands +# Generated for patchutils package + +# Common options used across multiple commands +_patchutils_common_opts() { + echo "--help --version" +} + +_patchutils_filter_opts() { + echo "--exclude -x --exclude-from-file -X --include -i --include-from-file -I --hunks -# --lines --files -F --annotate --as-numbered-lines --format --remove-timestamps --clean --decompress -z --strip-match -p --strip --addprefix --addoldprefix --addnewprefix" +} + +_patchutils_list_opts() { + echo "--line-number -n --number-files -N --with-filename -H --no-filename -h --status -s --empty-files-as-absent -E" +} + +_patchutils_grep_opts() { + echo "--output-matching --only-match --extended-regexp -E --file -f" +} + +_patchutils_interdiff_opts() { + echo "--unified -U --ignore-case -i --ignore-all-space -w --ignore-space-change -b --ignore-blank-lines -B --color --quiet -q --drop-context -d --decompress -z --strip-match -p --interpolate --combine --flip --no-revert-omitted --in-place" +} + +# File completion helper +_patchutils_files() { + local cur="${COMP_WORDS[COMP_CWORD]}" + COMPREPLY=($(compgen -f -- "$cur")) +} + +# Completion for filterdiff +_filterdiff() { + local cur prev opts + COMP_WORDBREAKS=${COMP_WORDBREAKS//=} + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="$(_patchutils_common_opts) $(_patchutils_filter_opts) $(_patchutils_list_opts) --verbose -v --filter --grep --list" + + case "${prev}" in + --exclude|-x|--include|-i) + # Pattern completion - no specific completion + return 0 + ;; + --exclude-from-file|-X|--include-from-file|-I|--file|-f) + _patchutils_files + return 0 + ;; + --hunks|-#|--lines|--files|-F) + # Range completion - no specific completion + return 0 + ;; + --as-numbered-lines) + COMPREPLY=($(compgen -W "before after" -- "$cur")) + return 0 + ;; + --format) + COMPREPLY=($(compgen -W "context unified" -- "$cur")) + return 0 + ;; + --output-matching) + COMPREPLY=($(compgen -W "hunk file" -- "$cur")) + return 0 + ;; + --only-match) + COMPREPLY=($(compgen -W "rem removals add additions mod modifications all" -- "$cur")) + return 0 + ;; + --strip-match|-p|--strip) + # Number completion - no specific completion + return 0 + ;; + --addprefix|--addoldprefix|--addnewprefix) + # Prefix completion - no specific completion + return 0 + ;; + esac + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Completion for lsdiff (same as filterdiff with --list mode) +_lsdiff() { + local cur prev opts + COMP_WORDBREAKS=${COMP_WORDBREAKS//=} + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="$(_patchutils_common_opts) $(_patchutils_filter_opts) $(_patchutils_list_opts) --verbose -v --filter --grep" + + case "${prev}" in + --exclude|-x|--include|-i) + return 0 + ;; + --exclude-from-file|-X|--include-from-file|-I) + _patchutils_files + return 0 + ;; + --hunks|-#|--lines|--files|-F) + return 0 + ;; + --strip-match|-p|--strip) + return 0 + ;; + --addprefix|--addoldprefix|--addnewprefix) + return 0 + ;; + esac + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Completion for grepdiff +_grepdiff() { + local cur prev opts + COMP_WORDBREAKS=${COMP_WORDBREAKS//=} + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="$(_patchutils_common_opts) $(_patchutils_filter_opts) $(_patchutils_list_opts) $(_patchutils_grep_opts) --verbose -v --filter --list" + + case "${prev}" in + --exclude|-x|--include|-i) + return 0 + ;; + --exclude-from-file|-X|--include-from-file|-I|--file|-f) + _patchutils_files + return 0 + ;; + --hunks|-#|--lines|--files|-F) + return 0 + ;; + --as-numbered-lines) + COMPREPLY=($(compgen -W "before after" -- "$cur")) + return 0 + ;; + --format) + COMPREPLY=($(compgen -W "context unified" -- "$cur")) + return 0 + ;; + --output-matching) + COMPREPLY=($(compgen -W "hunk file" -- "$cur")) + return 0 + ;; + --only-match) + COMPREPLY=($(compgen -W "rem removals add additions mod modifications all" -- "$cur")) + return 0 + ;; + --strip-match|-p|--strip) + return 0 + ;; + --addprefix|--addoldprefix|--addnewprefix) + return 0 + ;; + esac + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Completion for interdiff, combinediff, flipdiff +_interdiff() { + local cur prev opts + COMP_WORDBREAKS=${COMP_WORDBREAKS//=} + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="$(_patchutils_common_opts) $(_patchutils_interdiff_opts)" + + case "${prev}" in + --unified|-U) + # Number completion + return 0 + ;; + --drop-context|-d) + # Pattern completion + return 0 + ;; + --strip-match|-p) + # Number completion + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "never always auto" -- "$cur")) + return 0 + ;; + esac + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Completion for rediff +_rediff() { + local cur prev opts + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="--help --version" + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Completion for splitdiff +_splitdiff() { + local cur prev opts + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="--help --version -a -p -d -D -E" + + case "${prev}" in + -p) + # Number completion + return 0 + ;; + -D) + # Directory completion + COMPREPLY=($(compgen -d -- "$cur")) + return 0 + ;; + esac + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Completion for recountdiff +_recountdiff() { + local cur prev opts + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="--help --version" + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Completion for unwrapdiff +_unwrapdiff() { + local cur prev opts + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="--help --version" + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Completion for dehtmldiff +_dehtmldiff() { + local cur prev opts + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="--help --version" + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Completion for editdiff +_editdiff() { + local cur prev opts + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="--help --version" + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Completion for espdiff +_espdiff() { + local cur prev opts + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="--help --version" + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Completion for fixcvsdiff +_fixcvsdiff() { + local cur prev opts + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="--help --version -p -b" + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Completion for patchview +_patchview() { + local cur prev opts + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + # patchview is a wrapper around filterdiff, so use similar completion + opts="$(_patchutils_common_opts) $(_patchutils_filter_opts) --verbose -v --filter --grep" + + case "${prev}" in + --exclude|-x|--include|-i) + return 0 + ;; + --exclude-from-file|-X|--include-from-file|-I) + _patchutils_files + return 0 + ;; + --hunks|-#|--lines|--files|-F) + return 0 + ;; + --strip-match|-p|--strip) + return 0 + ;; + --addprefix|--addoldprefix|--addnewprefix) + return 0 + ;; + esac + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + _patchutils_files +} + +# Simple completion for git/svn diff wrappers +_gitdiff() { + local cur prev opts + cur="${COMP_WORDS[COMP_CWORD]}" + + # These are wrappers that pass arguments to filterdiff + opts="$(_patchutils_filter_opts)" + + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return 0 + fi + + return 0 +} + +_svndiff() { + _gitdiff +} + +_gitdiffview() { + _gitdiff +} + +_svndiffview() { + _gitdiff +} + +# Register completions for all patchutils commands +complete -F _filterdiff filterdiff +complete -F _lsdiff lsdiff +complete -F _grepdiff grepdiff +complete -F _interdiff interdiff +complete -F _interdiff combinediff +complete -F _interdiff flipdiff +complete -F _rediff rediff +complete -F _splitdiff splitdiff +complete -F _recountdiff recountdiff +complete -F _unwrapdiff unwrapdiff +complete -F _dehtmldiff dehtmldiff +complete -F _editdiff editdiff +complete -F _espdiff espdiff +complete -F _fixcvsdiff fixcvsdiff +complete -F _patchview patchview +complete -F _gitdiff gitdiff +complete -F _svndiff svndiff +complete -F _gitdiffview gitdiffview +complete -F _svndiffview svndiffview