From e5ce91530751db1e00584d915c70ea99e7bddae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= Date: Mon, 27 Jan 2025 23:23:11 +0100 Subject: [PATCH 1/7] WIP: Support more bind9 utilities host and nslookup are already supported. But dig is not, similarly with delv and others. --- completions/bind9 | 205 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 completions/bind9 diff --git a/completions/bind9 b/completions/bind9 new file mode 100644 index 00000000000..464a1f041b0 --- /dev/null +++ b/completions/bind9 @@ -0,0 +1,205 @@ +# bash completion for nslookup -*- shell-script -*- +# bind9 utilities completion + +_comp_cmd_rndc__list_commands() +{ + rndc 2>&1 | awk '/^ / {print $1}' | sort -u +} + +_comp_cmd_rndc__list_parameters() +{ + local SUBCMD=$1 + rndc 2>&1 | awk "/^ ${SUBCMD} / { print \$2 }" + if [[ $cur == @* ]]; then + _comp_compgen_known_hosts -- "$cur" + return + fi + +} + +# TODO: not used yet, useful for dnssec-signzone etc. +_comp_cmd_named_checkconf__list_zones() +{ + named-checkconf -l | awk '{print $1}' +} + +# TODO: named-rrchecker provides -T -C listings of supported query types. +# should replace _comp_cmd_nslookup__queryclass, _comp_cmd_nslookup__querytype +# when command is present. + +_comp_cmd_rndc() +{ + local cur prev words cword comp_args + _comp_initialize -n = -- "$@" || return + + case $prev in + -c|-k) + _comp_compgen -a filedir + return + ;; + esac + + local REPLY + _comp_count_args + if [[ $cur == -* ]]; then + _comp_compgen_usage + return + fi + if ((REPLY == 1)); then + _comp_compgen -- -W "$(_comp_cmd_rndc__list_commands)" + fi + if ((REPLY == 2)); then + _comp_compgen -- -W "$(_comp_cmd_rndc__list_parameters $prev)" + fi +} && complete -F _comp_cmd_rndc rndc + +_comp_cmd_dig__list_plusopts() +{ + local CMD=${1:-dig} # delv and mdig has similar style options + $CMD -h 2>&1 | awk '/^\s+\+\[no\]/ { sub("+\\[no\\]", "", $1); sub("=##+$", "=", $1); sub("\\[=##+\\]", "", $1); print "+"$1, "+no"$1} /^\s+\+[^[]/ {sub("=##+", "=", $1); print $1}' +} + +_comp_cmd_dig() +{ + local cur prev words cword comp_args + _comp_initialize -n = -- "$@" || return + + case $prev in + -c) + _comp_cmd_nslookup__queryclass + return + ;; + -t) + _comp_cmd_nslookup__querytype + return + ;; + -q) + _comp_compgen_known_hosts -- "$cur" + return + ;; + -k|-f) + _comp_compgen -a filedir + return + ;; + -x|-b) + _comp_compgen_ip_addresses -- "$cur" + return + ;; + esac + + if [[ $cur == @* ]]; then + _comp_compgen_known_hosts -- "$cur" + return + fi + if [[ $cur == -* ]]; then + _comp_compgen_usage + return + fi + if [[ $cur == +* ]]; then + _comp_compgen -- -W "$(_comp_cmd_dig__list_plusopts dig)" + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + + fi + + # TODO: dig is tricky. It can accept hostname, queryclass or querytype without any parameter. + # Not sure how to autocomplete all of them. + _comp_compgen_known_hosts -- "$cur" +} && complete -F _comp_cmd_dig dig + +_comp_cmd_mdig() +{ + local cur prev words cword comp_args + _comp_initialize -n = -- "$@" || return + + case $prev in + -c) + _comp_cmd_nslookup__queryclass + return + ;; + -t) + _comp_cmd_nslookup__querytype + return + ;; + -q) + _comp_compgen_known_hosts -- "$cur" + return + ;; + -f) + _comp_compgen -a filedir + return + ;; + -x|-b) + _comp_compgen_ip_addresses -- "$cur" + return + ;; + esac + + if [[ $cur == -* ]]; then + _comp_compgen_usage + return + fi + if [[ $cur == @* ]]; then + _comp_compgen_known_hosts -- "$cur" + return + fi + + if [[ $cur == +* ]]; then + _comp_compgen -- -W "$(_comp_cmd_dig__list_plusopts mdig)" + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + + fi + + # TODO: dig is tricky. It can accept hostname, queryclass or querytype without any parameter. + # Not sure how to autocomplete all of them. + _comp_compgen_known_hosts -- "$cur" +} && complete -F _comp_cmd_mdig mdig + +_comp_cmd_delv() +{ + local cur prev words cword comp_args + _comp_initialize -n = -- "$@" || return + + case $prev in + -c) + _comp_cmd_nslookup__queryclass + return + ;; + -t) + _comp_cmd_nslookup__querytype + return + ;; + -q) + _comp_compgen_known_hosts -- "$cur" + return + ;; + -a) + _comp_compgen -a filedir + return + ;; + -x|-b) + _comp_compgen_ip_addresses -- "$cur" + return + ;; + esac + + if [[ $cur == -* ]]; then + _comp_compgen_usage + return + fi + if [[ $cur == @* ]]; then + _comp_compgen_known_hosts -- "$cur" + return + fi + + if [[ $cur == +* ]]; then + _comp_compgen -- -W "$(_comp_cmd_dig__list_plusopts delv)" + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + + fi + + # TODO: dig is tricky. It can accept hostname, queryclass or querytype without any parameter. + # Not sure how to autocomplete all of them. + _comp_compgen_known_hosts -- "$cur" +} && complete -F _comp_cmd_delv delv + +# ex: filetype=sh From 9c16c3736e64b7b66d54490b6b70e8cdd03c18ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= Date: Tue, 28 Jan 2025 00:21:00 +0100 Subject: [PATCH 2/7] More experimental changes --- completions/bind9 | 50 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/completions/bind9 b/completions/bind9 index 464a1f041b0..ff6377e70b5 100644 --- a/completions/bind9 +++ b/completions/bind9 @@ -6,26 +6,16 @@ _comp_cmd_rndc__list_commands() rndc 2>&1 | awk '/^ / {print $1}' | sort -u } -_comp_cmd_rndc__list_parameters() -{ - local SUBCMD=$1 - rndc 2>&1 | awk "/^ ${SUBCMD} / { print \$2 }" - if [[ $cur == @* ]]; then - _comp_compgen_known_hosts -- "$cur" - return - fi - -} - -# TODO: not used yet, useful for dnssec-signzone etc. _comp_cmd_named_checkconf__list_zones() { named-checkconf -l | awk '{print $1}' } -# TODO: named-rrchecker provides -T -C listings of supported query types. -# should replace _comp_cmd_nslookup__queryclass, _comp_cmd_nslookup__querytype -# when command is present. +_comp_cmd_rndc__list_parameters() +{ + local SUBCMD=$1 + rndc 2>&1 | awk "/^ ${SUBCMD} / { print \$2 }" +} _comp_cmd_rndc() { @@ -37,19 +27,29 @@ _comp_cmd_rndc() _comp_compgen -a filedir return ;; + -s) + _comp_compgen_known_hosts -- "$cur" + return + ;; esac local REPLY _comp_count_args - if [[ $cur == -* ]]; then - _comp_compgen_usage - return - fi if ((REPLY == 1)); then _comp_compgen -- -W "$(_comp_cmd_rndc__list_commands)" fi if ((REPLY == 2)); then - _comp_compgen -- -W "$(_comp_cmd_rndc__list_parameters $prev)" + local PARAMS="$(_comp_cmd_rndc__list_parameters $prev)" + if [[ "$PARAMS" == zone ]]; then + _comp_compgen -- -W "$(_comp_cmd_named_checkconf__list_zones)" + return + else + _comp_compgen -- -W "$PARAMS" + fi + fi + if [[ $cur == -* ]]; then + _comp_compgen_usage + return fi } && complete -F _comp_cmd_rndc rndc @@ -87,14 +87,14 @@ _comp_cmd_dig() ;; esac - if [[ $cur == @* ]]; then - _comp_compgen_known_hosts -- "$cur" - return - fi if [[ $cur == -* ]]; then _comp_compgen_usage return fi + if [[ $cur == @* ]]; then + _comp_compgen_known_hosts -- "$cur" + return + fi if [[ $cur == +* ]]; then _comp_compgen -- -W "$(_comp_cmd_dig__list_plusopts dig)" [[ ${COMPREPLY-} == *= ]] && compopt -o nospace @@ -142,7 +142,6 @@ _comp_cmd_mdig() _comp_compgen_known_hosts -- "$cur" return fi - if [[ $cur == +* ]]; then _comp_compgen -- -W "$(_comp_cmd_dig__list_plusopts mdig)" [[ ${COMPREPLY-} == *= ]] && compopt -o nospace @@ -190,7 +189,6 @@ _comp_cmd_delv() _comp_compgen_known_hosts -- "$cur" return fi - if [[ $cur == +* ]]; then _comp_compgen -- -W "$(_comp_cmd_dig__list_plusopts delv)" [[ ${COMPREPLY-} == *= ]] && compopt -o nospace From 5f9226203f18c310f6adfdf6b89b3ad3f1988592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= Date: Tue, 28 Jan 2025 14:33:58 +0100 Subject: [PATCH 3/7] Review PR changes Partial fixes from review. --- completions/bind9 | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/completions/bind9 b/completions/bind9 index ff6377e70b5..f36bf136e53 100644 --- a/completions/bind9 +++ b/completions/bind9 @@ -24,7 +24,7 @@ _comp_cmd_rndc() case $prev in -c|-k) - _comp_compgen -a filedir + _comp_compgen filedir return ;; -s) @@ -36,15 +36,14 @@ _comp_cmd_rndc() local REPLY _comp_count_args if ((REPLY == 1)); then - _comp_compgen -- -W "$(_comp_cmd_rndc__list_commands)" - fi - if ((REPLY == 2)); then + _comp_compgen_split -- "$(_comp_cmd_rndc__list_commands)" + elif ((REPLY == 2)); then local PARAMS="$(_comp_cmd_rndc__list_parameters $prev)" if [[ "$PARAMS" == zone ]]; then - _comp_compgen -- -W "$(_comp_cmd_named_checkconf__list_zones)" + _comp_compgen_split -- "$(_comp_cmd_named_checkconf__list_zones)" return else - _comp_compgen -- -W "$PARAMS" + _comp_compgen_split -- "$PARAMS" fi fi if [[ $cur == -* ]]; then @@ -55,8 +54,8 @@ _comp_cmd_rndc() _comp_cmd_dig__list_plusopts() { - local CMD=${1:-dig} # delv and mdig has similar style options - $CMD -h 2>&1 | awk '/^\s+\+\[no\]/ { sub("+\\[no\\]", "", $1); sub("=##+$", "=", $1); sub("\\[=##+\\]", "", $1); print "+"$1, "+no"$1} /^\s+\+[^[]/ {sub("=##+", "=", $1); print $1}' + local CMD="${1:-dig}" # delv and mdig has similar style options + "$CMD" -h 2>&1 | awk '/^\s+\+\[no\]/ { sub("+\\[no\\]", "", $1); sub("=##+$", "=", $1); sub("\\[=##+\\]", "", $1); print "+"$1, "+no"$1} /^\s+\+[^[]/ {sub("=##+", "=", $1); print $1}' } _comp_cmd_dig() @@ -78,7 +77,7 @@ _comp_cmd_dig() return ;; -k|-f) - _comp_compgen -a filedir + _comp_compgen filedir return ;; -x|-b) @@ -90,15 +89,13 @@ _comp_cmd_dig() if [[ $cur == -* ]]; then _comp_compgen_usage return - fi - if [[ $cur == @* ]]; then + elif [[ $cur == @* ]]; then _comp_compgen_known_hosts -- "$cur" return - fi - if [[ $cur == +* ]]; then - _comp_compgen -- -W "$(_comp_cmd_dig__list_plusopts dig)" + elif [[ $cur == +* ]]; then + _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts dig)" [[ ${COMPREPLY-} == *= ]] && compopt -o nospace - + return fi # TODO: dig is tricky. It can accept hostname, queryclass or querytype without any parameter. @@ -125,7 +122,7 @@ _comp_cmd_mdig() return ;; -f) - _comp_compgen -a filedir + _comp_compgen filedir return ;; -x|-b) @@ -137,13 +134,11 @@ _comp_cmd_mdig() if [[ $cur == -* ]]; then _comp_compgen_usage return - fi - if [[ $cur == @* ]]; then + elif [[ $cur == @* ]]; then _comp_compgen_known_hosts -- "$cur" return - fi - if [[ $cur == +* ]]; then - _comp_compgen -- -W "$(_comp_cmd_dig__list_plusopts mdig)" + elif [[ $cur == +* ]]; then + _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts mdig)" [[ ${COMPREPLY-} == *= ]] && compopt -o nospace fi @@ -172,7 +167,7 @@ _comp_cmd_delv() return ;; -a) - _comp_compgen -a filedir + _comp_compgen filedir return ;; -x|-b) @@ -190,7 +185,7 @@ _comp_cmd_delv() return fi if [[ $cur == +* ]]; then - _comp_compgen -- -W "$(_comp_cmd_dig__list_plusopts delv)" + _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts delv)" [[ ${COMPREPLY-} == *= ]] && compopt -o nospace fi From 8c1eac94e70582d3846d3d1addae3b1021e81707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= Date: Tue, 28 Jan 2025 15:34:35 +0100 Subject: [PATCH 4/7] Properly use shared xfunc from nslookup and kdig support Adds multiple types specification for dig. It suggests qtypes and query classes (only uppercase!), known hostnames in addition. Add also quite similar support for knot's kdig, which is more or less directl dig alternative. --- completions/bind9 | 80 +++++++++++++++++++++++++++++++++++--------- completions/nslookup | 12 +++---- 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/completions/bind9 b/completions/bind9 index f36bf136e53..9227b83dc11 100644 --- a/completions/bind9 +++ b/completions/bind9 @@ -52,6 +52,7 @@ _comp_cmd_rndc() fi } && complete -F _comp_cmd_rndc rndc +# Generate list of +example opts from dig help, including negative. _comp_cmd_dig__list_plusopts() { local CMD="${1:-dig}" # delv and mdig has similar style options @@ -65,11 +66,11 @@ _comp_cmd_dig() case $prev in -c) - _comp_cmd_nslookup__queryclass + _comp_compgen -x nslookup queryclass return ;; -t) - _comp_cmd_nslookup__querytype + _comp_compgen -x nslookup querytype return ;; -q) @@ -101,6 +102,8 @@ _comp_cmd_dig() # TODO: dig is tricky. It can accept hostname, queryclass or querytype without any parameter. # Not sure how to autocomplete all of them. _comp_compgen_known_hosts -- "$cur" + _comp_compgen -x nslookup queryclass + _comp_compgen -x nslookup querytype } && complete -F _comp_cmd_dig dig _comp_cmd_mdig() @@ -110,11 +113,11 @@ _comp_cmd_mdig() case $prev in -c) - _comp_cmd_nslookup__queryclass + _comp_compgen -x nslookup queryclass return ;; -t) - _comp_cmd_nslookup__querytype + _comp_compgen -x nslookup querytype return ;; -q) @@ -140,12 +143,12 @@ _comp_cmd_mdig() elif [[ $cur == +* ]]; then _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts mdig)" [[ ${COMPREPLY-} == *= ]] && compopt -o nospace - + return fi - # TODO: dig is tricky. It can accept hostname, queryclass or querytype without any parameter. - # Not sure how to autocomplete all of them. _comp_compgen_known_hosts -- "$cur" + _comp_compgen -x nslookup queryclass + _comp_compgen -x nslookup querytype } && complete -F _comp_cmd_mdig mdig _comp_cmd_delv() @@ -155,11 +158,11 @@ _comp_cmd_delv() case $prev in -c) - _comp_cmd_nslookup__queryclass + _comp_compgen -x nslookup queryclass return ;; -t) - _comp_cmd_nslookup__querytype + _comp_compgen -x nslookup querytype return ;; -q) @@ -179,20 +182,65 @@ _comp_cmd_delv() if [[ $cur == -* ]]; then _comp_compgen_usage return - fi - if [[ $cur == @* ]]; then + elif [[ $cur == @* ]]; then _comp_compgen_known_hosts -- "$cur" return - fi - if [[ $cur == +* ]]; then + elif [[ $cur == +* ]]; then _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts delv)" [[ ${COMPREPLY-} == *= ]] && compopt -o nospace - + return fi - # TODO: dig is tricky. It can accept hostname, queryclass or querytype without any parameter. - # Not sure how to autocomplete all of them. _comp_compgen_known_hosts -- "$cur" + _comp_compgen -x nslookup queryclass + _comp_compgen -x nslookup querytype } && complete -F _comp_cmd_delv delv +# kdig is provided by knot-utils, but is more or less a drop-in replacement for dig +# Reuse common parts for it too. +_comp_cmd_kdig() +{ + local cur prev words cword comp_args + _comp_initialize -n = -- "$@" || return + + case $prev in + -c) + _comp_compgen -x nslookup queryclass + return + ;; + -t) + _comp_compgen -x nslookup querytype + return + ;; + -q) + _comp_compgen_known_hosts -- "$cur" + return + ;; + -k|-E|-G) + _comp_compgen filedir + return + ;; + -x|-b) + _comp_compgen_ip_addresses -- "$cur" + return + ;; + esac + + if [[ $cur == -* ]]; then + _comp_compgen_usage + return + elif [[ $cur == @* ]]; then + _comp_compgen_known_hosts -- "$cur" + return + elif [[ $cur == +* ]]; then + _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts kdig)" + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _comp_compgen_known_hosts -- "$cur" + _comp_compgen -x nslookup queryclass + _comp_compgen -x nslookup querytype +} && complete -F _comp_cmd_kdig kdig + # ex: filetype=sh diff --git a/completions/nslookup b/completions/nslookup index b04b03a4904..d965a9390a4 100644 --- a/completions/nslookup +++ b/completions/nslookup @@ -1,11 +1,11 @@ # bash completion for nslookup -*- shell-script -*- -_comp_cmd_nslookup__queryclass() +_comp_xfunc_nslookup_compgen_queryclass() { _comp_compgen -a -- -W 'IN CH HS ANY' } -_comp_cmd_nslookup__querytype() +_comp_xfunc_nslookup_compgen_querytype() { # https://en.wikipedia.org/wiki/List_of_DNS_record_types # Resource records @@ -31,12 +31,12 @@ _comp_cmd_nslookup() case $cur in -class=* | -cl=*) cur=${cur#*=} - _comp_cmd_nslookup__queryclass + _comp_xfunc_nslookup_compgen_queryclass return ;; -querytype=* | -type=* | -q=* | -ty=*) cur=${cur#*=} - _comp_cmd_nslookup__querytype + _comp_xfunc_nslookup_compgen_querytype return ;; -?*=*) @@ -68,11 +68,11 @@ _comp_cmd_host() case $prev in -c) - _comp_cmd_nslookup__queryclass + _comp_xfunc_nslookup_compgen_queryclass return ;; -t) - _comp_cmd_nslookup__querytype + _comp_xfunc_nslookup_compgen_querytype return ;; -m) From 8f3a03921433313eb7c1d23cb96624ddb27be74f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= Date: Tue, 28 Jan 2025 20:45:08 +0100 Subject: [PATCH 5/7] Reduce some repetitions for dig and similar Except kdig, they have different parameters presentation. Use simple awk to print parameters offered. --- completions/bind9 | 98 ++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 60 deletions(-) diff --git a/completions/bind9 b/completions/bind9 index 9227b83dc11..3ebb5c2aadd 100644 --- a/completions/bind9 +++ b/completions/bind9 @@ -55,8 +55,40 @@ _comp_cmd_rndc() # Generate list of +example opts from dig help, including negative. _comp_cmd_dig__list_plusopts() { - local CMD="${1:-dig}" # delv and mdig has similar style options - "$CMD" -h 2>&1 | awk '/^\s+\+\[no\]/ { sub("+\\[no\\]", "", $1); sub("=##+$", "=", $1); sub("\\[=##+\\]", "", $1); print "+"$1, "+no"$1} /^\s+\+[^[]/ {sub("=##+", "=", $1); print $1}' + local cmd="${1:-dig}" # delv and mdig has similar style options + "$cmd" -h 2>&1 | awk '/^\s+\+\[no\]/ { sub("+\\[no\\]", "", $1); sub("=##+$", "=", $1); sub("\\[=##+\\]", "", $1); print "+"$1, "+no"$1} /^\s+\+[^[]/ {sub("=##+", "=", $1); print $1}' +} + +# Extract dig -parameters list, modified version of _comp_compgen_help +_comp_cmd_dig__help_params() +{ + local cmd="$1" + "$cmd" -h 2>&1 | awk '/^\s+-[a-z0-9]\s/ {print $1}' +} + +# Implements common dig usage patterns +_comp_cmd_dig__common() +{ + local cmd="$1" + local cur="$2" + shift + shift + + if [[ $cur == -* ]]; then + _comp_compgen_split -- "$(_comp_cmd_dig__help_params "$cmd")" + return + elif [[ $cur == @* ]]; then + _comp_compgen_known_hosts -- "$cur" + return + elif [[ $cur == +* ]]; then + _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts "$cmd")" + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _comp_compgen_known_hosts -- "$cur" + _comp_compgen -x nslookup queryclass + _comp_compgen -x nslookup querytype } _comp_cmd_dig() @@ -87,23 +119,7 @@ _comp_cmd_dig() ;; esac - if [[ $cur == -* ]]; then - _comp_compgen_usage - return - elif [[ $cur == @* ]]; then - _comp_compgen_known_hosts -- "$cur" - return - elif [[ $cur == +* ]]; then - _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts dig)" - [[ ${COMPREPLY-} == *= ]] && compopt -o nospace - return - fi - - # TODO: dig is tricky. It can accept hostname, queryclass or querytype without any parameter. - # Not sure how to autocomplete all of them. - _comp_compgen_known_hosts -- "$cur" - _comp_compgen -x nslookup queryclass - _comp_compgen -x nslookup querytype + _comp_cmd_dig__common dig "$cur" "$@" } && complete -F _comp_cmd_dig dig _comp_cmd_mdig() @@ -134,21 +150,7 @@ _comp_cmd_mdig() ;; esac - if [[ $cur == -* ]]; then - _comp_compgen_usage - return - elif [[ $cur == @* ]]; then - _comp_compgen_known_hosts -- "$cur" - return - elif [[ $cur == +* ]]; then - _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts mdig)" - [[ ${COMPREPLY-} == *= ]] && compopt -o nospace - return - fi - - _comp_compgen_known_hosts -- "$cur" - _comp_compgen -x nslookup queryclass - _comp_compgen -x nslookup querytype + _comp_cmd_dig__common mdig "$cur" "$@" } && complete -F _comp_cmd_mdig mdig _comp_cmd_delv() @@ -179,21 +181,7 @@ _comp_cmd_delv() ;; esac - if [[ $cur == -* ]]; then - _comp_compgen_usage - return - elif [[ $cur == @* ]]; then - _comp_compgen_known_hosts -- "$cur" - return - elif [[ $cur == +* ]]; then - _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts delv)" - [[ ${COMPREPLY-} == *= ]] && compopt -o nospace - return - fi - - _comp_compgen_known_hosts -- "$cur" - _comp_compgen -x nslookup queryclass - _comp_compgen -x nslookup querytype + _comp_cmd_dig__common delv "$cur" "$@" } && complete -F _comp_cmd_delv delv # kdig is provided by knot-utils, but is more or less a drop-in replacement for dig @@ -229,18 +217,8 @@ _comp_cmd_kdig() if [[ $cur == -* ]]; then _comp_compgen_usage return - elif [[ $cur == @* ]]; then - _comp_compgen_known_hosts -- "$cur" - return - elif [[ $cur == +* ]]; then - _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts kdig)" - [[ ${COMPREPLY-} == *= ]] && compopt -o nospace - return fi - - _comp_compgen_known_hosts -- "$cur" - _comp_compgen -x nslookup queryclass - _comp_compgen -x nslookup querytype + _comp_cmd_dig__common kdig "$cur" "$@" } && complete -F _comp_cmd_kdig kdig # ex: filetype=sh From 2c119dc534b8178f3809661de81a9b98cc405f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= Date: Tue, 28 Jan 2025 21:06:39 +0100 Subject: [PATCH 6/7] Adjust to coding style Use more hints from PR, use existing help with specified parameter. --- completions/bind9 | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/completions/bind9 b/completions/bind9 index 3ebb5c2aadd..b68fb68a812 100644 --- a/completions/bind9 +++ b/completions/bind9 @@ -24,7 +24,7 @@ _comp_cmd_rndc() case $prev in -c|-k) - _comp_compgen filedir + _comp_compgen_filedir return ;; -s) @@ -59,13 +59,6 @@ _comp_cmd_dig__list_plusopts() "$cmd" -h 2>&1 | awk '/^\s+\+\[no\]/ { sub("+\\[no\\]", "", $1); sub("=##+$", "=", $1); sub("\\[=##+\\]", "", $1); print "+"$1, "+no"$1} /^\s+\+[^[]/ {sub("=##+", "=", $1); print $1}' } -# Extract dig -parameters list, modified version of _comp_compgen_help -_comp_cmd_dig__help_params() -{ - local cmd="$1" - "$cmd" -h 2>&1 | awk '/^\s+-[a-z0-9]\s/ {print $1}' -} - # Implements common dig usage patterns _comp_cmd_dig__common() { @@ -75,12 +68,15 @@ _comp_cmd_dig__common() shift if [[ $cur == -* ]]; then - _comp_compgen_split -- "$(_comp_cmd_dig__help_params "$cmd")" + _comp_compgen_help -- -h return elif [[ $cur == @* ]]; then _comp_compgen_known_hosts -- "$cur" return elif [[ $cur == +* ]]; then + if [[ $cur == *= ]]; then + return + fi _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts "$cmd")" [[ ${COMPREPLY-} == *= ]] && compopt -o nospace return @@ -110,7 +106,7 @@ _comp_cmd_dig() return ;; -k|-f) - _comp_compgen filedir + _comp_compgen_filedir return ;; -x|-b) @@ -141,7 +137,7 @@ _comp_cmd_mdig() return ;; -f) - _comp_compgen filedir + _comp_compgen_filedir return ;; -x|-b) @@ -172,7 +168,7 @@ _comp_cmd_delv() return ;; -a) - _comp_compgen filedir + _comp_compgen_filedir return ;; -x|-b) @@ -205,7 +201,7 @@ _comp_cmd_kdig() return ;; -k|-E|-G) - _comp_compgen filedir + _comp_compgen_filedir return ;; -x|-b) From 56685610a260bdf9d989c6f8d2e42387a9e7be4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= Date: Tue, 28 Jan 2025 21:27:41 +0100 Subject: [PATCH 7/7] Use local variables inheritance Selected local variables from caller functions are accessible in nested functions, no need to pass them inside. Pass just remaining parameters. --- completions/bind9 | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/completions/bind9 b/completions/bind9 index b68fb68a812..51791763035 100644 --- a/completions/bind9 +++ b/completions/bind9 @@ -55,18 +55,12 @@ _comp_cmd_rndc() # Generate list of +example opts from dig help, including negative. _comp_cmd_dig__list_plusopts() { - local cmd="${1:-dig}" # delv and mdig has similar style options - "$cmd" -h 2>&1 | awk '/^\s+\+\[no\]/ { sub("+\\[no\\]", "", $1); sub("=##+$", "=", $1); sub("\\[=##+\\]", "", $1); print "+"$1, "+no"$1} /^\s+\+[^[]/ {sub("=##+", "=", $1); print $1}' + "${comp_args[0]}" -h 2>&1 | awk '/^\s+\+\[no\]/ { sub("+\\[no\\]", "", $1); sub("=##+$", "=", $1); sub("\\[=##+\\]", "", $1); print "+"$1, "+no"$1} /^\s+\+[^[]/ {sub("=##+", "=", $1); print $1}' } # Implements common dig usage patterns _comp_cmd_dig__common() { - local cmd="$1" - local cur="$2" - shift - shift - if [[ $cur == -* ]]; then _comp_compgen_help -- -h return @@ -77,7 +71,7 @@ _comp_cmd_dig__common() if [[ $cur == *= ]]; then return fi - _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts "$cmd")" + _comp_compgen_split -- "$(_comp_cmd_dig__list_plusopts)" [[ ${COMPREPLY-} == *= ]] && compopt -o nospace return fi @@ -115,7 +109,7 @@ _comp_cmd_dig() ;; esac - _comp_cmd_dig__common dig "$cur" "$@" + _comp_cmd_dig__common "$@" } && complete -F _comp_cmd_dig dig _comp_cmd_mdig() @@ -146,7 +140,7 @@ _comp_cmd_mdig() ;; esac - _comp_cmd_dig__common mdig "$cur" "$@" + _comp_cmd_dig__common "$@" } && complete -F _comp_cmd_mdig mdig _comp_cmd_delv() @@ -177,7 +171,7 @@ _comp_cmd_delv() ;; esac - _comp_cmd_dig__common delv "$cur" "$@" + _comp_cmd_dig__common "$@" } && complete -F _comp_cmd_delv delv # kdig is provided by knot-utils, but is more or less a drop-in replacement for dig @@ -214,7 +208,7 @@ _comp_cmd_kdig() _comp_compgen_usage return fi - _comp_cmd_dig__common kdig "$cur" "$@" + _comp_cmd_dig__common "$@" } && complete -F _comp_cmd_kdig kdig # ex: filetype=sh