Skip to content

Instantly share code, notes, and snippets.

@xieve
Forked from reiver-dev/fira_code_patch.py
Last active March 30, 2021 19:53
Show Gist options
  • Save xieve/d5a01cc59896c3973cb16df9ba8d30d4 to your computer and use it in GitHub Desktop.
Save xieve/d5a01cc59896c3973cb16df9ba8d30d4 to your computer and use it in GitHub Desktop.
Move ligatures for Fira Code font to private unicode area at U+e100
#!/bin/env python3
import os
import sys
import argparse
from glob import glob
from itertools import chain
import fontforge
ADDITIONAL_LIGATURES = [
'x.multiply',
'colon.uc',
'plus.lc',
'plus.tosf2',
]
def run(fontpath, outpath, starting_point=0xe100):
try:
font = fontforge.open(fontpath)
ligatures = list(filter(lambda x: x.glyphname.endswith('.liga'),
font.glyphs()))
for i, glyph in enumerate(ligatures):
point = starting_point + i
# You could also create a reference instead of defining an
# encoding, but I don't recommend that, as it causes some
# problems with character width
# name = glyph.glyphname
# newchar = font.createChar(point, name + '.private')
# newchar.addReference(name)
glyph.unicode = point
font.generate(outpath)
finally:
font.close()
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument('--output-dir', '-o', type=str)
parser.add_argument('fonts', nargs='+',
help='font files to process')
argvals = parser.parse_args(argv)
output = argvals.output_dir
fonts = argvals.fonts
os.makedirs(output, exist_ok=True)
for f in chain.from_iterable(map(glob, fonts)):
run(f, os.path.join(output, os.path.basename(f)))
if __name__ == '__main__':
main(sys.argv[1:])
(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" "--" "---" "-->" "-|" "->" "->>" "-<" "-<<" "-~" "{|" "[|" "]#" ".-"
".." "..." "..=" "..<" ".?" ".=" "::" ":::" "::=" ":=" ":>" ":<" ";;" "!!"
"!!." "!=" "!==" "?." "??" "?=" "**" "***" "*>" "*/" "#(" "#{" "#[" "#:"
"#!" "#?" "##" "###" "####" "#=" "#_" "#_(" "/*" "/=" "/==" "/>" "//" "///"
"/\\" "\\/" "_|_" "__" "&&" "|-" "|->" "|}" "|]" "||" "||-" "|||>" "||="
"||>" "|=" "|=>" "|>" "$>" "++" "+++" "+>" "=:=" "=!=" "==" "===" "==>"
"=>" "=>>" "=<<" "=/=" ">-" ">->" ">:" ">=" ">=>" ">>" ">>-" ">>=" ">>>"
"<-" "<--" "<-|" "<->" "<-<" "<:" "<!--" "<*" "<*>" "<|" "<||" "<|||"
"<|>" "<$" "<$>" "<+" "<+>" "<=" "<=|" "<==" "<==>" "<=>" "<=<" "<>" "<<"
"<<-" "<<->>" "<<=" "<<<" "<~" "<~>" "<~~" "</" "</>" "~-" "~@" "~>" "~~"
"~~>" "^=" "%%"))
(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)))
(provide 'fira-code-mode)
(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)))
(provide 'fira-code-mode)
@Maralbada
Copy link

Maralbada commented May 16, 2020

Lines 1 to 41 of ligatures.el are a duplication of lines 42 to 82, you can delete them.

Also I had to change the ligatures list or some ligatures didn't display properly, I probably left some out though.
I'm leaving my list here just in case someone finds it useful:

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

@xieve
Copy link
Author

xieve commented Jul 16, 2020

Lines 1 to 41 of ligatures.el are a duplication of lines 42 to 82, you can delete them.

Also I had to change the ligatures list or some ligatures didn't display properly, I probably left some out though.

Deleted the redundant lines (how'd they get there, anyway?!) and checked your updated list against FontForge. Good job, I found 2 or 3 errors in the less widely used ones, that was it! Thank you for your contribution, this should now be compatible with Fira Code 2.x.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment