bash 完成 makefile 目标

问题描述 投票:0回答:8

假设我有一个简单的 makefile,例如:

hello:
   echo "hello world"

bye:
   echo "bye bye"

然后在 bash 中我想要这样的东西:

做h< tab >

所以它可以完成

打个招呼

我找到了一个简单的方法,比如创建空文件

hello
bye
但我正在寻找更复杂的东西 sophisticated.

makefile bash-completion
8个回答
79
投票

将此添加到您的 ~/.bash_profile 文件或 ~/.bashrc 文件

complete -W "\`grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' ?akefile | sed 's/[^a-zA-Z0-9_.-]*$//'\`" make

这会使用 grep 在名为“Makefile”或“makefile”的 Makefile 中搜索目标(注意

?
中的大写
?akefile
通配符),并将其通过管道传递给 bash 中的
complete
命令,该命令用于指定如何自动完成参数。
-W
标志表示
complete
命令的输入将是一个单词列表,它是通过将 grep 的结果传递给
sed
来完成的,它将其排列成所需的 wordlist 格式。

注意事项和陷阱:

  1. 您的 make 文件名为“GNUMakefile”或除“Makefile”或“makefile”以外的任何其他名称。如果您经常遇到此类标题,请考虑相应地更改正则表达式

    ?akefile

  2. 在进行更改后忘记获取 ~/.bash_profile 或 ~/.bashrc 文件。我添加这个看似微不足道的细节,因为对于外行来说,它是陌生的。 要使 bash 文件的任何更改生效,请使用以下命令source它们

    source ~/.bashrc
    

    source ~/.bash_profile
    

附言。您现在还可以通过按 [Tab] 两次来显示 possible make 目标,就像在 bash 完成中一样。在键入 [Tab] 两次之前,请确保在命令 make 之后添加一个空格。


14
投票

这个 2010 年的答案已经过时了——这里提到的项目似乎已经停止了。

这会是您要找的吗?

http://freshmeat.net/projects/bashcompletion/

make [Tab] 将完成所有 Makefile 中的目标。这个项目是 设想生产可编程 大多数完成例程 常用的 Linux/UNIX 命令,减少 键入系统管理员的数量和 程序员需要每天做 基础。


12
投票

有一个名为 bash-completion 的有用包,适用于大多数操作系统。它包括 Makefile 补全。

(如果您使用的是 macOS 和 Homebrew,您可以通过

brew install bash-completion
获取。)


3
投票

这似乎至少在 Debian Lenny 中是默认的:

$ grep Makefile /etc/bash_completion
    # make reads `GNUmakefile', then `makefile', then `Makefile'
    elif [ -f ${makef_dir}/Makefile ]; then
        makef=${makef_dir}/Makefile
    # before we scan for targets, see if a Makefile name was
    # deal with included Makefiles

此文件的标题说明:

#   The latest version of this software can be obtained here:
#
#   http://bash-completion.alioth.debian.org/
#
#   RELEASE: 20080617.5

2
投票

这是一个查看 .PHONY: 声明的完成脚本。

_make_phony_words() {
  local opt_revert

  if [ -n "${BASH_VERSION:-}" ]; then
    shopt -q nullglob || {
      opt_revert=1 ; shopt -s nullglob ;
    }

  elif [ -n "${ZSH_VERSION:-}" ]; then
    [[ -o nullglob ]] || {
      opt_revert=1 ; setopt nullglob
    }
  fi

  for f in ./?akefile ./*.make ; do
    sed -nEe '/^.PHONY/ { s/^.PHONY:[ ]?// ; p ; } ' "$f" | tr ' ' $'\n' | sort -u
  done

  if [ -n "$opt_revert" ]; then

    [ -n "${ZSH_VERSION:-}" ] && unsetopt nullglob
    [ -n "${BASH_VERSION:-}" ] && shopt -u nullglob
  fi
  unset opt_revert

}

_make_phony_complete() {
  local cur="${COMP_WORDS[COMP_CWORD]}"

  COMPREPLY+=( $(compgen -W "$( _make_phony_words )" -- ${cur}) )

}
complete -F _make_phony_complete make

1
投票

Makefile 完成类固醇!

正常完成时我有2个问题

问题#1

有时你有你想要调用的目标,比如

make greet:hi
make greet:hola
有点像命名空间
Makefile
目标名称。所以你的
Makefile
最终看起来像:

greet\:hola:
   echo "hola world"

# OR a .PHONY target
.PHONY: greet\:hi
greet\:hi:
   echo "hi world"

在这种情况下,

:
之后的自动完成不会显示,因为它在 Makefile 中使用了
\:
,如上所示。

问题#2

没有办法在我的

Makefile
shell 中使用箭头键(或
CTRL-p
/
CTRL-n
)浏览与我的输入匹配的所有
bash
目标列表。

基本上,我想在目标上使用类似模糊搜索的方法(即

fzf
)。 FZF 回购:https://github.com/junegunn/fzf

解决方案

安装 FZF 依赖

使用自制软件

您可以使用 Homebrew(在 macOS 或 Linux 上) 安装 fzf.

brew install fzf
$(brew --prefix)/opt/fzf/install
使用 Linux 包管理器
包管理器 Linux 发行版 命令
APK 高山Linux
sudo apk add fzf
公寓 Debian 9+/Ubuntu 19.10+
sudo apt-get install fzf
康达
conda install -c conda-forge fzf
地下城与勇士 软呢帽
sudo dnf install fzf
尼克斯 NixOS等
nix-env -iA nixpkgs.fzf
吃豆子 Arch Linux
sudo pacman -S fzf
包装 FreeBSD
pkg install fzf
打包 NetBSD
pkgin install fzf
pkg_add OpenBSD
pkg_add fzf
XBPS 虚空 Linux
sudo xbps-install -S fzf
Zypper openSUSE
sudo zypper install fzf

FZF 和
:
兼容的自动完成命令

把这个放在你的

.bashrc

complete -W "\`grep -oE '^[a-zA-Z0-9_.-]+[\\:]*[a-zA-Z0-9_.-]+:([^=]|$)' ?akefile | sort | uniq | sed 's/[^a-zA-Z0-9_.-]*$//' | sed 's/[\]//g' | fzf\`" make

现在只要输入

make 
然后敲击键就可以了!

演示:在行动!

然后你可以使用如下:

make using fzf


0
投票

我添加了所以我遵循 Makefile 中的“include”指令。所以我的 .bashrc 看起来像这样:

function followMakefile() {
  grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' ?akefile | sed 's/[^a-zA-Z0-9_.-]*$//'
  for x in `grep -E '^include' ?akefile | sed 's/include //'`
  do
    grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' $x | sed 's/[^a-zA-Z0-9_.-]*$//'
  done
}
complete -W "\`followMakefile\`" make

-3
投票

在 Ubuntu 10.04 中,获取以下文件:

. /etc/bash_completion

或在

中取消注释
/etc/bash.bashrc
© www.soinside.com 2019 - 2024. All rights reserved.