1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 06:20:55 -08:00

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.texi: 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.
* test/lisp/autoinsert-tests.el
(autoinsert-tests-auto-insert-lambda/-nil): Add two tests for
lambdas (nil and t cases)
(autoinsert-tests-auto-insert-predicate/-nil): Add two tests for named
predicates (nil and t cases) (Bug#79178)
This commit is contained in:
mattiasdrp 2025-08-08 15:16:24 +02:00 committed by Eli Zaretskii
parent 6ffa926f90
commit bd1362b686
4 changed files with 72 additions and 12 deletions

View file

@ -273,13 +273,15 @@ empty file is visited. This is accomplished by putting
@vindex auto-insert-alist @vindex auto-insert-alist
What gets inserted, if anything, is determined by the variable What gets inserted, if anything, is determined by the variable
@code{auto-insert-alist}. The @sc{car} of each element of this list @code{auto-insert-alist}. The @sc{car} of each element of this list is
is either a mode name, making the element applicable when a buffer is either a mode name, making the element applicable when a buffer is in
in that mode, or a string, which is a regexp matched against a that mode, or a string, which is a regexp matched against a buffer's
buffer's file name (the latter enables you to distinguish between file name (the latter enables you to distinguish between different kinds
different kinds of files that have the same mode in Emacs). The of files that have the same mode in Emacs). It can also be a predicate
@sc{car} of an element may also be a cons cell, consisting of mode declared through a plist of the form @code{(predicate @var{function})}.
name or regexp, as above, and an additional descriptive string. @var{function} should be a predicate function of no arguments. 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.
When a matching element is found, the @sc{cdr} says what to do. It may When a matching element is found, the @sc{cdr} says what to do. It may
be a string, which is a file name, whose contents are to be inserted, if be a string, which is a file name, whose contents are to be inserted, if

View file

@ -700,6 +700,15 @@ 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 * 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. These types of conditions should be declared
with '(predicate FUNCTION)'. This allows to trigger 'auto-insert'
with finer grained control.
** Register ** Register
*** The "*Register Preview*" buffer shows only suitable registers. *** The "*Register Preview*" buffer shows only suitable registers.

View file

@ -325,6 +325,9 @@ The document was typeset with
Elements look like (CONDITION . ACTION) or ((CONDITION . DESCRIPTION) . ACTION). 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 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. a symbol that must match the major mode for this element to apply.
CONDITION can also be a custom predicate of no arguments declared with
'(predicate FUNCTION)'. Emacs will insert the text if the predicate
function returns non-nil.
Only the first matching element is effective. Only the first matching element is effective.
Optional DESCRIPTION is a string for filling `auto-insert-prompt'. Optional DESCRIPTION is a string for filling `auto-insert-prompt'.
ACTION may be a skeleton to insert (see `skeleton-insert'), an absolute ACTION may be a skeleton to insert (see `skeleton-insert'), an absolute
@ -368,12 +371,24 @@ Matches the visited file name against the elements of `auto-insert-alist'."
(pcase-lambda (`(,cond . ,action)) (pcase-lambda (`(,cond . ,action))
(if (atom cond) (if (atom cond)
(setq desc cond) (setq desc cond)
(setq desc (cdr cond) ;; if `cond' is a predicate, don't split it but set `desc' to a custom string
cond (car cond))) (if (and (consp cond) (equal (car cond) 'predicate))
(when (if (symbolp cond) (setq desc "predicate")
(derived-mode-p cond) (setq desc (cdr cond)
cond (car cond))))
(when (cond
;; `cond' should be a major-mode variable
((symbolp cond)
(derived-mode-p cond))
;; `cond' should be a predicate that takes no argument
((and (consp cond) (equal (car cond) 'predicate))
(funcall (cadr cond)))
;; cond should be a regexp
(t
(and buffer-file-name (and buffer-file-name
(string-match cond buffer-file-name))) (string-match cond buffer-file-name))))
action)) action))
auto-insert-alist))) auto-insert-alist)))
(goto-char 1) (goto-char 1)

View file

@ -76,6 +76,40 @@
(auto-insert) (auto-insert)
(should (equal (buffer-string) "2nd"))))) (should (equal (buffer-string) "2nd")))))
(ert-deftest autoinsert-tests-auto-insert-lambda ()
(let ((auto-insert-alist
'(((predicate (lambda () t)) . (lambda () (insert "foo")))))
(auto-insert-query nil))
(with-temp-buffer
(auto-insert)
(should (equal (buffer-string) "foo")))))
(ert-deftest autoinsert-tests-auto-insert-predicate ()
(defun predicate () t)
(let ((auto-insert-alist
'(((predicate predicate) . (lambda () (insert "foo")))))
(auto-insert-query nil))
(with-temp-buffer
(auto-insert)
(should (equal (buffer-string) "foo")))))
(ert-deftest autoinsert-tests-auto-insert-lambda-nil ()
(let ((auto-insert-alist
'(((predicate (lambda () nil)) . (lambda () (insert "foo")))))
(auto-insert-query nil))
(with-temp-buffer
(auto-insert)
(should (equal (buffer-string) "")))))
(ert-deftest autoinsert-tests-auto-insert-predicate-nil ()
(defun predicate () nil)
(let ((auto-insert-alist
'(((predicate predicate) . (lambda () (insert "foo")))))
(auto-insert-query nil))
(with-temp-buffer
(auto-insert)
(should (equal (buffer-string) "")))))
(ert-deftest autoinsert-tests-define-auto-insert-before () (ert-deftest autoinsert-tests-define-auto-insert-before ()
(let ((auto-insert-alist (let ((auto-insert-alist
(list (cons 'text-mode (lambda () (insert "foo"))))) (list (cons 'text-mode (lambda () (insert "foo")))))