2020-08-12 18:52:14 -04:00
|
|
|
|
;;; ui/ligatures/config.el -*- lexical-binding: t; -*-
|
2018-07-05 19:37:06 -07:00
|
|
|
|
|
2020-08-20 02:40:57 -04:00
|
|
|
|
(defvar +ligatures-extra-symbols
|
2019-10-28 21:44:42 -04:00
|
|
|
|
'(;; org
|
|
|
|
|
:name "»"
|
|
|
|
|
:src_block "»"
|
|
|
|
|
:src_block_end "«"
|
2020-04-03 12:01:34 +02:00
|
|
|
|
:quote "“"
|
|
|
|
|
:quote_end "”"
|
2019-10-28 21:44:42 -04:00
|
|
|
|
;; Functional
|
|
|
|
|
:lambda "λ"
|
|
|
|
|
:def "ƒ"
|
|
|
|
|
:composition "∘"
|
|
|
|
|
:map "↦"
|
|
|
|
|
;; Types
|
|
|
|
|
:null "∅"
|
|
|
|
|
:true "𝕋"
|
|
|
|
|
:false "𝔽"
|
|
|
|
|
:int "ℤ"
|
|
|
|
|
:float "ℝ"
|
|
|
|
|
:str "𝕊"
|
|
|
|
|
:bool "𝔹"
|
2020-06-07 14:21:45 -04:00
|
|
|
|
:list "𝕃"
|
2019-10-28 21:44:42 -04:00
|
|
|
|
;; Flow
|
|
|
|
|
:not "¬"
|
|
|
|
|
:in "∈"
|
|
|
|
|
:not-in "∉"
|
|
|
|
|
:and "∧"
|
|
|
|
|
:or "∨"
|
|
|
|
|
:for "∀"
|
|
|
|
|
:some "∃"
|
|
|
|
|
:return "⟼"
|
|
|
|
|
:yield "⟻"
|
|
|
|
|
;; Other
|
2020-06-07 14:21:45 -04:00
|
|
|
|
:union "⋃"
|
|
|
|
|
:intersect "∩"
|
|
|
|
|
:diff "∖"
|
2019-10-28 21:44:42 -04:00
|
|
|
|
:tuple "⨂"
|
|
|
|
|
:pipe "" ;; FIXME: find a non-private char
|
|
|
|
|
:dot "•")
|
2020-08-20 02:40:57 -04:00
|
|
|
|
"Maps identifiers to symbols, recognized by `set-ligatures'.
|
2019-10-28 21:44:42 -04:00
|
|
|
|
|
|
|
|
|
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.")
|
|
|
|
|
|
2024-08-19 16:43:22 -04:00
|
|
|
|
(defvar +ligatures-alist
|
|
|
|
|
'((prog-mode "|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
|
|
|
|
|
":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
|
|
|
|
|
"!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
|
|
|
|
|
"<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
|
|
|
|
|
"<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
|
|
|
|
|
"..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
|
|
|
|
|
"~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
|
|
|
|
|
"[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
|
|
|
|
|
">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
|
|
|
|
|
"<$" "<=" "<>" "<-" "<<" "<+" "</" "#{" "#[" "#:" "#=" "#!"
|
|
|
|
|
"##" "#(" "#?" "#_" "%%" ".=" ".-" ".." ".?" "+>" "++" "?:"
|
|
|
|
|
"?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)"
|
|
|
|
|
"\\\\" "://")
|
|
|
|
|
(t))
|
2024-09-12 23:18:30 -04:00
|
|
|
|
"A alist of ligatures to enable in specific modes.
|
|
|
|
|
|
|
|
|
|
To configure this variable, use `set-ligatures!'.")
|
2024-08-19 16:43:22 -04:00
|
|
|
|
|
2024-09-11 03:21:05 -04:00
|
|
|
|
(defvar +ligatures-in-modes nil
|
|
|
|
|
"List of major modes where ligatures should be enabled.")
|
|
|
|
|
(make-obsolete-variable '+ligatures-in-modes "Use `ligature-ignored-major-modes' instead" "24.10.0")
|
|
|
|
|
|
2024-08-19 16:43:22 -04:00
|
|
|
|
(defvar +ligatures-prog-mode-list nil
|
2021-05-23 11:27:57 +02:00
|
|
|
|
"A list of ligatures to enable in all `prog-mode' buffers.")
|
2024-08-31 16:38:28 -04:00
|
|
|
|
(make-obsolete-variable '+ligatures-prog-mode-list "Use `+ligatures-alist' instead" "24.09.0")
|
2021-05-23 11:27:57 +02:00
|
|
|
|
|
2024-08-19 16:43:22 -04:00
|
|
|
|
(defvar +ligatures-all-modes-list nil
|
2021-05-23 11:27:57 +02:00
|
|
|
|
"A list of ligatures to enable in all buffers.")
|
2024-08-31 16:38:28 -04:00
|
|
|
|
(make-obsolete-variable '+ligatures-all-modes-list "Use `+ligatures-alist' instead" "24.09.0")
|
2024-08-19 16:43:22 -04:00
|
|
|
|
|
|
|
|
|
(defvar +ligatures-extra-alist '((t))
|
2024-09-12 23:18:30 -04:00
|
|
|
|
"A map of major modes to symbol lists (for `prettify-symbols-alist').
|
|
|
|
|
|
|
|
|
|
To configure this variable, use `set-ligatures!'.")
|
2020-03-31 00:59:14 -04:00
|
|
|
|
|
2020-08-12 18:52:14 -04:00
|
|
|
|
(defvar +ligatures-extras-in-modes t
|
|
|
|
|
"List of major modes where extra ligatures should be enabled.
|
2020-04-30 19:23:49 -04:00
|
|
|
|
|
2020-08-20 02:40:57 -04:00
|
|
|
|
Extra ligatures are mode-specific substituions, defined in
|
|
|
|
|
`+ligatures-extra-symbols' and assigned with `set-ligatures!'. This variable
|
|
|
|
|
controls where these are enabled.
|
2020-03-31 00:59:14 -04:00
|
|
|
|
|
2020-08-12 18:52:14 -04:00
|
|
|
|
If t, enable it everywhere (except `fundamental-mode').
|
2024-09-11 03:21:05 -04:00
|
|
|
|
If the first element is not, enable it in any mode besides what is listed.
|
2020-08-12 18:52:14 -04:00
|
|
|
|
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).")
|
2020-03-31 00:59:14 -04:00
|
|
|
|
|
2020-08-12 18:52:14 -04:00
|
|
|
|
(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)))))
|
|
|
|
|
|
2024-09-11 03:21:05 -04:00
|
|
|
|
(defun +ligatures-init-extra-symbols-h ()
|
|
|
|
|
"Set up `prettify-symbols-mode' for the current buffer.
|
2020-08-12 18:52:14 -04:00
|
|
|
|
|
fix(ligatures): activate prettify-symbols-mode conditionally
With +extra enabled, this module would activate `prettify-symbols-mode`
in any buffer where `prettify-symbols-alist` is non-nil, whether or not
`+ligatures-extra-alist` has an entry for the current major mode (or a
parent thereof). This behavior is poor UX, since the user may be
expecting that a empty entry for some `X-mode` in
`+ligatures-extra-alist` should mean *no` prettify-symbols-mode` at all
in `X-mode`.
With this, `+ligatures-extra-alist` is now the authority. An empty entry
for `X-mode` will result in `prettify-symbols-mode` *not* being
activated there. If that entry *isn't* empty, it will be combined only
with the global default value of `prettify-symbols-alist`, not any
pre-existing buffer-local value, to make the end result deterministic,
because some modes have their own defaults for it (like
`lisp-prettify-symbols-alist`, `js--prettify-symbols-alist`, and
`rust-prettify-symbols-alist`).
Fix: #7440
2024-09-12 23:18:08 -04:00
|
|
|
|
Overwrites `prettify-symbols-alist' and activates `prettify-symbols-mode' if
|
|
|
|
|
(and only if) there is an associated entry for the current major mode (or a
|
|
|
|
|
parent mode) in `+ligatures-extra-alist' AND the current mode (or a parent mode)
|
|
|
|
|
isn't disabled in `+ligatures-extras-in-modes'."
|
|
|
|
|
(when after-init-time
|
|
|
|
|
(when-let*
|
|
|
|
|
(((+ligatures--enable-p +ligatures-extras-in-modes))
|
|
|
|
|
(symbols
|
|
|
|
|
(if-let ((symbols (assq major-mode +ligatures-extra-alist)))
|
2024-09-14 01:46:52 -04:00
|
|
|
|
(cdr symbols)
|
fix(ligatures): activate prettify-symbols-mode conditionally
With +extra enabled, this module would activate `prettify-symbols-mode`
in any buffer where `prettify-symbols-alist` is non-nil, whether or not
`+ligatures-extra-alist` has an entry for the current major mode (or a
parent thereof). This behavior is poor UX, since the user may be
expecting that a empty entry for some `X-mode` in
`+ligatures-extra-alist` should mean *no` prettify-symbols-mode` at all
in `X-mode`.
With this, `+ligatures-extra-alist` is now the authority. An empty entry
for `X-mode` will result in `prettify-symbols-mode` *not* being
activated there. If that entry *isn't* empty, it will be combined only
with the global default value of `prettify-symbols-alist`, not any
pre-existing buffer-local value, to make the end result deterministic,
because some modes have their own defaults for it (like
`lisp-prettify-symbols-alist`, `js--prettify-symbols-alist`, and
`rust-prettify-symbols-alist`).
Fix: #7440
2024-09-12 23:18:08 -04:00
|
|
|
|
(cl-loop for (mode . symbols) in +ligatures-extra-alist
|
|
|
|
|
if (derived-mode-p mode)
|
|
|
|
|
return symbols))))
|
|
|
|
|
(setq prettify-symbols-alist
|
|
|
|
|
(append symbols
|
|
|
|
|
;; Don't overwrite global defaults
|
|
|
|
|
(default-value 'prettify-symbols-alist)))
|
|
|
|
|
(when (bound-and-true-p prettify-symbols-mode)
|
2024-09-11 03:21:05 -04:00
|
|
|
|
(prettify-symbols-mode -1))
|
|
|
|
|
(prettify-symbols-mode +1))))
|
2018-07-06 20:18:04 +02:00
|
|
|
|
|
2020-01-09 10:24:41 +01:00
|
|
|
|
|
2020-04-30 19:23:49 -04:00
|
|
|
|
;;
|
|
|
|
|
;;; 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)
|
|
|
|
|
|
2024-09-11 03:21:05 -04:00
|
|
|
|
(when (modulep! +extra)
|
|
|
|
|
(add-hook 'after-change-major-mode-hook #'+ligatures-init-extra-symbols-h))
|
2020-08-12 18:52:14 -04:00
|
|
|
|
|
2020-04-30 19:23:49 -04:00
|
|
|
|
(cond
|
2020-08-12 18:52:14 -04:00
|
|
|
|
;; The emacs-mac build of Emacs appears to have built-in support for ligatures,
|
2020-04-30 19:23:49 -04:00
|
|
|
|
;; 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.
|
2023-12-05 17:05:13 -05:00
|
|
|
|
((if (featurep :system 'macos)
|
|
|
|
|
(fboundp 'mac-auto-operator-composition-mode))
|
2020-08-12 18:52:14 -04:00
|
|
|
|
(add-hook 'doom-init-ui-hook #'mac-auto-operator-composition-mode 'append))
|
2020-04-30 19:23:49 -04:00
|
|
|
|
|
2024-03-26 10:39:24 -04:00
|
|
|
|
;; This 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.
|
2022-08-12 20:07:08 +02:00
|
|
|
|
((and (> emacs-major-version 27)
|
2020-08-09 14:09:05 +02:00
|
|
|
|
(or (featurep 'ns)
|
2024-03-26 10:39:59 -04:00
|
|
|
|
(featurep 'harfbuzz))
|
|
|
|
|
(featurep 'composite)) ; Emacs loads `composite' at startup
|
2021-05-23 11:27:57 +02:00
|
|
|
|
|
2024-08-19 16:43:22 -04:00
|
|
|
|
(after! ligature
|
|
|
|
|
;; DEPRECATED: For backwards compatibility. Remove later.
|
|
|
|
|
(with-no-warnings
|
|
|
|
|
(when +ligatures-prog-mode-list
|
|
|
|
|
(setf (alist-get 'prog-mode +ligatures-alist) +ligatures-prog-mode-list))
|
|
|
|
|
(when +ligatures-all-modes-list
|
|
|
|
|
(setf (alist-get t +ligatures-alist) +ligatures-all-modes-list)))
|
|
|
|
|
(dolist (lig +ligatures-alist)
|
|
|
|
|
(ligature-set-ligatures (car lig) (cdr lig))))
|
|
|
|
|
|
|
|
|
|
(add-hook 'doom-init-ui-hook #'global-ligature-mode 'append)))
|