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.
haskell-mode
is detailed in this gist.prettify-symbols-mode
, and it works pretty good with PragmataPro 0.822.