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
181 lines
6.9 KiB
EmacsLisp
181 lines
6.9 KiB
EmacsLisp
;;; 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)))))
|