Search code examples
widgetzshcompletionzsh-zlefzf

widgets can only be called when ZLE is active


I have been dealing with this problem for almost a month now, and I feel frustrated, Any help would be greatly appreciated.

I am trying to write a widget for my takenote command. The purpose of the widget is to feed all the markdown files in ~/notes folder into fzf so that the user can select one of them and starts editing it. After the user types takenote and presses <tab> I expect the widget to run.

Here is the _takenote.zsh widget definition:

#compdef takenote
local file=$( find -L "$HOME/notes/" -print 2> /dev/null | fzf-tmux +m )
zle reset-prompt
compadd $file
return 1

Unfortunately, the above code doesn't work because of zle reset-prompt, if I remove it then the result would be like this:

before selection

And after selecting the file it would turn into:

After selecting the file

Which as you see will corrupt the prompt and the command itself. It appears to me that what I need to do is do a zle reset-prompt before calling compadd but this can only work when I bind the function to a key otherwise, I will get the following error:

widgets can only be called when ZLE is active


Solution

  • After two days, I finally managed to find a hint on how to achieve it thanks to the excellent fzf-tab-completion project:

    https://github.com/lincheney/fzf-tab-completion/blob/c91959d81320935ae88c090fedde8dcf1ca70a6f/zsh/fzf-zsh-completion.sh#L120

    So actually, all that you need to do is:

    #compdef takenote
    local file=$( find -L "$HOME/notes/" -print 2> /dev/null | fzf-tmux +m )
    compadd $file
        
    TRAPEXIT() {
       zle reset-prompt
    }
    return 0
    

    And it finally works. Cheers!