Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ZSH auto-complete screws up command name

When I start doing tab auto-complete of a command, it keeps what I initally typed next to it and the command becomes unreadable. In the example below, I typed 'git che' and hit tab. Once I select 'checkout' the command prompt becomes 'git che git checkout'. The command still works and in my history it stores 'git checkout'. But its pretty annoying visually. Is there anyway to change this behavior. I tried this in 2 different terminal emulators, so I can confirm its ZSH and not the emulator. Thanks

Screenshot

EDIT:

echo $ZSH_VERSION
4.3.10

It doesnt seem to happen with zsh -f. Though its hard to tell since the only autocomplete that works is directories. I'm using 'oh-my-zsh' with this custom theme:

autoload -U add-zsh-hook
add-zsh-hook chpwd do_ls_on_chdir

function do_ls_on_chdir() {
    ls; 
}

function dirStack(){
OUT='';
NUM=1;
for X in $(dirs | cut -d ' ' -f2-10); do
    OUT="$OUT$1%B$NUM:%b$1$X ";
    (( NUM=NUM+1 ))
done
echo $OUT;

}

ZSH_THEME_GIT_PROMPT_ADDED=""
ZSH_THEME_GIT_PROMPT_MODIFIED=""
ZSH_THEME_GIT_PROMPT_DELETED=""
ZSH_THEME_GIT_PROMPT_RENAMED=""
ZSH_THEME_GIT_PROMPT_UNMERGED=""
ZSH_THEME_GIT_PROMPT_UNTRACKED=""

ZSH_THEME_GIT_PROMPT_AHEAD="%{$fg_bold[yellow]%}↑"
ZSH_THEME_GIT_PROMPT_PREFIX=""
ZSH_THEME_GIT_PROMPT_SUFFIX=""
ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg_bold[red]%}✗"
ZSH_THEME_GIT_PROMPT_CLEAN=" %{$fg_bold[green]%}✔"

local user_color='blue'
local back="${BG[237]}"
test $UID -eq 0 && user_color='red'

PROMPT='$(dirStack $back)
$back%B%!%b$back %{$fg_bold[$user_color]%}%~%{$reset_color%}'\
'$back $(git_prompt_status)%{$reset_color%}'\
'$back%{$fg_bold[magenta]%}$(git_prompt_info)%{$reset_color%}'\
'$back$(git_prompt_ahead)$reset_color'\
'$back%(!.#.>)$reset_color '

PROMPT2='%{$fg[red]%}%_ %{$reset_color%}'
PROMPT3='%{$fg[red]%}... %{$reset_color%}'
RPROMPT='%(?..%{$fg_bold[red]%}exit %?%{$reset_color%})'\
' %{$FG[186]%}(%D %*)%{$reset_color%}'

SOLUTION:

NOTE: stackoverflow wont let me answer my own question since I asked it within the past 8 hours. I dont feel like waiting.

So I figured it out. It turns out I wasnt properly escaping the ANSI color codes (I think). Everywhere I had $reset_color in my PROMPT variable, I changed that to %{$reset_color%} and it fixed it.

like image 716
Chris Avatar asked Oct 31 '11 17:10

Chris


1 Answers

So I figured it out. It turns out I wasnt properly escaping the ANSI color codes (I think). Everywhere I had $reset_color in my PROMPT variable, I changed that to %{$reset_color%} and it fixed it.

I only discovered this link tonight, after messing with my prompt - I'd always wondered why the ZSH prompt examples seemed so needlessly complex.

When you set up the colors in your zsh prompt, you should escape things with %{ [...] %}, so that 'the shell knows there is no output from these sequences and the cursor hasn't moved'.

If you don't escape this, the shell believes that your cursor has moved (even though it hasn't). This leads to messed up prompts, and rather annoying visual effects when you use tab-completion etc.

Here's some screenshots without escaping the reset-color prompt sequence (PR_NO_COLOUR="%{$terminfo[sgr0]%}", in my prompt settings). As we can see, the cursor starts in the wrong place:

Cursor starts in the wrong place

It should be here:

Correctly-placed cursor

And after trying tab-completion without escaping, the prompt is all confused about where the text is, and where the cursor should be placed:

Cursor is in the middle of the word

(The cursor should be placed at the end of the directory, not halfway through).

So the prompt sequences look like this:

PS1="%{$fg[red]%}%n%{$reset_color%}@%{$fg[blue]%}%m %{$fg[yellow]%}%~ %{$reset_color%}%% "

because everything has to be escaped nicely inside %{...%} pairs.

like image 111
simont Avatar answered Sep 20 '22 03:09

simont