Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove delay after pressing Esc key #111

Closed
3 tasks done
Hubro opened this issue Jul 1, 2021 · 19 comments
Closed
3 tasks done

Remove delay after pressing Esc key #111

Hubro opened this issue Jul 1, 2021 · 19 comments
Assignees
Labels
bug Something isn't working verified This issue was already verified

Comments

@Hubro
Copy link

Hubro commented Jul 1, 2021

General information

Basic examination

  • I have read through the README page
  • I have the latest version of zsh-vi-mode
  • I have tested with another terminal program (Gnome Terminal)

Problem description

After pressing Esc, there is a short delay before ZVM enters Normal mode.

  1. Press down Esc key
  2. Release Esc key
  3. ~200 ms
  4. Normal mode

This means that very often when I press: EsckEnter in order to run the previous command, nothing happens. If I intentionally do it slowly, it works, but this is a key combination I press very, very often, so I naturally do it really fast.

Reproduction steps

Read above

Expected behavior

Ideally ZVM would enter Normal mode immediately when the Esc key is pressed down, with no delay.

To compare, I have tried:

  • vim/nvim in the terminal
  • Bash built-in vi-mode
  • ZSH built-in vi-mode

None of the above have any perceivable delay after pressing Esc. I can press EsckEnter as fast as I possibly can, and they never miss any of the keystrokes.

@jeffreytse jeffreytse self-assigned this Jul 2, 2021
@jeffreytse
Copy link
Owner

jeffreytse commented Jul 2, 2021

Hi @Hubro

Thanks for the reporting, could your provide me your dotfiles (e.g. .zshrc) and keybindings (i.e. typing this command bindkey -M viins | grep '"\^\[' in your term)? I will try to help you solve this issue as soon as possible.

Thanks and regards

@Hubro
Copy link
Author

Hubro commented Jul 2, 2021

Hi @Hubro

Thanks for the reporting, could your provide me your dotfiles (e.g. .zshrc) and keybindings (i.e. typing this command bindkey -M viins | grep '"\^\[' in your term)? I will try to help you solve this issue as soon as possible.

Thanks and regards

Of course:

.zshrc

HISTFILE=~/.histfile
HISTSIZE=10000
SAVEHIST=10000
KEYTIMEOUT=1
setopt SHARE_HISTORY nomatch notify
#bindkey -v
bindkey '^R' history-incremental-search-backward

WORDCHARS='*?_-.[]~=&;!#$%^(){}<>'

fpath=(~/Dropbox/Config/zsh-completions $fpath)


#
# Completion config
#

zstyle ':completion:*' completer _expand _complete _ignored _correct _approximate
zstyle ':completion:*' max-errors 2
zstyle :compinstall filename '/home/tomas/.zshrc'

autoload -Uz compinit
compinit

#
# Antigen plugin manager
#
# This block of config works automatically with the "antigen-git" AUR package
# on Arch and with the "antigen" homebrew package on macOS.
#

# Possible init script locations
ANTIGEN_INIT_SCRIPT=(
    "/usr/share/zsh/share/antigen.zsh"
    "/usr/local/share/antigen/antigen.zsh"
)

for ANTIGEN_INIT_SCRIPT_PATH in "${ANTIGEN_INIT_SCRIPT[@]}"; do
    if [[ -f "$ANTIGEN_INIT_SCRIPT_PATH" ]]; then
        source "$ANTIGEN_INIT_SCRIPT_PATH"

        antigen bundle jeffreytse/zsh-vi-mode

        #NVM_NO_USE=true
        #NVM_AUTO_USE=true
        ##NVM_LAZY_LOAD=true
        #antigen bundle lukechilds/zsh-nvm

        antigen apply

        # Configure zsh-vi-mode
        ZVM_INSERT_MODE_CURSOR=$ZVM_CURSOR_BLINKING_BEAM
        ZVM_NORMAL_MODE_CURSOR=$ZVM_CURSOR_BLOCK
        ZVM_LINE_INIT_MODE=$ZVM_MODE_INSERT
        ZVM_CURSOR_STYLE_ENABLED=true
        #ZVM_INSERT_MODE_CURSOR=$ZVM_CURSOR_BLINKING_BLOCK
        #ZVM_NORMAL_MODE_CURSOR=$ZVM_CURSOR_BLOCK

        break
    fi
done

unset ANTIGEN_INIT_SCRIPT
unset ANTIGEN_INIT_SCRIPT_PATH

