aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-26 12:47:30 -0500
committerCraig Jennings <c@cjennings.net>2026-05-26 12:47:30 -0500
commit783bc1ad9bc782b852e0661440499577dc6b6c63 (patch)
tree17ae22dde58888898129949e1840c4081b0daacd
parent25a26b945d2078b7eb43dfbdf98ff3ba55458072 (diff)
downloaddotemacs-783bc1ad9bc782b852e0661440499577dc6b6c63.tar.gz
dotemacs-783bc1ad9bc782b852e0661440499577dc6b6c63.zip
fix(text): compose every org src-block marker to the lambda glyph
The prettify-symbols alist already mapped #+begin_src and #+end_src to a lambda, but only some markers actually rendered as one. prettify-symbols-default-compose-p decides composition from a syntax heuristic on the characters around the match, and inside org's src-block fontification that heuristic vetoed most of the markers. In todo.org only one of five composed. I added cj/prettify-compose-block-markers-p, a compose predicate that always composes the block markers (case-insensitive, since the alist carries upcased variants) and defers to the default for everything else like lambda. Every marker composes now. Tests cover the marker branch and the deferral to the default.
-rw-r--r--modules/text-config.el14
-rw-r--r--tests/test-text-config.el41
2 files changed, 55 insertions, 0 deletions
diff --git a/modules/text-config.el b/modules/text-config.el
index 5a946d525..14e06f3e8 100644
--- a/modules/text-config.el
+++ b/modules/text-config.el
@@ -89,6 +89,20 @@ PAIR is a cons cell of (string . symbol)."
("#+end_src" . "λ")
("lambda" . "λ")))))
+(defun cj/prettify-compose-block-markers-p (start end match)
+ "Always compose the org src-block markers; defer to the default otherwise.
+`prettify-symbols-default-compose-p' uses a syntax heuristic on the
+characters around MATCH that fires inconsistently for `#+begin_src' /
+`#+end_src' across blocks in the same org buffer, an interaction with org's
+own src-block fontification: some markers compose to the lambda glyph and
+others stay literal. Force composition for the markers (matched
+case-insensitively, since the alist carries upcased variants too) and let
+everything else, such as `lambda', use the standard boundary check."
+ (or (member (downcase match) '("#+begin_src" "#+end_src"))
+ (prettify-symbols-default-compose-p start end match)))
+
+(setopt prettify-symbols-compose-predicate #'cj/prettify-compose-block-markers-p)
+
(add-hook 'prog-mode-hook #'turn-on-prettify-symbols-mode)
(add-hook 'org-mode-hook #'turn-on-prettify-symbols-mode)
diff --git a/tests/test-text-config.el b/tests/test-text-config.el
new file mode 100644
index 000000000..96935e1b8
--- /dev/null
+++ b/tests/test-text-config.el
@@ -0,0 +1,41 @@
+;;; test-text-config.el --- Tests for text-config -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Covers cj/prettify-compose-block-markers-p, the prettify-symbols compose
+;; predicate that forces org src-block markers (#+begin_src / #+end_src) to
+;; compose while deferring to the default predicate for everything else.
+
+;;; Code:
+
+(require 'ert)
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'text-config)
+
+(ert-deftest test-text-config-compose-markers-composes-begin-src ()
+ "Normal: the begin-src marker always composes.
+The bounds are arbitrary because the marker branch short-circuits before
+touching the buffer."
+ (should (cj/prettify-compose-block-markers-p 1 12 "#+begin_src")))
+
+(ert-deftest test-text-config-compose-markers-composes-end-and-upcased ()
+ "Boundary: the end marker and the upcased variants also compose."
+ (should (cj/prettify-compose-block-markers-p 1 10 "#+end_src"))
+ (should (cj/prettify-compose-block-markers-p 1 12 "#+BEGIN_SRC"))
+ (should (cj/prettify-compose-block-markers-p 1 10 "#+END_SRC")))
+
+(ert-deftest test-text-config-compose-markers-defers-for-non-markers ()
+ "Error: a non-marker match defers to the default predicate.
+The predicate must return exactly what `prettify-symbols-default-compose-p'
+returns for a symbol that is not a block marker, so `lambda' keeps the
+standard boundary check."
+ (with-temp-buffer
+ (insert "x lambda y")
+ (goto-char (point-min))
+ (re-search-forward "lambda")
+ (let ((start (match-beginning 0))
+ (end (match-end 0)))
+ (should (eq (cj/prettify-compose-block-markers-p start end "lambda")
+ (prettify-symbols-default-compose-p start end "lambda"))))))
+
+(provide 'test-text-config)
+;;; test-text-config.el ends here