2

I normally start Emacs in daemon mode and reload my last session with the desktop package. This causes whichever file desktop-read open last to remain visited in a buffer which is selected in the window which is selected in the “dummy” frame created for the daemon. As far as Emacs is concerned, this file is visible in a frame. But as far as I'm concerned, it's not.

I could fix all my code to skip the daemon's frame… if I could identify it. But it would be easier to just make the daemon frame visit a buffer whose visibility I don't particularly care about, like *Messages* or ​ *Minibuf-0.

What can I put in my init file to

  • identify whether Emacs was started in daemon mode;
  • identify the frame corresponding to the daemon;
  • make this frame visit a harmless buffer, or kill it (what can go wrong if I do that), or otherwise not let it continue “showing” some interesting buffer?

Test by running emacs --daemon -q -l foo.emacs where foo.emacs is

;; -*-emacs-lisp-*- (setq server-name "foo") ;; Simulate loading a desktop session (find-file "~/.emacs") ;; Test code (defun foo () (interactive) (let* ((buffer (find-buffer-visiting "~/.emacs")) (window (get-buffer-window buffer t))) (if (interactive-p) (message "%S" window) window))) ;; Here goes the code I want 

then I want emacsclient -s foo -e '(foo)' to return nil.

1 Answer 1

0

Immediately after starting Emacs, the daemon frame is the last one in the frame list. It has a single window which shows the last visited file.

(set-window-buffer (car (window-list (car (last (frame-list))))) "*Messages*") 

In my use case, which is loading a desktop session, I need to do this after loading the session. I do this through a one-time hook.

(when (and (fboundp 'daemonp) (daemonp)) (defun my-desktop-after-read-hook-set-window-buffer () "Make the last frame in the frame list visit *Messages*. This is intended for use after the first call to `desktop-read' in a daemon Emacs. In this situation, the (sole) window in the daemon frame ends up visiting the last buffer that was restored. Since this buffer is visited in a window, some automation makes that window pop up (which has no actual effect) instead of displaying the buffer in the current window or a new one." (set-window-buffer (car (window-list (car (last (frame-list))))) "*Messages*") (remove-hook 'desktop-after-read-hook 'my-desktop-after-read-hook-set-window-buffer)) (add-hook 'desktop-after-read-hook 'my-desktop-after-read-hook-set-window-buffer)) 

Ugly, but it works.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.