Subject: Re: bug#79178: [Improvement] Allow auto-insert to have functions as conditions

From: Mattias <[email-masked]>
Date: Thu, 7 Aug 2025 15:18:43 +0200

Hi and thanks again,

> It is best to use change-log-mode for formatting commit log messages,
> as it will allow you to use M-q and other conveniences, and will obey
> the formatting according to our conventions.  Also, don't forget the
> periods at the end of each sentence (I added them above).

I tried using change-log-mode but it indented the whole commit 
message with 4 spaces when I used M-q on it. My current mode seems to do 
the job with M-q, I just didn't use it before (and it removes the : 
between lisp/autoinsert and (auto-insert-alist) which looks like the 
intended formatting since other commit logs are formatted this way).
From 95535c7017f1920fa28a56e301095e6be36095b1 Mon Sep 17 00:00:00 2001
From: mattiasdrp <[email-masked]>
Date: Tue, 5 Aug 2025 18:11:58 +0200
Subject: [PATCH] [bug#79178] Autoinsert: Allow condition to be a function

Currently a condition can only be a regexp or a major-mode symbol but
there's no real reason to not allow any predicate as a condition.

* doc/misc/autotype.text: Document the new condition type in
'auto-insert-alist'.
* etc/NEWS: Announce the new condition type in 'auto-insert-alist'.
* lisp/autoinsert.el (auto-insert-alist): Add the new condition type to
the variable documentation.
(auto-insert): Change the way the condition is matched to allow for
custom predicates.
---
 doc/misc/autotype.texi |  5 +++--
 etc/NEWS               |  7 +++++++
 lisp/autoinsert.el     | 29 ++++++++++++++++++++++-------
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/doc/misc/autotype.texi b/doc/misc/autotype.texi
index c53be54d0af..3a1eef1c694 100644
--- a/doc/misc/autotype.texi
+++ b/doc/misc/autotype.texi
@@ -275,9 +275,10 @@ empty file is visited.  This is accomplished by putting
   What gets inserted, if anything, is determined by the variable
 @code{auto-insert-alist}.  The @sc{car} of each element of this list
 is either a mode name, making the element applicable when a buffer is
-in that mode, or a string, which is a regexp matched against a
+in that mode, a string, which is a regexp matched against a
 buffer's file name (the latter enables you to distinguish between
-different kinds of files that have the same mode in Emacs).  The
+different kinds of files that have the same mode in Emacs) or a custom
+predicate that takes no argument.  The
 @sc{car} of an element may also be a cons cell, consisting of mode
 name or regexp, as above, and an additional descriptive string.
 
diff --git a/etc/NEWS b/etc/NEWS
index e4fb833c0be..e4c1fe647a9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -688,6 +688,13 @@ you could already use 'C-u C-x C-n' to clear the goal column.
 
 * Changes in Specialized Modes and Packages in Emacs 31.1
 
+** Autoinsert
+
++++
+*** New condition for 'auto-insert-alist'.
+'auto-insert-alist' now also allows to have a predicate taking no argument
+as conditions.  This allows to trigger 'auto-insert' with finer grained control.
+
 ** Register
 
 *** The "*Register Preview*" buffer shows only suitable registers.
diff --git a/lisp/autoinsert.el b/lisp/autoinsert.el
index e7492d1b9ed..3c4057f1623 100644
--- a/lisp/autoinsert.el
+++ b/lisp/autoinsert.el
@@ -323,8 +323,10 @@ The document was typeset with
 "))
   "A list specifying text to insert by default into a new file.
 Elements look like (CONDITION . ACTION) or ((CONDITION . DESCRIPTION) . ACTION).
-CONDITION may be a regexp that must match the new file's name, or it may be
-a symbol that must match the major mode for this element to apply.
+CONDITION may be a regexp that must match the new file's name or a symbol that
+must match the major mode for this element to apply.
+CONDITION can also be custom predicate function of no arguments; Emacs will
+insert the text if the predicate function returns non-nil.
 Only the first matching element is effective.
 Optional DESCRIPTION is a string for filling `auto-insert-prompt'.
 ACTION may be a skeleton to insert (see `skeleton-insert'), an absolute
@@ -368,12 +370,25 @@ Matches the visited file name against the elements of `auto-insert-alist'."
                 (pcase-lambda (`(,cond . ,action))
                   (if (atom cond)
                       (setq desc cond)
-                    (setq desc (cdr cond)
-                          cond (car cond)))
-                  (when (if (symbolp cond)
-                            (derived-mode-p cond)
+                    ;; if `cond' is a lambda, don't split it but set `desc' to a custom string
+                    (if (and (not (symbolp cond)) (functionp cond))
+                        (setq desc "`lambda condition'")
+                      (setq desc (cdr cond)
+                            cond (car cond))))
+                  (when (cond
+                         ;; `cond' should be a major-mode variable
+                         ((and (symbolp cond) (not (functionp cond)))
+                          (derived-mode-p cond))
+
+                         ;; `cond' should be a predicate that takes no argument
+                         ;; It can either be a named function or a lambda
+                         ((functionp cond)
+                          (funcall cond))
+
+                         ;; cond should be a regexp
+                         (t
                           (and buffer-file-name
-                               (string-match cond buffer-file-name)))
+                               (string-match cond buffer-file-name))))
                     action))
                 auto-insert-alist)))
          (goto-char 1)
-- 
2.50.1