Making Emacs More Presentable

05/03/2017

I do occasionally hold talks, mostly about Lisp-related topics. My medium of choice is PDF, as generated by Org’s export with the Beamer backend. When it’s demonstration time, Emacs isn’t nearly as simple to adjust for comfortable viewing as a browser or terminal. My first instinct was to look for a function that allows increasing the font size, similar to C-+. It turns out that C-x C-+ is a thing, however it’s not ideal as it only increases the font size of the current buffer. A quick look at the sources reveals why:

(define-minor-mode text-scale-mode
  "..."
  :lighter (" " text-scale-mode-lighter)
  (when text-scale-mode-remapping
    (face-remap-remove-relative text-scale-mode-remapping))
  (setq text-scale-mode-lighter
        (format (if (>= text-scale-mode-amount 0) "+%d" "%d")
                text-scale-mode-amount))
  (setq text-scale-mode-remapping
        (and text-scale-mode
             (face-remap-add-relative 'default
                                          :height
                                          (expt text-scale-mode-step
                                                text-scale-mode-amount))))
  (force-window-update (current-buffer)))

text-scale-mode is implemented in terms of face-remap-add-relative, a function describing itself as “Add a face remapping entry of FACE to SPECS in the current buffer.”. Funnily enough, both live in face-remap.el, probably because scaling text is merely a demonstration of the buffer-local face remapping capabilities of Emacs. While it’s a cute demo, it’s clearly not what I’d want from a C-+ replacement, so I wrote an alternative solution operating on the frame:

(defun my-alter-frame-font-size (fn)
  (let* ((current-font-name (frame-parameter nil 'font))
         (decomposed-font-name (x-decompose-font-name current-font-name))
         (font-size (string-to-int (aref decomposed-font-name 5))))
    (aset decomposed-font-name 5 (int-to-string (funcall fn font-size)))
    (set-frame-font (x-compose-font-name decomposed-font-name))))

(defun my-inc-frame-font-size ()
  (interactive)
  (my-alter-frame-font-size '1+))

(defun my-dec-frame-font-size ()
  (interactive)
  (my-alter-frame-font-size '1-))

(global-set-key (kbd "C-+") 'my-inc-frame-font-size)
(global-set-key (kbd "C-=") 'my-inc-frame-font-size)
(global-set-key (kbd "C--") 'my-dec-frame-font-size)

This is a bit less hacky, but still disgusting. The code fetches the font name (which curiously comes in the XLFD notation) from the frame, converts it into an array, extracts the font size, manipulates it, puts it back into the array, converts it to a font name and sets the frame’s font to it. You can find this snippet and many more in my init.org, so if you haven’t already, give it a look to find more goodies!