1

When I need to change the font size I evaluate the following region:

  (set-frame-font "JetBrains Mono-14")

This is far from optimal since it involves a lot of typing.

I'm looking for an interactive function that would ask me for the new font size and modify the numeric value passed to set-frame-font.

As a workaround I wrote the following function:

(defun change-font-size (new-size)
  "Change the font size to the given value"
  (interactive "sNew font size: ")
  (set-frame-font (concat (face-attribute 'default :family) "-" new-size)
                  )
  )

(bind-key "C-x f" #'change-font-size)

But I wonder if there's a better way of doing this.

The best solution for me would be to change the font size of emacs based in the monitor in which it is being displayed, but I could not find any satisfactory solution. I do not want to do busy waiting on my emacs, instead I'd like emacs listening to notifications of the windows manager. However I do not know whether this is possible.

EDIT using the suggestion in one of the answers I wrote this hook to resize the window based on the display emacs is in.

(defun my/adjust-font-size-based-on-display ()
  (let ((display-width (nth 3 (assq 'geometry (frame-monitor-attributes))))
        )
    (change-font-size
     (cond ((<= display-width 1920) 18) ;; HD
           ((<= display-width 2560) 11) ;; UWHD
           ((<= display-width 4096) 14) ;; 4K
           )
     )
    )
  )

(add-hook 'window-size-change-functions (lambda (frame) (my/adjust-font-size-based-on-display)))
(add-hook 'focus-in-hook 'my/adjust-font-size-based-on-display)

Suggestions on how to improve the hook above are welcome!

2
  • The Emacs default C-x C-+ and/or C-x C-- for increase/decrease font size does not work?
    – Ian
    Sep 16 '20 at 13:13
  • No, they only change the size for the current buffer and not globally. Sep 16 '20 at 16:12
2

The :height attribute of a face is ten times the font size. You can directly set the height attribute:

(defun change-font-size (new-size)
  "Change the font size to the given value"
  (interactive "nNew font size: ")
  (set-face-attribute 'default nil :height (* 10 new-size)))

Note that it needs a number, not a string, so I changed your interactive s to n.

For the second part, where you have it depend on monitor size,

(defun my/check-monitor ()
 (change-font-size 
   (if (<= (display-pixel-width) 1440) 16 20)))

This will set the font size to 16 if the monitor width is up to 1440px and 20 if it's a wider monitor. You can extend this to include more logic depending on width and height.

I am not sure if emacs has any built in hooks to detect a monitor change, but if not, either find a way to send a command to emacs (e.g. run emacsclient -e "(my/check-monitor)" from a shell script), or have it check the monitor width occasionally in a timer, maybe with run-with-idle-timer.

4
  • That works much better! Thank you! And I didn't think about sending a command to emacs from the window manager. That sounds like a good alternative. I have to check whether gnome WM supports these kind of hooks. Sep 17 '20 at 7:47
  • Regarding the hook, it seems focus-in-hook is what I need. Now I only need to figure out how to get emacs to correctly report the size of the display it is in: display-pixel-width reports always the pixel width of the external monitor. Sep 17 '20 at 8:25
  • I edited my question with a hook that achieves the automagically resizing. Has some caveats, but works for me :) Sep 17 '20 at 11:00
  • Great! I think (display-pixel-width (car (frame-list))) will tell you the pixel width of the monitor emacs is on, but emacs could have a frame on each monitor, so that would end up being ambiguous.
    – amitp
    Sep 17 '20 at 15:41
0

I don't know if that will appeal to you but what I do is use text-scale-increase and text-scale-decrease. Putting them in a hydra like this:

(require 'hydra)

(defhydra hydra-zoom (global-map "<f2>")
  "zoom"
  ("g" text-scale-increase "in")
  ("l" text-scale-decrease "out"))

then allows me to increase it a couple of times by typing <F2> g g ..., repeating the g (g for greater but suit yourself :-) ).

Although this is not a global change, I generally find that I don't need to change the font size globally: I set the font (including its size) once and for all in my init file to whatever I need for most of my work and then just use the above to change the size of the font in a buffer e.g. when presenting my screen in a meeting to make it readable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.