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

📺 Add zsh completions #514

Open
wants to merge 2 commits into
base: main
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
1 change: 1 addition & 0 deletions Homebrew/mas-tap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def install

bash_completion.install "contrib/completion/mas-completion.bash" => "mas"
fish_completion.install "contrib/completion/mas.fish"
zsh_completion.install "contrib/completion/mas-completion.zsh" => "_mas"
end

test do
Expand Down
1 change: 1 addition & 0 deletions Homebrew/mas.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def install

bash_completion.install "contrib/completion/mas-completion.bash" => "mas"
fish_completion.install "contrib/completion/mas.fish"
zsh_completion.install "contrib/completion/mas-completion.zsh" => "_mas"
end

test do
Expand Down
172 changes: 172 additions & 0 deletions contrib/completion/mas-completion.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
#compdef mas
Logicer16 marked this conversation as resolved.
Show resolved Hide resolved
_mas() {
local ret=1

_arguments -C \
'1: :__mas_subcommands' \
'*::arg:->args' && ret=0

case "$state" in
Logicer16 marked this conversation as resolved.
Show resolved Hide resolved
args)
case ${words[1]} in
help)
_arguments -C \
'1:: :__mas_subcommands' \
&& ret=0
;;
home|info|open|vendor)
Logicer16 marked this conversation as resolved.
Show resolved Hide resolved
Logicer16 marked this conversation as resolved.
Show resolved Hide resolved
_arguments -C \
'1:availableIDs:__mas_list_installed_ids' \
&& ret=0
;;
install)
_arguments -C \
'--force[Force reinstall]' \
'*:availableIDs:' \
&& ret=0
;;
purchase)
_arguments -C \
'*:availableIDs:' \
&& ret=0
;;
lucky)
_arguments -C \
'--force[Force reinstall]' \
'1:name:__mas_list_available_names' \
&& ret=0
;;
reset)
_arguments -C \
'--debug[Enable debug mode]' \
&& ret=0
;;
search)
_arguments -C \
'--price[Show price of found apps]' \
'1:name:__mas_list_available_names' \
&& ret=0
;;
signin)
_arguments -C \
'--dialog[Complete login with graphical dialog]' \
'1:AppleID:' \
'2::password:' \
&& ret=0
;;
uninstall)
_arguments -C \
'--dry-run[Dry run]' \
'1:installedIDs:__mas_list_installed_ids' \
&& ret=0
;;
upgrade)
_arguments -C \
'*:app:__mas_list_outdated' \
&& ret=0
;;
account|list|outdated|signout|version)
ret=0
;;
*)
(( ret )) && _message 'No more arguments'
;;
esac
;;
esac

return $ret
}

__mas_subcommands() {
local -a commands=(
Logicer16 marked this conversation as resolved.
Show resolved Hide resolved
'account:Prints the primary account Apple ID'
'help:Display general or command-specific help'
'home:Opens MAS Preview app page in a browser'
'info:Display app information from the Mac App Store'
'install:Install from the Mac App Store'
'list:Lists apps from the Mac App Store which are currently installed'
'lucky:Install the first result from the Mac App Store'
'open:Opens app page in AppStore.app'
'outdated:Lists pending updates from the Mac App Store'
'purchase:Purchase and download free apps from the Mac App Store'
'reset:Resets the Mac App Store'
'search:Search for apps from the Mac App Store'
'signin:Sign in to the Mac App Store'
'signout:Sign out of the Mac App Store'
'uninstall:Uninstall app installed from the Mac App Store'
'upgrade:Upgrade outdated apps from the Mac App Store'
"vendor:Opens vendor's app page in a browser"
'version:Print version number'
)

_describe -t commands 'command' commands "$@"
}

__mas_list_available_names() {
_alternative \
'searchedNames:apps:__mas_search_names' \
'installedNames:apps:__mas_list_installed_names'
}

# Autocomplete for the names returned by searching for the current word
__mas_search_names() {
# Don't search if no query has been entered
[[ -z "${(Q)words[-1]}" ]] && return

local -a searchNames=("${(f)"$(__mas_filter_names "$(mas search ${(Q)words[-1]} 2>/dev/null)")"}")
_describe -t searchNames 'search' searchNames "$@"
}

# Autocomplete for the names of installed apps
__mas_list_installed_names() {
local -a installedNames=("${(f)"$(__mas_filter_names "$(mas list 2>/dev/null)")"}")
_describe -t installedNames 'installed' installedNames "$@"
}

# Autocomplete for the ids of installed apps
__mas_list_installed_ids() {
local -A installedApps=("${(f)"$(__mas_filter_descriptive_ids "$(mas list 2>/dev/null)")"}")
local -a installedIDs=("${(f)"$(printf '%s:%s\n' "${(@kv)installedApps}")"}")
_describe -t installedIDs 'installed' installedIDs "$@"
}

# Autocomplete for the ids or names of installed apps
__mas_list_outdated() {
rgoldberg marked this conversation as resolved.
Show resolved Hide resolved
local -A unfilteredOutdated=(
"${(f)"$(__mas_filter_descriptive_ids "$(mas outdated 2>/dev/null)")"}"
)

# Exclude apps which have already been stated
local -a previousApps=(${(Q@)words:1})
local -a outdated=()

for id name in ${(kv)unfilteredOutdated}; do
rgoldberg marked this conversation as resolved.
Show resolved Hide resolved
local -a searchValues=( "$id" "$name" )
[[ ${#previousApps:*searchValues} == 0 ]] && outdated+=( "$id:$name" "$name" )
done

_describe -t outdated 'outdated' outdated "$@"
}

# Extract app names
__mas_filter_names() {
local -A apps=("${(f)$(__mas_filter_descriptive_ids "$1")}")
printf "${(F)apps}"
}

# Extract app ids as an alternating, new-line seperated list of id and name, designed to be used to create an associative array.
__mas_filter_descriptive_ids() {
printf ${(QF)${(*fqqq)"$(__mas_isolate_id_and_name "$1")"}/ ##/\\n}
}

# Remove leading spaces and the trailing version from the list of apps returned by mas
__mas_isolate_id_and_name() {
printf ${(*F)${${(*@)${(f)1}%% ##\([^(]##}//:/\\:}## ##}
}

if [[ $zsh_eval_context[-1] == loadautofunc ]]; then
Logicer16 marked this conversation as resolved.
Show resolved Hide resolved
_mas "$@"
else
compdef _mas 'mas'
fi