Let's say my Makefile
is something like:
DIR :=#
foobar:
ls ${DIR}
When i type
mak[tab] f[tab]
it gives correctly
make foobar
But
make foobar D[tab]
doesn't do the magic
make foobar DIR=
So my question is: is there a way to autocomplete Makefile variables too (aside targets) in bash?
Bash completion is a bash function that allows you to auto complete commands or arguments by typing partially commands or arguments, then pressing the [Tab] key. This will help you when writing the bash command in terminal.
The programmable completion feature in Bash permits typing a partial command, then pressing the [Tab] key to auto-complete the command sequence. [1] If multiple completions are possible, then [Tab] lists them all. Let's see how it works. Tab completion also works for variables and path names.
This answer is far from complete. To grep all variables in a Makefile we use make -p
to print the Makefile database:
# GNU Make 3.81
# Copyright (C) 2006 Free Software Foundation, Inc.
# This is free software; see the source for copying conditions.
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# This program built for x86_64-pc-linux-gnu
# Make data base, printed on Mon Oct 13 13:36:12 2014
# Variables
# automatic
<D = $(patsubst %/,%,$(dir $<))
# automatic
?F = $(notdir $?)
# environment
DESKTOP_SESSION = kde-plasma
# ...
# makefile (from `Makefile', line 1)
DIR :=
We are looking for lines starting with # makefile (from 'Makefile', line xy)
and extract the name of the following variable:
$ make -p | sed -n '/# makefile (from/ {n; p;}'
MAKEFILE_LIST := Makefile
DIR :=
In the next step we remove everything but the variable name (everything after :=
):
$ make -p Makefile | sed -n '/# makefile (from/ {n; s/^\([^.#:= ]\+\) *:\?=.*$/\1/p;}'
MAKEFILE_LIST
DIR
The following lines demonstrate how it could be done:
_make_variables()
{
# get current completion
local cur=${COMP_WORDS[COMP_CWORD]}
# get list of possible makefile variables
local var=$(make -p Makefile | sed -n '/# makefile (from/ {n; s/^\([^.#:= ]\+\) *:\?=.*$/\1=/p;}')
# don't add a space after completion
compopt -o nospace
# find possible matches
COMPREPLY=( $(compgen -W "${var}" -- ${cur}) )
}
# use _make_variables to complete make arguments
complete -F _make_variables make
Now make D[tab]
results in make DIR=
.
Sadly you will loose all the file and target completion with this approach. Also it would be useful to remove some more variables (e.g. MAKEFILE_LIST
) from the completion output.
Maybe it is worth to fill a wish/bug report against the bash-completion project to add this feature.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With