Makefile autocompletion on Mac
This seems to achieve simple bash completions for me on El Capitan:
# .bashrc
function _makefile_targets {
local curr_arg;
local targets;
# Find makefile targets available in the current directory
targets=''
if [[ -e "$(pwd)/Makefile" ]]; then
targets=$( \
grep -oE '^[a-zA-Z0-9_-]+:' Makefile \
| sed 's/://' \
| tr '\n' ' ' \
)
fi
# Filter targets based on user input to the bash completion
curr_arg=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $(compgen -W "${targets[@]}" -- $curr_arg ) );
}
complete -F _makefile_targets make
Here's how this works:
complete -F [function name] [command name] -- this bash builtin register a new completion for [command name] which is generated by the bash function [function name]. So in my code above, if you type
make [TAB][TAB]
into your shell, you'll trigger the_makefile_targets()
function.if [[ -e "$(pwd)/Makefile" ]]; then -- make sure there's a Makefile in the current directory, otherwise don't try a bash completion.
grep -oE '^[a-zA-Z0-9_-]+:' Makefile -- filter every line of Makefile using the regex for a target name like "test:".
-o
means only return the part of the line that matches. For example, given a Makefile target like "test: build package", only "test:" will be returned| sed 's/://' -- taking the grep results, remove the colon from the end of line
| tr '\n' ' ' -- smoosh all targets onto one line, separated by one space
Inside a bash completion function, complete
sets several environment variables for you. COMP_WORDS
is an array of the list of available bash completion choises based on what the user typed. COMP_CWORD
is the index of the currently selected word.
Another very magical builtin compgen
will take a list of space separately strings and filter them using the currently selected word. I'm not at all clear how that works.
So, the bottom line is that the last two lines in the function filter our list of makefile targets (stored inside $targets
) and shoves them into an array COMPREPLY
. The bash completion reads and displays COMPREPLY
as choices in the shell.
Inspired by:
- https://gist.github.com/tlrobinson/1073865
- http://www.thegeekstuff.com/2013/12/bash-completion-complete/ (Esp 9.)
This worked for me on Catalina in the standard zsh terminal
Edit the file named
.zshrc
in you home directory this can be done with this command in the terminalnano ~/.zshrc
Add the following lines
zstyle ':completion:*:*:make:*' tag-order 'targets'
autoload -U compinit && compinit
- exit and save by pressing
ctrl + x
and then saveY