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

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

Closed
aaronjensen opened this issue Mar 8, 2016 · 33 comments
Closed

Comments

@aaronjensen
Copy link
Contributor

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
Copy link
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

@aaronjensen
Copy link
Contributor Author

@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
Copy link
Owner

syl20bnr commented Mar 9, 2016

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

@aaronjensen
Copy link
Contributor Author

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
Copy link
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.

@aaronjensen
Copy link
Contributor Author

@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
Copy link
Contributor Author

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
Copy link
Contributor Author

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
Copy link
Contributor

justbur commented Mar 10, 2016

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

@justbur
Copy link
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
Copy link
Contributor Author

@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 ESC in hybrid mode on terminal doesn't always work ESC in terminal doesn't always work Mar 10, 2016
@aaronjensen aaronjensen changed the title ESC in terminal doesn't always work ESC in terminal (and many other things) sometimes get 10 second delay Mar 10, 2016
@justbur
Copy link
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
Copy link
Contributor

justbur commented Mar 10, 2016

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

@aaronjensen
Copy link
Contributor Author

@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
Copy link
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
Copy link
Contributor Author

@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
Copy link
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
Copy link
Contributor Author

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

Work around:

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

@syl20bnr
Copy link
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.

@syl20bnr syl20bnr reopened this Mar 12, 2016
@aaronjensen
Copy link
Contributor Author

@syl20bnr good idea. Here's the bug report: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=22993

@ghost
Copy link

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
Copy link

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
Copy link
Contributor Author

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

@fatlazycat
Copy link

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

@aaronjensen
Copy link
Contributor Author

@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
Copy link

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
Copy link
Contributor Author

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

@LukeXuan
Copy link
Contributor

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.

@winmillwill
Copy link

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
Copy link
Contributor Author

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

@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Please let us know if this issue is still valid!

@github-actions github-actions bot added the stale marked as a stale issue/pr (usually by a bot) label Feb 29, 2020
@nixmaniack
Copy link
Contributor

FAQ entry isn't added yet. Let's keep this open.

@duianto duianto removed the stale marked as a stale issue/pr (usually by a bot) label Mar 15, 2020
@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Please let us know if this issue is still valid!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Upstream bugs
Reported, waiting
Development

No branches or pull requests