4 ms·
When you install bash-completion on your system, usually a function is defined to autocomplete make rules for you. It works with all projects, as it does not re
by grive 6y ago
When you install bash-completion on your system, usually a function is defined to autocomplete make rules for you. It works with all projects, as it does not rely on the rules being specially marked. (https://github.com/scop/bash-completion/blob/master/completions/make https://github.com/scop/bash-completion/blob/master/completi...)
Before I knew about it, I had written a similar thing:
# Autocomplete make rules
_make () {
local cur prev words cword cmdline
_init_completion || return
# command to generate the rules
words="$(make -pRrq |\
awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($1 !~ "^[#.]") {print $1}}' |\
sort | egrep -v -e '^[^[:alnum:]]' | xargs)"
COMPREPLY+=( $( compgen -W "$words" -- $cur) )
}
if declare -f _init_completion > /dev/null; then
complete -F _make make
fi
It relies on `make -pRrq`, that is a very useful command to debug your makefiles, especially in a big project. The option `-p` prints the make data-base, -R and -r removes the implicit rules and variables, and -q indicates only asking make a question about current state, avoid executing anything.
Well, it worked for a time, but the bash-completion one is nicer (though much, much more complex). Very nice however to know about `-pRrq`, definitely helps when working on big projects.
- Lammy 6y agoKeep in mind that you are referring to GNU Make specifically and won't be truly portable. BSD Make, for example, doesn't have -p: https://www.freebsd.org/cgi/man.cgi?make(1) https://www.freebsd.org/cgi/man.cgi?make(1)
- mturmon 6y agoThis is a good point. One big problem with solutions that match the text of the makefile is that they don't catch dynamically-generated targets. I have makefiles used for data-crunching that are parametrically-generated using $foreach in gnu make. One typical use case is "make these plots for all the data, for 10% of the data, or for just one example" - with targets generated by a $foreach(...) construct. Asking make to regurgitate the targets it knows about catches these guys, grep doesn't. There are many other examples of dynamically-generated rules, such as using macros that create rules via gnu make's "define".
- emmelaich 6y agoThere is a similar snippet by user 'cies' here on HN just 6 months ago. https://news.ycombinator.com/item?id=21812897 https://news.ycombinator.com/item?id=21812897
- oefrha 6y agoHere's zsh's implementation: https://github.com/zsh-users/zsh/blob/master/Completion/Unix/Command/_make https://github.com/zsh-users/zsh/blob/master/Completion/Unix... It's more complete, since it implements completion for bsdmake too, where there's no -p but a comparable debug option.[1] It completes variables in addition to targets, too. [1] https://www.freebsd.org/cgi/man.cgi?make(1) https://www.freebsd.org/cgi/man.cgi?make(1)