JetBrains / JetBrainsMono

JetBrains Mono – the free and open-source typeface for developers
https://jetbrains.com/mono
SIL Open Font License 1.1
10.58k stars 298 forks source link

Add composed ligatures to Private Use Area for manual ligature placement #156

Open curtmack opened 4 years ago

curtmack commented 4 years ago

In some editors that don't support ligatures in fonts, it is possible to emulate the effect of ligatures by configuring the editor to replace the text manually; this is only possible if the ligatures themselves are available as characters somewhere in the font (often in the Private Use Area). For example, in Emacs, one can use prettify-symbols-mode to accomplish this.

Ideally, a data file would be provided that could be automatically consumed to produce configuration files. For example, given a JSON file like this:

{
    "ligatures": [
        {
            "text": "->",
            "replacement": "\ue100"
        },
        "..."
    ]
}

Code could be written in Emacs to consume it into a format suitable for prettify-symbols-alist, like so:

(require 'json) ;; https://github.com/ryancrum/json.el
(require 'dash) ;; https://github.com/magnars/dash.el

(defun parse-jetbrains-mono-ligatures (ligatures)
  (mapcar
   (lambda (ligature)
     (let ((text (cdr (assoc 'text ligature)))
           (replacement (cdr (assoc 'replacement ligature))))
       (cons text
             (vconcat
              (-flatten
               (make-list
                (1- (length text))
                '(?\s (Br . Bl))))
              (list (aref replacement 0))))))
   ligatures))

(defun read-jetbrains-mono-ligatures (filename)
  (let* ((json-object-type 'alist)
         (json-array-type 'vector)
         (json-key-type 'symbol)
         (json (read-json-file filename)))
    (parse-jetbrains-mono-ligatures (cdr (assoc 'ligatures json)))))

(defconst jetbrains-mono-ligatures (read-jetbrains-mono-ligatures "/path/to/ligatures.json"))

(add-hook 'prog-mode-hook
          (lambda ()
            (setq prettify-symbols-alist
                  (append jetbrains-mono-ligatures prettify-symbols-alist))
            (prettify-symbols-mode t)))

Which would install the JetBrains Mono ligatures and enable prettify-symbols-mode whenever a new programming buffer is opened.

This is done by other major programming fonts that offer ligatures, including Fira Code, Hasklig, and PragmataPro. It would be nice to see it offered here as well.

philippnurullin commented 4 years ago

@curtmack Can you write names of editors you talking about?

curtmack commented 4 years ago

Emacs is the main editor that would benefit from this.

Now that I'm on the spot, I realize I'm not aware of any other editors that have this feature.

kryptt commented 4 years ago

It is probably only an emacs thing; and only useful until emacs gets proper ligatures itself... but it would be REALLY nice in the mean time :)

philippnurullin commented 4 years ago

Sorry, i have no idea how to make this. Right now all the focus is on the lighter weights, so properly researching & implementing this feature will take time. And considering that this feature is needed only in one editor, which in time will have the normal support of ligatures, the priority os low. If anybody can help with it, i will be grateful.

VojtechStep commented 4 years ago

FWIW Emacs 27 can now be compiled with harfbuzz support, which allows the user to define regexes which should be checked for alternative rendering.

You can check out this section of my config which adds all the ligatures from JetBrains Mono I could find.

@philippnurullin Is there a list of all the supported ligatures somewhere? All I could find was the showcase on the webpage which was not consistent with the page header where I could type stuff, and judging by the releases on GitHub it wasn't updated since at least v1.0.2 (it shows the /\ glyph which was removed in 1.0.3 for example).

I also think either the README or the wiki should have a note on setting up Emacs (Fira Code has a nice section in their wiki from which I adapted my code).