Fira Code Font Ligatures in Emacs/Spacemacs on (Arch) Linux

03/08/20191 Min Read — In DevTools, Vim, Emacs, Linux

I'm playing around with editors. It seems like some Elixir people use Spacemacs instead of Vim for their needs.

Spacemacs is an Emacs distribution that comes with default configuration and (optional) Vim keybindings - the best of both worlds!

I dabbled in Emacs a while ago when I learned Clojure. But the keybindings were mind-boggling. Even more insane than Vim.

So, lets set up Spacemacs with Fira Code Font Ligatures.

There is a Wiki entry with Emacs instructions but I had to try out several methods until I got it working.

Step 1

or

Both are available in Arch's package manager/AUR.

Step 2

Get the Fira Code Symbol Font and install it.

For Arch Linux/Manjaro Linux, it's easy: unzip, move to /usr/share/fonts and reload the font-cache with fc-cache -vf. (see instructions by Erik Hellman.)

Step 3

Open up your spacemacs config file. ~/.spacemacs. Emacs users, yours will normally be under ~/.emacs.d/init.el.

In spacemacs you can define a default font under dotespacemacs-default font, like so:

dotspacemacs-default-font '(("FuraCode Nerd Font Mono"
                               :size 16
                               :weight medium
                               :width normal
                               :powerline-scale 1.1)
                               ("Fira Code Symbol"
                               :size 16
                               :weight normal
                               :width normal
                               :powerline-scale 1.1))

In Emacs you can either change the font globally or just for the current frame.

Step 4

Now for some arcane magic - stolen from Profpatsch's github.

In spacemacs, add this to your dotspacemacs-user-config, so that the function looks like this:

(defun dotspacemacs/user-config()
 "Configuration function for user code."

;; Font Ligatures
  (defun my-correct-symbol-bounds (pretty-alist)
      "Prepend a TAB character to each symbol in this alist,
  this way compose-region called by prettify-symbols-mode
  will use the correct width of the symbols
  instead of the width measured by char-width."
      (mapcar (lambda (el)
                (setcdr el (string ?\t (cdr el)))
                el)
              pretty-alist))

  (defun my-ligature-list (ligatures codepoint-start)
      "Create an alist of strings to replace with
  codepoints starting from codepoint-start."
      (let ((codepoints (-iterate '1+ codepoint-start (length ligatures))))
        (-zip-pair ligatures codepoints)))

  (setq my-fira-code-ligatures
      (let* ((ligs '("www" "**" "***" "**/" "*>" "*/" "\\\\" "\\\\\\"
                    "{-" "[]" "::" ":::" ":=" "!!" "!=" "!==" "-}"
                    "--" "---" "-->" "->" "->>" "-<" "-<<" "-~"
                    "#{" "#[" "##" "###" "####" "#(" "#?" "#_" "#_("
                    ".-" ".=" ".." "..<" "..." "?=" "??" ";;" "/*"
                    "/**" "/=" "/==" "/>" "//" "///" "&&" "||" "||="
                    "|=" "|>" "^=" "$>" "++" "+++" "+>" "=:=" "=="
                    "===" "==>" "=>" "=>>" "<=" "=<<" "=/=" ">-" ">="
                    ">=>" ">>" ">>-" ">>=" ">>>" "<*" "<*>" "<|" "<|>"
                    "<$" "<$>" "<!--" "<-" "<--" "<->" "<+" "<+>" "<="
                    "<==" "<=>" "<=<" "<>" "<<" "<<-" "<<=" "<<<" "<~"
                    "<~~" "</" "</>" "~@" "~-" "~=" "~>" "~~" "~~>" "%%"
                    "x" ":" "+" "+" "*")))
        (my-correct-symbol-bounds (my-ligature-list ligs #Xe100))))

  (defun my-set-fira-code-ligatures ()
      "Add fira code ligatures for use with prettify-symbols-mode."
      (setq prettify-symbols-alist
            (append my-fira-code-ligatures prettify-symbols-alist))
      (prettify-symbols-mode))

  (add-hook 'prog-mode-hook 'my-set-fira-code-ligatures))

Emacs, users, just add the above function without the nesting inside dotspacemacs-user-config to your init.el.

Step 5

Done. Make sure to reload spacemacs/emacs and your font-cache.