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

Emacsclient seems slower starting when emacs is in --daemon mode (on Windows) #6181

Closed
pfmoore opened this issue May 31, 2016 · 17 comments
Closed

Comments

@pfmoore
Copy link
Contributor

pfmoore commented May 31, 2016

I'm using "GNU Emacs 25.0.93.1 (x86_64-w64-mingw32) of 2016-04-23" on Windows, and spacemacs from master. I've done nothing to configure the system yet, just installed it and I'm trying it out.

Using emacs filename to run a new instance of Emacs, and open a file, takes 2-3 seconds on my current PC. That's not really acceptable - my previous editor (gvim) was essentially instant. I understand that this isn't comparing like for like in terms of power, but ultimately I need that instant response for simple editing jobs.

If I use emacsclient to open a file in an existing Emacs instance, I get the instant response that I want. Which is fine, but my muscle memory (inherited from many years of vim use) is to close the window when I'm finished - not to use a special command like C-x #. So, with the best will in the world, I always forget, and end up having to restart the server over and over.

The --daemon mode in Emacs solves this perfectly for me. When I (briefly) used vanilla Emacs, it worked exactly as I expected, I could start teh daemon once, and use emacsclient for instant editing.

But with spacemacs, when the server is in daemon mode, I get that 2-3 second delay again every time I use emacsclient. There's clearly some issue with spacemacs doing too much work but I don't know what.

From what I've found out investigating the situation, when Emacs starts in daemon mode on Windows, it has a frame opened on the "tty" (console) terminal. Whenever emacsclient opens a new (gui) frame, it is opened on the "w32" (gui) terminal. I wonder if the issue here is that there is some form of (expensive, by the look of it) initialisation that gets done when a new terminal or display is opened? I couldn't see any hooks related to this from a quick grep at the code, but maybe someone could look at what might be the issue here.

I appreciate that a couple of seconds when opening a file isn't exactly a disaster, but it is problematic for me, so any suggestions on what might be causing this would be useful.

@pfmoore
Copy link
Contributor Author

pfmoore commented May 31, 2016

FWIW, I just checked against develop, and the behaviour is the same there.

@StreakyCobra
Copy link
Contributor

Linux user here. I'm using Spacemacs in the same way as you are, i.e. à la vim, by opening and closing frames on an unique instance. I also have the same setup: a emacs --daemon that is started by systemd at login time, and a keybinding in my windows manager that starts an emacsclient -c. I don't notice any special delay: I would say that 0.5 second after I've pressed the keybinding the frame is ready and responsive, and I have a pretty large configuration.

So my first guess would be that it is a Windows-specific issue, and sadly I can't help on this topic 😒


System Info 💻

  • OS: gnu/linux
  • Emacs: 24.5.1
  • Spacemacs: 0.105.20
  • Spacemacs branch: develop (rev. ad40bae)
  • Graphic display: t
  • Distribution: spacemacs
  • Editing style: vim
  • Completion: helm
  • Layers:
