我有一个用于Apache Hadoop的Bash制表符补全脚本。通常,我将zsh用作日常外壳。当我需要它时,它往往看上去很像bash,但是看起来它们之间的制表符完成系统根本不同。有没有一种简单的方法可以“转换”现有的bash-tab-completion定义以使其在zsh中工作?我不想为此花很多时间,但是如果简单的话,我会省些力气。
Answers:
从此页面(日期为2010/01/05):
Zsh可以处理bash补全功能。zsh的最新开发版本具有bashcompinit函数,该函数在运行时将允许zsh读取bash完成规范和函数。zshcompsys手册页中对此进行了记录。要使用它,您需要做的就是在compinit之后的任何时间运行bashcompinit。它将定义与bash内置程序相对应的complete和compgen函数。
/etc/zsh/zshrc
。此外,还要检查以下文件以相反的顺序(在他们的zsh启动期间货源的顺序排列): ,,和(可能),看看是否变量为no。如果是的话,那将防止源于未设置该文件的文件之后的后续文件。最后,检查用户所在的外壳程序,并确保该外壳程序没有参数。/etc/zsh/zshenv
$ZDOTDIR/.zshenv
/etc/zsh/zprofile
$ZDOTDIR/.zprofile
~/.zprofile
RCS
/etc/passwd
zsh
-f
autoload bashcompinit
bashcompinit
source /path/to/your/bash_completion_file
complete:13: command not found: compdef
错误。
if is-bash
在顶部有一个勾号。
_get_comp_words_by_ref
未使用定义的脚本,这不起作用bashcompinit
。不过,大多数补全不使用此功能。
autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit
source /path/to/your/bash_completion_script
我正在zsh 5.0.2 (x86_64-apple-darwin13.0)
不带任何〜/ .zshrc的情况下运行zsh ,并且以上序列在新近产生的zsh shell中起作用。
感谢git-completion.bash脚本的提示:D
Bash有内置的自动完成支持真棒但zsh的环境不具备基本的bash自动完成辅助功能喜欢的bash脚本自动完成不直接工作的zsh compgen
,complete
。这样做是为了保持zsh会话的快速。
这些天,zsh附带了适当的完成脚本,例如compinit
和bashcompinit
,它们具有支持bash自动完成脚本的必需功能。
autoload <func_name>
注意:自动加载是在zsh中定义的,而不是bash。autoload
在fpath
命令返回的目录路径中查找命名的文件,并标记一个函数,使其在首次调用时加载该文件。
例如在我的系统echo $fpath
恢复/usr/share/zsh/site-functions
和/usr/share/zsh/5.0.5/functions
无一不compinit
和bashcompinit
可在/usr/share/zsh/5.0.5/functions
。
而且对于大多数人来说可能只是autoload -U +X bashcompinit && bashcompinit
需要的,因为其他一些脚本(例如git autocomplete或他们自己的脚本~/.zshrc
可能正在执行)autoload -U +X compinit && compinit
,但是只运行两个脚本是安全的。
-U
和+X
呢?
+X foo
执行与调用时相同的自动加载foo
,但是没有立即执行它的意义……因此autoload +X foo && foo
似乎完全多余。您能解释一下为什么选择这种模式吗?
autoload -U +X bashcompinit && bashcompinit
目的是(由于&&
)它将bashcompinit
在实际找到该模块的情况下执行IFF。正常autoload foo
总是返回true。后来,当你尝试运行foo
,然后zsh的最后告诉你“没有找到函数定义文件”。随着autoload +X
您立即得到错误。
autoload +X
在不执行函数的情况下加载函数-这比不使用时要多。没有,autoload甚至不会加载该函数。它仅将名称标记为引用稍后要加载的函数。在首次调用该函数之前,不会尝试实际加载。如果要确定命名函数是否成功加载,则需要使用来立即执行加载步骤。autoload
+X
+X
+X
对于zsh
使用:
compdef
compadd
我的例子:
# bash completion for bxrun (/home/ecuomo/projects/bashx/bxrun)
_bxrun_methods() {
grep "^\s*\(function\s\+\)\?__.\+()\s*{.*$" "${1}" | while read line ; do
echo "$line" | sed "s/()\s*{.*//g" | sed "s/\s*\(function\s\+\)\?__//g"
done
}
_bxrun_lst() {
if [ -d "/home/ecuomo/projects/bashx/src/actions" ]; then
for f in /home/ecuomo/projects/bashx/src/actions/* ; do
if [ -f "${f}" ]; then
basename "${f}" | sed 's/\..*$//g'
fi
done
fi
_bxrun_methods "/home/ecuomo/projects/bashx/bxrun"
_bxrun_methods "/home/ecuomo/projects/bashx/src/bashx.sh"
}
_bxrun() {
local cur
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $( compgen -W '$( _bxrun_lst )' -- $cur ) )
}
_bxrun_zsh() {
compadd `_bxrun_lst`
}
if type complete >/dev/null 2>/dev/null; then
# bash
complete -F _bxrun bxrun
else if type compdef >/dev/null 2>/dev/null; then
# zsh
compdef _bxrun_zsh bxrun
fi; fi
我将Antigen作为Oh-My-Zsh插件管理器运行。我有一些同事写的bash完成脚本,我想用一个简单的脚本加载到Zsh中source /path/to/completion
。
我遇到了一些麻烦,因为似乎Antigen或OMZ(很难说)只关心从插件中加载完成脚本。我终于通过自动加载bashcompinit
及 compinit
之后解决了这个问题antigen apply
。仅仅自动加载bashcompinit
是不够的。
source ~/.antigen/antigen.zsh
antigen use oh-my-zsh
antigen apply
autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit
source /path/to/bash_completion
Antigen创建的.zcompdump
文件$ANTIGEN_COMPDUMP
对我来说是~/.antigen/.zcompdump
重新调用compinit和bashcompinit会在以下位置创建第二个.zcompdump $HOME/.zcompdump
这似乎可以解决所有问题,因为我可以使用设置的完成功能/path/to/bash_completion
。我已经删除了两个.zcompdump文件几次,以确保它们已重新生成并且似乎可以正常工作。
由于尝试制表完成时抛出错误,我不得不在计算机重新启动后rm .zcompdump文件几次,但是我不确定这是由于此设置还是其他原因。rm ~/.zcompdump && rm $ANTIGEN_COMPDUMP
一个新的外壳为我解决了这个问题。
撰写本文时使用的版本:
Antigen = v2.2.3 = d3d4ee0
Oh-my-zsh = c3b072e
Zsh = 5.3