在实际发帖之前,我已经非常努力地弄清楚了这一点,但我似乎找不到任何其他人解决这个特定问题的例子。
我正在运行 Ubuntu 17.10
我编写了一个自定义函数来处理我的一个脚本的制表符完成。目的是当我输入脚本的名称并点击 [TAB] 时,它会列出 /opt/use 中以“.use”结尾的所有文件(不显示“.use”或前导路径) . 到目前为止,我似乎已经完成了这项工作。
/opt/use 中的文件如下:
blender-2.79.use
chrome.use
clarisse-3.6.use
unity-2017.3.0p2.use
该函数的代码和完成是:
_use () {
files=( `compgen -f -X "!*.use" /opt/use/` )
output=()
for file in "${files[@]}"; do
fileBaseName=`basename $file .use`
output+=("$fileBaseName")
done
COMPREPLY=( ${output[@]} )
}
complete -F _use use
请不要对我评价太苛刻,我是图形艺术家,不是程序员。:)
此外,我的“使用”脚本实际上是以下命令的别名:
source /opt/scripts/use.sh
现在当我输入:
use[SPACE][TAB][TAB]
我成功地获得了 /opt/use 中以“.use”结尾的文件列表。
到目前为止,一切都很好。例如,我输入“use[SPACE][TAB][TAB]”,它看起来是这样的:
bvz@bvz-xps15-linux:~$ use
blender-2.79 chrome clarisse-3.6 unity-2017.3.0p2
我的第一个问题是为什么我必须点击 [TAB] 两次?第一次只是发出哔哔声。第二次它向我展示了我的选择。这对我来说不是问题,我只是想知道这是否是我的问题的线索,这是:
如果我键入足够多的字母以完全唯一,则制表符完成实际上并没有“完成”该行。它只是按照我输入的方式留下条目,并重新显示 /opt/use 中的文件列表。因此,例如,如果我输入:
use clar[TAB][TAB]
而不是填写要阅读的行:
use clarisse-3.6
这是我所期望的(以及我所追求的)它离开了这条线:
use clar
并在可能完成的完整列表下方显示我。这是一个示例:
bvz@bvz-xps15-linux:~$ use clar[TAB][TAB]
blender-2.79 chrome clarisse-3.6 unity-2017.3.0p2
bvz@bvz-xps15-linux:~$ use clar
请注意它实际上并没有完成读取“clarisse-3.6”的行,即使这是唯一可能的完成。
谁能告诉我我做错了什么?另外,如果这是重复的,我深表歉意。我已经环顾了几天,但找不到任何甚至有人遇到这个问题的例子,更不用说解决了。
谢谢
感谢 Muru 为我指出了解决方案。
显然我的问题是每次调用我的函数时,它总是返回可能匹配的完整列表。我只需要返回与用户迄今为止输入的内容相匹配的那些可能的完成。一旦我只返回一个项目,那么 bash 将自动完成该行的其余部分。
这是有效的功能。在添加每个可能的补全之前,我会快速检查一下补全是否以最初输入的单词开头。我使用正则表达式来做到这一点。我还必须测试他们是否还没有输入任何内容——在这种情况下,我总是返回所有内容。
我还对其进行了更改以使更多变量成为“本地”变量。
既然我有时间考虑这个,我认为完成功能可以简化为:
假设您
basename
的新版本足以支持-a
,否则请-exec basename {} .use \;
改用。