zshのデフォルトの補完の定義を使わないことにした

zshで以下のように設定しておくと

autoload -Uz compinit
compinit

様々な補完がデフォルトで定義されますが、ほとんどの定義は自分には不要であることが最近分かってきました。

むしろ

make ファイル名

と実行したいのにファイル名を補完できないなど、不便な点のほうが目立ちます。

compinit を行わなければデフォルトの補完も定義されないので上記のような不便はないのですが、その代わり補完候補に色が付かなくなってしまうのでそれはそれで不便です。

そこで、compinit を実行した上で不要な定義をばっさり削除することにしました。

autoload -Uz compinit
compinit

# ほとんどの補完の定義を削除する。
# special contexts の定義のみ残す (see: man zshcompsys)
fix_comp_assoc() {
	local var=$1
	shift
	for key in "$argv[@]"; do
		case $key in
		-redirect-,\<,*) unset "${var}[$key]";;
		-redirect-,\>,*) unset "${var}[$key]";;
		-value-,-*) ;;
		-value-,*) unset "${var}[$key]";;
		-*) ;;
		*) unset "${var}[$key]";;
		esac
	done
}
fix_comp_assoc _comps        "${(k)_comps[@]}"
fix_comp_assoc _services     "${(k)_services[@]}"
fix_comp_assoc _patcomps     "${(k)_patcomps[@]}"
fix_comp_assoc _postpatcomps "${(k)_postpatcomps[@]}"

compinit では、補完する時にどのようなコンテキストでどのコマンドを利用するという一覧は _comps, _services, _patcomps, _postpatcomps という連想配列に格納されるようです*1。そこで、それらの定義の中から special contexts の定義以外をばっさり削るようにしました。

これで

make ファイル名

も実行可能になり、快適zshライフを送ることができそうです。

# しかし、もっと良いやりかたがありそうなものですが…

*1:これらの変数のデフォルトの内容は ~/.zcompdump へダンプされているのでそこで確認するのが楽です