Zsh选项卡补全复制命令名称

30

我使用的是装有 Oh-My-ZSH 的自带 ZSH shell(4.3.11)的 OS X Mountain Lion。

在使用像 homebrew 这样的命令时,当 ZSH 列出可用命令时,它也会复制该命令。例如:

$ brew {tab}

将导致如下结果:

$ brew brew 
[list of homebrew commands]

我不确定是什么原因导致这个错误,因为当我调整终端窗口大小时,命令名称的第一个实例会消失。

如果在显示重复内容时按退格键,我只能删除命令的第二个实例,zsh不让我再往前删除。此外,如果我用退格键删除了重复项,zsh会认为根本没有输入任何命令。

我的 .zshrc 文件和其他所有配置文件都可以在https://github.com/daviesjamie/dotfiles找到。

更新:我在 这篇文章中找到了一个有关Ubuntu上出现相同问题的帖子。然而,我不理解给出的解决方案,也不确定它是否适用于我的设置?

6个回答

36

如果使用任何像箭头、“git分支”字符等漂亮的UTF-8字符,则也可以复制此效果。

只需从提示中删除这些字符,就不会发生重复。

同时在~/.profile中添加

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

可以有所帮助。


这就是我的问题了。有什么想法可以在不搞乱行编辑的情况下启用使用花式Unicode字符吗? - Alex North
设置 LC_ALL 对我有用,但是我必须将导出指令插入到 ~/.zshenv 中,因为它没有被从 ~/.profile 中选取。 - Cec

31
问题很可能出现在放错位置的%{%}括号中,这些括号告诉zsh文本内部的宽度为零。唯一应该放在其中的是改变文本颜色或加粗的转义序列。如果您正在使用新的zsh(>=4.3.{未知版本}),我甚至建议使用%F{color}...%f%K{color}...%k%B...%b,而不是%{${fg[green]}%} 或其他类似的语句。
问题在于没有办法通过像“嘿,我输出了一些文本,光标现在在哪里?”这样的问题来查询终端,zsh必须自己计算其提示的长度。当你键入一些文本并要求zsh完成时,zsh会告诉终端将光标移动到特定位置并在那里输入已完成的命令行。使用放错位置的%{%}括号时,这个特定位置是错误的。

1
谢谢!我现在明白为什么它没有工作了;将颜色更改为您指定的格式完美地解决了问题。 - Jamie
同样地,就像我的情况一样,在提示符中使用\b字符进行花式操作会导致位置偏移2个字符。 - Martín Valdés de León
1
似乎除了将${fg[color]}颜色包裹在%{ %}括号中,您还需要将$reset_color也包裹在其中。 - Isabell Cowan
这个问题也与以下内容相关:https://superuser.com/questions/230301/strange-zsh-autocomplete-behaviour ,答案给出了正确替换字符的示例。作为一名业余爱好者,这对我很有帮助。 - thegreatcoder

13
如果您在Mac上使用iTerm,请确保在配置文件的偏好设置中勾选“自动设置区域变量”。我在SSH连接中没有勾选它,导致出现了相同的错误,后来我通过保持该选项被勾选来修复了这个问题。

哦,天啊,我都快被自己忘记做了同样的更改搞疯了。谢谢! - Christian
最后,这就是我缺少的东西。感谢你提到了它! - Frerich Raabe

12

这是一个旧的帖子,但我在使用oh-my-zsh配置的zsh设置中遇到了类似的问题。

export LC_ALL=en_US.UTF-8 设置解决了此问题。


这对我在OSx Mojave(10.14.6)和iTerm2中解决了问题。 - cimere

9
许多地方的答案都建议使用export LC_ALL=en_US.UTF-8的解决方法。但是这对我没有用。我在Arch Linux和PopOS上使用oh-my-zsh仍然遇到了这个问题。
唯一有效的解决方法是this,由romkatv在oh-my-zsh的github存储库上提出的建议。
事实证明,在我的情况下,如果一行中有非ASCII字符(比如一个表情符号),自动补全重复问题只会出现一次。ZSH会错误地假定这个非ASCII字符需要占用两个字符位置,而不是一个。
所以,有效的解决方法是打开你正在使用的主题的.zsh-theme文件,找到所有的非ASCII字符,并使用%{%G%}告诉ZSH只使用一个字符宽度来表示该字符。
例如,默认的oh-my-zsh主题robbyrussel包含2个非ASCII字符。提示符中的'➜'字符。
PROMPT="%(?:%{$fg_bold[green]%}➜ :%{$fg_bold[red]%}➜ )"

在git目录的提示符中,'✗'字符表示未提交的更改。
ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}✗"

使用%{%G<character>%}将这两个非ASCII字符包裹起来,就像这样

PROMPT="%(?:%{$fg_bold[green]%}%{%G➜%} :%{$fg_bold[red]%}%{%G➜%} )"

和这个

ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}%{%G✗%}"

这对我最终解决了问题。

所以,您需要做的就是复制要使用的主题文件,并像上面展示的那样编辑所有非ASCII字符,然后您就不应该再次看到重复问题了。


0

我解决本地和ssh同时工作的方法类似于@Marc和@neotohin的答案的结合:

  1. 设置export LANG=en_US.UTF-8(只需取消模板.zshrc中的该部分的注释;导出LC_ALL,如@neotohin的答案所述,而不是LANG也可能有效,我没有尝试)
  2. 取消选中终端配置文件的“高级”部分中的“启动时设置区域环境变量”(原因:该设置会将LC_CTYPE=UTF-8设置为en_US.UTF-8,这会使我在ssh中破坏语言环境)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接