Bash中的Makefile变量自动补全

12

假设我的Makefile是这样的:

DIR :=#

foobar:

   ls ${DIR}

当我输入时

mak[tab] f[tab]

它给出了正确的结果。

make foobar

但是

make foobar D[tab]

不能产生神奇效果

make foobar DIR=

所以我的问题是:在bash中是否有一种方法可以自动完成Makefile变量(除目标外)?


要做到这一点,您需要修改make bash完成函数,以提取变量名称,而不仅仅是目标名称。虽然我无法确定需要多少工作,但应该有可能做到这一点。 - Etan Reisner
我非常确定Bash正在完成“foobar”,并不是因为“foobar”是Makefile中的目标,而是因为您有一个名为foobar的文件。 - Beta
@Beta 感谢您的反馈!不过出于测试目的,我在 Makefile 目录下创建了 2 个子目录(名为“asd”和“qwe”)。顺便一提,我使用的是 Debian testing、make 4.0 和 bash 4.3.24。 - Luca Braglia
@Beta...而且我的目录中没有进一步的文件(特别是名为“foobar”的文件),只有Makefile。 - Luca Braglia
1个回答

3

这个回答远非完整。要在Makefile中grep所有变量,我们使用make -p打印Makefile数据库:

# 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 := 

我们正在寻找以# makefile (from 'Makefile', line xy)开头的行,并提取以下变量的名称:
$ make -p | sed -n '/# makefile (from/ {n; p;}'
MAKEFILE_LIST :=  Makefile
DIR :=

在下一步中,我们将删除除变量名以外的所有内容(即:=之后的所有内容):
$ make -p Makefile | sed -n '/# makefile (from/ {n; s/^\([^.#:= ]\+\) *:\?=.*$/\1/p;}'
MAKEFILE_LIST
DIR

以下代码演示了如何实现它:
_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

现在使用make D[tab]将得到make DIR=。但是,这种方法会导致失去所有文件和目标完成的功能。另外,从完成输出中删除更多变量(例如MAKEFILE_LIST)也会很有用。也许值得向bash-completion项目提交意见/错误报告以添加此功能。

感谢,+1。在bash-completion项目中填写了一个心愿清单项。 - Luca Braglia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接