-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathzsh-make-completion.plugin.zsh
More file actions
64 lines (59 loc) · 2.21 KB
/
zsh-make-completion.plugin.zsh
File metadata and controls
64 lines (59 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# make-completion.zsh — correct, fast zsh tab completion for make targets
# https://github.com/pksublime/zsh-make-completion
# MIT License — Copyright (c) 2026 Patrick Little
# ── make tab completion: correct expanded targets, cached ──────────────────
#
# Uses `make -qp` to fully expand all targets including those generated via
# $(eval $(call ...)) and similar metaprogramming patterns, which naive
# Makefile text parsers miss. Results are cached per-directory (keyed by
# $PWD) and invalidated automatically when Makefile or any *.mk file changes.
#
# Filters out:
# - Pattern rules containing %
# - Internal make variables leaking through as targets (VAR := / VAR ?= etc.)
# - Special targets beginning with .
# - Targets containing $ (unexpanded template bodies)
# - Targets containing whitespace
#
_make_cached_targets() {
local cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/zsh-make-completion"
mkdir -p "$cache_dir"
local key
key=$(printf '%s' "$PWD" | cksum | awk '{print $1}')
local cache="$cache_dir/$key"
local stale=0 f
if [[ ! -f $cache ]]; then
stale=1
else
for f in Makefile makefile GNUmakefile mk/**/*.mk(N) *.mk(N); do
[[ -f $f && $f -nt $cache ]] && { stale=1; break }
done
fi
if (( stale )); then
make -qp 2>/dev/null | awk '
/^# Not a target:/ { skip=1; next }
/^[^#\t ][^=]*:/ {
if ($0 ~ /:=/) { skip=0; next }
if (!skip) {
t = $0
sub(/:.*/, "", t)
gsub(/^[[:space:]]+|[[:space:]]+$/, "", t)
if (length(t) > 0 && t !~ /^\./ && t !~ /\$/ && t !~ /[[:space:]]/ && t !~ /%/)
print t
}
skip=0; next
}
{ skip=0 }
' | sort -u > "$cache"
fi
cat "$cache"
}
_make() {
local targets expl
if [[ -f Makefile || -f makefile || -f GNUmakefile ]]; then
targets=("${(f)$(_make_cached_targets)}")
_wanted targets expl 'make target' compadd -a targets
fi
}
(( $+functions[compdef] )) && compdef _make make
# ──────────────────────────────────────────────────────────────────────────