Skip to content
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

Bash completions #4

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions zyp-bash-completions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# zypper bash completion script
#
# A hackweek gift from Marek Stopka <[email protected]>
# Major rewrite by Josef Reidinger <[email protected]>
# 2009-02-19 Allow empty spaces in repos names, Werner Fink <[email protected]>
# 2015-04-26 add completion for install+remove+update commands, Bernhard M. Wiedemann <[email protected]>
#

_strip()
{
local s c o
if test ${#COMPREPLY[@]} -gt 0 ; then
s="${COMP_WORDBREAKS// }"
s="${s// }"
s="${s//[\{\}()\[\]]}"
s="${s} (){}[]"
o=${#s}
while test $((o--)) -gt 0 ; do
c="${s:${o}:1}"
COMPREPLY=(${COMPREPLY[*]//${c}/\\${c}})
done
fi
}

_installed_packages() {
! [[ $cur =~ / ]] || return
grep -s --no-filename "^$cur" "/var/cache/zypp/solv/@System/solv.idx" | cut -f1
}

_available_solvables2() {
local lcur=$1
! [[ $cur =~ / ]] || return # for installing local packages
set +o noglob
grep -s --no-filename "^$lcur" /var/cache/zypp/solv/*/solv.idx |\
cut -f1 | sort --unique
set -o noglob
}
_available_solvables() {
_available_solvables2 "$1:$cur" | sed -e "s/^$1://"
}
_available_packages() {
[[ $cur ]] || return # this case is too slow with tenthousands of completions
_available_solvables2 $cur
}

_zyp() {
ZYPPER="$(type -P zypper)"

local noglob=$(shopt -po noglob)
local comp cur prev command
local -a opts=()
local -i ITER=0
local IFS=$'\n'

# Do not expand `?' for help
set -o noglob

if test ${#ZYPPER_CMDLIST[@]} -eq 0; then
ZYPPER_CMDLIST=($(
{
zypper -q subcommand;
LC_ALL=POSIX zypper -q -h | sed -n '/[Cc]ommands:$/,$ s/^ \{6\}\([^ ,]\+\(,[ *][^ ,]\+\)*\).*/\1/p';
} | sed 's/, */\n/g'
))
fi

if test $COMP_CWORD -lt 1 ; then
let COMP_CWORD=${#COMP_WORDS[@]}
fi
prev=${COMP_WORDS[COMP_CWORD-1]}
cur=${COMP_WORDS[COMP_CWORD]}

let ITER=COMP_CWORD
while test $((ITER--)) -ge 0 ; do
comp="${COMP_WORDS[ITER]}"
# bsc#1049826 - surrounding ' 's are important to get a word-match of ${comp}:
if [[ " ${ZYPPER_CMDLIST[@]} " =~ " ${comp} " ]]; then
command=${COMP_WORDS[ITER]}
break;
fi
if [[ "${comp}" =~ "zypper" ]]; then
command="zypper"
break;
fi
done
unset ITER comp

case "$prev" in
"--type" | "-t")
opts=(package patch pattern product srcpackage)
COMPREPLY=($(compgen -W "${opts[*]}" -- ${cur}))
_strip
eval $noglob
return 0;
;;
"--repo" | "-r" | "--from")
opts=(${opts[@]}$(echo; LC_ALL=POSIX $ZYPPER -q lr | \
sed -rn '/^[0-9]/{
s/^[0-9]+[[:blank:]]*\|[[:blank:]]*([^|]+).*/\1/
s/[[:blank:]]*$//
p
}'))
COMPREPLY=($(compgen -W "${opts[*]}" -- ${cur}))
_strip
eval $noglob
return 0;
;;
esac
unset prev

if [[ "$command" =~ "zypper" ]]; then
opts=(${ZYPPER_CMDLIST[*]}$(echo; LC_ALL=POSIX $ZYPPER -q help 2>&1 | \
sed -n '/[Oo]ptions:$/,/[Cc]ommands:$/ s/^[[:blank:]]*\(--[^[:blank:],[]*\).*/\1/p'))
COMPREPLY=($(compgen -W "${opts[*]}" -- ${cur}))
_strip
eval $noglob
return 0;
fi

if test -n "$command" ; then
if ! [[ $cur =~ ^[^-] ]] ; then
opts=$(LC_ALL=POSIX $ZYPPER -q help $command 2>&1 | sed -n '1,/[Oo]ptions:$/d; s/^[[:blank:]]*\(-[^-]*\)\?\(--[^[:blank:][]*\).*/\2/p')
fi

#handling individual commands if they need more then we can dig from help
if ! [[ $cur =~ ^- ]] ; then
case "$command" in
help | \?)
opts=(${ZYPPER_CMDLIST[@]})
;;
removerepo | rr | modifyrepo | mr | renamerepo | nr | refresh | ref)
opts=(${opts[@]}$(echo; LC_ALL=POSIX $ZYPPER -q lr | \
sed -rn '/^[0-9]/{
s/^[0-9]+[[:blank:]]*\|[[:blank:]]*([^|]+).*/\1/
s/[[:blank:]]*$//
/^$/d
p
}'))
;;
addservice | as | modifyservice | ms | removeservice | rs)
opts=(${opts[@]}$(echo; LC_ALL=POSIX $ZYPPER -q ls | \
sed -rn '/^[0-9]/{
s/^[0-9]+[[:blank:]]*\|[[:blank:]]*([^|]+).*/\1/
s/[[:blank:]]*$//
/^$/d
p
}'))
;;
removelock | rl)
opts=(${opts[@]}$(echo; LC_ALL=POSIX $ZYPPER -q ll | \
sed -rn '/^[0-9]/{
s/^[0-9]+[[:blank:]]*\|[[:blank:]]*([^|]+).*/\1/p
s/[[:blank:]]*$//
/^$/d
p
}'))
;;
product-info)
opts=(${opts[@]}$(echo; _available_solvables product ))
;;
pattern-info)
opts=(${opts[@]}$(echo; _available_solvables pattern ))
;;
patch-info )
opts=(${opts[@]}$(echo; _available_solvables patch ))
;;
remove | rm | update | up | ch | changes | lf | list-files )
opts=(${opts[@]}$(echo; _installed_packages ))
;;
install | lin | local-install | in | source-install | si | download | info | if | addlock | al)
opts=(${opts[@]}$(echo; _available_packages ))
;;
esac
fi
IFS=$'\n'
COMPREPLY=($(compgen -W "${opts[*]}" -- ${cur}))
_strip
fi
eval $noglob
}

