main
1# Deferred completion system — runs on first prompt, not at startup
2# Saves ~53ms by deferring compinit to precmd
3
4autoload -Uz compinit
5
6__deferred_compinit() {
7 local dump=${XDG_CACHE_HOME:-$HOME/.cache}/zsh/.zcompdump
8 mkdir -p "${dump:h}" 2>/dev/null
9
10 if [[ ! -f $dump ]]; then
11 compinit -d "$dump"
12 else
13 compinit -C -d "$dump" # -C skips security check (single-user machine)
14 fi
15 _zsh_compile_if_needed "$dump"
16
17 # Wire up alias expansion (needs compinit)
18 # ctrl-x ctrl-a to expand aliases in place (ctrl-a stays as beginning-of-line)
19 zle -C alias-expansion complete-word _generic
20 bindkey '^x^a' alias-expansion
21 zstyle ':completion:alias-expansion:*' completer _expand_alias
22
23 add-zsh-hook -d precmd __deferred_compinit
24 unfunction __deferred_compinit
25}
26autoload -Uz add-zsh-hook
27add-zsh-hook precmd __deferred_compinit
28
29# Completion styles (zstyle declarations are cheap — no need to defer)
30zstyle ':completion:*' menu select
31zstyle ':completion::complete:*' use-cache on
32zstyle ':completion::complete:*' cache-path "${XDG_CACHE_HOME:-$HOME/.cache}/zsh/zcompcache"
33
34# Case-insensitive, partial-word, substring completion
35zstyle ':completion:*' matcher-list '' \
36 'm:{a-z\-}={A-Z\_}' \
37 'r:[^[:alpha:]]||[[:alpha:]]=** r:|=* m:{a-z\-}={A-Z\_}' \
38 'r:[[:ascii:]]||[[:ascii:]]=** r:|=* m:{a-z\-}={A-Z\_}'
39
40# Group matches and describe
41zstyle ':completion:*:*:*:*:*' menu select
42zstyle ':completion:*:matches' group 'yes'
43zstyle ':completion:*:options' description 'yes'
44zstyle ':completion:*:options' auto-description '%d'
45zstyle ':completion:*:corrections' format ' %F{green}-- %d (errors: %e) --%f'
46zstyle ':completion:*:descriptions' format ' %F{yellow}-- %d --%f'
47zstyle ':completion:*:messages' format ' %F{purple} -- %d --%f'
48zstyle ':completion:*:warnings' format ' %F{red}-- no matches found --%f'
49zstyle ':completion:*:default' list-prompt '%S%M matches%s'
50zstyle ':completion:*' format ' %F{yellow}-- %d --%f'
51zstyle ':completion:*' group-name ''
52zstyle ':completion:*' verbose yes
53
54# Fuzzy match mistyped completions
55zstyle ':completion:*' completer _complete _list _match _approximate
56zstyle ':completion:*:match:*' original only
57zstyle ':completion:*:approximate:*' max-errors 1 numeric
58zstyle -e ':completion:*:approximate:*' max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)'
59
60# Don't complete unavailable commands
61zstyle ':completion:*:functions' ignored-patterns '(_*|pre(cmd|exec))'
62
63# Array completion element sorting
64zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
65
66# Directories
67zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
68zstyle ':completion:*:*:cd:*' ignore-parents parent pwd
69zstyle ':completion:*:*:cd:*' tag-order local-directories directory-stack path-directories
70zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
71zstyle ':completion:*:-tilde-:*' group-order 'named-directories' 'path-directories' 'users' 'expand'
72zstyle ':completion:*' squeeze-slashes true
73zstyle ':completion:*' special-dirs true
74
75# Environmental variables
76zstyle ':completion::*:(-command-|export):*' fake-parameters ${${${_comps[(I)-value-*]#*,}%%,*}:#-*-}
77
78# Populate hostname completion
79zstyle -e ':completion:*:hosts' hosts 'reply=(
80 ${=${=${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) 2>/dev/null)"}%%[#| ]*}//\]:[0-9]*/ }//,/ }//\[/ }
81 ${=${${${${(@M)${(f)"$(cat ~/.ssh/config 2>/dev/null)"}:#Host *}#Host }:#*\**}:#*\?*}}
82)'
83
84# Don't complete uninteresting users
85zstyle ':completion:*:*:*:users' ignored-patterns \
86 adm amanda apache avahi beaglidx bin cacti canna clamav daemon \
87 dbus distcache dovecot fax ftp games gdm gkrellmd gopher \
88 hacluster haldaemon halt hsqldb ident junkbust ldap lp mail \
89 mailman mailnull mldonkey mysql nagios \
90 named netdump news nfsnobody nobody nscd ntp nut nx openvpn \
91 operator pcap postfix postgres privoxy pulse pvm quagga radvd \
92 rpc rpcuser rpm shutdown squid sshd sync uucp vcsa xfs '_*'
93zstyle '*' single-ignored show
94
95# Ignore multiple entries
96zstyle ':completion:*:(rm|kill|diff):*' ignore-line other
97zstyle ':completion:*:rm:*' file-patterns '*:all-files'
98
99# Man
100zstyle ':completion:*:manuals' separate-sections true
101zstyle ':completion:*:manuals.(^1*)' insert-sections true
102
103# SSH/SCP/RSYNC
104zstyle ':completion:*:(scp|rsync):*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *'
105zstyle ':completion:*:(scp|rsync):*' group-order users files all-files hosts-domain hosts-host hosts-ipaddr
106zstyle ':completion:*:ssh:*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *'
107zstyle ':completion:*:ssh:*' group-order users hosts-domain hosts-host users hosts-ipaddr
108zstyle ':completion:*:(ssh|scp|rsync):*:hosts-host' ignored-patterns '*(.|:)*' loopback ip6-loopback localhost ip6-localhost broadcasthost
109zstyle ':completion:*:(ssh|scp|rsync):*:hosts-domain' ignored-patterns '<->.<->.<->.<->' '^[-[:alnum:]]##(.[-[:alnum:]]##)##' '*@*'
110zstyle ':completion:*:(ssh|scp|rsync):*:hosts-ipaddr' ignored-patterns '^(<->.<->.<->.<->|(|::)([[:xdigit:].]##:(#c,2))##(|%*))' '127.0.0.<->' '255.255.255.255' '::1' 'fe80::*'