doomemacs/modules/ui/ligatures/config.el
Henrik Lissner 659f7bfc71
refactor!: deprecate IS-* OS constants
BREAKING CHANGE: This deprecates the IS-(MAC|WINDOWS|LINUX|BSD) family
of global constants in favor of a native `featurep` check:

  IS-MAC      ->  (featurep :system 'macos)
  IS-WINDOWS  ->  (featurep :system 'windows)
  IS-LINUX    ->  (featurep :system 'linux)
  IS-BSD      ->  (featurep :system 'bsd)

The constants will stick around until the v3 release so folks can still
use it -- and there are still some modules that use it, but I'll phase
those uses out gradually.

Fix: #7479
2024-02-04 17:54:29 -05:00

181 lines
6.9 KiB
EmacsLisp
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; ui/ligatures/config.el -*- lexical-binding: t; -*-
(defvar +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 "" ;; FIXME: find a non-private char
:dot "")
"Maps identifiers to symbols, recognized by `set-ligatures'.
This should not contain any symbols from the Unicode Private Area! There is no
universal way of getting the correct symbol as that area varies from font to
font.")
(defvar +ligatures-extra-alist '((t))
"A map of major modes to symbol lists (for `prettify-symbols-alist').")
(defvar +ligatures-prog-mode-list
'("|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
"!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
"<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
"<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
"..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
"~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
"[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
"<$" "<=" "<>" "<-" "<<" "<+" "</" "#{" "#[" "#:" "#=" "#!"
"##" "#(" "#?" "#_" "%%" ".=" ".-" ".." ".?" "+>" "++" "?:"
"?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)"
"\\\\" "://")
"A list of ligatures to enable in all `prog-mode' buffers.")
(defvar +ligatures-all-modes-list
'()
"A list of ligatures to enable in all buffers.")
(defvar +ligatures-in-modes
'(not special-mode comint-mode eshell-mode term-mode vterm-mode Info-mode
elfeed-search-mode elfeed-show-mode)
"List of major modes where ligatures should be enabled.
If t, enable it everywhere (except `fundamental-mode').
If the first element is 'not, enable it in any mode besides what is listed.
If nil, don't enable ligatures anywhere.")
(defvar +ligatures-extras-in-modes t
"List of major modes where extra ligatures should be enabled.
Extra ligatures are mode-specific substituions, defined in
`+ligatures-extra-symbols' and assigned with `set-ligatures!'. This variable
controls where these are enabled.
If t, enable it everywhere (except `fundamental-mode').
If the first element is 'not, enable it in any mode besides what is listed.
If nil, don't enable these extra ligatures anywhere (though it's more
efficient to remove the `+extra' flag from the :ui ligatures module instead).")
(defvar +ligatures--init-font-hook nil)
(defun +ligatures--correct-symbol-bounds (ligature-alist)
"Prepend non-breaking spaces to a ligature.
This way `compose-region' (called by `prettify-symbols-mode') will use the
correct width of the symbols instead of the width measured by `char-width'."
(let ((len (length (car ligature-alist)))
(acc (list (cdr ligature-alist))))
(while (> len 1)
(setq acc (cons #X00a0 (cons '(Br . Bl) acc))
len (1- len)))
(cons (car ligature-alist) acc)))
(defun +ligatures--enable-p (modes)
"Return t if ligatures should be enabled in this buffer depending on MODES."
(unless (eq major-mode 'fundamental-mode)
(or (eq modes t)
(if (eq (car modes) 'not)
(not (apply #'derived-mode-p (cdr modes)))
(apply #'derived-mode-p modes)))))
(defun +ligatures-init-buffer-h ()
"Set up ligatures for the current buffer.
Extra ligatures are mode-specific substituions, defined in
`+ligatures-extra-symbols', assigned with `set-ligatures!', and made possible
with `prettify-symbols-mode'. This variable controls where these are enabled.
See `+ligatures-extras-in-modes' to control what major modes this function can
and cannot run in."
(when after-init-time
(let ((in-mode-p
(+ligatures--enable-p +ligatures-in-modes))
(in-mode-extras-p
(and (modulep! +extra)
(+ligatures--enable-p +ligatures-extras-in-modes))))
(when in-mode-p
;; If ligature-mode has been installed, there's no
;; need to do anything, we activate global-ligature-mode
;; later and handle all settings from `set-ligatures!' later.
(unless (fboundp #'ligature-mode-turn-on)
(run-hooks '+ligatures--init-font-hook)
(setq +ligatures--init-font-hook nil)))
(when in-mode-extras-p
(prependq! prettify-symbols-alist
(alist-get major-mode +ligatures-extra-alist)))
(when (and (or in-mode-p in-mode-extras-p)
prettify-symbols-alist)
(when prettify-symbols-mode
(prettify-symbols-mode -1))
(prettify-symbols-mode +1)))))
;;
;;; Bootstrap
;;;###package prettify-symbols
;; When you get to the right edge, it goes back to how it normally prints
(setq prettify-symbols-unprettify-at-point 'right-edge)
(add-hook! 'doom-init-ui-hook :append
(defun +ligatures-init-h ()
(add-hook 'after-change-major-mode-hook #'+ligatures-init-buffer-h)))
(cond
;; The emacs-mac build of Emacs appears to have built-in support for ligatures,
;; using the same composition-function-table method
;; https://bitbucket.org/mituharu/emacs-mac/src/26c8fd9920db9d34ae8f78bceaec714230824dac/lisp/term/mac-win.el?at=master#lines-345:805
;; so use that instead if this module is enabled.
((if (featurep :system 'macos)
(fboundp 'mac-auto-operator-composition-mode))
(add-hook 'doom-init-ui-hook #'mac-auto-operator-composition-mode 'append))
;; NOTE: the module does not support Emacs 27 and less, but if we still try to enable ligatures,
;; it will end up in catastrophic work-loss errors, so we leave the check here for safety.
((and (> emacs-major-version 27)
(or (featurep 'ns)
(string-match-p "HARFBUZZ" system-configuration-features))
(featurep 'composite)) ; Emacs loads `composite' at startup
(use-package! ligature
:config
;; Enable all `+ligatures-prog-mode-list' ligatures in programming modes
(ligature-set-ligatures 'prog-mode +ligatures-prog-mode-list)
(ligature-set-ligatures 't +ligatures-all-modes-list))
(add-hook! 'doom-init-ui-hook :append
(defun +ligature-enable-globally-h ()
"Enables ligature checks globally in all buffers.
You can also do it per mode with `ligature-mode'."
(global-ligature-mode t)))))