Include ligature.el in a new set-font-ligatures! function, so that "normal" (read: "font-based") ligatures can also be controlled on a per-major mode basis from a user function in configuration. This commit also drops support for Emacs 27 to reduce the maintenance burden. BREAKING CHANGE: font ligatures for Harfbuzz/Coretext composition table-based ligations are no longer controlled with `+ligatures-composition-alist`, but is handled with `+ligatures-prog-mode-list` and `+ligatures-all-modes-list` for most common cases. See the README for the mode-specific methods BREAKING CHANGE: the `:ui ligatures` module will not work anymore with Emacs 27 or older. Also, there is no need to keep patched fonts (for Fira, Hasklig, Iosevka) if you use the module. Update Emacs if you want to keep using ligatures, or disable the module (`doom doctor` will tell you if your current version of Emacs stopped working with the module)
261 lines
8.9 KiB
Org Mode
261 lines
8.9 KiB
Org Mode
#+title: :ui ligatures
|
||
#+subtitle: Distract folks from your code
|
||
#+created: June 16, 2018
|
||
#+since: 21.12.0
|
||
|
||
* Description :unfold:
|
||
* Table of Contents :TOC_3:noexport:
|
||
- [[#description][Description]]
|
||
- [[#maintainers][Maintainers]]
|
||
- [[#module-flags][Module flags]]
|
||
- [[#packages][Packages]]
|
||
- [[#hacks][Hacks]]
|
||
- [[#changelog][Changelog]]
|
||
- [[#installation][Installation]]
|
||
- [[#usage][Usage]]
|
||
- [[#mathematical-symbols-replacement][Mathematical symbols replacement]]
|
||
- [[#coding-ligatures][Coding ligatures]]
|
||
- [[#details][Details]]
|
||
- [[#configuration][Configuration]]
|
||
- [[#symbol-replacements-λ-for-lambda][Symbol replacements (λ for "lambda"...)]]
|
||
- [[#font-ligatures-turning--into-an-arrow][Font ligatures (turning "=>" into an arrow...)]]
|
||
- [[#setting-ligatures-for-specific-font-or-major-mode][Setting ligatures for specific font or major mode]]
|
||
- [[#overwriting-all-default-ligatures][Overwriting all default ligatures]]
|
||
- [[#troubleshooting][Troubleshooting]]
|
||
- [[#some-symbols-are-not-rendering-correctly][Some symbols are not rendering correctly]]
|
||
- [[#frequently-asked-questions][Frequently asked questions]]
|
||
- [[#appendix][Appendix]]
|
||
|
||
** Maintainers
|
||
- [[doom-user:][@gagbo]]
|
||
|
||
[[doom-contrib-maintainer:][Become a maintainer?]]
|
||
|
||
** Module flags
|
||
- +extra ::
|
||
Enables extra symbol substitutions in certain modes, for example ~lambda~ in
|
||
lisps are replaced with ~λ~.
|
||
|
||
** Packages
|
||
- [[https://github.com/mickeynp/ligature.el][ligature.el]] (on Emacs 28+ with Harfbuzz)
|
||
|
||
** Hacks
|
||
/No hacks documented for this module./
|
||
|
||
** TODO Changelog
|
||
# This section will be machine generated. Don't edit it by hand.
|
||
/This module does not have a changelog yet./
|
||
|
||
* Installation
|
||
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]
|
||
|
||
This module requires one of three setups for ligatures to work:
|
||
|
||
- A recent enough version of Emacs which will compose ligatures automatically
|
||
(Emacs 28 with Harfbuzz support), or
|
||
- Mitsuharu's =emacs-mac= build on macOS (available on Homebrew), or
|
||
- A patched font for Doom's fallback ligature support.
|
||
|
||
/This module does not have specific installation instructions/
|
||
|
||
~doom doctor~ will tell you if the module is incompatible with your current
|
||
Emacs version, and what you can do to remediate.
|
||
|
||
* Usage
|
||
#+begin_quote
|
||
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||
#+end_quote
|
||
|
||
** Mathematical symbols replacement
|
||
If you want to set symbol replacements for modules that don't have them by
|
||
default you can use the ~set-ligatures!~ function in your config.el file
|
||
#+BEGIN_SRC emacs-lisp
|
||
(after! PACKAGE
|
||
(set-ligatures! 'MAJOR-MODE
|
||
:symbol "keyword"))
|
||
#+end_src
|
||
|
||
E.g.
|
||
#+begin_src emacs-lisp
|
||
(after! go-mode ; in this case the major mode and package named the same thing
|
||
(set-ligatures! 'go-mode
|
||
:def "func" ; function keyword
|
||
:true "true" :false "false"
|
||
; this will replace not only definitions
|
||
; but coresponding functions aswell
|
||
:int "int" :str "string"
|
||
:float "float" :bool "bool"
|
||
:for "for"
|
||
:return "return" :yield "yield"))
|
||
#+end_src
|
||
|
||
You can set these symbols out of the box:
|
||
#+begin_src emacs-lisp
|
||
(set-ligatures! 'MAJOR-MODE
|
||
;; Functional
|
||
:lambda "lambda keyword"
|
||
:def "function keyword"
|
||
:composition "composition"
|
||
:map "map/dictionary keyword"
|
||
;; Types
|
||
:null "null type"
|
||
:true "true keyword"
|
||
:false "false keyword"
|
||
:int "int keyword"
|
||
:float "float keyword"
|
||
:str "string keyword"
|
||
:bool "boolean keyword"
|
||
:list "list keyword"
|
||
;; Flow
|
||
:not "not operator"
|
||
:in "in operator"
|
||
:not-in "not in operator"
|
||
:and "and keyword"
|
||
:or "or keyword"
|
||
:for "for keyword"
|
||
:some "some keyword"
|
||
:return "return"
|
||
:yield "yeild"
|
||
;; Other
|
||
:union "Union keyword"
|
||
:intersect "Intersect keyword"
|
||
:diff "diff keyword"
|
||
:tuple "Tuple Keyword "
|
||
:pipe "Pipe Keyword"
|
||
:dot "Dot operator")
|
||
#+end_src
|
||
|
||
If you have multiple versions of the same keyword you can set the symbol twice:
|
||
#+begin_src emacs-lisp
|
||
(set-ligatures! scala-mode
|
||
:null "none"
|
||
:null "None")
|
||
#+end_src
|
||
|
||
|
||
** Coding ligatures
|
||
This module includes configuration to compose combinations like =->= or =::=
|
||
into prettier glyphs (called a ligature), specific for your font, or specific
|
||
for the major modes that you want to use.
|
||
|
||
As these ligatures come from the font itself instead of elisp symbols, we use
|
||
=set-font-ligatures!=
|
||
|
||
#+begin_src elisp
|
||
(set-font-ligatures! '(haskell-mode clojure-mode) ">>=" ">>-")
|
||
#+end_src
|
||
|
||
*** Details
|
||
Ligatures are implemented using a **composition-function-table** method: regexps are
|
||
used to match all the usual sequences which are composed into ligatures. These
|
||
regexps are passed to emacs directly, which asks Harfbuzz to shape it. Ligatures
|
||
are obtained automatically depending on the capabilities of the font, and no
|
||
font-specific configuration is necessary.
|
||
|
||
Emacs-mac port implements the same method natively in [[https://bitbucket.org/mituharu/emacs-mac/src/26c8fd9920db9d34ae8f78bceaec714230824dac/lisp/term/mac-win.el?at=master#lines-345:805][its code]], nothing is
|
||
necessary on Doom side; otherwise, Doom uses the [[https://github.com/mickeynp/ligature.el][ligature.el]] package that
|
||
implements this method for Emacs 28+ built with Harfbuzz support. Therefore, the
|
||
module will not work with Emacs 27 or previous.
|
||
|
||
Even though harfbuzz has been included in emacs 27, there is currently a
|
||
[[https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-04/msg01121.html][bug
|
||
(#40864)]] which prevents a safe usage of the /composition-function-table/ method in
|
||
Emacs 27.
|
||
|
||
* Configuration
|
||
** Symbol replacements (λ for "lambda"...)
|
||
if you don't like the symbols chosen you can change them by using:
|
||
#+begin_src emacs-lisp
|
||
;; you don't need to include all of them you can pick and mix
|
||
(plist-put! +ligatures-extra-symbols
|
||
;; org
|
||
:name "»"
|
||
:src_block "»"
|
||
:src_block_end "«"
|
||
:quote "“"
|
||
:quote_end "”"
|
||
;; Functional
|
||
:lambda "λ"
|
||
:def "ƒ"
|
||
:composition "∘"
|
||
:map "↦"
|
||
;; Types
|
||
:null "∅"
|
||
:true "𝕋"
|
||
:false "𝔽"
|
||
:int "ℤ"
|
||
:float "ℝ"
|
||
:str "𝕊"
|
||
:bool "𝔹"
|
||
:list "𝕃"
|
||
;; Flow
|
||
:not "¬"
|
||
:in "∈"
|
||
:not-in "∉"
|
||
:and "∧"
|
||
:or "∨"
|
||
:for "∀"
|
||
:some "∃"
|
||
:return "⟼"
|
||
:yield "⟻"
|
||
;; Other
|
||
:union "⋃"
|
||
:intersect "∩"
|
||
:diff "∖"
|
||
:tuple "⨂"
|
||
:pipe ""
|
||
:dot "•") ;; you could also add your own if you want
|
||
#+end_src
|
||
|
||
** Font ligatures (turning "=>" into an arrow...)
|
||
*** Setting ligatures for specific font or major mode
|
||
As the [[https://github.com/mickeynp/ligature.el][README]] for ligature.el states, you can manipulate the ligatures that you
|
||
want to enable, specific for your font, or specific for the major modes that you
|
||
want to use. =set-font-ligatures!= is a thin wrapper around =ligature.el= to control these.
|
||
|
||
#+begin_src elisp
|
||
(set-font-ligatures! '(haskell-mode clojure-mode) ">>=" ">>-")
|
||
#+end_src
|
||
|
||
This call will:
|
||
- overwrite all preceding calls to =set-font-ligatures!=
|
||
for =haskell-mode= and =clojure-mode= specifically, but
|
||
- keep the inheritance to ligatures set for all modes, or parent modes like =prog-mode=
|
||
|
||
*** Overwriting all default ligatures
|
||
If you want to "start from scratch" and get control over all ligatures that
|
||
happen in all modes, you can use
|
||
|
||
#+begin_src elisp
|
||
;; Set all your custom ligatures for all prog-modes here
|
||
;; This section is *out of* the after! block
|
||
;; Example: only get ligatures for "==" and "===" in programming modes
|
||
;; by default, and get only "www" in all buffers by default.
|
||
(setq +ligatures-prog-mode-list '("==" "===")
|
||
+ligatures-all-modes-list '("www"))
|
||
;; Set any of those variables to nil to wipe all defaults.
|
||
|
||
;; Set all your additional custom ligatures for other major modes here.
|
||
;; Example: enable traditional ligature support in eww-mode, if the
|
||
;; `variable-pitch' face supports it
|
||
(set-font-ligatures! 'eww-mode "ff" "fi" "ffi")
|
||
#+end_src
|
||
|
||
* Troubleshooting
|
||
[[doom-report:][Report an issue?]]
|
||
|
||
** Some symbols are not rendering correctly
|
||
This can usually be fixed by doing one of the following:
|
||
|
||
- Make sure Symbola (the font) is installed on your system.
|
||
- Otherwise, change [[var:doom-unicode-font]] (set to Symbola by default).
|
||
- Disable the [[doom-module::ui unicode]] module. It not only overrides [[var:doom-unicode-font]], but
|
||
should only be used as a last resort.
|
||
|
||
* Frequently asked questions
|
||
/This module has no FAQs yet./ [[doom-suggest-faq:][Ask one?]]
|
||
|
||
* TODO Appendix
|
||
#+begin_quote
|
||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||
#+end_quote
|