(asciidoc
 (auto-completion :variables auto-completion-enable-snippets-in-popup t)
 bb-git bb-latex bepo better-defaults c-c++ clojure colors command-log csv dash deft dockerfile
 (elfeed :variables rmh-elfeed-org-files
         (list "~/org/main.org"))
 encoding emacs-lisp emoji erc erlang ess evil-cleverparens extra-langs finance git github haskell html imenu-list ipython-notebook java javascript latex markdown mu4e nginx no-dots ocaml org pandoc php plantuml python ranger rebox restclient ruby rust scala semantic shell shell-scripts speed-reading
 (spell-checking :variables spell-checking-enable-auto-dictionary t spell-checking-enable-by-default nil)
 sql syntax-checking systemd themes-megapack theming typography
 (version-control :variables version-control-diff-tool 'diff-hl)
 vimscript yaml)

@syl20bnr
Copy link
Owner

Worth noting the --daemon is supported on Windows since version 25 of Emacs so it is pretty new feature, maybe it should be reported on the Emacs bug tracker.

@pfmoore
Copy link
Contributor Author

pfmoore commented Jun 1, 2016

I'm assuming it's not an Emacs issue (although I do know it's very new) because I don't get the same difference in startup time when using a vanilla copy of Emacs. (I assume a bug report for Emacs would need a test case without extensive customisations like spacemacs?)

If anyone can help me pinpoint what might be causing the delay, I'm more than happy to report it as an Emacs problem if that's what it turns out to be?

@StreakyCobra One difference between Windows and Linux, which I guess isn't precisely platform specific (but rather is a configuration that's uncommon on Linux, but normal on Windows) is that the hidden daemon frame is on a different terminal to the visible frame. If you have just one visible frame open in your configuration, what do you get from the following?

(mapcar #'frame-terminal (visible-frame-list)) 

My result is

(#<terminal 0 on initial_terminal> #<terminal 1 on w32>)

Note the 2 different terminals. At initialisation time, only terminal 0 is open. Terminal 1 only gets opened when a GUI frame is created. But it's not purely a cost of opening the new terminal, as otherwise it'd occur on vanilla, as well... (One other nasty side-effect of this is that checking a font exists on startup doesn't work, as terminal 0 has no access to the GUI and so (find-font) doesn't work. I have to set the font later, when the first GUI frame is created - which is something I got working on vanilla, but need to recreate for Spacemacs...)

@pfmoore
Copy link
Contributor Author

pfmoore commented Jun 1, 2016

FWIW, I submitted the following bug report to the Emacs list. It's focused specifically on the "there's no GUI terminal on startup" issue, which may or may not be behind the slow frame opening issue, but has the advantage of being a behaviour I can at least describe properly in the context of emacs -Q. We'll see what response I get...

Daemon mode on Windows (initialised by calling "emacs --daemon") starts
up Emacs with a frame running on a non-GUI terminal. This can be seen by
starting Emacs with "emacs -Q --daemon" and then "emacsclient -c". In the
scratch buffer, execute

(mapcar #'frame-terminal (visible-frame-list))

The result is

(#<terminal 0 on initial_terminal> #<terminal 1 on w32>)

Because Emacs is started with only a non-GUI terminal, GUI functions
such as find-font do not work as expected, so it's not possible to
configure GUI settings from init.el without complex workarounds (e.g.
deferring font selection until a GUI frame is open). Few packages seem
to expect this situation (for example, Spacemacs and Powerline), and as
a result configuration does not work as expected.

Would it be possible to modify the --daemon behaviour to open the initial
hidden frame on the "w32" GUI terminal, as this would avoid packages
having to modify their configuration process to deal with not having
access to the GUI terminal on startup?

@StreakyCobra
Copy link
Contributor

what do you get from the following?
(mapcar #'frame-terminal (visible-frame-list))

(#<terminal 0 on initial_terminal> #<terminal 1 on :0.0>)

@pfmoore
Copy link
Contributor Author

pfmoore commented Jun 1, 2016

Hmm, that's interesting. That's the same I get. However, when I run

(mapcar (lambda (f) (if (find-font (font-spec :name "Consolas") f) "Yes" "No")) (visible-frame-list)) 

I get ("No" "Yes") (so GUI fonts can't be found in the first terminal). Do you get the same? (Substitute the name of a font you know you have, obviously). I'm expecting you to get ("Yes" "Yes") which would explain where Windows and Linux differ - if not why the difference causes slowdowns...

(In the short term, btw, I have switched to using dotspacemacs-persistent-server rather than daemon mode. It works much more cleanly, but it has a tendency to shut down when I don't want it to, and otherwise behave a bit oddly :-( But it'll do for now).

@pfmoore
Copy link
Contributor Author

pfmoore commented Jun 1, 2016

Apparently this is the same behaviour as on Linux (I just set up a Linux VM and checked).

So I'm left not knowing what else could be slowing down the Spacemacs emacsclient setup when I run daemon mode. Can anyone suggest how I can get some information out of emacs as to where the time is being spent? I'm happy to debug this issue, but I don't really know where to start.

@StreakyCobra
Copy link
Contributor

If I replace Consolas by Source Code Pro, I got ("No" "Yes")

@StreakyCobra
Copy link
Contributor

There are commands profiler-start and profiler-report that are useful, but I don't really know how to use them correctly in your case (i.e. how to start directly the profiler in a new emacsclient instance).

@pfmoore
Copy link
Contributor Author

pfmoore commented Jun 3, 2016

If I replace Consolas by Source Code Pro, I got ("No" "Yes")

Yeah, I set up a Linux VM and tried it too, and got the same. So it looks like it's not that that is causing the differences. Ah, well, one theory down the drain :-)

Thanks for the pointers to the profiler commands. I'll see if I can find a way to use them.

@jbaum98
Copy link

jbaum98 commented Dec 2, 2016

I think I might be experiencing a similar issue. When I open a file with emacsclient, it starts instantly but displays the home buffer for 2-3 seconds before switching to the buffer for that file. However, even when I start the emacs daemon with emacs -Q --daemon to use vanilla emacs, I have the same issue except that it shows the scratch buffer instead, which implies this might not be a spacemacs issue.

@jbaum98
Copy link

jbaum98 commented Dec 2, 2016

Based on this thread I changed my $TERM environment variable to screen-256color from xterm-256color and this fixed the delay. This isn't a fix, but indicates both that it is a problem with emacs and where we should focus on trying to fix it.
Can somebody else confirm if changing the $TERM environment variable works for them?

@jbaum98
Copy link

jbaum98 commented Dec 2, 2016

Again, I'm very sorry to be posting so much here without confirmation that my problem is the same as the problem others are describing. I found a solution in this gist that fixes the problem.

; xterm-fix.el
(eval-after-load "xterm" ;; term/xterm.el does not provide 'xterm
  '(defadvice xterm--query (around tweak-for-gnu-screen (query handlers) activate)
     ;; GNU screen does not support this sequence
     (unless (string= query "\e]11;?\e\\")
       ad-do-it)))
emacs -Q -l xterm-fix.el --daemon
emacsclient -t foo.txt # instant
emacsclient -c foo.txt # also instant

However, when I add the contents of xterm-fix.el to the dotspacemacs/user-config function in my config file and remove the -Q flag, I still see flash of the home buffer before showing the correct buffer. It only spends about half a second there now as opposed to 2-3 seconds before. I guess this fixes the emacs part of the problem, and the rest of the problem is probably spacemacs specific.

@jbaum98
Copy link

jbaum98 commented Dec 2, 2016

I actually think it has to do with the value of xterm-query-timeout. Adding this to my init file

(setq-default xterm-query-timeout nil) 

got rid of the delay completely. However, I'm sure there's a reason for this timeout existing. It was introduced here to "Avoid generating garbage" in the course of addresing this bug, and indeed a nil timeout you get some random characters the first time you open a file with emacsclient after starting the daemon. So I'm not quite sure what the solution should be.

@collinjackson93
Copy link

Any updates on this? I seem to be experiencing the same problem where $TERM=xterm-256color shows a previously opened buffer for a short time before switching to the requested buffer. Modifying the value of xterm-query-timeout to nil also seems to help. Great detective work @jbaum98!

If there is any system information that I can provide that may be of use, please let me know. If this happens to be an Emacs bug rather than Spacemacs, I may be of limited assistance because I am not too familiar with Emacs (not that I'm all that familiar with Spacemacs, either), but I am willing to spend some time digging to try resolving it.

@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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants