[英]Can a Bash tab-completion script be used in zsh?
I have a Bash tab-completion script for Apache's Hadoop.我有一个用于 Apache Hadoop 的 Bash 选项卡完成脚本。 Normally, I use zsh as my day-to-day shell.
通常,我使用 zsh 作为我的日常 shell。 It tends to be pretty bash-like when I need it to be, but it looks like the tab-completion systems are radically different between them.
当我需要它时,它往往非常像 bash,但看起来它们之间的制表符完成系统完全不同。 Is there a simple way to "convert" the existing bash-tab-completion definitions to work in zsh?
有没有一种简单的方法可以“转换”现有的 bash-tab-completion 定义以在 zsh 中工作? I don't want to invest a ton of time in this, but if it's easy I'd save a moderate amount of effort.
我不想在这方面投入大量时间,但如果这很容易,我会节省一些精力。
autoload bashcompinit
bashcompinit
source /path/to/your/bash_completion_file
autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit
source /path/to/your/bash_completion_script
I am running zsh zsh 5.0.2 (x86_64-apple-darwin13.0)
without any ~/.zshrc and the above sequence worked in a freshly spawned zsh shell.我正在运行 zsh
zsh 5.0.2 (x86_64-apple-darwin13.0)
没有任何 ~/ zsh 5.0.2 (x86_64-apple-darwin13.0)
并且上述序列在新生成的 zsh shell 中工作。
Thanks to git-completion.bash script for the hint :D感谢 git-completion.bash 脚本的提示:D
Bash has awesome in built auto completion support but the bash autocomplete scripts don't work directly zsh as zsh environment doesn't have the essential bash autocomplete helper functions like compgen
, complete
. Bash 在内置自动完成支持方面非常
compgen
,但 bash 自动完成脚本不能直接运行 zsh,因为 zsh 环境没有必要的 bash 自动完成辅助功能,如compgen
、 complete
。 It does so in an effort to keep zsh session fast.这样做是为了让 zsh 会话保持快速。
These days zsh is shipped with appropriate completion scripts like compinit
and bashcompinit
which have the required functions to support bash autocomplete scripts. compinit
,zsh 附带了适当的完成脚本,如compinit
和bashcompinit
,它们具有支持 bash 自动完成脚本所需的功能。
autoload <func_name>
: Note that autoload is defined in zsh and not bash. autoload <func_name>
:请注意,自动加载是在 zsh 而不是 bash 中定义的。 autoload
looks for a file named in the directory paths returned by fpath
command and marks a function to load the same when it is first invoked. autoload
查找在fpath
命令返回的目录路径中命名的文件,并标记一个函数以在第一次调用时加载该文件。
For example on my system echo $fpath
returns /usr/share/zsh/site-functions
and /usr/share/zsh/5.0.5/functions
and both compinit
and bashcompinit
are available at /usr/share/zsh/5.0.5/functions
.例如在我的系统上
echo $fpath
返回/usr/share/zsh/site-functions
和/usr/share/zsh/5.0.5/functions
并且compinit
和bashcompinit
都可以在/usr/share/zsh/5.0.5/functions
。
Also for most people may be only autoload -U +X bashcompinit && bashcompinit
is required because some other script like git autocomplete or their own ~/.zshrc
may be doing autoload -U +X compinit && compinit
, but it's safe to just run both of them.同样对于大多数人来说,可能只需要
autoload -U +X bashcompinit && bashcompinit
因为其他一些脚本,如 git autocomplete 或他们自己的~/.zshrc
可能正在执行autoload -U +X compinit && compinit
,但只运行两者是安全的其中。
From this page (dated 2010/01/05):从此页面(日期为 2010/01/05):
Zsh can handle bash completions functions.
Zsh 可以处理 bash 完成功能。 The latest development version of zsh has a function bashcompinit, that when run will allow zsh to read bash completion specifications and functions.
zsh 的最新开发版本有一个函数 bashcompinit,运行时将允许 zsh 读取 bash 完成规范和函数。 This is documented in the zshcompsys man page.
这记录在 zshcompsys 手册页中。 To use it all you need to do is run bashcompinit at any time after compinit.
要使用它,您需要做的就是在 compinit 之后随时运行 bashcompinit。 It will define complete and compgen functions corresponding to the bash builtins.
它将定义与 bash 内置函数相对应的 complete 和 compgen 函数。
I am running Antigen as a Oh-My-Zsh plugin manager.我将Antigen作为 Oh-My-Zsh 插件管理器运行。 I had a few bash completion scripts written by coworkers that I wanted to load into Zsh with a simple
source /path/to/completion
.我有一些由同事编写的 bash 完成脚本,我想使用简单的
source /path/to/completion
将它们加载到 Zsh 中。
I had some trouble, because it seems like either Antigen or OMZ (hard to tell) concern themselves with only loading completion scripts from their plugins.我遇到了一些麻烦,因为似乎 Antigen 或 OMZ(很难说)只关心从他们的插件加载完成脚本。 I finally got around this by autoloading
bashcompinit
and compinit
after antigen apply
.我终于通过在
antigen apply
之后自动加载bashcompinit
和compinit
解决了这个问题。 Simply autoloading bashcompinit
wasn't enough.仅仅自动加载
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 creates its .zcompdump
file at $ANTIGEN_COMPDUMP
which for me was ~/.antigen/.zcompdump
Antigen 在
$ANTIGEN_COMPDUMP
创建它的.zcompdump
文件,对我来说是~/.antigen/.zcompdump
The re-invoke of compinit and bashcompinit create a second .zcompdump at $HOME/.zcompdump
重新调用 compinit 和 bashcompinit 在
$HOME/.zcompdump
创建第二个$HOME/.zcompdump
That seems to all work out, because I am able to use the completions set up by /path/to/bash_completion
.这似乎都解决了,因为我能够使用
/path/to/bash_completion
设置的完成。 I've deleted both .zcompdump files a few times to make sure they're regenerated and seems to work.我已经多次删除了 .zcompdump 文件以确保它们重新生成并且似乎可以工作。
I've had to rm the .zcompdump files a few times after a machine reboot because of errors thrown when trying to tab complete, but I'm unsure if that's due to this set up or something else.由于尝试完成选项卡时抛出错误,我不得不在机器重新启动后多次 rm .zcompdump 文件,但我不确定这是由于此设置还是其他原因。
rm ~/.zcompdump && rm $ANTIGEN_COMPDUMP
and a new shell fixes that for me. rm ~/.zcompdump && rm $ANTIGEN_COMPDUMP
和一个新的 shell 为我修复了这个问题。
Versions used at time of writing:撰写本文时使用的版本:
Antigen = v2.2.3 = d3d4ee0
Oh-my-zsh = c3b072e
Zsh = 5.3
For zsh
use:对于
zsh
使用:
compdef
compadd
My example:我的例子:
# 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
Source: My code https://github.com/reduardo7/bashx来源:我的代码https://github.com/reduardo7/bashx
@JatinKumar's answer got me on the right track, but I had to use complete
instead of source
. @JatinKumar 的回答让我走上了正确的道路,但我不得不使用
complete
而不是source
。 So all together:所以大家一起:
autoload -Uz compinit && compinit
autoload -U +X bashcompinit && bashcompinit
complete -C /usr/local/bin/terraform terraform
complete -C /usr/local/aws/bin/aws_completer aws
complete -C /usr/local/bin/az az
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.