![完成命令名称时添加参数](https://linux22.com/image/52644/%E5%AE%8C%E6%88%90%E5%91%BD%E4%BB%A4%E5%90%8D%E7%A7%B0%E6%97%B6%E6%B7%BB%E5%8A%A0%E5%8F%82%E6%95%B0.png)
我正在寻找一种方法,可以在按下选项卡(或其他组合键)时在终端中展开一些预定义的字符串。这与制表符补全不同。我的终端已经扩展到我的主目录(我不记得我是如何计算出来的,但我很确定这只是我正在寻找的一个特殊情况)。
例子:
假设您键入cdd
并按 Tab 键,它会扩展为cd /your/home/folder/Downloads/
并且光标放置在行尾。因此,您可以在文件夹内键入文件夹的名称Downloads
并运行命令。更好的示例是将光标展开sshu
并将ssh |@a-pre-defined-host.foo
光标放在@
符号后面以输入用户名。
这类似于许多 IDE 中的代码片段扩展功能。请不要说我可以通过将参数写入.bashrc
文件中的 bash 函数来实现同样的事情。
重点是什么?
那么与函数调用相比,使用这样的东西有什么意义呢?嗯,与你们许多命令行人员不同,我的记忆力不好。即使对于我经常使用的命令,我也记不起参数等细节。我通常在网上搜索诸如“如何使用curl POST a json file?”之类的内容。好吧,我可以创建一个接受文件名、主机名、端口名以及可能的其他一些参数的函数并执行 POST。但是,记住参数及其顺序并不比记住整个命令简单。通过片段扩展,我只需要记住片段的名称,例如snppost
,或者我什至不需要记住片段的名称。我可以输入snp
并按 Tab 来获取片段列表,找到我要查找的片段。再次按 Tab 键可展开该片段。我有我正在寻找的命令,无需搜索网络和复制/粘贴。我可以对命令进行任何我喜欢的自定义并运行它。
答案1
这不会像你想要的那么容易。可编程完成无法替代命令。并且您必须在可编程完成启动之前完成命令字(即尾随空格)。
这意味着您必须创建一个别名或函数,cdd
并将其替换为cd
。这应该不是问题(除了包含换行符的目录名称......)。其余的可以这样完成:
_cdd () { IFS=$'\n'; if [ 1 -eq "$COMP_CWORD" -a 0 -eq "${#COMP_WORDS[1]}" ];
then COMPREPLY=("/your/home/folder/Downloads/");
else COMPREPLY=($(compgen -A directory "${COMP_WORDS[1]}"));fi; }
complete -o filenames -F _cdd cdd
将光标置于单词内
我认为这不是一个好主意。但考虑到这一点:可以向后移动光标,但我没有在可编程完成中实现这一点:
back_seq=$'\e[D'
output=""; for((i=0;i<5;i++)); do output+="$back_seq"; done
echo -n 123456789"$output"; sleep 5
答案2
您可能会在 READLINE 函数中找到一些可以使用的东西。
看看LESS='+/shell-expand-line' man bash
开始吧。
shell-expand-line
可能不是最适合您的目的,但它是默认设置的(假设您有默认的 shell 选项,即echo $SHELLOPTS
contains :emacs:
)。
通过运行可以看到其他一些可能性bind -p | grep expand
。这些“扩展”功能中的任何一个都会以某种形式完成您所要求的工作。
基本上你会设置一个别名:
alias cdd='cd /your/home/folder/Downloads/'
...在您的 中.bashrc
,当您想要扩展它时,您可以键入它cdd<Esc><C-e>
,它就会扩展。这是使用上面提到的已经设置的shell-expand-line
——它扩展别名和历史扩展,以及变量。 (尝试输入l.; echo $SHELLOPTS; !!
并按<Esc><C-e>
。)
您可以绑定其他功能,例如简单地绑定alias-expand-line
哪些功能可以更好地满足您的目的。