# Executed automatically by zsh-vi-mode for setting up keybindings
function zvm_after_lazy_keybindings() {
    # Put custom keybinds in here
}

#
# Kubectl completion
#
#if which kubectl &>/dev/null; then
#    eval "$(kubectl completion zsh 2>/dev/null)"
#fi

#
# Shell init script
#
SHELL_SETUP="$HOME/Dropbox/Config/shell-setup.zsh"
[[ -f "$SHELL_SETUP" ]] && source "$SHELL_SETUP"
unset SHELL_SETUP

#
# Pyenv
#
if which pyenv &>/dev/null; then
    eval "$(pyenv init - --no-rehash)"
    eval "$(pyenv virtualenv-init - --no-rehash)"
fi

#
# NVM (Node Version Manager)
#
NVM_INIT_SCRIPT="/usr/share/nvm/init-nvm.sh"
if [[ -f "$NVM_INIT_SCRIPT" ]]; then
    source "$NVM_INIT_SCRIPT" --no-use
    #source "$NVM_INIT_SCRIPT"
fi

#
# Starship
#
if which starship &>/dev/null; then
    eval "$(starship init zsh)"
fi

#
# Direnv (https://direnv.net/)
#
if which direnv &>/dev/null; then
    eval "$(direnv hook zsh)"
fi

#
# Broot
#
if which broot &>/dev/null; then
    source /home/tomas/.config/broot/launcher/bash/br
fi

#
# Allow parent to initialize shell
#
# This is awesome for opening terminals in VSCode.
#
if [[ -n $ZSH_INIT_COMMAND ]]; then
    echo "Running: $ZSH_INIT_COMMAND"
    eval "$ZSH_INIT_COMMAND"
fi

#
# Syntax highlighting
#
SYNTAX_HIGHLIGHTING_INIT="/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
if [[ -f "$SYNTAX_HIGHLIGHTING_INIT" ]]; then
    source "$SYNTAX_HIGHLIGHTING_INIT"
fi

.zprofile

export PATH="$HOME/Dropbox/bin:$PATH"
export PATH="$HOME/bin:$PATH"
export PATH="$HOME/.local/bin:$PATH"
export PATH="$HOME/.poetry/bin:$PATH"

# Used by direnv
export NODE_VERSIONS="$HOME/.nvm/versions/node"
export NODE_VERSION_PREFIX="v"

# Tell Neovide to use extra fancy animations
export NeovideMultiGrid=1

# Very Linux specific stuff here
if [[ "$(uname)" != "Darwin" ]]; then
    export SWAYSOCK="/run/user/$UID/sway.sock"

    export EDITOR=vim
    export LESSCHARSET=UTF-8

    export PYENV_ROOT="$HOME/.pyenv"
    export PATH="$PYENV_ROOT/bin:$PATH"
    eval "$(pyenv init --path)"
fi

#[[ -f ~/.zshrc ]] && . ~/.zshrc
➜ bindkey -M viins | grep '"\^\['
"^[" zvm_readkeys_handler
"^[," _history-complete-newer
"^[/" _history-complete-older
"^[OA" up-line-or-history
"^[OB" down-line-or-history
"^[OC" vi-forward-char
"^[OD" vi-backward-char
"^[[200~" bracketed-paste
"^[[A" up-line-or-history
"^[[B" down-line-or-history
"^[[C" vi-forward-char
"^[[D" vi-backward-char
"^[~" _bash_complete-word

@jeffreytse jeffreytse added bug Something isn't working verified This issue was already verified labels Jul 3, 2021
@jeffreytse
Copy link
Owner

Hi @Hubro

This issue has been addressed and fixed. Please update to the latest version and try again.

Thanks and regards

@Hubro
Copy link
Author

Hubro commented Jul 3, 2021

@jeffreytse Awesome! The delay is still there, but now my keystrokes are never lost. They are just slightly delayed. That's a massive improvement 😄

@Alex-duzhichao
Copy link

@jeffreytse Hi, I am using blinking beam as insert mode cursor style and blinking block as normal mode cursor style. When I switch from insert mode to normal mode, I noticed there is a little delay between when I press ESC key and when the cursor becomes to blinking block. But when I switch from normal mode to insert mode, the cursor becomes to blinking beam instantly. I searched this problem on the internet and find this question.
Is there any solution that can switch the cursor style from insert mode to normal mode instantly? Thank you very much.

@jeffreytse
Copy link
Owner

Hi @Alex-duzhichao

Thanks for your question, can you provide me some more details such as a video record for this behavior, your environment info and so on.

