[英]git completion in zsh: __git_func_wrap:3: : not found
git-completion.zsh
and git-completion.bash
are installed automatically when running brew install git
:运行
brew install git
时会自动安装git-completion.zsh
和git-completion.bash
:
❯ ls -l /usr/local/share/zsh/site-functions/_git
lrwxr-xr-x 56 quanta 7 Jul 18:54 /usr/local/share/zsh/site-functions/_git -> ../../../Cellar/git/2.27.0/share/zsh/site-functions/_git
❯ ls -l /usr/local/share/zsh/site-functions/git-completion.bash
lrwxr-xr-x 71 quanta 7 Jul 18:54 /usr/local/share/zsh/site-functions/git-completion.bash -> ../../../Cellar/git/2.27.0/share/zsh/site-functions/git-completion.bash
/usr/local/share/zsh/site-functions
is included in fpath
: /usr/local/share/zsh/site-functions
包含在fpath
中:
❯ echo $fpath
/usr/local/share/zsh-completions
/usr/local/share/zsh/site-functions
/usr/share/zsh/site-functions
/usr/share/zsh/5.7.1/functions
For some reasons, sometimes when I type git reba
and press tab :由于某些原因,有时当我输入
git reba
并按tab时:
❯ git reba
__git_func_wrap:3: : not found
__git_func_wrap:3: : not found
❯ type __git_func_wrap
__git_func_wrap is a shell function from /usr/local/share/zsh/site-functions/git-completion.bash
https://github.com/git/git/blob/master/contrib/completion/git-completion.bash#L3517-L3522 https://github.com/git/git/blob/master/contrib/completion/git-completion.bash#L3517-L3522
❯ grep -A5 '^__git_func_wrap' /usr/local/share/zsh/site-functions/git-completion.bash
__git_func_wrap ()
{
local cur words cword prev
_get_comp_words_by_ref -n =: cur words cword prev
$1
}
What the default completion is:默认完成是什么:
❯ complete -p git
complete -o bashdefault -o default -o nospace -F __git_wrap_tig tig
complete _bash bash
Continue inspect:继续检查:
❯ type __git_wrap_tig
__git_wrap_tig is a shell function from /usr/local/share/zsh/site-functions/tig-completion.bash
The thing is I cannot find this function in tig-completion.bash问题是我在 tig -completion.bash中找不到这个 function
tig: stable 2.5.1 (bottled), HEAD
Text interface for Git repositories
https://jonas.github.io/tig/
/usr/local/Cellar/tig/2.5.1 (15 files, 875.9KB) *
Poured from bottle on 2020-07-06 at 16:01:38
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/tig.rb
==> Dependencies
Required: readline ✔
==> Options
--HEAD
Install HEAD version
==> Caveats
A sample of the default configuration has been installed to:
/usr/local/opt/tig/share/tig/examples/tigrc
to override the system-wide default configuration, copy the sample to:
/usr/local/etc/tigrc
Bash completion has been installed to:
/usr/local/etc/bash_completion.d
zsh completions and functions have been installed to:
/usr/local/share/zsh/site-functions
Looks like there is some changed recently: https://github.com/jonas/tig/commit/26ab51d28133354bfaa94d064bff37d29b3c30e3看起来最近有一些变化: https://github.com/jonas/tig/commit/26ab51d28133354bfaa94d064bff37d29b3c30e3
but where is __git_wrap_tig
function?但是
__git_wrap_tig
function在哪里?
PS: As I said above, this problem is not happen every time. PS:正如我上面所说,这个问题并非每次都会发生。 Sometimes, when I opened a new tab and check the default completion and it is just:
有时,当我打开一个新选项卡并检查默认完成时,它只是:
❯ complete -p git
complete _bash bash
and git
completion worked as expected.和
git
完成按预期工作。
Reply to @user1934428:回复@user1934428:
❯ grep '__git_complete ' /usr/local/share/zsh/site-functions/git-completion.bash
__git_complete ()
__git_complete git __git_main
__git_complete gitk __gitk_main
__git_complete git.exe __git_main
and one more invocation of __git_complete
is in tig-completion.bash :又一次调用
__git_complete
在 tig -completion.bash中:
# we use internal git-completion functions, so wrap _tig for all necessary
# variables (like cword and prev) to be defined
__git_complete tig _tig
This is a problem with the tig
completion definitions, and not with the git
completion definitions.这是
git
tig
定义的问题。
Activating completion on tig
breaks completion for git
.在
git
tig
完成。
tig
is activated after git
, then tig
completion works and git
completion is broken.git
tig
激活,则git
tig
被破坏。tig
completion is activated before git
, then they are both broken.tig
之前激活了git
完成,那么它们都被破坏了。 Install the old versions of the completion scripts.安装旧版本的完成脚本。
Unlink _tig and tig-completion.bash in /usr/local/share/zsh/site-functions
and replace with these older versions.在
/usr/local/share/zsh/site-functions
中取消链接 _tig 和 tig-completion.bash 并替换为这些旧版本。 Rename tig-completion.zsh
as _tig
when downloading.下载时将 tig
tig-completion.zsh
重命名为_tig
。
cd /usr/local/share/zsh/site-functions && \
rm -f _tig tig-completion.bash && \
wget -O _tig https://raw.githubusercontent.com/jonas/tig/91912eb97da4f6907015dab41ef9bba315730854/contrib/tig-completion.zsh && \
wget -O tig-completion.bash https://raw.githubusercontent.com/jonas/tig/c72aa4dab21077231a97dcca8e3821d7b35fe7db/contrib/tig-completion.bash
TODO: File issue with tig. TODO:tig 的文件问题。 This is a regression with the new completion script as implemented in jonas/tig#960
这是在jonas/tig#960中实现的新完成脚本的回归
I start with git tab completion working, and then at some point the shell "goes bad."我从 git 选项卡完成工作开始,然后在某个时候 shell “变坏了”。 I actually have three states
我实际上有三个状态
complete
not defined. complete
未定义。 % which complete
complete
complete
后仍在工作% git <TAB> add -- add file contents to the index bisect -- find by binary search the change that introduced a bug... % which complete complete () { return 0 }
complete
function defined referencing bash complete
的 function 定义参考 bash complete () { emulate -L zsh local args void cmd print remove args=("$@") zparseopts -D -a void o: A: G: W: C: F: P: S: X: ab c defgjkuvp=print r=remove if [[ -n $print ]] then printf 'complete %2$s %1$s\n' "${(@kv)_comps[(R)_bash*]#* }" elif [[ -n $remove ]] then for cmd do unset "_comps[$cmd]" done else compdef _bash_complete\ ${(j. .)${(q)args[1,-1-$#]}} "$@" fi }
unsetting the complete function unset -f complete
does not magically fix it.取消设置完整的 function
unset -f complete
并不能神奇地修复它。 I think this may leave me with no completion for git?我认为这可能会让我无法完成 git?
I jump in and out of virtual envs, and thought that was related, but a controlled example of jumping in and out and manually setting VIRTUAL_ENV and etc did not bleed over and affect the completion system.我跳进跳出虚拟环境,并认为这是相关的,但是跳进和跳出并手动设置 VIRTUAL_ENV 等的受控示例并没有溢出并影响完成系统。
distraction, not related分心,不相关
Digging further I found a lot of local variables set in the third case, "bad shell."进一步挖掘,我发现在第三种情况下设置了很多局部变量,“bad shell”。
I removed each of these local variables without any positive effect:我删除了这些局部变量中的每一个,但没有任何积极影响:
% unset REPLY
% unset __git_repo_path
% unset __tig_commands
% unset __tig_options
% unset _ack_raw_types
% unset $_cmd_variant
% unset _cmd_variant
Progress: I can move from state 1 to state 2 by invoking completion on tig:进度:我可以通过在 tig 上调用完成从 state 1 移动到 state 2:
% git <TAB>
add -- add file contents to the index
bisect -- find by binary search the change that introduced a bug
...
% tig <TAB>
% git <TAB>
__git_func_wrap:3: : not found
related broken state by completing with tig first:通过首先完成 tig 相关损坏的 state:
% tig <TAB>
__git_complete:5: command not found: complete
% which complete
complete () {
emulate -L zsh
local args void cmd print remove
args=("$@")
zparseopts -D -a void o: A: G: W: C: F: P: S: X: a b c d e f g j k u v p=print r=remove
if [[ -n $print ]]
then
printf 'complete %2$s %1$s\n' "${(@kv)_comps[(R)_bash*]#* }"
elif [[ -n $remove ]]
then
for cmd
do
unset "_comps[$cmd]"
done
else
compdef _bash_complete\ ${(j. .)${(q)args[1,-1-$#]}} "$@"
fi
}
% git <TAB>
__git_func_wrap:3: : not found
% echo $fpath
/usr/local/share/zsh/site-functions /usr/share/zsh/site-functions /usr/share/zsh/5.7.1/functions
% for f in $fpath; do ls $f/*tig*; done | cat
/usr/local/share/zsh/site-functions/_tig
/usr/local/share/zsh/site-functions/tig-completion.bash
zsh: no matches found: /usr/share/zsh/site-functions/*tig*
zsh: no matches found: /usr/share/zsh/5.7.1/functions/*tig*
% cd /usr/local/share/zsh/site-functions
% ls -l *tig*
_tig -> ../../../Cellar/tig/2.5.1/share/zsh/site-functions/_tig
tig-completion.bash -> ../../../Cellar/tig/2.5.1/share/zsh/site-functions/tig-completion.bash
% ls -l *git*
_git -> ../../../Cellar/git/2.28.0/share/zsh/site-functions/_git
git-completion.bash -> ../../../Cellar/git/2.28.0/share/zsh/site-functions/git-completion.bash
/usr/local/share/zsh/site-functions
/usr/local/share/zsh/site-functions
中的 Tig 完成_tig
#compdef tig # # zsh completion wrapper for tig # ============================== # # You need to install this script to zsh fpath with tig-completion.bash. # # The recommended way to install this script is to copy this and tig-completion.bash # to '~/.zsh/_tig' and '~/.zsh/tig-completion.bash' and # then add following to your ~/.zshrc file: # # fpath=(~/.zsh $fpath) _tig () { local ee=$(dirname ${funcsourcetrace[1]%:*})/git-completion.bash if [ -f $e ]; then GIT_SOURCING_ZSH_COMPLETION=y. $e fi e=$(dirname ${funcsourcetrace[1]%:*})/tig-completion.bash if [ -f $e ]; then. $e fi }
tig-completion.bash
#compdef git gitk # zsh completion wrapper for git # # Copyright (c) 2012-2013 Felipe Contreras <felipe.contreras@gmail.com> # # You need git's bash completion script installed somewhere, by default it # would be the location bash-completion uses. # # If your script is somewhere else, you can configure it on your ~/.zshrc: # # zstyle ':completion:*:*:git:*' script ~/.git-completion.zsh # # The recommended way to install this script is to make a copy of it in # ~/.zsh/ directory as ~/.zsh/git-completion.zsh and then add the following # to your ~/.zshrc file: # # fpath=(~/.zsh $fpath) complete () { # do nothing return 0 } zstyle -T ':completion:*:*:git:*' tag-order && \ zstyle ':completion:*:*:git:*' tag-order 'common-commands' zstyle -s ":completion:*:*:git:*" script script if [ -z "$script" ]; then local -a locations local e locations=( $(dirname ${funcsourcetrace[1]%:*})/git-completion.bash '/etc/bash_completion.d/git' # fedora, old debian '/usr/share/bash-completion/completions/git' # arch, ubuntu, new debian '/usr/share/bash-completion/git' # gentoo ) for e in $locations; do test -f $e && script="$e" && break done fi GIT_SOURCING_ZSH_COMPLETION=y. "$script" __gitcomp () { emulate -L zsh local cur_="${3-$cur}" case "$cur_" in --*=);; *) local c IFS=$' \t\n' local -a array for c in ${=1}; do c="$c${4-}" case $c in --*=*|*.);; *) c="$c ";; esac array+=("$c") done compset -P '*[=:]' compadd -Q -S '' -p "${2-}" -a -- array && _ret=0;; esac } __gitcomp_direct () { emulate -L zsh local IFS=$'\n' compset -P '*[=:]' compadd -Q -- ${=1} && _ret=0 } __gitcomp_nl () { emulate -L zsh local IFS=$'\n' compset -P '*[=:]' compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0 } __gitcomp_nl_append () { emulate -L zsh local IFS=$'\n' compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0 } __gitcomp_file_direct () { emulate -L zsh local IFS=$'\n' compset -P '*[=:]' compadd -f -- ${=1} && _ret=0 } __gitcomp_file () { emulate -L zsh local IFS=$'\n' compset -P '*[=:]' compadd -p "${2-}" -f -- ${=1} && _ret=0 } __git_zsh_bash_func () { emulate -L ksh local command=$1 local completion_func="_git_${command//-/_}" declare -f $completion_func >/dev/null && $completion_func && return local expansion=$(__git_aliased_command "$command") if [ -n "$expansion" ]; then words[1]=$expansion completion_func="_git_${expansion//-/_}" declare -f $completion_func >/dev/null && $completion_func fi } __git_zsh_cmd_common () { local -a list list=( add:'add file contents to the index' bisect:'find by binary search the change that introduced a bug' branch:'list, create, or delete branches' checkout:'checkout a branch or paths to the working tree' clone:'clone a repository into a new directory' commit:'record changes to the repository' diff:'show changes between commits, commit and working tree, etc' fetch:'download objects and refs from another repository' grep:'print lines matching a pattern' init:'create an empty Git repository or reinitialize an existing one' log:'show commit logs' merge:'join two or more development histories together' mv:'move or rename a file, a directory, or a symlink' pull:'fetch from and merge with another repository or a local branch' push:'update remote refs along with associated objects' rebase:'forward-port local commits to the updated upstream head' reset:'reset current HEAD to the specified state' restore:'restore working tree files' rm:'remove files from the working tree and from the index' show:'show various types of objects' status:'show the working tree status' switch:'switch branches' tag:'create, list, delete or verify a tag object signed with GPG') _describe -t common-commands 'common commands' list && _ret=0 } __git_zsh_cmd_alias () { local -a list list=(${${${(0)"$(git config -z --get-regexp '^alias\.')"}#alias.}%$'\n'*}) _describe -t alias-commands 'aliases' list $* && _ret=0 } __git_zsh_cmd_all () { local -a list emulate ksh -c __git_compute_all_commands list=( ${=__git_all_commands} ) _describe -t all-commands 'all commands' list && _ret=0 } __git_zsh_main () { local curcontext="$curcontext" state state_descr line typeset -A opt_args local -a orig_words orig_words=( ${words[@]} ) _arguments -C \ '(-p --paginate --no-pager)'{-p,--paginate}'[pipe all output into ''less'']' \ '(-p --paginate)--no-pager[do not pipe git output into a pager]' \ '--git-dir=-[set the path to the repository]: :_directories' \ '--bare[treat the repository as a bare repository]' \ '(-:)--version[prints the git suite version]' \ '--exec-path=-[path to where your core git programs are installed]:: :_directories' \ '--html-path[print the path where git''s HTML documentation is installed]' \ '--info-path[print the path where the Info files are installed]' \ '--man-path[print the manpath (see `man(1)`) for the man pages]' \ '--work-tree=-[set the path to the working tree]: :_directories' \ '--namespace=-[set the git namespace]' \ '--no-replace-objects[do not use replacement refs to replace git objects]' \ '(-:)--help[prints the synopsis and a list of the most commonly used commands]: :->arg' \ '(-): :->command' \ '(-)*:: :->arg' && return case $state in (command) _alternative \ 'alias-commands:alias:__git_zsh_cmd_alias' \ 'common-commands:common:__git_zsh_cmd_common' \ 'all-commands:all:__git_zsh_cmd_all' && _ret=0;; (arg) local command="${words[1]}" __git_dir if (( $+opt_args[--bare] )); then __git_dir='.' else __git_dir=${opt_args[--git-dir]} fi (( $+opt_args[--help] )) && command='help' words=( ${orig_words[@]} ) __git_zsh_bash_func $command;; esac } _git () { local _ret=1 local cur cword prev cur=${words[CURRENT]} prev=${words[CURRENT-1]} let cword=CURRENT-1 if (( $+functions[__${service}_zsh_main] )); then __${service}_zsh_main else emulate ksh -c __${service}_main fi let _ret && _default && _ret=0 return _ret } _git
The __git_complete
function contains this: __git_complete
function 包含以下内容:
__git_complete ()
{
local wrapper="__git_wrap${2}"
eval "$wrapper () { __git_func_wrap $2 ; }"
}
The new code of tig calls it like this: tig 的新代码这样称呼它:
__git_complete tig _tig
This code is effectively creating a wrapper called __git_wrap_tig
.此代码有效地创建了一个名为
__git_wrap_tig
的包装器。
__git_wrap_tig { __git_func_wrap _tig }
However, these functions are not meant to be used by the Zsh completion.但是,这些函数并不打算由 Zsh 补全使用。
The Zsh completion (latest version here ) is meant to be sourcing the bash completion by itself, and then calling __tig_main
directly, bypassing any wrappers. Zsh 补全( 此处为最新版本)旨在自行获取 bash 补全,然后直接调用
__tig_main
,绕过任何包装器。
The problem is that the main tig function must be called __tig_main
, not _tig
.问题是主 tig function必须称为
__tig_main
,而不是_tig
。 I've sent a patch to fix this and other discrepancies with the official git completion.我已经发送了一个补丁来修复这个和其他与官方 git 完成的差异。
If you install all the latest relevant files:如果您安装所有最新的相关文件:
Into your fpath
(eg ~/.zsh/
), it should work correctly.进入您的
fpath
(例如~/.zsh/
),它应该可以正常工作。
In your comment, you wrote, that you have installed the completion system from https://github.com/git/git/blob/master/contrib/completion/git-completion.bash , but for zsh, the correct sources should be the ones at https://github.com/git/git/blob/master/contrib/completion/git-completion.zsh在您的评论中,您写道,您已经从https://github.com/git/git/blob/master/contrib/completion/git-completion.bash安装了完成系统,但是对于 zsh,正确的来源应该是https://github.com/git/git/blob/master/contrib/completion/git-completion.zsh
According to the installation instruction: git-completion.zsh must be sourced from.zshrc.根据安装说明:git-completion.zsh 必须来源于.zshrc。 The bash version must be accessible from it.
必须可以从中访问 bash 版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.