lib/mix/complete/zsh.ex
defmodule Mix.Tasks.Complete.Zsh do
use Mix.Task
@shortdoc "Output zsh completion source for mix"
def run(_) do
Mix.Tasks.Complete.run([])
IO.puts("""
#compdef mix
_mix() {
local options completion_line filtered_options
local -a completions
local current_word=${words[-1]}
local previous_word=${words[-2]}
if [[ -f 'mix.exs' && -f '.mix_complete.cache' ]]; then
options=$(cat .mix_complete.cache)
elif [[ ! -z "$XDG_CACHE_HOME" && -f "$XDG_CACHE_HOME/.mix_complete.cache" ]]; then
options=$(cat "$XDG_CACHE_HOME/.mix_complete.cache")
elif [[ -f "$HOME/.cache/.mix_complete.cache" ]]; then
options=$(cat "$HOME/.cache/.mix_complete.cache")
else
options=""
fi
filtered_options=$(echo "$options" | grep "^$current_word")
while IFS='\n' read -r completion_line; do
if [ -n "$completion_line" ]; then
# zsh's _describe needs a : instead of a TAB.
# So we first escape any : as part of the completion itself.
completion_line=${completion_line//:/\\:}
local tab="$(printf '\t')"
completion_line=${completion_line//$tab/:}
completions+=${completion_line}
fi
done <<<"$filtered_options"
if [[ $previous_word == 'mix' ]]; then
_describe "completions" completions
else
_arguments '*:filenames:_files'
fi
}
""")
end
end