complete -F _zyp -o default zyp
24 changes: 23 additions & 1 deletion zyp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ printf '%s\n' "
orphaned, or Lists installed packages which no longer have a repository associated with them.
'--list or -l' may be used to list only the package names.
'--remove or -r' may be used to remove all orphaned packages (USE WITH CAUTION).
unneeded, un Lists installed packages which may no longer be needed.
'--list' or '-l' may be used to list only the package names.
'--remove' or '-r' may be used to remove all unneeded packages (USE WITH CAUTION).
"
}

Expand Down Expand Up @@ -524,6 +527,26 @@ case "$1" in
;;
esac
;;
un|unneeded)
case "$2" in
# list orphaned packages separated by spaces
-l|--list) zypper --no-color --no-refresh -q pa --unneeded | tail -n +3 | cut -f3 -d'|' | tr -d ' ' | tr '\n' ' '; echo;;
# prompt to remove all orphaned packages
-r|--remove) sudo zypper --no-refresh rm -u $(zypper --no-color --no-refresh -q pa --unneeded | tail -n +3 | cut -f3 -d'|' | tr -d ' ' | tr '\n' ' ');;
# list orphaned packages in similar fashion to search output
*)
zypper --no-color --no-refresh -q pa --unneeded | tail -n +3 > "$HOME"/.cache/zyp/zypunneeded.txt
for package in $(cat "$HOME"/.cache/zyp/zypunneeded.txt | cut -f3 -d'|' | tr -d ' '); do
echo "$(tput setaf $COLOR_INFO)Name: $(cat "$HOME"/.cache/zyp/zypunneeded.txt | grep -w "$package" | cut -f3 -d'|' | tr -d ' ')$(tput sgr0)"
echo "Status: $(cat "$HOME"/.cache/zyp/zypunneeded.txt | grep -w "$package" | cut -f1 -d'|' | tr -d ' ')"
echo "Version: $(cat "$HOME"/.cache/zyp/zypunneeded.txt | grep -w "$package" | cut -f4 -d'|' | tr -d ' ')"
echo "Arch: $(cat "$HOME"/.cache/zyp/zypunneeded.txt | grep -w "$package" | cut -f5 -d'|' | tr -d ' ')"
echo "Repo: $(cat "$HOME"/.cache/zyp/zypunneeded.txt | grep -w "$package" | cut -f2 -d'|' | tr -d ' ')"
done
rm -f "$HOME"/.cache/zyp/zypunneeded.txt
;;
esac
;;
# --no-refresh to save time
pa|packages) zypper --no-refresh "$@";;
# use rpm to get changelog for installed packages
Expand Down Expand Up @@ -571,4 +594,3 @@ case "$1" in
esac
;;
esac