TransWikia.com

Font and frame configuration in daemon mode

Emacs Asked by Thomas Kahle on December 11, 2021

In my .emacs I have

(set-frame-font "Source Code Pro")
(set-face-attribute 'default nil :font "Source Code Pro" :height 140)
(set-face-font 'default "Source Code Pro")

Which sets the fonts to source code pro. To do its job, this code apparently needs to run once after the first frame has been created. How can I achieve that?

  • I’m on MacOS and use emacs-plus.
  • Emacs Deamon is started on boot as a service, I only ever call emacsclient.
  • If I run this code once, all new frames have the right fonts.
  • If Emacs Daemon restarts, I need to run the code again, but after the first frame has been created.
  • Putting it in .emacs runs it too early so it’s not working.
  • If I start emacs as emacs, not as the deamon, the code in .emacs works and the first frame uses Source Code Pro.

How can I set the fonts or other frame parameters on deamon start?

2 Answers

To do its job, this code apparently needs to run once after the first frame has been created. How can I achieve that?

The standard hooks for this are listed under (info "(elisp) Standard Hooks"):

‘after-make-frame-functions’
‘before-make-frame-hook’
‘server-after-make-frame-hook’
     see Creating Frames.

Following the link to (info "(elisp) Creating Frames"):

 -- Variable: before-make-frame-hook
     A normal hook run by ‘make-frame’ before it creates the frame.

 -- Variable: after-make-frame-functions
     An abnormal hook run by ‘make-frame’ after it created the frame.
     Each function in ‘after-make-frame-functions’ receives one
     argument, the frame just created.

   Note that any functions added to these hooks by your initial file are
usually not run for the initial frame, since Emacs reads the initial
file only after creating that frame.  However, if the initial frame is
specified to use a separate minibuffer frame (see Minibuffers and
Frames), the functions will be run for both, the minibuffer-less and
the minibuffer frame.

 -- User Option: server-after-make-frame-hook
     A normal hook run when the Emacs server creates a client frame.
     When this hook is called, the created frame is the selected one.
     See (emacs)Emacs Server.

(Note that the last server- hook is new in Emacs 27.)

To ensure a hook function is run only once, after the first non-daemon frame is created, just remove the function from the hook as its last step. For example:

(defun my-configure-font (frame)
  "Configure font given initial non-daemon FRAME.
Intended for `after-make-frame-functions'."
  ;; Do stuff with FRAME...
  (remove-hook 'after-make-frame-functions #'my-configure-font))

(add-hook 'after-make-frame-functions #'my-configure-font)

Some things to consider:

  • Both after-make-frame-functions and server-after-make-frame-hook are called for non-graphical frames as well, so add appropriate checks for this as needed.
  • Neither of these hooks is run in a non-daemon Emacs session. To also support non-daemon sessions, add your function to window-setup-hook instead (or as well). To check whether the current session is a daemon or not, there's the predicate daemonp.

Answered by Basil on December 11, 2021

It sounds like you would need a function to run once per server invocation.

You can probably use the information in this post to help you set up a hook that would run a function to set the fonts, and then not run that function for subsequent frames until the next time the server is (re)started.

Answered by einfeyn496 on December 11, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP