ajeetdsouza / zoxide

A smarter cd command. Supports all major shells.
MIT License
20.54k stars 523 forks source link

zsh cd completions duplicate with group-name enabled #491

Open grimm26 opened 1 year ago

grimm26 commented 1 year ago

I stripped down my completions setup in zshrc to be just:

autoload -Uz compinit && compinit -C
eval "$(zoxide init -zsh)"

Now, I add a format and group-name setting and the strange behavior starts. When using cd tab completion, I get expected suggestions. When using z, I get a duplicate set of suggestions. Screenshot from 2022-12-05 08-30-00 Screenshot from 2022-12-05 08-29-46

ericbn commented 1 year ago

For reference, this is how to reproduce:

$ cd $(mktemp -d)
$ touch .zshrc
$ ZDOTDIR=${PWD} HOME=${PWD} exec zsh
$ autoload -Uz compinit && compinit -C
$ eval "$(zoxide init zsh)"
$ zstyle ':completion:*' format '%F{yellow}-- %d --%f'
$ zstyle ':completion:*' group-name ''
$ mkdir test{1,2}
$ z test<TAB>
-- file --
test1/  test2/
-- file --
test1/  test2/

@grimm26, I noticed it works as expected if you do eval "$(zoxide init zsh)" before autoload -Uz compinit && compinit -C, which is the opposite of what the zoxide documentation recommends:

For completions to work, the above line must be added after compinit is called. You may have to rebuild your cache by running rm ~/.zcompdump*; compinit.

grimm26 commented 1 year ago

@ericbn You are correct! I have no idea how/why but it works. Maybe just a documentation change is needed?

timkgh commented 1 year ago

I noticed it works as expected if you do eval "$(zoxide init zsh)" before autoload -Uz compinit && compinit -C

Not easy to do if you use prezto which does the autoload in its modules. ohmyzsh may have the same issue too.

timkgh commented 1 year ago

FWIW, zi doesn't have the duplicate behavior.

Subjective commented 10 months ago

I'm also experiencing this issue, but calling eval "$(zoxide init zsh)" before autoload -Uz compinit && compinit -C seems to completely break completions for me.

Squirreljetpack commented 8 months ago

I found a solution haha. I'm using zi so zoxide is run before compinit, but I still got the duplicate. Turns out the z commands default to a certain completion if no compdef is provided. To override this, add this: compdef zoxide_z=vim; compdef __zoxide_zi=vim;.

Kranzes commented 5 months ago

I found a solution haha. I'm using zi so zoxide is run before compinit, but I still got the duplicate. Turns out the z commands default to a certain completion if no compdef is provided. To override this, add this: compdef zoxide_z=vim; compdef __zoxide_zi=vim;.

That's not a solution, this makes it so the completions for zoxide will be the completions of vim.

Kranzes commented 5 months ago

I'm also experiencing this issue, but calling eval "$(zoxide init zsh)" before autoload -Uz compinit && compinit -C seems to completely break completions for me.

Same

urob commented 4 months ago

For anyone looking for a workaround, I got things working by replacing _files -/ in __zoxide_z_complete() with _path_files -/. Despite it being recommended against, this is also incidentally what the builtin _cd completion function for cd calls.

Here's the full completions snippet with the fix:

# Completions.
if [[ -o zle ]]; then
    function __zoxide_z_complete() {
        # Only show completions when the cursor is at the end of the line.
        # shellcheck disable=SC2154
        [[ "${#words[@]}" -eq "${CURRENT}" ]] || return 0

        if [[ "${#words[@]}" -eq 2 ]]; then
            # call _path_files directly to avoid duplication issue #491
            _path_files -/
        elif [[ "${words[-1]}" == '' ]] && [[ "${words[-2]}" != "${__zoxide_z_prefix}"?* ]]; then
            \builtin local result
            # shellcheck disable=SC2086,SC2312
            if result="$(\command zoxide query --exclude "$(__zoxide_pwd)" --interactive -- ${words[2,-1]})"; then
                result="${__zoxide_z_prefix}${result}"
                # shellcheck disable=SC2296
                compadd -Q "${(q-)result}"
            fi
            \builtin printf '\e[5n'
        fi
        return 0
    }

    \builtin bindkey '\e[0n' 'reset-prompt'
    [[ "${+functions[compdef]}" -ne 0 ]] && \compdef __zoxide_z_complete __zoxide_z
fi
mikegreiling commented 2 months ago

this bug is quite annoying, I'm surprised more people have not been running into it

Kranzes commented 2 months ago

This solved it for me #787

urob commented 2 months ago

This solved it for me #787

~Seems to be the fix that I have posted above. Glad someone picked it up and submitted a PR.~

EDIT: scratch that. The PR uses the builtin cd auto completion.

grimm26 commented 2 months ago

I do notice that using _cd vs _path_file gives slightly different result in that it is titled with local when using _cd. :shrug:

urob commented 2 months ago

I do notice that using _cd vs _path_file gives slightly different result in that it is titled with local when using _cd. :shrug:

Yes, nevermind my previous comment. Not sure where my head was. I remember considering just applying the builtin autocompletion (like the PR does) and then discarding it for _path_file. I don't quite recall my reasoning atm, will look into it later.

11Firefox11 commented 1 month ago

I met this problem too. As @urob mentioned you shouldn't change the autocomplete behaviour, but changing the _files -/ line helps. Since the upper referenced 787 pull request replaces the _files -/ line with _cd -/ I did that too. For a simple sed solution I put this code in my ~/.zshrc: eval "$(zoxide init --cmd cd zsh | sed 's/_files/_cd/g')".