Thanks & Regards

@Alex-duzhichao
Copy link

Hi @Alex-duzhichao

Thanks for your question, can you provide me some more details such as a video record for this behavior, your environment info and so on.

Thanks & Regards

Hi @jeffreytse
Thank you for you reply. After some test, I find the npm plugin in ohmyzsh is the reason causes the delay. After uninstall the npm plugin, the delay disappears.
Thank you for your help again.

@jeffreytse
Copy link
Owner

jeffreytse commented Feb 23, 2022

Hi @Alex-duzhichao

It's glad to hear your good news. Welcome to star this project for further update in the future.
And hope you have a good day! : )

Thanks & Regards

@Hubro
Copy link
Author

Hubro commented Feb 23, 2022

Thank you for you reply. After some test, I find the npm plugin in ohmyzsh is the reason causes the delay. After uninstall the npm plugin, the delay disappears.

I had the exact same issue with the exact same plugin. I don't think it's really the plugin's fault, but NVM itself. When you source the NVM script it takes a second or two for some reason. I worked around the issue by installing NVM through my package manager and sourcing it myself with the --no-use flag, which avoids the startup delay.

# Arch Linux
NVM_INIT_SCRIPT="/usr/share/nvm/init-nvm.sh"
if [[ -f "$NVM_INIT_SCRIPT" ]]; then
    source "$NVM_INIT_SCRIPT" --no-use
fi

@Alex-duzhichao
Copy link

Thank you for you reply. After some test, I find the npm plugin in ohmyzsh is the reason causes the delay. After uninstall the npm plugin, the delay disappears.

I had the exact same issue with the exact same plugin. I don't think it's really the plugin's fault, but NVM itself. When you source the NVM script it takes a second or two for some reason. I worked around the issue by installing NVM through my package manager and sourcing it myself with the --no-use flag, which avoids the startup delay.

# Arch Linux
NVM_INIT_SCRIPT="/usr/share/nvm/init-nvm.sh"
if [[ -f "$NVM_INIT_SCRIPT" ]]; then
    source "$NVM_INIT_SCRIPT" --no-use
fi

@Hubro Hi, I face this problem with npm plugin in ohmyzsh and it has nothing to do with NVM.

https://github.com/ohmyzsh/ohmyzsh/blob/914b6399e88a16fdced427c2ae7738785dcb16b0/plugins/npm/npm.plugin.zsh#L108-L111
Actually I find if I annotate above code in npm plugin and then the delay disappered. So I think the reason is those three bindkey line code.

Best Regards

@cd-a
Copy link

cd-a commented Mar 2, 2022

I have the same issue, not using ohmyzsh but Prezto

@ljurk
Copy link

ljurk commented Jul 13, 2022

@jeffreytse Hi, I am using blinking beam as insert mode cursor style and blinking block as normal mode cursor style. When I switch from insert mode to normal mode, I noticed there is a little delay between when I press ESC key and when the cursor becomes to blinking block. But when I switch from normal mode to insert mode, the cursor becomes to blinking beam instantly. I searched this problem on the internet and find this question. Is there any solution that can switch the cursor style from insert mode to normal mode instantly? Thank you very much.

Thanks for this link. I experienced the same issue and for me, tmux was the problem. Adding set -s escape-time 0 to my .tmux.conf solved the issue for me.

@hgl
Copy link

hgl commented Oct 14, 2022

I have the same issue, using presto, without nvm or tmux. zsh-vi-mode is installed by cloning them renaming zsh-vi-mode.plugin.zsh to init.zsh. Normal to Insert mode is fine, but Insert to Normal manifests a noticeable delay where the bar cursor is turned into block after the delay.

@MahdiNazemi
Copy link

Thanks for developing this great plugin!

I experience about half a second delay when changing from the insert mode to normal mode. I experience this delay on a Linux server, an M1 Mac, and both inside and outside tmux (my tmux escape-time is 1 ms). I use Oh My Zsh as my package manager.

These are the plugins I have installed:

plugins=(
    git
    colored-man-pages
    colorize
    zsh-syntax-highlighting
    zsh-autosuggestions
    autoupdate
    sudo
    fzf
    zsh-vi-mode
)

Today I learned that I can reduce my Vim's delay of going from insert mode to normal mode from about two to three seconds to near zero by set noescapekeys (or adjusting timeoutlen and ttimeoutlen). So I started looking for a similar option in zsh-vi-mode and ended up in this issue.

@maptv
Copy link

maptv commented Jun 22, 2023

