3

I just installed zsh and oh-my-zsh (my previous shell was bash). My .zshrc is completely unmodified from oh-my-zsh's default settings. The "git" plugin is the only enabled plugin (it's enabled by default).

I created a very simple theme using this technique:

setopt PROMPT_SUBST
PROMPT='[%D{%L:%M:%S}] '
TMOUT=1
TRAPALRM() {
  zle reset-prompt
}

After enabling this theme, I am finding that the up and down arrow keys do not properly recall my history:

  • When I press the up arrow once, my most recent command is recalled, as expected.
  • When I press the up arrow a second time, nothing happens. I expected my next-most-recent command to be recalled.
  • When I press the down arrow after pressing the up arrow the first time, nothing happens. I expected the prompt to go back to the empty prompt I started with.

If I replace my .zshrc with only the contents of the script above (essentially using the prompt settings from the theme but disabling oh-my-zsh), my up and down arrows work as expected.

If I go back to my oh-my-zsh .zshrc and comment out the zle reset-prompt line in my theme, my history works fine (but the clock is no longer live).

How can I use both oh-my-zsh and zle reset-prompt without causing my up/down arrows to behave differently? Is this a bug in oh-my-zsh, or a configuration error?

3
  • if i increase the TMOUT, it becomes clear that the arrow keys work fine until the TRAPALRM gets fired, then it locks up. Commented Feb 23, 2017 at 23:17
  • What version of zsh is this? I don't see this problem on zsh 5.7.1.
    – Phil Hord
    Commented Jan 7, 2020 at 20:19
  • @phord i don't know but when i got rid of oh-my-zsh the problem went away. Commented Jan 7, 2020 at 20:22

1 Answer 1

1

you can use this function instead

TRAPALRM() {
    case "$WIDGET" in
        expand-or-complete|self-insert|up-line-or-beginning-search|down-line-or-beginning-search|backward-delete-char|.history-incremental-search-backward|.history-incremental-search-forward)
            :
            ;;

        *)
            zle reset-prompt
            ;;
    esac
}

Basically, this runs zle reset-prompt only when the WIDGET is not inside the case. You can add the list of widgets for ignoring the reset-prompt there by seperating with |

The problem is, TMOUT actually specifies the timeout of a shell. After the shell timeout, it will fire SIGALRM signal and exit the shell. The TRAPALRM() function will catch the SIGALRM signals and intercept the exit, while executing the defined function instead.

Your up/down arrows does not behave differently, instead it fires when the prompt is resetting, thus behave strangely. The function above will not run zle reset-prompt when you are typing or scrolling through history, and removes the lag. The only drawbacks is that the prompt won't be able to update after you type, until you do something that is outside of the widgets (like pressing ENTER which fires the accept-line widgets).

You must log in to answer this question.

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