Skip to content

fix: add misc fixes before _parse_{help,usage} changes #950

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 3, 2023
6 changes: 3 additions & 3 deletions completions/_adb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

_comp_cmd_adb__command_usage()
{
COMPREPLY=($(compgen -W \
'$("$1" help 2>&1 | command grep "^ *\(adb \)\? *$2 " \
| command sed -e "s/[]|[]/\n/g" | _parse_help -)' -- "$cur"))
COMPREPLY=($(compgen -W '$("$1" help 2>&1 | \
command sed -e "/^ *\(adb \)\{0,1\} *$2 /!d;s/[]|[]/\n/g" | \
_parse_help -)' -- "$cur"))
}

_comp_cmd_adb()
Expand Down
4 changes: 2 additions & 2 deletions completions/_udevadm
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ _comp_cmd_udevadm()
local cur prev words cword was_split comp_args
_comp_initialize -s -- "$@" || return

local i udevcmd has_udevcmd=""
local i udevcmd="" has_udevcmd=""
for ((i = 1; i < cword; i++)); do
if [[ ${words[i]} != -* ]]; then
udevcmd=${words[i]}
Expand Down Expand Up @@ -69,7 +69,7 @@ _comp_cmd_udevadm()

if [[ $cur == -* ]]; then
COMPREPLY=($(compgen -W \
'$("$1" ${udevcmd-} --help 2>/dev/null | _parse_help -)' -- "$cur"))
'$(_parse_help "$1" "${udevcmd-} --help")' -- "$cur"))
[[ ${COMPREPLY-} == *= ]] && compopt -o nospace
fi
} &&
Expand Down
2 changes: 1 addition & 1 deletion completions/badblocks
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ _comp_cmd_badblocks()

if [[ $cur == -* ]]; then
# Filter out -w (dangerous) and -X (internal use)
COMPREPLY=($(compgen -X -[wX] -W '$(_parse_usage "$1")' -- "$cur"))
COMPREPLY=($(compgen -X '-[wX]' -W '$(_parse_usage "$1")' -- "$cur"))
return
fi

Expand Down
2 changes: 1 addition & 1 deletion completions/complete
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ _comp_cmd_complete()
local -a opts=($(compgen -W '$(_parse_usage help "-s $1")' -- "$cur"))
# -F, -C do not work the expected way with compgen
[[ $1 != *compgen ]] || opts=("${opts[@]//-[FC]/}")
COMPREPLY=($(compgen -W '"${opts[@]}"' -- "$cur"))
COMPREPLY=($(compgen -W '"${opts[@]}"' -X '' -- "$cur"))
else
COMPREPLY=($(compgen -A command -- "$cur"))
fi
Expand Down
14 changes: 9 additions & 5 deletions completions/gnokii
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,18 @@ _comp_cmd_gnokii()
esac
fi

# safer to use LANG=C
local all_cmd="$(LANG=C _parse_help "$1" "--help all")"
# these 2 below are allowed in combination with others
local main_cmd=$(command grep -v -- '--config\|--phone' <<<"$all_cmd")
local all_cmd="$(_parse_help "$1" "--help all")"

# these 2 below are allowed in combination with others
local main_cmd
_comp_split -l main_cmd "$(command sed -e '/--config/d;/--phone/d' -e \
's/[][\(){}|^$*+?.]/\\&/g' <<<"$all_cmd")"
# don't provide main command completions if one is
# already on the command line
[[ $COMP_LINE =~ $(tr ' ' '\b|' <<<"$main_cmd") ]] && return
local IFS='|'
local regex_main_cmd="(${main_cmd[*]})($|[^_[:alnum:]])"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this could end up as an invalid regex if _parse_help lets any strings through to main_cmd that make it so. The previous implementation had the same issue though, so not a regression. Leaving up to you to decide whether to address or merge as is.

Some array utilities would be nice to help with cases like this. I have this ages old unfinished patch for the main bash_completion in my stash, probably broken in the first place and uses namerefs so requires bash >= 4.3, but to illustrate what I was thinking back $then

+_bashcomp_uniq()
+{
+    local -n _bashcomp_uniq_array_=$1
+    local -A tmp
+    local -i i
+    for i in ${!_bashcomp_uniq_array_[*]}; do
+        (( tmp["${_bashcomp_uniq_array_[i]}"]++ > 0 )) &&
+            unset '_bashcomp_uniq_array_[i]'
+    done
+}
+
+_bashcomp_last_index() {
+    local -n _bashcomp_last_index_array_=$1 _bashcomp_last_index_ret_=$2
+    local -i i
+    for i in ${!_bashcomp_last_index_array_[*]}; do :; done
+    _bashcomp_last_index_ret_=$i
+}
+
+_bashcomp_compact() {
+    local -n _bashcomp_compact_array_=$1
+    local i j=0
+
+    for i in ${!_bashcomp_compact_array_[*]}; do
+        if (( i > j )); then
+            _bashcomp_compact_array_[j]="${_bashcomp_compact_array_[i]}"
+            unset "_bashcomp_compact_array_[i]"
+        fi
+        (( j++ ))
+    done
+}
+
+_bashcomp_index_of() {
+    # TODO getopts -> -r gets rightmost (last) index
+    # TODO getopts: -R uses regex instead of glob
+    local -n _bashcomp_index_of_array_=$1
+    local pattern=$2
+    local -n _bashcomp_index_of_ret_=$3
+
+    local -i i
+    for i in ${!_bashcomp_index_of_array_[*]}; do
+        # shellcheck disable=SC2053
+        if [[ ${_bashcomp_index_of_array_[i]} == $pattern ]]; then
+            _bashcomp_index_of_ret_=$i
+            return 0
+        fi
+    done
+
+    _bashcomp_index_of_ret_=-1
+    return 1
+}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this could end up as an invalid regex if _parse_help lets any strings through to main_cmd that make it so. The previous implementation had the same issue though, so not a regression. Leaving up to you to decide whether to address or merge as is.

OK, I think I can try to escape special characters in sed in the previous line.

Some array utilities would be nice to help with cases like this. I have this ages old unfinished patch for the main bash_completion in my stash, probably broken in the first place and uses namerefs so requires bash >= 4.3, but to illustrate what I was thinking back $then

Thank you for the suggestion. In this case, I indeed wanted to have something like remove and join (like _comp_array_remove main_cmd '--config' '--phone' and _comp_join '|' "${main_cmd[@]}"). The suggested uniq, last_index, compact, and index_of do not seem to be specifically able to be used for the present case, but I guess your idea is to give names to array manipulations as independent functions.

This might also be related to the discussion of _comp_xfunc_ARRAY_filter in #739.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a2d756e that escapes the ERE special characters.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array utilities are moved to #953

IFS=$' \t\n'
[[ $COMP_LINE =~ $regex_main_cmd ]] && return

COMPREPLY=($(compgen -W "$all_cmd" -- "$cur"))
} &&
Expand Down
7 changes: 2 additions & 5 deletions completions/postfix
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@ _comp_cmd_postfix()
esac

if [[ $cur == -* ]]; then
COMPREPLY=($(
compgen -W \
'$(_bashcomp_try_faketty "$1" --help 2>&1 | _parse_usage -)' \
-- "$cur"
))
COMPREPLY=($(compgen -W \
'$(_parse_usage _bashcomp_try_faketty "$1 --help")' -- "$cur"))
return
fi

Expand Down