Hope you're doing well.

I have the following in my .zshrc:

# 1. invoke zoxide to pick dir
# 2. open target dir in ranger
# 3. when exiting ranger, cd into last dir
zoxide_to_ranger () {
    eval 'ranger "$(zoxide query -i)" --choosedir=$HOME/.rangerdir < $TTY'
    LASTDIR=$(< ~/.rangerdir)
    cd "$LASTDIR" || exit

    # ensure `precmds` are run after `cd`
    local precmd
    for precmd in $precmd_functions; do
    zle reset-prompt

zle -N zoxide_to_ranger
bindkey '^f' zoxide_to_ranger

As suggested in the inline comment, it's a handy tool such that when I trigger Ctrl-f, it'll prompt me a fzf menu, and upon selection it'll open ranger in that dir.

The problem is that, when I want to cancel selection by pressing Esc, it'll still open up ranger and send me the home dir, which is not what I want.

So my question is, how do I cancel such a zle function after triggering the bindkey?


zsh 5.9 (x86_64-pc-linux-gnu)

OS: Manjaro Linux

Any input is much appreciated. Thank you:)

1 Answer 1


The eval line is doing several things. Maybe too many things. One approach would be to separate out the zoxide call, and to check whether it has returned something. Another need would be to check whether ~/.rangerdir has a directory (or something) in it, and to empty that file after use. These new checks create multiple points the function must cleanup and exit from:

function zoxide_to_ranger {
  local zz; zz=$(zoxide query -i)
  [[ -z $zz ]] && { zle reset-prompt; return }

  # not sure if the 'eval' is necessary; does ranger ever exit with
  # shell commands to be run?
  ranger $zz --choosedir=~/.rangerdir < $TTY

  local dd; dd=$(< ~/.rangerdir)
  [[ -z $dd ]] && { zle reset-prompt; return }
  :> ~/.rangerdir

  # this could be "local" unless you use it elsewhere
  cd $LASTDIR || { zle reset-prompt; return }

  local precmd; for precmd in $precmd_functions; $precmd
  zle reset-prompt
  • Hello @thrig. Thank you so much for helping me out. I really appreciate it. However, I tried both solutions but ended up hanging in the terminal (empty screen with no cursor). I need to press Esc again to go back to prompt. I looked into man zoxide but couldn't find the exit code. zoxide query -i and then a simple Esc takes me back to prompt. I suspect it's a ranger issue? Any idea?
    – kohane15
    Jul 7, 2022 at 5:20
  • Hello @thrig. You just made my day! Thank you again after almost a year later. I see that you've edited your answer and it's exactly what I needed. I've studied how you restructured with multiple checks. Thank you again!
    – kohane15
    Apr 18 at 13:48
  • I've tried the edited solution but found that I need to change from --choosedir=~/.rangerdir to --choosedir=$HOME/.rangerdir (i.e., you need to change from ~ to $HOME) in order for it to work. Cheers!
    – kohane15
    Apr 19 at 7:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .