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

ESC in terminal (and many other things) sometimes get 10 second delay #5413

Open
aaronjensen opened this Issue Mar 8, 2016 · 30 comments

Comments

@aaronjensen
Contributor

aaronjensen commented Mar 8, 2016

Description

It is possible to get emacs into a state where several things take much longer than they should, including pressing ESC to exit insert mode.

Many things rely on read-event, and if emacs is in this state then read-event will sometimes take 10 seconds to return instead of immediately.

Once emacs is in this state, this is the minimum repro for the delay: https://gist.github.com/aaronjensen/5fd6521acd7add2a8be5

To get into the bad state, the repro steps below are the most consistent way I can find. This is odd enough that it could be a bug in emacs for mac. I can't seem to reproduce it if emacs is only running in the terminal and not a window as well. I've noticed other peculiar behavior as well while things are in this state. If I press ESC, then cmd+tab out, sometimes it immediately goes back to normal mode, and sometimes whichkey pops expecting a key after ESC:

shell 2016-03-10 07-17-01

Also, which-key takes a really long time to pop, much longer than it normally does.

Reproduction guide

  • Start Emacs gui
  • Start Emacs in terminal with emacsclient --tty file
  • Go into insert mode: i
  • Press esc, it should go back to normal mode immediately
  • Arrange your windows so you can still see emacs terminal and some other application, like Chrome
  • Repeat these steps or steps like them until esc no longer exits insert mode immediately:
    • Go into insert mode again: i
    • Press some meta key like: M-f
    • Make some changes to the file, just type, staying in insert mode
    • CMD+tab to another application, like Chromel. Wait for an autosave to happen in the terminal.
    • CMD+tab back to the terminal application
    • Press esc.

Observed behaviour:
It does not go back to normal mode, or if it does, it takes a few seconds.

Expected behaviour:
Immediate switch to normal mode.

System Info

  • OS: darwin
  • Emacs: 25.1.50.1
  • Spacemacs: 0.105.11
  • Spacemacs branch: enable-non-native-fullscreen-without-mac-port (rev. 891e704)
  • Graphic display: nil
  • Distribution: spacemacs
  • Editing style: hybrid
  • Completion: helm
  • Layers:
(better-defaults spacemacs-layouts spacemacs-helm emacs-lisp markdown
                 (syntax-checking :variables syntax-checking-enable-tooltips nil)
                 (auto-completion :variables auto-completion-enable-sort-by-usage nil)
                 erlang elixir git dash html org colors osx github javascript deft floobits ruby semantic
                 (shell :variables shell-default-shell 'ansi-term shell-default-height 30 shell-default-position 'bottom)
                 spell-checking ranger version-control rcirc evil-little-word jb-lispy auto-correct frame-geometry)
@nixmaniack

This comment has been minimized.

Show comment
Hide comment
@nixmaniack

nixmaniack Mar 9, 2016

Contributor

Are you using terminal emacs in tmux? In that case you might be good with setting escape-time to 0 in tmux with set -s escape-time 0

Contributor

nixmaniack commented Mar 9, 2016

Are you using terminal emacs in tmux? In that case you might be good with setting escape-time to 0 in tmux with set -s escape-time 0

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Mar 9, 2016

Contributor

@nixmaniack yes, and it is set to that. I have also lowered evil-esc-delay to 0.001 and it does not make a difference in this situation.

Contributor

aaronjensen commented Mar 9, 2016

@nixmaniack yes, and it is set to that. I have also lowered evil-esc-delay to 0.001 and it does not make a difference in this situation.

@syl20bnr

This comment has been minimized.

Show comment
Hide comment
@syl20bnr

syl20bnr Mar 9, 2016

Owner

What about outside of tmux ? Is this behaviour still the same ?

Owner

syl20bnr commented Mar 9, 2016

What about outside of tmux ? Is this behaviour still the same ?

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Mar 9, 2016

Contributor

Yes, it is. The repro seems to be a little bit more tricky than I described as well, that doesn't consistently reproduce it. Instead, I must work in a buffer for a minute or so, hitting esc many times, going into and out of insert (hybrid) mode, using M-f, M-b. After some time the ESC will start to stick. I can't figure out consistent repro steps, but I can consistently get into the failure mode.

Contributor

aaronjensen commented Mar 9, 2016

Yes, it is. The repro seems to be a little bit more tricky than I described as well, that doesn't consistently reproduce it. Instead, I must work in a buffer for a minute or so, hitting esc many times, going into and out of insert (hybrid) mode, using M-f, M-b. After some time the ESC will start to stick. I can't figure out consistent repro steps, but I can consistently get into the failure mode.

@nixmaniack

This comment has been minimized.

Show comment
Hide comment
@nixmaniack

nixmaniack Mar 9, 2016

Contributor

Are you using any special configuration for customizing keys using OS config or using softwares like Karabiner. I had issues with them which introduced delay, specially for modifiers.

Contributor

nixmaniack commented Mar 9, 2016

Are you using any special configuration for customizing keys using OS config or using softwares like Karabiner. I had issues with them which introduced delay, specially for modifiers.

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Mar 9, 2016

Contributor

@nixmaniack Good question, I do use Karabiner, but this delay is an intermittent thing. I'll see if I can reproduce it without Karabiner just to be sure. It's sort of a paint to reproduce. I've also eliminated all of the layers in spacemacs and it still repros, so its' not one of the layers/extra packages I had or custom config.

Contributor

aaronjensen commented Mar 9, 2016

@nixmaniack Good question, I do use Karabiner, but this delay is an intermittent thing. I'll see if I can reproduce it without Karabiner just to be sure. It's sort of a paint to reproduce. I've also eliminated all of the layers in spacemacs and it still repros, so its' not one of the layers/extra packages I had or custom config.

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Mar 10, 2016

Contributor

I can reproduce with Karabiner disabled. I updated the repro steps, because it seems it may have something to do with having both a terminal and a gui open. The repro is now pretty convoluted, but it's the most consistent way for me to reproduce it.

Contributor

aaronjensen commented Mar 10, 2016

I can reproduce with Karabiner disabled. I updated the repro steps, because it seems it may have something to do with having both a terminal and a gui open. The repro is now pretty convoluted, but it's the most consistent way for me to reproduce it.

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Mar 10, 2016

Contributor

Ok, this appears to be an emacs bug. Specifically, a bug in sit-for. I replaced the usage of sit-for in evil-esc with this:

(defun sit-for2 (x)
  (message "sitting for %S %S" x (current-time-string))
  (prog1 (sit-for x)
    (message "done sitting %S" (current-time-string))))

And got this:

sitting for 0.001 "Thu Mar 10 07:53:17 2016"
done sitting "Thu Mar 10 07:53:26 2016"

Attempting to sit for 0.001 seconds took 10 seconds.

Contributor

aaronjensen commented Mar 10, 2016

Ok, this appears to be an emacs bug. Specifically, a bug in sit-for. I replaced the usage of sit-for in evil-esc with this:

(defun sit-for2 (x)
  (message "sitting for %S %S" x (current-time-string))
  (prog1 (sit-for x)
    (message "done sitting %S" (current-time-string))))

And got this:

sitting for 0.001 "Thu Mar 10 07:53:17 2016"
done sitting "Thu Mar 10 07:53:26 2016"

Attempting to sit for 0.001 seconds took 10 seconds.

@justbur

This comment has been minimized.

Show comment
Hide comment
@justbur

justbur Mar 10, 2016

Contributor

@aaronjensen what's the value of the variable noninteractive for you?

Contributor

justbur commented Mar 10, 2016

@aaronjensen what's the value of the variable noninteractive for you?

@justbur

This comment has been minimized.

Show comment
Hide comment
@justbur

justbur Mar 10, 2016

Contributor

BTW, it's unlikely that this has anything to do with hybrid mode. vim style should behave the same way.

Contributor

justbur commented Mar 10, 2016

BTW, it's unlikely that this has anything to do with hybrid mode. vim style should behave the same way.

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Mar 10, 2016

Contributor

@justbur it's nil. I narrowed it down further, this is the minimum way to reproduce the delay once emacs is in this state: https://gist.github.com/aaronjensen/5fd6521acd7add2a8be5

Basically, a (redisplay) followed by a (read-event nil t 0.001) will take 10 seconds instead of 0.001

Edit: You're right justbur, it's not hybrid specific.

Contributor

aaronjensen commented Mar 10, 2016

@justbur it's nil. I narrowed it down further, this is the minimum way to reproduce the delay once emacs is in this state: https://gist.github.com/aaronjensen/5fd6521acd7add2a8be5

Basically, a (redisplay) followed by a (read-event nil t 0.001) will take 10 seconds instead of 0.001

Edit: You're right justbur, it's not hybrid specific.

@aaronjensen aaronjensen changed the title from ESC in hybrid mode on terminal doesn't always work to ESC in terminal doesn't always work Mar 10, 2016

@aaronjensen aaronjensen changed the title from ESC in terminal doesn't always work to ESC in terminal (and many other things) sometimes get 10 second delay Mar 10, 2016

@justbur

This comment has been minimized.

Show comment
Hide comment
@justbur

justbur Mar 10, 2016

Contributor

@aaronjensen

have you tried increasing evil-esc-delay?

If in your test you use a delay of 1 sec, do you get the proper result?

Contributor

justbur commented Mar 10, 2016

@aaronjensen

have you tried increasing evil-esc-delay?

If in your test you use a delay of 1 sec, do you get the proper result?

@justbur

This comment has been minimized.

Show comment
Hide comment
@justbur

justbur Mar 10, 2016

Contributor

Also what's the value of redisplay-dont-pause?

Contributor

justbur commented Mar 10, 2016

Also what's the value of redisplay-dont-pause?

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Mar 10, 2016

Contributor

@justbur see my update, it has nothing to do w/ evil-esc-delay i can reproduce the delay w/ a simple read-event (as long as it is preceded by redisplay). My redisplay-dont-pause is t

Contributor

aaronjensen commented Mar 10, 2016

@justbur see my update, it has nothing to do w/ evil-esc-delay i can reproduce the delay w/ a simple read-event (as long as it is preceded by redisplay). My redisplay-dont-pause is t

@justbur

This comment has been minimized.

Show comment
Hide comment
@justbur

justbur Mar 10, 2016

Contributor

@aaronjensen What I was going for is maybe the timeout on read-event is too short on your computer for some reason. evil-esc-delay controls the timeout.

You can prevent the redisplay by passing a flag to sit-for, which seems like it would solve the problem. Like this

(defun evil-esc (map)
  "Translate \\e to 'escape if no further event arrives.
This function is used to translate a \\e event either to 'escape
or to the standard ESC prefix translation map. If \\e arrives,
this function waits for `evil-esc-delay' seconds for another
event. If no other event arrives, the event is translated to
'escape, otherwise it is translated to the standard ESC prefix
map stored in `input-decode-map'. If `evil-inhibit-esc' is
non-nil or if evil is in emacs state, the event is always
translated to the ESC prefix.

The translation to 'escape happens only if the current command
has indeed been triggered by \\e. In other words, this will only
happen when the keymap is accessed from `read-key-sequence'. In
particular, if it is access from `define-key' the returned
mapping will always be the ESC prefix map."
  (if (and (not evil-inhibit-esc)
           (or evil-local-mode (evil-ex-p))
           (not (evil-emacs-state-p))
           (let ((keys (this-single-command-keys)))
             (and (> (length keys) 0)
                  (= (aref keys (1- (length keys))) ?\e)))
           (sit-for evil-esc-delay t))
      (prog1 [escape]
        (when defining-kbd-macro
          (end-kbd-macro)
          (setq last-kbd-macro (vconcat last-kbd-macro [escape]))
          (start-kbd-macro t t)))
    map))
Contributor

justbur commented Mar 10, 2016

@aaronjensen What I was going for is maybe the timeout on read-event is too short on your computer for some reason. evil-esc-delay controls the timeout.

You can prevent the redisplay by passing a flag to sit-for, which seems like it would solve the problem. Like this

(defun evil-esc (map)
  "Translate \\e to 'escape if no further event arrives.
This function is used to translate a \\e event either to 'escape
or to the standard ESC prefix translation map. If \\e arrives,
this function waits for `evil-esc-delay' seconds for another
event. If no other event arrives, the event is translated to
'escape, otherwise it is translated to the standard ESC prefix
map stored in `input-decode-map'. If `evil-inhibit-esc' is
non-nil or if evil is in emacs state, the event is always
translated to the ESC prefix.

The translation to 'escape happens only if the current command
has indeed been triggered by \\e. In other words, this will only
happen when the keymap is accessed from `read-key-sequence'. In
particular, if it is access from `define-key' the returned
mapping will always be the ESC prefix map."
  (if (and (not evil-inhibit-esc)
           (or evil-local-mode (evil-ex-p))
           (not (evil-emacs-state-p))
           (let ((keys (this-single-command-keys)))
             (and (> (length keys) 0)
                  (= (aref keys (1- (length keys))) ?\e)))
           (sit-for evil-esc-delay t))
      (prog1 [escape]
        (when defining-kbd-macro
          (end-kbd-macro)
          (setq last-kbd-macro (vconcat last-kbd-macro [escape]))
          (start-kbd-macro t t)))
    map))
@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Mar 10, 2016

Contributor

@justbur gotcha. evil-esc-delay was 0.001, which is why I was passing that to read-event in my minimal repro. Unfortunately, more than just ESC is broken when emacs is in this state. Pretty much everything is a little off, like helm doesn't show the last key I typed in the highlight. It really smells like an emacs bug w/ read-event

monosnap 2016-03-10 10-09-51

Contributor

aaronjensen commented Mar 10, 2016

@justbur gotcha. evil-esc-delay was 0.001, which is why I was passing that to read-event in my minimal repro. Unfortunately, more than just ESC is broken when emacs is in this state. Pretty much everything is a little off, like helm doesn't show the last key I typed in the highlight. It really smells like an emacs bug w/ read-event

monosnap 2016-03-10 10-09-51

@justbur

This comment has been minimized.

Show comment
Hide comment
@justbur

justbur Mar 10, 2016

Contributor

It could be. It's going to be hard to track down though I'm afraid.

On Thu, Mar 10, 2016 at 1:10 PM Aaron Jensen notifications@github.com
wrote:

@justbur https://github.com/justbur gotcha. Timeout was 0.001, which is
why I was passing that to read-event in my minimal repro. Unfortunately,
more than just ESC is broken when emacs is in this state. Pretty much
everything is a little off, like helm doesn't show the last key I typed in
the highlight. It really smells like an emacs bug w/ read-event

[image: monosnap 2016-03-10 10-09-51]
https://cloud.githubusercontent.com/assets/8588/13679365/3c3485de-e6a8-11e5-9689-f469d7e2419b.png


Reply to this email directly or view it on GitHub
#5413 (comment)
.

Contributor

justbur commented Mar 10, 2016

It could be. It's going to be hard to track down though I'm afraid.

On Thu, Mar 10, 2016 at 1:10 PM Aaron Jensen notifications@github.com
wrote:

@justbur https://github.com/justbur gotcha. Timeout was 0.001, which is
why I was passing that to read-event in my minimal repro. Unfortunately,
more than just ESC is broken when emacs is in this state. Pretty much
everything is a little off, like helm doesn't show the last key I typed in
the highlight. It really smells like an emacs bug w/ read-event

[image: monosnap 2016-03-10 10-09-51]
https://cloud.githubusercontent.com/assets/8588/13679365/3c3485de-e6a8-11e5-9689-f469d7e2419b.png


Reply to this email directly or view it on GitHub
#5413 (comment)
.

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Mar 12, 2016

Contributor

IT IS APP NAP! I've reported to emacs bugs.

Work around:

$ defaults write org.gnu.Emacs NSAppSleepDisabled -bool YES
Contributor

aaronjensen commented Mar 12, 2016

IT IS APP NAP! I've reported to emacs bugs.

Work around:

$ defaults write org.gnu.Emacs NSAppSleepDisabled -bool YES
@syl20bnr

This comment has been minimized.

Show comment
Hide comment
@syl20bnr

syl20bnr Mar 12, 2016

Owner

@aaronjensen can you post the link to the bug report for reference ?

Also I reopen the issue to add a FAQ entry in the OS X section.

Owner

syl20bnr commented Mar 12, 2016

@aaronjensen can you post the link to the bug report for reference ?

Also I reopen the issue to add a FAQ entry in the OS X section.

@syl20bnr syl20bnr reopened this Mar 12, 2016

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen
Contributor

aaronjensen commented Mar 12, 2016

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Dec 8, 2016

/me showers @aaronjensen with dancing girls.

You solved it!!!!!!!

@syl20bnr This needs to be in the OS X section pronto. Every time I left Emacs alone for a few minutes it went into super-syrupy mode with 10-20 second delays before it reacted to esc or space anymore, and only a restart of emacs could fix it.

Disabling App Nap (low-priority "sleep" background threading in OS X) fixes it.

ghost commented Dec 8, 2016

/me showers @aaronjensen with dancing girls.

You solved it!!!!!!!

@syl20bnr This needs to be in the OS X section pronto. Every time I left Emacs alone for a few minutes it went into super-syrupy mode with 10-20 second delays before it reacted to esc or space anymore, and only a restart of emacs could fix it.

Disabling App Nap (low-priority "sleep" background threading in OS X) fixes it.

@fatlazycat

This comment has been minimized.

Show comment
Hide comment
@fatlazycat

fatlazycat Jan 5, 2017

I'm still getting this even after disabling App Nap. Perhaps it's a different issue but unfortunately making it a bit unusable.

Is there likely to be any difference between emacs-mac and emacs-plus ?

fatlazycat commented Jan 5, 2017

I'm still getting this even after disabling App Nap. Perhaps it's a different issue but unfortunately making it a bit unusable.

