commit 0dd8138d3f1a5ce8f5bde5cc671fe22b9b00912d (HEAD, refs/remotes/origin/master) Author: Jonas Bernoulli Date: Mon Oct 13 20:33:30 2025 +0200 Update to Transient v0.10.1-8-g188ec9a1 diff --git a/doc/misc/transient.texi b/doc/misc/transient.texi index f2e06009771..71f35011496 100644 --- a/doc/misc/transient.texi +++ b/doc/misc/transient.texi @@ -31,7 +31,7 @@ General Public License for more details. @finalout @titlepage @title Transient User and Developer Manual -@subtitle for version 0.10.0 +@subtitle for version 0.10.1 @author Jonas Bernoulli @page @vskip 0pt plus 1filll @@ -53,7 +53,7 @@ resource to get over that hurdle is Psionic K's interactive tutorial, available at @uref{https://github.com/positron-solutions/transient-showcase}. @noindent -This manual is for Transient version 0.10.0. +This manual is for Transient version 0.10.1. @insertcopying @end ifnottex diff --git a/lisp/transient.el b/lisp/transient.el index 1f458be8829..520270972e8 100644 --- a/lisp/transient.el +++ b/lisp/transient.el @@ -5,7 +5,7 @@ ;; Author: Jonas Bernoulli ;; URL: https://github.com/magit/transient ;; Keywords: extensions -;; Version: 0.10.0 +;; Version: 0.10.1 ;; SPDX-License-Identifier: GPL-3.0-or-later @@ -33,7 +33,7 @@ ;;; Code: ;;;; Frontmatter -(defconst transient-version "0.10.0-builtin") +(defconst transient-version "v0.10.1-8-g188ec9a1-builtin") (require 'cl-lib) (require 'eieio) @@ -1961,9 +1961,10 @@ probably use this instead: (t nil)))) ((and-let* ((obj (transient--suffix-prototype (or command this-command))) (obj (clone obj))) - (transient-init-scope obj) - (transient-init-value obj) - obj)))) + (progn + (transient-init-scope obj) + (transient-init-value obj) + obj))))) (defun transient--suffix-prototype (command) (or (get command 'transient--suffix) @@ -2249,10 +2250,10 @@ of the corresponding object." map)) (defun transient--make-predicate-map () - (let* ((default (transient--resolve-pre-command - (oref transient--prefix transient-suffix))) - (return (and transient--stack (oref transient--prefix return))) - (map (make-sparse-keymap))) + (let ((default (transient--resolve-pre-command + (oref transient--prefix transient-suffix))) + (return (and transient--stack (oref transient--prefix return))) + (map (make-sparse-keymap))) (set-keymap-parent map transient-predicate-map) (when (or (and (slot-boundp transient--prefix 'transient-switch-frame) (transient--resolve-pre-command @@ -2463,9 +2464,9 @@ value. Otherwise return CHILDREN as is.") (cl-etypecase spec (symbol (mapcan (lambda (c) (transient--init-child levels c parent)) (transient--get-children spec))) - (vector (transient--init-group levels spec parent)) - (list (transient--init-suffix levels spec parent)) - (string (list spec)))) + (vector (transient--init-group levels spec parent)) + (list (transient--init-suffix levels spec parent)) + (string (list spec)))) (defun transient--init-group (levels spec parent) (pcase-let* ((`[,class ,args ,children] spec) @@ -2479,8 +2480,9 @@ value. Otherwise return CHILDREN as is.") (oset obj inapt t)))) (suffixes (mapcan (lambda (c) (transient--init-child levels c obj)) (transient-setup-children obj children)))) - (oset obj suffixes suffixes) - (list obj)))) + (progn + (oset obj suffixes suffixes) + (list obj))))) (defun transient--init-suffix (levels spec parent) (let* ((class (car spec)) @@ -4037,7 +4039,7 @@ the value." (and (not (and (slot-exists-p obj 'unsavable) (oref obj unsavable))) (transient--get-wrapped-value obj))) - transient--suffixes))) + (or transient--suffixes transient-current-suffixes)))) (defun transient--get-wrapped-value (obj) "Return a list of the value(s) of suffix object OBJ. commit aae6a9a74017207a1251d272892d141cec9cf0fb Author: Sean Whitton Date: Mon Oct 13 16:38:49 2025 +0100 ; * lisp/vc/vc-dir.el (vc-dir-resynch-file): Use cl-nset-difference. diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index bdb8b8134ae..b75d258b158 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -1262,7 +1262,8 @@ that file." status-buf (or (not state) (eq state 'up-to-date))))))))))) ;; Remove out-of-date entries from vc-dir-buffers. - (dolist (b drop) (setq vc-dir-buffers (delq b vc-dir-buffers))))) + (setq vc-dir-buffers + (cl-nset-difference vc-dir-buffers drop :test #'eq)))) (defvar use-vc-backend) ;; dynamically bound commit 78416e8bed12c6540adb9f0f5407726bea6ab928 Author: Sean Whitton Date: Mon Oct 13 16:38:14 2025 +0100 * lisp/vc/vc-dir.el (vc-dir-resynch-file): Use file-in-directory-p. For better compatibility with MS-Windows. diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index f6f5714519d..bdb8b8134ae 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -1249,7 +1249,7 @@ that file." ;; `default-directory' in order to do its work, ;; but that's irrelevant to us here. (buffer-local-toplevel-value 'default-directory)))) - (when (string-prefix-p ddir file) + (when (file-in-directory-p file ddir) (if (file-directory-p file) (progn (vc-dir-resync-directory-files file) commit 7e38562bcd4725bc45f2fc47d2b5fbacde498898 Author: Sean Whitton Date: Mon Oct 13 16:37:40 2025 +0100 ; Fix recently introduced uses of "ELisp". diff --git a/etc/NEWS b/etc/NEWS index 4baf81f9ebb..4e27d6fc44e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1168,7 +1168,7 @@ at run-time for the use of the associated deprecated features. '(setq eieio-backward-compatibility t)' can be used to recover the previous silence. -** ELisp mode +** Emacs Lisp mode +++ *** Semantic highlighting support for Emacs Lisp. diff --git a/lisp/emacs-lisp/elisp-scope.el b/lisp/emacs-lisp/elisp-scope.el index 955616e5e42..5230da17cc4 100644 --- a/lisp/emacs-lisp/elisp-scope.el +++ b/lisp/emacs-lisp/elisp-scope.el @@ -1,4 +1,4 @@ -;;; elisp-scope.el --- Semantic analysis for ELisp symbols -*- lexical-binding: t; -*- +;;; elisp-scope.el --- Semantic analysis for Elisp symbols -*- lexical-binding: t; -*- ;; Copyright (C) 2025 Free Software Foundation, Inc. @@ -21,7 +21,7 @@ ;;; Commentary: ;; This library implements an analysis that determines the role of each -;; symbol in ELisp code. +;; symbol in Emacs Lisp code. ;; The analysis assigns to each symbol a "symbol role", such as ;; `function', `bound-variable', `binding-variable', `face', etc. Each @@ -139,8 +139,8 @@ "Define NAME as the name of a symbol role that inherits from PARENTS. A symbol role is a symbol that Emacs uses to describe the role -of (other) symbols in ELisp source code. For example, the symbol role -`face' characterizes symbols that are face names. +of (other) symbols in Emacs Lisp source code. For example, the symbol +role `face' characterizes symbols that are face names. PROPS is a plist specifying the properties of the new symbol role NAME. NAME inherits properties that do not appear in PROPS from its PARENTS. @@ -392,12 +392,12 @@ Interactively, prompt for ROLE." :help "Widget type definition") (elisp-scope-define-symbol-role type () - :doc "ELisp object type names." + :doc "Elisp object type names." :face 'elisp-type :help "Type") (elisp-scope-define-symbol-role deftype (type) - :doc "ELisp object type definitions." + :doc "Elisp object type definitions." :help "Type definition") (elisp-scope-define-symbol-role group () diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 5f79909be56..87c7a53b057 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -526,7 +526,7 @@ code analysis." 'elisp-highlight-variable t))) (defun elisp-cursor-sensor (pos) - "Return `cursor-sensor-functions' for ELisp symbol at POS." + "Return `cursor-sensor-functions' for Emacs Lisp symbol at POS." (list (lambda (_win old dir) (cl-case dir commit fff1c66830ec8a44551ed80e725f421faa65f0d5 Author: Eshel Yaron Date: Mon Oct 13 11:39:12 2025 +0200 ; Improve 'elisp-unknown-call' face for dark backgrounds * lisp/progmodes/elisp-mode.el (elisp-unknown-call): Use a lighter foreground color on dark backgrounds for legibility. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index c484056f2b5..5f79909be56 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -344,7 +344,10 @@ code analysis." "Face for highlighting calls to functions that do not return." :version "31.1") -(defface elisp-unknown-call '((t :inherit elisp-function :foreground "#2f4f4f")) +(defface elisp-unknown-call + '((default :inherit elisp-function) + (((background light)) :foreground "#2f4f4f") + (((background dark)) :foreground "#7fa9a9")) "Face for highlighting unknown functions/macros in Emacs Lisp code." :version "31.1") commit 00b92cd9329320a54631432fcae31c4408cd1afa Author: Eli Zaretskii Date: Mon Oct 13 11:32:23 2025 +0300 ; Improve documentation of semantic highlighting * lisp/progmodes/elisp-mode.el (elisp) (elisp-fontify-semantically, elisp-symbol-at-mouse) (elisp-free-variable, elisp-special-variable-declaration) (elisp-condition, elisp-major-mode-name, elisp-face) (elisp-symbol-role, elisp-symbol-role-definition) (elisp-function, elisp-non-local-exit, elisp-unknown-call) (elisp-macro, elisp-special-form, elisp-throw-tag) (elisp-feature, elisp-rx, elisp-theme, elisp-binding-variable) (elisp-bound-variable, elisp-shadowing-variable) (elisp-shadowed-variable, elisp-variable-at-point) (elisp-warning-type, elisp-function-property-declaration) (elisp-thing, elisp-slot, elisp-widget-type, elisp-type) (elisp-group, elisp-nnoo-backend, elisp-ampersand) (elisp-constant, elisp-defun, elisp-defmacro, elisp-defvar) (elisp-defface, elisp-icon, elisp-deficon, elisp-oclosure) (elisp-defoclosure, elisp-coding, elisp-defcoding) (elisp-charset, elisp-defcharset, elisp-completion-category) (elisp-completion-category-definition, elisp-add-help-echo) (elisp-fontify-symbol-precedence-function): Add :version tags. * lisp/emacs-lisp/elisp-scope.el: Fix references to meta-syntactic variables in the commentary. (elisp-scope-describe-symbol-role, coding, defcoding, charset) (defcharset): Doc fixes. (elisp-scope-safe-macros): Add :version tag. Doc fix. * doc/emacs/display.texi (Semantic Font Lock): Fix punctuation and wording, improve cross-references and indexing. diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index aef1047c17e..b982a39a980 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -1222,7 +1222,7 @@ their specific role in the program. Semantic highlighting is more sophisticated than traditional ``syntax highlighting'', which only considers the syntactic role of a token, -i.e. how it affects the code's @emph{parsing}, unlike semantic analysis +i.e., how it affects the code's @emph{parsing}, unlike semantic analysis which takes into account the token's effect on the program's @emph{execution}. For example, a semantic highlighting implementation may be able to tell apart local and global variables and give distinct @@ -1236,15 +1236,18 @@ about their programs. @vindex elisp-fontify-semantically Emacs implements semantic highlighting for Emacs Lisp as an optional -feature of @code{emacs-lisp-mode}. To enable it, set the option -@code{elisp-fontify-semantically} to non-@code{nil}. +feature of @code{emacs-lisp-mode} (@pxref{Executing Lisp}). To enable +it, customize the option @code{elisp-fontify-semantically} to a +non-@code{nil} value. When this option is enabled, @code{emacs-lisp-mode} analyzes your code and highlights symbols according to their semantic roles, as part of the -mode's usual Font Lock highlighting. It doesn't effect the highlighting -of strings, comments and other syntactic elements such as brackets; -@code{elisp-fontify-semantically} only affects symbol highlighting. +mode's usual Font Lock highlighting (@pxref{Font Lock}). It doesn't +affect the highlighting of strings, comments and other syntactic +elements such as brackets; @code{elisp-fontify-semantically} only +affects highlighting of symbols. +@cindex symbol role, in semantic analysis The semantic analysis assigns to each symbol a @dfn{symbol role}, such as ``function'', ``local variable'', ``face name'', etc. Each symbol role has an associated face property, which is applied to symbols with @@ -1254,12 +1257,12 @@ locally-bound variables get the @code{elisp-bound-variable} face, which inherits from @code{font-lock-variable-use-face}. @vindex elisp-add-help-echo -The analysis can differentiate between more than 50 such symbol roles, +The semantic analysis can differentiate between more than 50 such symbol roles, but you don't need to memorize the appearance of so many faces to leverage semantic highlighting: you can hover over an highlighted symbol with the mouse to see a tooltip with the exact role Emacs inferred for that symbol (@pxref{Tooltips}). If you want to disable this extra -information, set @code{elisp-add-help-echo} to @code{nil}. +information, customize @code{elisp-add-help-echo} to the @code{nil} value. There are a few more points you should keep in mind when using @code{elisp-fontify-semantically}: @@ -1270,13 +1273,16 @@ Syntax errors break semantic analysis, so for best results you may want to enable @code{electric-pair-mode} to keep your code syntactically correct while you edit it. @xref{Matching}. +@cindex trusted buffers, and semantic highlighting +@vindex elisp-scope-safe-macros @item The analysis uses macro-expansion in some cases, but by default it only does so in trusted buffers (@pxref{Host Security}). In @emph{untrusted} buffers, some macro arguments may not be highlighted. See the documentation string of @code{elisp-scope-safe-macro-p} for more information about which macros Emacs considers safe to expand for -analysis. +analysis. The user option @code{elisp-scope-safe-macros} controls which +macros are safe to expand during analysis in untrusted buffers. @item The analysis is informed by definitions in the current Emacs session, diff --git a/lisp/emacs-lisp/elisp-scope.el b/lisp/emacs-lisp/elisp-scope.el index 5933a92745f..955616e5e42 100644 --- a/lisp/emacs-lisp/elisp-scope.el +++ b/lisp/emacs-lisp/elisp-scope.el @@ -46,18 +46,18 @@ ;; implemented in the recursive function `elisp-scope-1', which analyzes ;; an sexp as an evaluated form, propagating contextual information such ;; as local variable bindings down to analyzed sub-forms. -;; `elisp-scope-1' takes two arguments: `form', which is the form to -;; analyze, and `outspec', which is a specification of the expected -;; value of `form' used to analyze quoted data. The analysis proceeds +;; `elisp-scope-1' takes two arguments: FORM, which is the form to +;; analyze, and OUTSPEC, which is a specification of the expected +;; value of FORM used to analyze quoted data. The analysis proceeds ;; as follows: ;; -;; - If `form' is a symbol, `elisp-scope-1' reports it as a variable. +;; - If FORM is a symbol, `elisp-scope-1' reports it as a variable. ;; -;; - If `form' is a cons cell (head . args), then the analysis depends -;; on `head'. `head' can have a bespoke "analyzer function" `af', -;; which is called as (af head . args) and is responsible for -;; (recursively) analyzing `form'. The analyzer function can be -;; associated to `head' either locally, as an alist entry in +;; - If FORM is a cons cell (HEAD . ARGS), then the analysis depends +;; on HEAD. HEAD can have a bespoke "analyzer function" AF, +;; which is called as (AF HEAD . ARGS) and is responsible for +;; (recursively) analyzing FORM. The analyzer function can be +;; associated to HEAD either locally, as an alist entry in ;; `elisp-scope-local-definitions', or globally, via the symbol ;; property `elisp-scope-analyzer'. ;; @@ -75,46 +75,46 @@ ;; argument according to `elisp-scope-output-spec', which is bound to ;; the value of the `outspec' argument passed to `elisp-scope-1'. ;; -;; - If `head' is a macro, normally it is expanded, and then the +;; - If HEAD is a macro, normally it is expanded, and then the ;; expanded form is analyzed recursively. Since macro-expansion may ;; involve arbitrary code execution, only "safe" macro invocations are -;; expanded: if `head' is one of the macros in +;; expanded: if HEAD is one of the macros in ;; `elisp-scope-unsafe-macros', then it is never considered safe. -;; Otherwise, `head' is safe if it specified in the variable +;; Otherwise, HEAD is safe if it specified in the variable ;; `elisp-scope-safe-macros'; or if it has a non-nil `safe-macro' ;; symbol property; or if the current buffer is trusted according to -;; `trusted-content-p'. If a macro `head' is not safe to expand (and +;; `trusted-content-p'. If a macro HEAD is not safe to expand (and ;; has no associated analyzer function), then the macro arguments -;; `args' are not analyzed. +;; ARGS are not analyzed. ;; -;; - If `head' is a function, it is reported as such, and `args' are +;; - If HEAD is a function, it is reported as such, and ARGS are ;; recursively analyzed as evaluated forms. ;; -;; - Otherwise, if `head' has no associated analyzer function, and it is +;; - Otherwise, if HEAD has no associated analyzer function, and it is ;; not a known macro or function, then it is reported with the `unknown' ;; symbol role. If the variable `elisp-scope-assume-func' is non-nil, -;; then unknown `head' is assumed to be a function call, and thus `args' -;; are analyzed as evaluated forms; otherwise `args' are not analyzed. +;; then unknown HEAD is assumed to be a function call, and thus ARGS +;; are analyzed as evaluated forms; otherwise ARGS are not analyzed. ;; -;; When `elisp-scope-1' encounters a variable reference `var', it checks -;; whether `var' has a local binding in `elisp-scope-local-bindings', and -;; whether `var' is a known special variable. If `var' is a locally-bound +;; When `elisp-scope-1' encounters a variable reference VAR, it checks +;; whether VAR has a local binding in `elisp-scope-local-bindings', and +;; whether VAR is a known special variable. If VAR is a locally-bound ;; special variable, `elisp-scope-1' reports the role `shadowed-variable'. -;; If `var' is locally-bound and not a special variable, it gets the role +;; If VAR is locally-bound and not a special variable, it gets the role ;; `bound-variable'. Lastly, if it not locally-bound, then it gets the ;; role `free-variable'. ;; ;; When analyzer functions invoke `elisp-scope-1/n' to analyze some -;; sub-forms, they specify the `outspec' argument to convey information +;; sub-forms, they specify the OUTSPEC argument to convey information ;; but the expected value of the evaluated sub-form(s), so ;; `elisp-scope-1/n' will know what to do with a sub-form that is just ;; (quoted) data. For example, the analyzer function for ;; `face-attribute' calls `elisp-scope-1' to analyze its first argument -;; with an `outspec' which says that a quoted symbol in this position +;; with an OUTSPEC which says that a quoted symbol in this position ;; refers to a face name. ;; That way, in a form such as (face-attribute 'default :foreground), ;; the symbol `default' is reported as a face reference (`face' role). -;; Moreover, the `outspec' is passed down as appropriate through various +;; Moreover, the OUTSPEC is passed down as appropriate through various ;; predefined analyzers, so every quoted symbol in a "tail position" of ;; the first argument to `face-attribute' will also be recognized as a ;; face. For instance, in the following form, both `success' and @@ -204,6 +204,8 @@ symbol role properties." ;;;###autoload (defun elisp-scope-describe-symbol-role (role &rest _) + "Describe ROLE of a symbol. +Interactively, prompt for ROLE." (interactive (list (elisp-scope-read-symbol-role "Describe symbol role" (when-let* ((def (symbol-at-point)) @@ -515,36 +517,36 @@ symbol role properties." :help "OClosure type definition") (elisp-scope-define-symbol-role coding () - :doc "Coding system names." + :doc "Coding-system names." :face 'elisp-coding :help (lambda (beg end _def) (if-let* ((sym (intern (buffer-substring-no-properties beg end)))) (lambda (&rest _) (if-let* ((doc (coding-system-doc-string sym))) - (format "Coding system `%S'.\n\n%s" sym doc) - "Coding system")) - "Coding system"))) + (format "Coding-system `%S'.\n\n%s" sym doc) + "Coding-system")) + "Coding-system"))) (elisp-scope-define-symbol-role defcoding () - :doc "Coding system definitions." + :doc "Coding-system definitions." :face 'elisp-defcoding - :help "Coding system definition") + :help "Coding-system definition") (elisp-scope-define-symbol-role charset () - :doc "Charset names." + :doc "Character set names." :face 'elisp-charset :help (lambda (beg end _def) (if-let* ((sym (intern (buffer-substring-no-properties beg end)))) (lambda (&rest _) (if-let* ((doc (charset-description sym))) - (format "Charset `%S'.\n\n%s" sym doc) - "Charset")) - "Charset"))) + (format "Character set `%S'.\n\n%s" sym doc) + "Character set")) + "Character set"))) (elisp-scope-define-symbol-role defcharset () - :doc "Charset definitions." + :doc "Character set definitions." :face 'elisp-defcharset - :help "Charset definition") + :help "Character set definition") (elisp-scope-define-symbol-role completion-category () :doc "Completion categories." @@ -1622,12 +1624,15 @@ Optional argument LOCAL is a local context to extend." "Specify which macros are safe to expand during code analysis. If this is t, macros are considered safe by default. Otherwise, this is -a (possibly empty) list of safe macros. +a (possibly empty) list of safe macros; nil means no macros are safe. + +Some macros are never safe, see `elisp-scope-safe-macro-p' for details. Note that this option only affects analysis of untrusted code, for trusted code macro expansion is always safe." :type '(choice (const :tag "Trust all macros" t) (repeat :tag "Trust these macros" symbol)) + :version "31.1" :group 'lisp) (defvar elisp-scope-unsafe-macros diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index c8a894fe3c5..c484056f2b5 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -278,10 +278,10 @@ Comments in the form will be lost." (string-to-syntax "'"))))) start end))) -(defgroup elisp nil "Emacs Lisp editing support." :group 'lisp) +(defgroup elisp nil "Emacs Lisp editing support." :version "31.1" :group 'lisp) (defcustom elisp-fontify-semantically nil - "Whether to highlight symbols according to their meaning. + "Whether to highlight symbols according to their semantic meaning. If this is non-nil, `emacs-lisp-mode' uses code analysis to determine the role of each symbol and highlight it accordingly. We call this kind @@ -295,157 +295,203 @@ expand some macro calls in your code to analyze the expanded forms. In untrusted buffers, for security reasons, macro-expansion is restricted to safe macros only (see `elisp-scope-safe-macro-p'). Hence in untrusted buffers the arguments of some macros might not be analyzed, -and therefore not highlighted. +and therefore will not be semantically highlighted. See the function `elisp-scope-analyze-form' for more details about the code analysis." - :type 'boolean) + :type 'boolean + :version "31.1") (defface elisp-symbol-at-mouse '((((background light)) :background "#fff6d8") (((background dark)) :background "#00422a")) - "Face for highlighting the symbol at mouse in Emacs Lisp code.") + "Face for highlighting the symbol at mouse in Emacs Lisp code." + :version "31.1") (defface elisp-free-variable '((t :underline t :foreground reset :inherit font-lock-variable-use-face)) - "Face for highlighting free (special) variables in Emacs Lisp code.") + "Face for highlighting free (special) variables in Emacs Lisp code." + :version "31.1") (defface elisp-special-variable-declaration '((t :inherit elisp-free-variable)) - "Face for highlighting free variable declarations in Emacs Lisp code.") + "Face for highlighting free variable declarations in Emacs Lisp code." + :version "31.1") (defface elisp-condition '((t :foreground "red")) - "Face for highlighting `condition-case' conditions in Emacs Lisp code.") + "Face for highlighting `condition-case' conditions in Emacs Lisp code." + :version "31.1") (defface elisp-major-mode-name '((t :foreground "#006400")) "Face for highlighting major mode names in Emacs Lisp code.") (defface elisp-face '((t :inherit font-lock-type-face)) - "Face for highlighting face names in Emacs Lisp code.") + "Face for highlighting face names in Emacs Lisp code." + :version "31.1") (defface elisp-symbol-role '((t :foreground "#00008b" :inherit font-lock-function-call-face)) - "Face for highlighting symbol role names in Emacs Lisp code.") + "Face for highlighting symbol role names in Emacs Lisp code." + :version "31.1") (defface elisp-symbol-role-definition '((t :foreground "#00008b" :inherit font-lock-function-name-face)) - "Face for highlighting symbol role definitions in Emacs Lisp code.") + "Face for highlighting symbol role definitions in Emacs Lisp code." + :version "31.1") (defface elisp-function '((t :inherit font-lock-function-call-face)) - "Face for highlighting function calls in Emacs Lisp code.") + "Face for highlighting function calls in Emacs Lisp code." + :version "31.1") (defface elisp-non-local-exit '((t :inherit elisp-function :underline "red")) - "Face for highlighting calls to functions that do not return.") + "Face for highlighting calls to functions that do not return." + :version "31.1") (defface elisp-unknown-call '((t :inherit elisp-function :foreground "#2f4f4f")) - "Face for highlighting unknown functions/macros in Emacs Lisp code.") + "Face for highlighting unknown functions/macros in Emacs Lisp code." + :version "31.1") (defface elisp-macro '((t :inherit font-lock-keyword-face)) - "Face for highlighting macro calls in Emacs Lisp code.") + "Face for highlighting macro calls in Emacs Lisp code." + :version "31.1") (defface elisp-special-form '((t :inherit elisp-macro)) - "Face for highlighting special forms in Emacs Lisp code.") + "Face for highlighting special forms in Emacs Lisp code." + :version "31.1") (defface elisp-throw-tag '((t :inherit font-lock-constant-face)) - "Face for highlighting `catch'/`throw' tags in Emacs Lisp code.") + "Face for highlighting `catch'/`throw' tags in Emacs Lisp code." + :version "31.1") (defface elisp-feature '((t :inherit font-lock-constant-face)) - "Face for highlighting feature names in Emacs Lisp code.") + "Face for highlighting feature names in Emacs Lisp code." + :version "31.1") (defface elisp-rx '((t :foreground "#00008b")) - "Face for highlighting `rx' constructs in Emacs Lisp code.") + "Face for highlighting `rx' constructs in Emacs Lisp code." + :version "31.1") (defface elisp-theme '((t :inherit font-lock-constant-face)) - "Face for highlighting custom theme names in Emacs Lisp code.") + "Face for highlighting custom theme names in Emacs Lisp code." + :version "31.1") (defface elisp-binding-variable '((t :slant italic :inherit font-lock-variable-name-face)) - "Face for highlighting binding occurrences of variables in Emacs Lisp code.") + "Face for highlighting binding occurrences of variables in Emacs Lisp code." + :version "31.1") (defface elisp-bound-variable '((t :slant italic :foreground reset :inherit font-lock-variable-use-face)) - "Face for highlighting bound occurrences of variables in Emacs Lisp code.") + "Face for highlighting bound occurrences of variables in Emacs Lisp code." + :version "31.1") (defface elisp-shadowing-variable '((t :inherit elisp-binding-variable :underline t)) - "Face for highlighting local bindings that shadow special variables.") + "Face for highlighting local bindings that shadow special variables." + :version "31.1") (defface elisp-shadowed-variable '((t :inherit elisp-bound-variable :underline t)) - "Face for highlighting special variables that are shadowed by a local binding.") + "Face for highlighting special variables that are shadowed by a local binding." + :version "31.1") (defface elisp-variable-at-point '((t :inherit bold)) - "Face for highlighting (all occurrences of) the variable at point.") + "Face for highlighting (all occurrences of) the variable at point." + :version "31.1") (defface elisp-warning-type '((t :inherit font-lock-type-face)) - "Face for highlighting byte-compilation warning type names in Emacs Lisp.") + "Face for highlighting byte-compilation warning type names in Emacs Lisp." + :version "31.1") (defface elisp-function-property-declaration '((t :inherit font-lock-variable-use-face)) - "Face for highlighting function/macro property declaration type names.") + "Face for highlighting function/macro property declaration type names." + :version "31.1") (defface elisp-thing '((t :inherit font-lock-type-face)) - "Face for highlighting `thing-at-point' \"thing\" names in Emacs Lisp.") + "Face for highlighting `thing-at-point' \"thing\" names in Emacs Lisp." + :version "31.1") (defface elisp-slot '((t :inherit font-lock-builtin-face)) - "Face for highlighting EIEIO slot names.") + "Face for highlighting EIEIO slot names." + :version "31.1") (defface elisp-widget-type '((t :inherit font-lock-type-face)) - "Face for highlighting widget type names in Emacs Lisp code.") + "Face for highlighting widget type names in Emacs Lisp code." + :version "31.1") (defface elisp-type '((t :inherit font-lock-type-face)) - "Face for highlighting object type names in Emacs Lisp code.") + "Face for highlighting object type names in Emacs Lisp code." + :version "31.1") (defface elisp-group '((t :inherit font-lock-type-face)) - "Face for highlighting customization group names in Emacs Lisp code.") + "Face for highlighting customization group names in Emacs Lisp code." + :version "31.1") (defface elisp-nnoo-backend '((t :inherit font-lock-type-face)) - "Face for highlighting `nnoo' backend names in Emacs Lisp code.") + "Face for highlighting `nnoo' backend names in Emacs Lisp code." + :version "31.1") (defface elisp-ampersand '((t :inherit font-lock-type-face)) - "Face for highlighting argument list markers, such as `&optional'.") + "Face for highlighting argument list markers, such as `&optional'." + :version "31.1") (defface elisp-constant '((t :inherit font-lock-builtin-face)) - "Face for highlighting self-evaluating symbols in Emacs Lisp code.") + "Face for highlighting self-evaluating symbols in Emacs Lisp code." + :version "31.1") (defface elisp-defun '((t :inherit font-lock-function-name-face)) - "Face for highlighting function definitions in Emacs Lisp code.") + "Face for highlighting function definitions in Emacs Lisp code." + :version "31.1") (defface elisp-defmacro '((t :inherit elisp-defun)) - "Face for highlighting macro definitions in Emacs Lisp code.") + "Face for highlighting macro definitions in Emacs Lisp code." + :version "31.1") (defface elisp-defvar '((t :inherit font-lock-variable-name-face)) - "Face for highlighting variable definitions in Emacs Lisp code.") + "Face for highlighting variable definitions in Emacs Lisp code." + :version "31.1") (defface elisp-defface '((t :inherit font-lock-variable-name-face)) - "Face for highlighting face definitions in Emacs Lisp code.") + "Face for highlighting face definitions in Emacs Lisp code." + :version "31.1") (defface elisp-icon '((t :inherit font-lock-type-face)) - "Face for highlighting icon names in Emacs Lisp code.") + "Face for highlighting icon names in Emacs Lisp code." + :version "31.1") (defface elisp-deficon '((t :inherit elisp-icon)) - "Face for highlighting icon definitions in Emacs Lisp code.") + "Face for highlighting icon definitions in Emacs Lisp code." + :version "31.1") (defface elisp-oclosure '((t :inherit font-lock-type-face)) - "Face for highlighting OClosure type names in Emacs Lisp code.") + "Face for highlighting OClosure type names in Emacs Lisp code." + :version "31.1") (defface elisp-defoclosure '((t :inherit elisp-oclosure)) - "Face for highlighting OClosure type definitions in Emacs Lisp code.") + "Face for highlighting OClosure type definitions in Emacs Lisp code." + :version "31.1") (defface elisp-coding '((t :inherit font-lock-type-face)) - "Face for highlighting coding system names in Emacs Lisp code.") + "Face for highlighting coding system names in Emacs Lisp code." + :version "31.1") (defface elisp-defcoding '((t :inherit elisp-coding)) - "Face for highlighting coding system definitions in Emacs Lisp code.") + "Face for highlighting coding system definitions in Emacs Lisp code." + :version "31.1") (defface elisp-charset '((t :inherit font-lock-type-face)) - "Face for highlighting charset names in Emacs Lisp code.") + "Face for highlighting charset names in Emacs Lisp code." + :version "31.1") (defface elisp-defcharset '((t :inherit elisp-charset)) - "Face for highlighting charset definitions in Emacs Lisp code.") + "Face for highlighting charset definitions in Emacs Lisp code." + :version "31.1") (defface elisp-completion-category '((t :inherit font-lock-type-face)) - "Face for highlighting completion category names in Emacs Lisp code.") + "Face for highlighting completion category names in Emacs Lisp code." + :version "31.1") (defface elisp-completion-category-definition '((t :inherit elisp-completion-category)) - "Face for highlighting completion category definitions in Emacs Lisp code.") + "Face for highlighting completion category definitions in Emacs Lisp code." + :version "31.1") (defun elisp-local-references (pos) "Return references to local variable at POS as (BEG . LEN) cons cells." @@ -503,7 +549,9 @@ code analysis." str)) (defcustom elisp-add-help-echo t - "Whether to add `help-echo' property to symbols while highlighting them." + "Whether to add `help-echo' property to symbols while highlighting them. +This option has effect only if `elisp-fontify-semantically' is non-nil." + :version "31.1" :type 'boolean) (defun elisp--annotate-symbol-with-help-echo (type beg end def) @@ -534,11 +582,13 @@ and end positions in the current buffer of a symbol that is about to be fontified during semantic highlighting. The function is called after `font-lock-keywords' were already applied. If the function returns nil, then semantic highlighting takes precedence, otherwise the highlighting -that `font-lock-keywords' applied takes precedence, if any." +that `font-lock-keywords' applied takes precedence, if any. By default, +semantic highlighting takes precedence." :type '(choice (function-item :tag "Prioritize semantic highlighting" ignore) (function-item :tag "Prioritize `font-lock-keywords'" always) - (function :tag "Custom function"))) + (function :tag "Custom function")) + :version "31.1") (defun elisp-fontify-symbol (type beg len id &optional def) (let ((end (+ beg len))) commit 750499e4b717882f44461c46fc2fa0ea4c4a55dc Author: Martin Rudalics Date: Mon Oct 13 10:22:04 2025 +0200 Rewrite 'minibuffer-nonselected-mode' to use 'window-state-change-functions' * lisp/minibuffer.el (minibuffer-nonselected): Rewrite doc-string. (minibuffer--nonselected-overlay): Define it global. Rewrite doc-string. (minibuffer--nonselected-check): Rewrite by comparing the active minibuffer window with the selected window. (minibuffer--nonselected-setup): Globally add 'minibuffer--nonselected-check' to list of functions called by 'window-state-change-functions'. (minibuffer--nonselected-exit): Remove 'minibuffer--nonselected-check' from list of functions called by 'window-state-change-functions' when exiting last recursive minibuffer. (minibuffer-nonselected-mode): Globally add/remove 'minibuffer--nonselected-setup' to/from list of functions called by 'minibuffer-setup-hook' and 'minibuffer--nonselected-exit' to/from list of functions called by 'minibuffer-exit-hook' when activating/deactivating 'minibuffer-nonselected-mode'. Rewrite doc-string. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 472bcf618bf..b002087d14d 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -5644,51 +5644,83 @@ interactions is customizable via `minibuffer-regexp-prompts'." (defface minibuffer-nonselected '((t (:background "yellow" :foreground "dark red" :weight bold))) - "Face for non-selected minibuffer prompts. -It's displayed on the minibuffer window when the minibuffer -remains active, but the minibuffer window is no longer selected." + "Face for highlighting contents of non-selected minibuffer window. +Used by `minibuffer-nonselected-mode' for the contents of the minibuffer +window when the minibuffer remains active but its window is currently +not selected." :version "31.1") -(defvar-local minibuffer--nonselected-overlay nil) - -(defun minibuffer--nonselected-check (window) - "Check if the active minibuffer's window is no longer selected. -Use overlay to highlight the minibuffer window when another window -is selected. But don't warn in case when the *Completions* window -becomes selected." - (if (eq window (selected-window)) - (with-current-buffer (window-buffer window) - (when (overlayp minibuffer--nonselected-overlay) - (delete-overlay minibuffer--nonselected-overlay))) - (unless (eq (buffer-local-value 'completion-reference-buffer - (window-buffer)) - (window-buffer window)) - (with-current-buffer (window-buffer window) - (let ((ov (make-overlay (point-min) (point-max)))) - (overlay-put ov 'face 'minibuffer-nonselected) - (overlay-put ov 'evaporate t) - (setq minibuffer--nonselected-overlay ov)))))) +(defvar minibuffer--nonselected-overlay nil + "Overlay for highlighting contents of non-selected minibuffer window. +Used by `minibuffer-nonselected-mode'.") + +(defun minibuffer--nonselected-check (_frame) + "Check if active minibuffer window is no longer selected. +Use overlay to highlight its contents when another window is selected. +But don't highlight when the *Completions* window is selected." + (let* ((active-minibuffer-window (active-minibuffer-window)) + (active-minibuffer (when active-minibuffer-window + (window-buffer active-minibuffer-window)))) + (cond + ((or (not active-minibuffer-window) + (eq active-minibuffer-window (selected-window)) + (equal (buffer-name (window-buffer)) "*Completions*")) + ;; When there's no active minibuffer window or either the + ;; minibuffer or *the Completions* window is selected, remove the + ;; overlay if it exists. + (when minibuffer--nonselected-overlay + (delete-overlay minibuffer--nonselected-overlay))) + ((not minibuffer--nonselected-overlay) + ;; When there's an active minibuffer window and neither it nor the + ;; *Completions* window is selected and there is no overlay, make + ;; the overlay in the active minibuffer. + (with-current-buffer active-minibuffer + (setq minibuffer--nonselected-overlay + (make-overlay (point-min) (point-max))) + (overlay-put + minibuffer--nonselected-overlay 'face 'minibuffer-nonselected) + (overlay-put + minibuffer--nonselected-overlay 'evaporate t))) + ((not (eq (overlay-buffer minibuffer--nonselected-overlay) + active-minibuffer)) + ;; When there is an overlay but it is not in the active minibuffer + ;; move it to that buffer. + (with-current-buffer active-minibuffer + (move-overlay minibuffer--nonselected-overlay + (point-min) (point-max) active-minibuffer)))))) (defun minibuffer--nonselected-setup () - "Setup hooks for `minibuffer-nonselected-mode' to update the overlay." - (add-hook 'window-buffer-change-functions - #'minibuffer--nonselected-check nil t) - (add-hook 'window-selection-change-functions - #'minibuffer--nonselected-check nil t)) + "Set up hook for `minibuffer-nonselected-mode' unless it's there already." + (add-hook 'window-state-change-functions + #'minibuffer--nonselected-check)) + +(defun minibuffer--nonselected-exit () + "Remove hook for `minibuffer-nonselected-mode' if it is there." + (when (= (minibuffer-depth) 1) + (remove-hook 'window-state-change-functions + #'minibuffer--nonselected-check))) (define-minor-mode minibuffer-nonselected-mode - "Minor mode to warn about non-selected active minibuffer. -Use the face `minibuffer-nonselected' to highlight the minibuffer -window when the minibuffer remains active, but the minibuffer window -is no longer selected." + "Minor mode to warn about non-selected active minibuffer window. +Use the face `minibuffer-nonselected' to highlight the contents of the +minibuffer window when the minibuffer remains active but its window is +no longer selected." :global t :initialize #'custom-initialize-delay :init-value t :version "31.1" (if minibuffer-nonselected-mode - (add-hook 'minibuffer-setup-hook #'minibuffer--nonselected-setup) - (remove-hook 'minibuffer-setup-hook #'minibuffer--nonselected-setup))) - + (progn + (add-hook 'minibuffer-setup-hook #'minibuffer--nonselected-setup) + (add-hook 'minibuffer-exit-hook #'minibuffer--nonselected-exit) + (when (active-minibuffer-window) + (minibuffer--nonselected-check (selected-frame)))) + (remove-hook 'minibuffer-setup-hook #'minibuffer--nonselected-setup) + (remove-hook 'minibuffer-exit-hook #'minibuffer--nonselected-exit) + (remove-hook 'window-state-change-functions + #'minibuffer--nonselected-check) + (when (overlayp minibuffer--nonselected-overlay) + (delete-overlay minibuffer--nonselected-overlay)))) (provide 'minibuffer) commit a184ae8eda0678da5dda608722c06f7f929a74ff Author: Joyer Huang Date: Mon Oct 13 11:11:04 2025 +0800 ; ido.el: Use find-program variable instead of literal "find" (bug#79620) Copyright-paperwork-exempt: yes diff --git a/lisp/ido.el b/lisp/ido.el index cd1f9260262..4aef0f18347 100644 --- a/lisp/ido.el +++ b/lisp/ido.el @@ -3305,7 +3305,7 @@ instead removed from the current item list." name)) (split-string (shell-command-to-string - (concat "find " + (concat find-program " " (shell-quote-argument dir) (if ido-case-fold " -iname " " -name ") (shell-quote-argument commit f2f544c1af139196e21a7711de34e2be8289053c Author: Eshel Yaron Date: Mon Oct 13 08:51:21 2025 +0200 ; Improve 'elisp-free/bound-variable' faces. * lisp/progmodes/elisp-mode.el (elisp-free-variable) (elisp-bound-variable): Reset the foreground face (to avoid inheriting it from 'font-lock-variable-use-face') instead of hardcoding it to "black". diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 979baa8c1fe..c8a894fe3c5 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -307,8 +307,8 @@ code analysis." "Face for highlighting the symbol at mouse in Emacs Lisp code.") (defface elisp-free-variable - '((t :underline t :foreground "black" :inherit font-lock-variable-use-face)) - "Face for highlighting free variables in Emacs Lisp code.") + '((t :underline t :foreground reset :inherit font-lock-variable-use-face)) + "Face for highlighting free (special) variables in Emacs Lisp code.") (defface elisp-special-variable-declaration '((t :inherit elisp-free-variable)) "Face for highlighting free variable declarations in Emacs Lisp code.") @@ -360,7 +360,7 @@ code analysis." "Face for highlighting binding occurrences of variables in Emacs Lisp code.") (defface elisp-bound-variable - '((t :slant italic :foreground "black" :inherit font-lock-variable-use-face)) + '((t :slant italic :foreground reset :inherit font-lock-variable-use-face)) "Face for highlighting bound occurrences of variables in Emacs Lisp code.") (defface elisp-shadowing-variable