完成命令名称时添加参数

完成命令名称时添加参数

我正在寻找一种方法,可以在按下选项卡(或其他组合键)时在终端中展开一些预定义的字符串。这与制表符补全不同。我的终端已经扩展到我的主目录(我不记得我是如何计算出来的,但我很确定这只是我正在寻找的一个特殊情况)。

例子:

假设您键入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 $SHELLOPTScontains :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哪些功能可以更好地满足您的目的。

相关内容