Is there likely to be any difference between emacs-mac and emacs-plus ?

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Jan 5, 2017

Contributor

@fatlazycat same issue everyone else is having? (gui app started, terminal emacsclient connects?)

Contributor

aaronjensen commented Jan 5, 2017

@fatlazycat same issue everyone else is having? (gui app started, terminal emacsclient connects?)

@fatlazycat

This comment has been minimized.

Show comment
Hide comment
@fatlazycat

fatlazycat Jan 5, 2017

Sorry no, just long pauses after hitting space etc using a gui app.

fatlazycat commented Jan 5, 2017

Sorry no, just long pauses after hitting space etc using a gui app.

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Jan 5, 2017

Contributor

@fatlazycat ah, that's a different thing, and if it's what I think, it's the desired behavior. See which-key-idle-delay

Contributor

aaronjensen commented Jan 5, 2017

@fatlazycat ah, that's a different thing, and if it's what I think, it's the desired behavior. See which-key-idle-delay

@fatlazycat

This comment has been minimized.

Show comment
Hide comment
@fatlazycat

fatlazycat Jan 5, 2017

Nah it's definitely not normal. Well to me anyway 😀

Hit space and a second later options appear. Then later hit space and 10 seconds or longer and it may show.

fatlazycat commented Jan 5, 2017

Nah it's definitely not normal. Well to me anyway 😀

Hit space and a second later options appear. Then later hit space and 10 seconds or longer and it may show.

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Jan 5, 2017

Contributor

Sounds like a bug/problem w/ which-key. You should open another issue w/ repro steps.

Contributor

aaronjensen commented Jan 5, 2017

Sounds like a bug/problem w/ which-key. You should open another issue w/ repro steps.

@LukeXuan

This comment has been minimized.

Show comment
Hide comment
@LukeXuan

LukeXuan Jan 13, 2017

Some updates about this issue. This happens when I'm in tty mode with emacsclient and no GUI window is open. However If I kept some GUI window somewhere, the delay no longer exists.

LukeXuan commented Jan 13, 2017

Some updates about this issue. This happens when I'm in tty mode with emacsclient and no GUI window is open. However If I kept some GUI window somewhere, the delay no longer exists.

@syl20bnr syl20bnr removed the Hacktoberfest label Feb 7, 2017

@winmillwill

This comment has been minimized.

Show comment
Hide comment
@winmillwill

winmillwill Mar 15, 2018

Just to close the loop here if another frustrated user arrives here from a web search, I'm pasting the workarounds that will work from the emacs bug thread:

1. At the command prompt: defaults write org.gnu.Emacs NSAppSleepDisabled -bool YES

2. Right-click on the Emacs icon and select 'get info' and tick the
   'Disable App Nap' checkbox. (Although I don't get that tick box...)

3. Run in daemon mode: Emacs as a daemon has no GUI so app nap
   is disabled automatically.

Note that (also from that thread) just changing the plist for emacs to set the NSAppSleepDisabled flag doesn't seem to work. Also, IIUC, you must quit the Emacs app and start it again for the changes to take effect, and they still may not (in my experience).

The smoothest solution here may be to provide a recommendation as to what combination of brew install emacs and brew cask install emacs gives what sort of experience. I'm personally doing both because the former provides a plist so you can start the daemon at login with brew services start emacs.

winmillwill commented Mar 15, 2018

Just to close the loop here if another frustrated user arrives here from a web search, I'm pasting the workarounds that will work from the emacs bug thread:

1. At the command prompt: defaults write org.gnu.Emacs NSAppSleepDisabled -bool YES

2. Right-click on the Emacs icon and select 'get info' and tick the
   'Disable App Nap' checkbox. (Although I don't get that tick box...)

3. Run in daemon mode: Emacs as a daemon has no GUI so app nap
   is disabled automatically.

Note that (also from that thread) just changing the plist for emacs to set the NSAppSleepDisabled flag doesn't seem to work. Also, IIUC, you must quit the Emacs app and start it again for the changes to take effect, and they still may not (in my experience).

The smoothest solution here may be to provide a recommendation as to what combination of brew install emacs and brew cask install emacs gives what sort of experience. I'm personally doing both because the former provides a plist so you can start the daemon at login with brew services start emacs.

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Mar 15, 2018

Contributor

Seems like we need an FAQ entry for this if we don't have one, then we can close this bug...

Contributor

aaronjensen commented Mar 15, 2018

Seems like we need an FAQ entry for this if we don't have one, then we can close this bug...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment