Zsh tab completion duplicating command name
Asked Answered
B

6

30

I'm on OS X Mountain Lion, running the included ZSH shell (4.3.11) with Oh-My-ZSH installed over the top.

When using tab completion with commands such as homebrew, when ZSH lists the available commands, it is also duplicating the command. For example:

$ brew {tab}

will result in:

$ brew brew 
[list of homebrew commands]

I'm unsure what is causing this error, as when I resize the terminal window, the first instance of the command name disappears.

If I hit backspace when the duplicates are displayed, I can only delete the second instance of the command, zsh won't let me backspace any further. Also, if I do remove the duplicate with backspace, zsh then acts as if there is no command typed at all.

My .zshrc along with all my other .configuration files can be found at https://github.com/daviesjamie/dotfiles

UPDATE: I found this post about someone having the same problem on Ubuntu. However, I don't understand the given solution, and I'm not even sure if it applies to my set up?

Babin answered 11/8, 2012 at 15:50 Comment(0)
J
32

The problem is likely to arise from misplaced %{ %} brackets that tell zsh that text inside has zero width. The only things that should be enclosed in them are escape sequences that change color or boldness of the text. If you are using new zsh (>=4.3.{unknown version}) I would even suggest to use %F{color}...%f, %K{color}...%k, %B...%b instead of %{${fg[green]}%} or what you have there.

The problem with them is that there is no way to query the terminal with a question like “Hey, I outputted some text. Where is the cursor now?” and zsh has to compute the length of its prompt by itself. When you type some text and ask zsh to complete zsh will say terminal to move cursor to specific location and type completed cmdline there. With misplaced %{%} brackets this specific location is wrong.

Justify answered 11/8, 2012 at 18:27 Comment(5)
Thank you! I now understand why it wasn't working; changing the colours to the format you specified fixed the problem perfectly.Babin
Also, as was my case, doing fancy stuff with the \b character in the prompt will cause the position to be off by 2.Predigest
It appears that in addition to wrapping ${fg[color]} colors in %{ %} brackets, you also need to wrap $reset_color in them.Another
This question is also relevant: superuser.com/questions/230301/… and the answer gives an example on replacing the characters correctly. As an amateur, it helped me.Shull
Worked, thank you!Bhagavadgita
R
36

This effect also could be reproduced if you use any of fancy UTF-8 characters like arrow, "git branch" character and so on.

Just remove this chars from prompt and duplication will not occur.

Also adding

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

to ~/.profile can help

Robbinrobbins answered 1/4, 2014 at 7:32 Comment(2)
That was it for me. Any idea how to enable the use of fancy unicode characters without messing up line editing?Morganite
Setting LC_ALL worked for me, but I had to insert the export instruction inside ~/.zshenv as it was not picked up from ~/.profileCorie
J
32

The problem is likely to arise from misplaced %{ %} brackets that tell zsh that text inside has zero width. The only things that should be enclosed in them are escape sequences that change color or boldness of the text. If you are using new zsh (>=4.3.{unknown version}) I would even suggest to use %F{color}...%f, %K{color}...%k, %B...%b instead of %{${fg[green]}%} or what you have there.

The problem with them is that there is no way to query the terminal with a question like “Hey, I outputted some text. Where is the cursor now?” and zsh has to compute the length of its prompt by itself. When you type some text and ask zsh to complete zsh will say terminal to move cursor to specific location and type completed cmdline there. With misplaced %{%} brackets this specific location is wrong.

Justify answered 11/8, 2012 at 18:27 Comment(5)
Thank you! I now understand why it wasn't working; changing the colours to the format you specified fixed the problem perfectly.Babin
Also, as was my case, doing fancy stuff with the \b character in the prompt will cause the position to be off by 2.Predigest
It appears that in addition to wrapping ${fg[color]} colors in %{ %} brackets, you also need to wrap $reset_color in them.Another
This question is also relevant: superuser.com/questions/230301/… and the answer gives an example on replacing the characters correctly. As an amateur, it helped me.Shull
Worked, thank you!Bhagavadgita
A
14

If you use iTerm on Mac, be sure to check "Set locale variables automatically" in your profile preferences. I had it unchecked for an SSH connection and it resulted in the same bug and I fixed it by leaving that option checked.

Aguste answered 6/4, 2015 at 13:5 Comment(2)
Oh man, it drove me crazy as I forgot I did the same change. Thanks!Younker
Finally, THIS was what was missing for me. Thanks for mentioning that!Inclinable
M
12

It's an old thread but I faced similar issue in my zsh setup with oh-my-zsh configuration.

Setting export LC_ALL=en_US.UTF-8 fixed the issue.

Monocular answered 1/7, 2014 at 11:30 Comment(1)
This resolved the problem for me with OSx Mojave (10.14.6) and iTerm2.Tenne
S
9

A lot of answers in a lot of places suggest the export LC_ALL=en_US.UTF-8 solution. This, however did not work for me. I continued to have this issue using oh-my-zsh on both Arch linux and PopOS.

The only solution that worked for me was this suggestion by romkatv on an issue on the oh-my-zsh github repository.

It turns out, at least in my case, that the autocomplete duplication issue would only show up if there was a non-ASCII character somewhere on the line (like an emoji). And ZSH would incorrectly assume that this non-ASCII character needs to take up 2 character spaces instead of 1.

So the solution that worked was to open up the .zsh-theme file of whatever theme you're using, find all non-ASCII characters and use %{%G%} to tell ZSH to only use one character width for that character

For example, the default oh-my-zsh theme robbyrussel contains 2 non-ASCII characters. The '➜' character in the prompt

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

and the '✗' character in the prompt for git directories

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

Using %{%G<character>%} around the 2 non-ASCII characters like this

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

and this

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

is what finally fixed the issue for me.

So all you need to do is make a copy of the theme file you want to use and edit all the non-ASCII characters as shown above and you should hopefully never see the duplication issue again.

Scrape answered 2/10, 2019 at 6:52 Comment(0)
L
0

My solution to make both local and ssh work is something like a combination of @Marc's and @neotohin's answers:

  1. Set export LANG=en_US.UTF-8 (simply uncomment that part in the template .zshrc; exporting LC_ALL, as in @neotohin's answer, instead of LANG may also work, I didn't try)
  2. Uncheck "Set locale environment variables on startup" in the Terminal profile's "Advanced" section (reason: that setting sets LC_CTYPE=UTF-8 instead of en_US.UTF-8, which brakes the locale for me in ssh)
Leonoreleonsis answered 20/4, 2017 at 7:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.