RSS Amplifier

Martin's Blog · Dec 7, 2024

Platform independent Emacs font settings

0
Sign in to vote or save

Martin Stemplinger · Martin's Blog

  • Note taken on [2024-12-07 Sat 14:57]
    Updated elisp code added.

Like most people I prefer some eye-candy in Emacs. An important role here plays the fonts of course. For a while I just copied different fonts and settings in my emacs configuration. This had the disadvantage that I had to remember to add it accordingly whenever I used a different machine. Also I use MacOS, Linux and Windows and the available fonts are quite different.

Then I decided to follow a similar approach as using web safe fonts with defined fallbacks for my font settings. I rely on fonts that should be present by default on the different platforms. The idea is to collect font families that look reasonably similar and choose the first which is available.

I set both a fixed-pitch font and a variable-pitch font.

First I define variables for the different font heights. It should look sensible together. On MacOS I need a higher setting.

(defvar my-fixed-pitch-height 0.8)
(defvar my-variable-height 1.2)
(if (eq system-type 'darwin)
    (setq my-font-height 160)
  (setq my-font-height 120))

Then like css font families I define different options which should exist on each platform.

I found the idea of the font-available-p function at Emacs Redux and like the slightly cleaner code.

(defun font-available-p (font-name)
  (member font-name (font-family-list)))

I test for different font families and then set the variable to the first family in font-family-list that is present. This sets both for a fixed font family and a variable font family.

Since i built it I noticed that Ubuntu and Fedora use different standard fonts so I added both DejaVu and Noto font families.

(defvar my-fixed-font-family
  (cond
   ((font-available-p "Consolas")         "Consolas") ; Windows
   ((font-available-p "SF Mono")          "SF Mono")  ; MacOS
   ((font-available-p "Roboto")           "Roboto")   ; Android
   ((font-available-p "DejaVu Sans Mono") "DejaVu Sans Mono") ; Ubuntu
   ((font-available-p "Noto Sans Mono") "NotoSans Mono") ; Fedora
   ((font-available-p "Helvetica")        "Helvetica Neue") ; generic fallback
     (nil (warn "Cannot find a Sans Serif Font. Install JetBrains Mono.")))
    "My fixed width font based on what is installed, nil if not defined.")

(defvar my-variable-font-family
  (cond
   ((font-available-p "Bodoni MT")       "Bodoni MT")
   ((font-available-p "Bodoni 72")       "Bodoni 72")
   ((font-available-p "EB Garamond")     "EB Garamond")
   ((font-available-p "Times New Roman") "Times new Roman")
   ((font-available-p "ETBembo")         "ETBembo")
   ((font-available-p "DejaVu Serif")    "DejaVu Serif")
   ((font-available-p "Noto Serif")         "Noto Serif")
   (nil (warn "Cannot find a Serif Font. Install ETBembo.")))
  "My variable width font based on what is installed, nil if not defined.")

If any of the fonts are present I use it to set the different face-attributes

(When my-fixed-font-family
      (set-frame-font my-fixed-font-family)
      (set-face-attribute 'default nil :weight 'regular :family my-fixed-font-family :height my-font-height)
      (set-face-attribute 'fixed-pitch nil :family my-fixed-font-family :height my-fixed-pitch-height))

(when my-variable-font-family
  (set-face-attribute 'variable-pitch nil :family my-variable-font-family :height my-variable-height))

And that’s it. Now I get similar looking Emacs buffers independent of the platform I run it on,

When I built this I encountered issues with some Unicode characters that weren’t shown until I installed the Symbola font. I’d rather get a warning to install it.

(unless (member "Symbola" (font-family-list))
  (warn "Please install Symbola font to avoid issues with unicode characters"))

I have no clue why that fixes the problem. If anyone knows I’d like to hear an explanation. The fewer fonts I have to install the better.

Read the original on mstempl.netlify.app

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.