aboutsummaryrefslogtreecommitdiff
path: root/bash/bash_completion.d/make.bash
blob: 909c52fbc6de90d892da4073d4bd5986e9b95bbd (plain) (blame)
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
# Load _completion_ignore_case helper function
if ! declare -F _completion_ignore_case >/dev/null ; then
    source "$HOME"/.bash_completion.d/_completion_ignore_case.bash
fi

# Completion setup for Make, completing targets
_make() {

    # Find a legible Makefile according to the POSIX spec (look for "makefile"
    # first, then "Makefile"). You may want to add "GNU-makefile" after this.
    local mf
    for mf in makefile Makefile '' ; do
        ! [[ -e $mf ]] || break
    done
    [[ -n $mf ]] || return

    # Iterate through completions produced by subshell
    local ci comp
    while read -r comp ; do
        COMPREPLY[ci++]=$comp
    done < <(
        while IFS= read -r line ; do

            # Match expected format
            case $line in
                # First char not a tab
                ($'\t'*) continue ;;
                # Has no equals sign anywhere
                (*=*) continue ;;
                # Has a colon on the line
                (*:*) ;;
                # Skip anything else
                (*) continue ;;
            esac

            # Break the target up with space delimiters
            IFS=' ' read -a targets -r \
                < <(printf '%s\n' "${line%%:*}")

            # Short-circuit if there are no targets
            # shellcheck disable=SC2154
            ((${#targets[@]})) || exit

            # Make matches behave correctly
            if _completion_ignore_case ; then
                shopt -s nocasematch 2>/dev/null
            fi

            # Examine each target for completion suitability
            for target in "${targets[@]}" ; do
                case $target in
                    # Not .PHONY, .POSIX etc
                    (.*) ;;
                    # Nothing with metacharacters
                    (*[^[:word:]./-]*) ;;
                    # Match!
                    ("$2"*) printf '%s\n' "$target" ;;
                esac
            done

        done < "$mf"
    )
}
complete -F _make -o bashdefault -o default make