In LilyPond v2.25.20 [1], `LilyPond-mode` was renamed to `lilypond-mode` in commit c7c6f14ede on 25 August 2024. Org still expects the old name, which makes LilyPond support moot. The attached patch fixes it.
[1] https://savannah.gnu.org/projects/lilypond
>From c2786aa6bbc1bf6b5256ad5fab916d20d082c7b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rudolf=20Adamkovi=C4=8D?= <[email protected]> Date: Tue, 27 Oct 2026 01:20:14 +0100 Subject: [PATCH] lisp/ob-lilypond.el: Support renamed LilyPond major mode * lisp/ob-lilypond.el (org-babel-tangle-lang-exts): Map lowercase lilypond blocks to .ly files. (org-src-lang-modes): Prefer lilypond-mode, with LilyPond-mode as a fallback. * lisp/org-src.el (org-src-lang-modes): Document and customize a list of major modes. (org-src-get-lang-mode): Select the first available mode. * testing/lisp/test-ob-lilypond.el (ob-lilypond/org-babel-tangle-lang-exts) (ob-lilypond/org-src-lang-mode): Test both language spellings and major mode names. --- lisp/ob-lilypond.el | 3 ++- lisp/org-src.el | 31 +++++++++++++++++++------------ testing/lisp/test-ob-lilypond.el | 21 ++++++++++++++------- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/lisp/ob-lilypond.el b/lisp/ob-lilypond.el index b2517fc82..5ab158c63 100644 --- a/lisp/ob-lilypond.el +++ b/lisp/ob-lilypond.el @@ -41,7 +41,8 @@ (require 'ob) (declare-function org-fold-show-all "org-fold" (&optional types)) (add-to-list 'org-babel-tangle-lang-exts '("LilyPond" . "ly")) -(add-to-list 'org-src-lang-modes '("lilypond" . LilyPond)) +(add-to-list 'org-babel-tangle-lang-exts '("lilypond" . "ly")) +(add-to-list 'org-src-lang-modes '("lilypond" . (lilypond LilyPond))) (defvar org-babel-default-header-args:lilypond '() "Default header arguments for lilypond code blocks. diff --git a/lisp/org-src.el b/lisp/org-src.el index 7fa8b8034..4eb14f161 100644 --- a/lisp/org-src.el +++ b/lisp/org-src.el @@ -235,7 +235,8 @@ (defcustom org-src-lang-modes "Alist mapping languages to their major mode. The key is the language name. The value is the mode name, as -a string or a symbol, without the \"-mode\" suffix. +a string or a symbol, without the \"-mode\" suffix. It may also +be a list of mode names, tried in order until one is available. For many languages this is simple, but for language where this is not the case, this variable provides a way to simplify things on @@ -246,7 +247,8 @@ (defcustom org-src-lang-modes :type '(repeat (cons (string :tag "Language name") - (symbol :tag "Major mode"))) + (choice (symbol :tag "Major mode") + (repeat :tag "Major modes" symbol)))) :safe #'listp) (defcustom org-src-block-faces nil @@ -993,16 +995,21 @@ (defun org-src-do-key-sequence-at-code-block (&optional key) (defun org-src-get-lang-mode (lang) "Return major mode that should be used for LANG. LANG is a string, and the returned value is a symbol." - (let ((mode (intern - (concat - (let ((l (or (cdr (assoc lang org-src-lang-modes)) lang))) - (if (symbolp l) (symbol-name l) l)) - "-mode")))) - (cond - ((fboundp 'major-mode-remap) (major-mode-remap mode)) - ((boundp 'major-mode-remap-alist) - (or (cdr (assq mode major-mode-remap-alist)) mode)) - (t mode)))) + (let* ((names (or (cdr (assoc lang org-src-lang-modes)) lang)) + (modes (mapcar + (lambda (name) + (let ((mode (intern (concat (if (symbolp name) + (symbol-name name) + name) + "-mode")))) + (cond + ((fboundp 'major-mode-remap) + (major-mode-remap mode)) + ((boundp 'major-mode-remap-alist) + (or (cdr (assq mode major-mode-remap-alist)) mode)) + (t mode)))) + (if (listp names) names (list names))))) + (or (cl-find-if #'functionp modes) (car modes)))) (defun org-src-get-lang-mode-if-bound (lang &optional fallback fallback-message-p) "Return major mode for LANG, if bound, and FALLBACK otherwise. diff --git a/testing/lisp/test-ob-lilypond.el b/testing/lisp/test-ob-lilypond.el index 3cfe1f5a9..de9e59430 100644 --- a/testing/lisp/test-ob-lilypond.el +++ b/testing/lisp/test-ob-lilypond.el @@ -39,13 +39,20 @@ (ert-deftest ob-lilypond/feature-provision () (should (featurep 'ob-lilypond))) (ert-deftest ob-lilypond/org-babel-tangle-lang-exts () - (let ((found nil) - (list org-babel-tangle-lang-exts)) - (while list - (when (equal (car list) '("LilyPond" . "ly")) - (setq found t)) - (setq list (cdr list))) - (should found))) + (should (equal (org-babel-effective-tangled-filename + "/score.org" "lilypond" "yes") + "/score.ly")) + (should (equal (org-babel-effective-tangled-filename + "/score.org" "LilyPond" "yes") + "/score.ly"))) + +(ert-deftest ob-lilypond/org-src-lang-mode () + (cl-letf (((symbol-function 'lilypond-mode) #'ignore) + ((symbol-function 'LilyPond-mode) #'ignore)) + (should (eq (org-src-get-lang-mode "lilypond") 'lilypond-mode))) + (cl-letf (((symbol-function 'lilypond-mode) nil) + ((symbol-function 'LilyPond-mode) #'ignore)) + (should (eq (org-src-get-lang-mode "lilypond") 'LilyPond-mode)))) (ert-deftest ob-lilypond/org-babel-prep-session:lilypond () (should-error (org-babel-prep-session:lilypond nil nil)) -- 2.54.0 (Apple Git-157)
-- There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors. --- Phil Karlton, Leon Bambrick Rudolf Adamkovič <[email protected]> [he/him] http://adamkovic.org
