bash - 启用 bash-completion 会禁用自动完成文件名的默认行为
问题描述
我make
在 macOS High Sierra 版本 10.13.6 上的版本如下所示:
$ make --version
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 i386-apple-darwin11.3.0
我的 Bash 版本如下所示:
$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
Copyright (C) 2007 Free Software Foundation, Inc.
我的当前目录如下所示:
$ ls -1
Makefile
a.txt
b.txt
c.txt
我的Makefile
样子是这样的:
hello:
echo hello
%.txt: FORCE
cat "$@"
FORCE:
案例一:没有bash-completion
当我没有bash-completion
安装时,我可以方便地自动完成当前目录中的文件名作为make
. 我的意思是,如果我输入:
make a<TAB>
它会自动完成:
make a.txt
案例2:有bash-completion
当我确实有bash-completion
(例如 with brew install bash-completion
)时,我不能再使用这种行为。
如果我输入:
make a<TAB>
它根本不会自动完成。make he<TAB>
它现在会自动完成其他目标,例如make FO<TAB>
之前不可能的,但我失去了自动完成任何任意文件名的功能。
问题
- 为什么安装会
bash-completion
禁用自动完成当前文件名的默认行为?我认为这是一个非常方便的行为。 - 我怎样才能在不删除
bash-completion
. 如果我能做到这一点,我可以两全其美。使用bash-completion
当前目录中提供的自动完成以及自动完成文件名。
解决方案
要回答您问题的第一部分,我认为大多数人不希望 Bash 将工作目录中的文件提供为建议的 make 目标。
但是您可以自定义行为而不会太麻烦。
可以在这里找到一些关于 Bash Tab Completion 的有用文档。
看起来 Mac OS X 上使用的 Bash Completion 的源代码在这里。您关心的是这一行:
COMPREPLY=( $( compgen -W "$( make -qp $makef $makef_dir 2>/dev/null | \
awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ \
{split($1,A,/ /);for(i in A)print A[i]}' )" \
-- "$cur" ) )
您可以看到,compgen
那里的内置函数根据make -qp Makefile .
.
你可以破解它以按照你想要的方式工作。首先,将特定于 make 的自动完成文件复制到您的用户 bash 完成文件:
cp /usr/local/Cellar/bash-completion/1.3_3/etc/bash_completion.d/make ~/.bash_completion
然后编辑该文件以指定稍微不同的行为。在这里,我将展示差异:
--- /usr/local/Cellar/bash-completion/1.3_3/etc/bash_completion.d/make 2019-02-06 18:35:00.000000000 +1100
+++ /Users/alexharvey/.bash_completion 2019-02-06 18:34:36.000000000 +1100
@@ -62,7 +62,7 @@
COMPREPLY=( $( compgen -W "$( make -qp $makef $makef_dir 2>/dev/null | \
awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ \
- {split($1,A,/ /);for(i in A)print A[i]}' )" \
+ {split($1,A,/ /);for(i in A)print A[i]}' ; ls * )" \
-- "$cur" ) )
fi
请注意,我所做的只是将 的输出附加ls *
到返回的响应中,compgen
以便它认为工作目录中的文件也可能是选项卡完成。
就是这样。启动一个新的外壳。
推荐阅读
- javascript - 点击触发两个不同的动画?
- android - sdk 升级到 30 后应用程序崩溃,DevSupportManager 类未找到异常
- odbc - 如何在客户端系统中创建多个 DSN(informix ODBC 驱动程序)?
- c# - 如何断言异常类型和异常消息?
- python - Kivy:如何在另一个屏幕中从当前屏幕更改属性值,例如标签文本
- unit-testing - "Show Tests covering line" disabled in Intellij
- visual-studio-code - Ansible VSCode Extention containing module snippsets
- c++ - String to int cpp
- flutter - setState() or markNeedsBuild() called when widget tree was locked
- ansible - Ansible is there any way to copy the groups