How to bind a keyboard shortcut in zsh to a program requiring stdin

keyboard shortcutsrangerzlezsh

This is a follow-up to this question: I'm trying to create a keyboard shortcut for the terminal file manager ranger, in order to jump from the zsh prompt into the file manager with a single keystroke. I was following the linked answer, adding this to my .zshrc:

run_ranger () { echo; ranger; zle redisplay }
zle -N run_ranger
bindkey '^f' run_ranger

The key binding itself works, however ranger fails to start with Error: Must run ranger from terminal. I had a look at the ranger code (Python) and it performs the common check sys.stdin.isatty() to verify that is has a TTY stdin. How can I modify the zle widget so that stdin is properly set?

Best Answer

@llua's comment was indeed the trick to solve the stdin issue, thanks!

My use case required yet another deviation from the linked question. I'm using ranger to change the working directory (using this trick). In this case the zle redisplay has to be replaced by zle reset-prompt to properly change the prompt (see this question). The full solution becomes:

run_ranger () {
    echo
    ranger --choosedir=$HOME/.rangerdir < $TTY
    LASTDIR=`cat $HOME/.rangerdir`
    cd "$LASTDIR"
    zle reset-prompt
}
zle -N run_ranger
bindkey '^f' run_ranger
Related Question