I still experience this delay. If anyone has a suggestion, please let me know.

@pwang2
Copy link

pwang2 commented Sep 24, 2024

I suddenly had an extreme slow 3-5 seconds delay when I press esc to exit normal mode.. Entering insert mode is instant. It is not related tmux as outside tmux, the situation is the same.

using zprof shows the zvm_readkeys took more than one sec.
image

not sure what has been wrong. Even clueless is, it only appears intermediately. my environment is WSL2+Ubuntu, reboot the vmcompute host can fix it. but still quite annoying. I recently upgrade to 24.04. not sure if that's related.

@jeffreytse
Copy link
Owner

Hi @pwang2,

I'm not sure what happened in your terminal. Could you provide a video record and reproducing steps for my further investigation?

Thanks & Regards

@pwang2
Copy link

pwang2 commented Sep 25, 2024

Thanks, Jeffrey! I do have a video before I restart my WSL
https://github.com/user-attachments/assets/0c1149aa-d6c6-4961-9974-0918137c137d
The video is not very obvious. but it feels like a at least 3 seconds freeze. also from the zprof above, it actually triggered 10 times.

If I profile now. here is the output.
image
I guess it might some rare IO glitch here. I will dive deeper if it occurs again.

jacobpbrugh pushed a commit to jacobpbrugh/zsh-vi-mode that referenced this issue Jan 1, 2025
@jacobpbrugh
Copy link

New to zsh-vi-mode—awesome project! Thanks for all the hard work on it. One of the rough edges that's been giving me grief is the delay when switching to normal mode reported here. Running zprof gave similar results to #111 (comment).

I traced the delay back to:

zsh-vi-mode/zsh-vi-mode.zsh

Lines 547 to 571 in cd730cd

if [[ "${keys}" == $'\e' ]]; then
timeout=$ZVM_ESCAPE_KEYTIMEOUT
# Check if there is any one custom escape sequence
for ((i=1; i<=${#result[@]}; i=i+2)); do
if [[ "${result[$i]}" =~ '^\^\[\[?[A-Z0-9]*~?\^\[' ]]; then
timeout=$ZVM_KEYTIMEOUT
break
fi
done
else
timeout=$ZVM_KEYTIMEOUT
fi
# Wait for reading next key, and we should save the widget
# as the final widget if it is full matching
key=
if [[ "${result[1]}" == "${pattern}" ]]; then
widget=${result[2]}
# Get current widget as final widget when reading key timeout
read -t $timeout -k 1 key || break
else
zvm_enter_oppend_mode
read -k 1 key
fi
done

The value of $ZVM_ESCAPE_KEYTIMEOUT is getting overridden with $ZVM_KEYTIMEOUT if a user has defined any keybindings beginning with escape (per line 551), leading to 0.4 second timeout for the read op on line 566 if $ZVM_KEYTIMEOUT is set to its default. zsh-vi-mode itself defines esc-prefixed keybindings, so I'd actually expect all users who haven't overridden ZVM_VI_ESCAPE_BINDKEY (or manually unset all the esc-prefixed keybindings) should be seeing this lag.

I provided a workaround in #308 that skips over this logic entirely and brings the time cost of entering entering normal mode in line with what I'm experiencing for the other modes. It'd be great to get some more-informed feedback on the safety of this change and whether it might be adapted into a total fix.

My reading of the code suggests we should entirely skip the additional key read logic here:

zsh-vi-mode/zsh-vi-mode.zsh

Lines 560 to 569 in cd730cd

# Wait for reading next key, and we should save the widget
# as the final widget if it is full matching
key=
if [[ "${result[1]}" == "${pattern}" ]]; then
widget=${result[2]}
# Get current widget as final widget when reading key timeout
read -t $timeout -k 1 key || break
else
zvm_enter_oppend_mode
read -k 1 key

if we're dealing with an escape keypress. We've already confirmed this isn't a proper escape sequence with:

zsh-vi-mode/zsh-vi-mode.zsh

Lines 507 to 514 in cd730cd

# Keep reading key for escape character
if [[ "$key" == $'\e' ]]; then
while :; do
local k=
read -t $ZVM_ESCAPE_KEYTIMEOUT -k 1 k || break
key="${key}${k}"
done
fi

and I think its unlikely folks using this extension will also want to rely only manual esc+<foo> keybindings. If they do they could set their $ZVM_ESCAPE_KEYTIMEOUT accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working verified This issue was already verified
Projects
None yet
Development

No branches or pull requests

10 participants