53

PragmataPro is a typeface that comes with a number of programming ligatures. My understanding is that these are OpenType face (OTF) ligatures.

I am aware that Emacs supports programmatic replacement of character combinations (for example -> to or lambda to λ). However, these are unicode faux ligatures, since they have their own code points, which real ligatures do not.

Am I correct that Emacs (as of 25) does not support OTF ligatures automatically? On a lower level, are there options available to manually specify glyph mappings?

If ligatures are unsupported, then what needs to be done for Emacs to support ligatures?

Matthew Piziak
  • 5,958
  • 3
  • 29
  • 77
  • 3
    Looks like it's not yet supported: http://lists.gnu.org/archive/html/emacs-devel/2015-01/msg00024.html – Kaushal Modi Feb 25 '15 at 22:52
  • Out of curiosity, what are some of the "number of useful enhancements" you have in mind? – Dan Jun 08 '15 at 12:16
  • 3
    Improved variable-width rendering in text mode, programming ligatures that make source code more attractive without affecting the shape of the code, and diagrammatic ligatures for boxes and arrows. In hindsight, "attractive" is probably a better descriptor than "useful". – Matthew Piziak Jun 08 '15 at 12:28
  • https://github.com/i-tu/Hasklig/issues/10 is tracking Emacs support for Hasklig. A partial solution, which works specifically for Hasklig and `haskell-mode` is detailed in [this gist](https://gist.github.com/i-tu/3e835955d0db554d76b7#file-gistfile1-el-L112). – Matthew Piziak Feb 19 '16 at 15:36
  • 3
    A [recent post on *r/emacs*](https://www.reddit.com/r/emacs/comments/4sm6fa/how_to_enable_pragmatapro_ligatures/) posted a workaround using `prettify-symbols-mode`, and it works pretty good with PragmataPro 0.822. – Kaushal Modi Aug 03 '16 at 16:55
  • The mappings for PragmataPro 0.825 changed and a new gist posted at https://gist.github.com/DeLaGuardo/fe1f3d9397d6ef7468460d54d5601156#gistcomment-2112387 worked for me. – xji Apr 22 '18 at 08:45

2 Answers2

10

emacs for now doesn't support ligatures (on OSX there is some support, but not on other platforms). However, emacs 24.4+ supports prettify-symbols-mode which in some ways is better than normal ligatures support.

That mode allows to subsitute for display any regex with any glyph. I am personnally using this snippet to get Fira Code ligatures to work in emacs on linux. (EDIT: unfortunately the link is now dead, the policy of stackoverflow to always copy inline is obviously the good one...)

The link I originally put is dead and I'm not certain exactly what it contained but I think these links should be good: https://github.com/tonsky/FiraCode/wiki/Emacs-instructions#using-prettify-symbols and https://github.com/tonsky/FiraCode/issues/312#issuecomment-262878734

Given the dead link issue, I'm putting the code inline this time:

(defun fira-code-mode--make-alist (list)
  "Generate prettify-symbols alist from LIST."
  (let ((idx -1))
    (mapcar
     (lambda (s)
       (setq idx (1+ idx))
       (let* ((code (+ #Xe100 idx))
          (width (string-width s))
          (prefix ())
          (suffix '(?\s (Br . Br)))
          (n 1))
     (while (< n width)
       (setq prefix (append prefix '(?\s (Br . Bl))))
       (setq n (1+ n)))
     (cons s (append prefix suffix (list (decode-char 'ucs code))))))
     list)))

(defconst fira-code-mode--ligatures
  '("www" "**" "***" "**/" "*>" "*/" "\\\\" "\\\\\\"
    "{-" "[]" "::" ":::" ":=" "!!" "!=" "!==" "-}"
    "--" "---" "-->" "->" "->>" "-<" "-<<" "-~"
    "#{" "#[" "##" "###" "####" "#(" "#?" "#_" "#_("
    ".-" ".=" ".." "..<" "..." "?=" "??" ";;" "/*"
    "/**" "/=" "/==" "/>" "//" "///" "&&" "||" "||="
    "|=" "|>" "^=" "$>" "++" "+++" "+>" "=:=" "=="
    "===" "==>" "=>" "=>>" "<=" "=<<" "=/=" ">-" ">="
    ">=>" ">>" ">>-" ">>=" ">>>" "<*" "<*>" "<|" "<|>"
    "<$" "<$>" "<!--" "<-" "<--" "<->" "<+" "<+>" "<="
    "<==" "<=>" "<=<" "<>" "<<" "<<-" "<<=" "<<<" "<~"
    "<~~" "</" "</>" "~@" "~-" "~=" "~>" "~~" "~~>" "%%"
    "x" ":" "+" "+" "*"))

(defvar fira-code-mode--old-prettify-alist)

(defun fira-code-mode--enable ()
  "Enable Fira Code ligatures in current buffer."
  (setq-local fira-code-mode--old-prettify-alist prettify-symbols-alist)
  (setq-local prettify-symbols-alist (append (fira-code-mode--make-alist fira-code-mode--ligatures) fira-code-mode--old-prettify-alist))
  (prettify-symbols-mode t))

(defun fira-code-mode--disable ()
  "Disable Fira Code ligatures in current buffer."
  (setq-local prettify-symbols-alist fira-code-mode--old-prettify-alist)
  (prettify-symbols-mode -1))

(define-minor-mode fira-code-mode
  "Fira Code ligatures minor mode"
  :lighter " Fira Code"
  (setq-local prettify-symbols-unprettify-at-point 'right-edge)
  (if fira-code-mode
      (fira-code-mode--enable)
    (fira-code-mode--disable)))

(defun fira-code-mode--setup ()
  "Setup Fira Code Symbols"
  (set-fontset-font t '(#Xe100 . #Xe16f) "Fira Code Symbol"))

(provide 'fira-code-mode)

I said that in some ways this is better than normal ligatures.. That's because it's "a la carte". You can mix-and-match, take only the symbols you like. You can say, I want the ";;" ligature, EXCEPT if the next character is again ";" in that case I don't want it... And about mix-and-matching... I'm using the 'Fira Mono' font, together with the 'Fira Code' ligatures. You don't have to buy in the whole font.

It's worse than pure ligatures because it doesn't work out of the box and it requires the font to be tuned in a certain way to make it possible.

Emmanuel Touzery
  • 961
  • 1
  • 8
  • 17
  • Hi! Could you share this snippet to get Fira Code ligatures work? Gist seems to be deleted. – xamenrax Mar 25 '19 at 03:03
  • huh sorry... updated the answer, I hope it helps – Emmanuel Touzery Mar 25 '19 at 06:25
  • 1
    Thank you! Almost 3 years has passed by but something never changes - people desperate about making ligatures work in Emacs... – xamenrax Mar 25 '19 at 07:52
  • This didn't work correctly for me with Emacs 26.3 on Ubuntu 18.04: I get the wrong symbols, when the line is highlighted and different wrong symbols when it doesn't. Also failed to use [this method with JetBrains Mono font](https://emacs.stackexchange.com/q/55059/) – Chen Levy Jan 23 '20 at 07:12
  • `prettify-symbols-mode` doesn't work as fine as *ligature*. It can only render symbols to **one** character. – shynur Jul 15 '23 at 01:31
0

If you are on OS X I believe the Carbon Mac Emacs port supports ligatures.

tgerdin
  • 11
  • 2