Search code examples
zshzshrc

Using bindkey to call a function in zsh requires pressing enter after function runs


I'm new to zsh and am trying to bind a key sequence to a function with the following in my .zshrc:

say_hello(){
    echo "hello"
}
zle -N say_hello
bindkey '^Y' say_hello

Pressing Ctrl-Y will call the function and I'll see "hello" printed to the terminal but after I need to press Enter again before I'm given another zsh prompt. Calling the function by just typing in say_hello at the zsh prompt and pressing Enter does what I want - I see hello printed and then I'm given another zsh prompt. How can I get this behavior when binding the function to a key sequence?

Above is a simple example, really the function I'm trying to write is below:

my_cd() {
    if [[ "$#" -ne 0 ]]; then
        cd $(autojump $@)
        return
    fi
    dir_to_cd_to=$(fasd_cd -dl |  fzf --height 40% --reverse --inline-info)
    # above isn't so important - dir_to_cd_to could be obtained in any way
    cd "$dir_to_cd_to"
}

zle -N my_cd
bindkey -v '^Y' 'my_cd'

Solution

  • To display messages in a zle widget, you're supposed to use zle -M rather than echo. echo will output your message at whatever the current cursor position is which isn't especially helpful. If you really want to use echo, calling zle reset-prompt afterwards will redraw a fresh prompt. If you don't want a potential mess in your terminal, consider starting with \r to move the cursor to the beginning of the line and ending with $termcap[ce] to clear to the end of the line.