commit 558e6792c0a920a691b6c70fd7eda6b5c6e85a80 (HEAD, refs/remotes/origin/master) Author: Stefan Kangas Date: Sun Mar 2 06:45:53 2025 +0100 ; Add Maintainer header to loaddefs-gen.el diff --git a/lisp/emacs-lisp/loaddefs-gen.el b/lisp/emacs-lisp/loaddefs-gen.el index 2a2f3747ac9..8a131bf885f 100644 --- a/lisp/emacs-lisp/loaddefs-gen.el +++ b/lisp/emacs-lisp/loaddefs-gen.el @@ -2,6 +2,7 @@ ;; Copyright (C) 2022-2025 Free Software Foundation, Inc. +;; Maintainer: emacs-devel@gnu.org ;; Keywords: maint ;; Package: emacs commit b7fdddc86ba1733633fa29a4dec6f76667d29aa5 Author: Stefan Kangas Date: Sun Mar 2 06:33:46 2025 +0100 Mark echistory.el as obsolete * lisp/obsolete/echistory.el: Add Obsolete-since header. * etc/TODO: Delete echistory. * etc/NEWS: Announce above obsoletion. (Bug#76506) diff --git a/etc/NEWS b/etc/NEWS index 7145b9eb09e..6ca36419116 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1356,6 +1356,9 @@ behavior, customize the value of 'tooltip-delay' to zero. *** cdl.el is now obsolete. Use 'shell-command' and 'shell-command-on-region' instead. +--- +*** echistory.el is now obsolete. + --- *** hashcash.el is now obsolete. It is believed to no longer be useful as a method to fight spam. diff --git a/etc/TODO b/etc/TODO index 122a09063be..1900cd5b159 100644 --- a/etc/TODO +++ b/etc/TODO @@ -860,7 +860,7 @@ for completeness, but some may be worth documenting. Here's a list which is probably not complete/correct: align, allout, artist, ansi-color, array, calculator, cdl, cmuscheme, completion, -delim-col, dirtrack, double, echistory, elide-head, easymenu, expand, +delim-col, dirtrack, double, elide-head, easymenu, expand, flow-ctrl, format [format-alist], generic/generic-x [various modes], kermit, log-edit, makesum, midnight [other than in Kill Buffer node], mouse-copy [?], mouse-drag, mouse-sel, net-utils, snmp-mode diff --git a/lisp/obsolete/echistory.el b/lisp/obsolete/echistory.el index d7cc5d6a5a5..5b530781188 100644 --- a/lisp/obsolete/echistory.el +++ b/lisp/obsolete/echistory.el @@ -4,6 +4,7 @@ ;; Author: K. Shane Hartman ;; Maintainer: emacs-devel@gnu.org +;; Obsolete-since: 31.1 ;; This file is part of GNU Emacs. commit 6f8c4581eaf8c45029171aa390f291faaa58d15f Author: Stefan Kangas Date: Sun Mar 2 06:32:35 2025 +0100 Move echistory.el to lisp/obsolete * lisp/echistory.el: Move from here... * lisp/obsolete/echistory.el: ...to here. (Bug#76506) diff --git a/lisp/echistory.el b/lisp/obsolete/echistory.el similarity index 100% rename from lisp/echistory.el rename to lisp/obsolete/echistory.el commit 33222bd000043ad79cf7d472fadf7cda6d49e31d Author: Stefan Kangas Date: Sun Mar 2 05:46:56 2025 +0100 Document apply-partially as inefficient * doc/lispref/functions.texi (Calling Functions): Document that it is less inefficient than a regular 'lambda'. * lisp/subr.el (apply-partially): Adjust documentation like above and remove compiler macro. Ref: https://lists.gnu.org/r/emacs-devel/2025-03/msg00024.html diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index 024ff2b7d5a..99dfca217c2 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -1055,7 +1055,17 @@ The result is a new function that accepts the rest of arguments and calls the original function with all the arguments combined. - Here's how to do partial application in Emacs Lisp: + In Emacs Lisp, this is best done with an anonymous function. For +example, if you have a function @samp{my-function} that takes two +arguments, you could do something like this: + +@example +(mapcar (lambda (x) (my-function 123 x)) @dots{}) +@end example + + You can also do partial application using the function +@code{apply-partially}. However, this will be slower than using an +anonymous function with @code{lambda}. @defun apply-partially func &rest args This function returns a new function which, when called, will call diff --git a/lisp/subr.el b/lisp/subr.el index 1647671d2b3..8f0366824d9 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -536,12 +536,13 @@ configuration." ARGS is a list of the first N arguments to pass to FUN. The result is a new function which does the same as FUN, except that the first N arguments are fixed at the values with which this function -was called." - (declare (side-effect-free error-free) - (compiler-macro - (lambda (_) - `(lambda (&rest args2) - ,`(apply ,fun ,@args args2))))) +was called. + +In almost all cases, you want to use a regular anonymous function +defined with `lambda' instead. It will be faster, because it does not +have the overhead of calling `apply' and `append', which this function +has to do internally." + (declare (side-effect-free error-free)) (lambda (&rest args2) (apply fun (append args args2)))) commit eff5a3e43ba886074c3a2e007a2bced9bcb85f17 Author: Stefan Kangas Date: Sun Mar 2 05:37:55 2025 +0100 Bump python.el requirement to Emacs 26.3 * lisp/progmodes/python.el: Require Emacs 26.3, flymake 1.0 and project 0.1. (Bug#75526) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 047ca54f755..64aca544fc4 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -5,7 +5,7 @@ ;; Author: Fabián E. Gallina ;; URL: https://github.com/fgallina/python.el ;; Version: 0.28 -;; Package-Requires: ((emacs "24.4") (compat "29.1.1.0") (seq "2.23")) +;; Package-Requires: ((emacs "26.3") (compat "29.1.1.0") (seq "2.23") (project "0.1") (flymake "1.0")) ;; Maintainer: emacs-devel@gnu.org ;; Created: Jul 2010 ;; Keywords: languages @@ -7233,7 +7233,8 @@ implementations: `python-mode' and `python-ts-mode'." (add-to-list 'auto-mode-alist (cons python--auto-mode-alist-regexp 'python-ts-mode)) (add-to-list 'interpreter-mode-alist '("python[0-9.]*" . python-ts-mode)))) -(derived-mode-add-parents 'python-ts-mode '(python-mode)) +(when (fboundp 'derived-mode-add-parents) ; Emacs 30.1 + (derived-mode-add-parents 'python-ts-mode '(python-mode))) ;;; Completion predicates for M-x ;; Commands that only make sense when editing Python code. commit d6dd9dd066e8db665b5c48a4b8fde4db1753e6ad Author: Pranshu Sharma Date: Sun Mar 2 05:02:13 2025 +0100 Pass buffer as object in gnus-highlight-selected-tree * lisp/gnus/gnus-salt.el (gnus-highlight-selected-tree): Correctly pass buffer object instead of string. (Bug#75557) diff --git a/lisp/gnus/gnus-salt.el b/lisp/gnus/gnus-salt.el index e1d9f8bf188..021a03d4b16 100644 --- a/lisp/gnus/gnus-salt.el +++ b/lisp/gnus/gnus-salt.el @@ -808,7 +808,7 @@ it in the environment specified by BINDINGS." (defun gnus-highlight-selected-tree (article) "Highlight the selected article in the tree." - (when (buffer-live-p gnus-tree-buffer) + (when (buffer-live-p (get-buffer gnus-tree-buffer)) (let ((buf (current-buffer)) region) (set-buffer gnus-tree-buffer) commit 735eace97b88c7e1a7864a0eb5caf2a6d263b60a Author: Stefan Kangas Date: Sun Mar 2 04:12:57 2025 +0100 Make package-install accept a string as well * lisp/emacs-lisp/package.el (package-install): Allow passing a string instead of a symbol. (Bug#72160) (package-upgrade): Improve docstring. * test/lisp/emacs-lisp/package-tests.el (package-test-install-single-from-archive/string-type): New test. diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 78bd846c951..cfe57fb9e35 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2196,7 +2196,8 @@ built-in package with a (possibly newer) version from a package archive." ;;;###autoload (defun package-install (pkg &optional dont-select) "Install the package PKG. -PKG can be a `package-desc' or a symbol naming one of the + +PKG can be a `package-desc', or a symbol or string naming one of the available packages in an archive in `package-archives'. Mark the installed package as selected by adding it to @@ -2229,6 +2230,8 @@ had been enabled." package-archive-contents) nil t)) nil))) + (cl-check-type pkg (or string symbol package-desc)) + (if (stringp pkg) (setq pkg (intern pkg))) (package--archives-initialize) (add-hook 'post-command-hook #'package-menu--post-refresh) (let ((name (if (package-desc-p pkg) @@ -2256,7 +2259,9 @@ had been enabled." ;;;###autoload (defun package-upgrade (name) - "Upgrade package NAME if a newer version exists." + "Upgrade package NAME if a newer version exists. + +NAME can be either a symbol or a string." (interactive (list (completing-read "Upgrade package: " (package--upgradeable-packages t) nil t))) diff --git a/test/lisp/emacs-lisp/package-tests.el b/test/lisp/emacs-lisp/package-tests.el index d8e260319bd..ed778049dcb 100644 --- a/test/lisp/emacs-lisp/package-tests.el +++ b/test/lisp/emacs-lisp/package-tests.el @@ -450,6 +450,13 @@ but with a different end of line convention (bug#48137)." (package-refresh-contents) (package-install 'simple-single))) +(ert-deftest package-test-install-single-from-archive/string-type () + "Install a single package from a package archive, using string argument." + (with-package-test () + (package-initialize) + (package-refresh-contents) + (package-install "simple-single"))) + (ert-deftest package-test-install-prioritized () "Install a lower version from a higher-prioritized archive." (with-package-test () commit 38782e684bf5f67e2d8f69daeeb17f37cf4b2c3f Author: Stefan Kangas Date: Sun Mar 2 03:59:22 2025 +0100 Improve use-package error message on wrong type * lisp/use-package/use-package-core.el (use-package): Improve error message when passed the wrong type. (Bug#72160) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 9d03d6d3021..84ff637435a 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1893,6 +1893,15 @@ Usage: :vc Install the package directly from a version control system (using `package-vc.el')." (declare (indent defun)) + (when (stringp name) + (user-error "String where there should be a symbol. \ +Try this instead: `(use-package %s ...)'" + name)) + (when (and (consp name) (eq (car name) 'quote)) + (user-error "Quoted symbol where it should be unquoted. \ +Try this instead: `(use-package %s ...)'" + (symbol-name (cadr name)))) + (cl-check-type name symbol) (unless (memq :disabled args) (macroexp-progn (use-package-concat commit be8a7c9c882540dd7267f9046166cb680f10fd9d Author: David Ponce Date: Sun Mar 2 02:41:24 2025 +0100 Simplify and speed up widget-get implementation * lisp/wid-edit.el (widget-get): Simplify and speed up. Ref: https://lists.gnu.org/r/emacs-devel/2025-03/msg00010.html diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index ff6550e852f..716b7894a2d 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -633,16 +633,12 @@ The value can later be retrieved with `widget-get'." "In WIDGET, get the value of PROPERTY. The value could either be specified when the widget was created, or later with `widget-put'." - (let (tmp) - (catch 'found - (while widget - (cond ((and (setq tmp (plist-member (cdr widget) property)) - (consp tmp)) - (throw 'found (cadr tmp))) - ((setq tmp (widget-type widget)) - (setq widget (get tmp 'widget-type))) - (t - (throw 'found nil))))))) + (let (value found) + (while (and widget (not found)) + (if (setq found (plist-member (cdr widget) property)) + (setq value (cadr found)) + (setq widget (get (widget-type widget) 'widget-type)))) + value)) (defun widget-get-indirect (widget property) "In WIDGET, get the value of PROPERTY. commit 49e3ef343784adaf967d1ff02a8499eb4d7d1ddd Author: Stefan Kangas Date: Sun Mar 2 02:16:11 2025 +0100 ; Add test for last change * test/lisp/wid-edit-tests.el (widget-test-editable-field-widget-get/put): Check return value of widget-put. (Bug#76664) diff --git a/test/lisp/wid-edit-tests.el b/test/lisp/wid-edit-tests.el index e99347f1666..1a3a35ff496 100644 --- a/test/lisp/wid-edit-tests.el +++ b/test/lisp/wid-edit-tests.el @@ -30,8 +30,8 @@ "My Name"))) (should (eq (widget-get widget :size) 13)) (should (equal (widget-get widget :format) "Name: %v ")) - (widget-put widget :size 1) - (widget-put widget :format "foo") + (should (eq (widget-put widget :size 1) 1)) + (should (equal (widget-put widget :format "foo") "foo")) (should (eq (widget-get widget :size) 1)) (should (equal (widget-get widget :format) "foo"))))) commit 5b13541858707a5cbb857b257e00848430d87c47 Author: David Ponce Date: Sun Mar 2 02:17:12 2025 +0100 Correctly return passed value from widget-put * lisp/wid-edit.el (widget-get-indirect): Return passed value to stay consistent with old C implementation. (Bug#76664) diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index d6fd1156123..ff6550e852f 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -625,7 +625,8 @@ and saves that overlay under the :inactive property for WIDGET." (defun widget-put (widget property value) "In WIDGET, set PROPERTY to VALUE. The value can later be retrieved with `widget-get'." - (setcdr widget (plist-put (cdr widget) property value))) + (setcdr widget (plist-put (cdr widget) property value)) + value) ;;;###autoload (defun widget-get (widget property) commit 10f11d730e3347f34d873c005ae8e4f830cf166f Author: Stefan Kangas Date: Sun Mar 2 01:16:20 2025 +0100 ; * etc/symbol-releases.eld: Add missing symbols. diff --git a/etc/symbol-releases.eld b/etc/symbol-releases.eld index 41200581be5..bed8c448a43 100644 --- a/etc/symbol-releases.eld +++ b/etc/symbol-releases.eld @@ -11,6 +11,9 @@ ( ("29.1" fun plistp) ("28.1" fun always) + ("27.1" fun project-files) + ("26.1" fun flymake--diag-region) + ("26.1" fun flymake-make-diagnostic) ("26.1" fun when-let*) ("26.1" fun and-let*) ("26.1" fun if-let*) commit 1e84a8767692f9f3a3bc37eba8eeb8f9d537322d Author: Pip Cet Date: Sat Mar 1 21:39:23 2025 +0000 Improve instructions for running with -fsanitize=address (bug#76393) * etc/DEBUG (ASAN_OPTIONS): Add 'detect_stack_use_after_return=0' requirement. Remove obsolete unexec commentary. diff --git a/etc/DEBUG b/etc/DEBUG index ca061063454..b95ea7e7e8c 100644 --- a/etc/DEBUG +++ b/etc/DEBUG @@ -1010,14 +1010,16 @@ program. ** Running Emacs with address sanitization Building Emacs with address sanitization can help debug memory-use -problems, such as freeing the same object twice. To use -AddressSanitizer with GCC and similar compilers, append +problems, such as freeing the same object twice. It does, however, +require special care to ensure that Emacs's garbage collection continues +working. To use AddressSanitizer with GCC and similar compilers, append '-fsanitize=address' to CFLAGS, either when running 'configure' or -running 'make'. Configure, build and run Emacs with -ASAN_OPTIONS='detect_leaks=0' in the environment to suppress -diagnostics of minor memory leaks in Emacs. For example: +running 'make'. When running Emacs, ensure the ASAN_OPTIONS environment +variable is set and includes 'detect_stack_use_after_return=0' (to keep +GC working) and 'detect_leaks=0' (to avoid noisy diagnostics about minor +memory leaks in Emacs). For example: - export ASAN_OPTIONS='detect_leaks=0' + export ASAN_OPTIONS='detect_leaks=0,detect_stack_use_after_return=0' ./configure CFLAGS='-O0 -g3 -fsanitize=address' make src/emacs @@ -1034,8 +1036,7 @@ will let you gain control when an error is detected and before AddressSanitizer outputs to stderr or terminates the program. Address sanitization is incompatible with undefined-behavior -sanitization, unfortunately. Address sanitization is also -incompatible with the --with-dumping=unexec option of 'configure'. +sanitization, unfortunately. *** Address poisoning/unpoisoning commit 354598874061ab9ecb9362d7ac4233494b51252b Author: Daniel Colascione Date: Sat Mar 1 12:27:08 2025 -0500 Make Emacs respond to NS activation clicks * src/nsterm.m (acceptsFirstMouse): Opt into receiving mouse events that activate the window. (bug#76629) diff --git a/src/nsterm.m b/src/nsterm.m index a4398e79211..12141dfac44 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -6820,6 +6820,13 @@ - (BOOL)acceptsFirstResponder return YES; } +/* Tell NS we want to accept clicks that activate the window */ +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent +{ + NSTRACE_MSG ("First mouse event: type=%ld, clickCount=%ld", + [theEvent type], [theEvent clickCount]); + return YES; +} - (void)resetCursorRects { NSRect visible = [self visibleRect]; commit 6a2f6056c5a079a7f3db240171680560a3bd9710 Author: Eli Zaretskii Date: Sat Mar 1 17:16:08 2025 +0200 Provide tool-tip display delays on TTY frames * lisp/tooltip.el (tooltip-show, tooltip-hide) (tooltip-show-help): Support delayed tool-tip display on TTY frames as well. (Bug#76653) * etc/NEWS: Announce the behavior change. diff --git a/etc/NEWS b/etc/NEWS index 2a973b77827..7145b9eb09e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1346,6 +1346,12 @@ change the selection rules. ** Miscellaneous +--- +*** 'tooltip-mode' now shows tooltips after delay on TTY frames. +Display of tooltips on text-only terminals now happens after +'tooltip-delay' as it does on GUI terminals. To get back the old +behavior, customize the value of 'tooltip-delay' to zero. + --- *** cdl.el is now obsolete. Use 'shell-command' and 'shell-command-on-region' instead. diff --git a/lisp/tooltip.el b/lisp/tooltip.el index 482af3bd7bf..51a9841b49f 100644 --- a/lisp/tooltip.el +++ b/lisp/tooltip.el @@ -251,7 +251,8 @@ Note that the last two arguments are not respected when `use-system-tooltips' is non-nil and Emacs is built with support for system tooltips, such as on NS, Haiku, and with the GTK toolkit." - (if use-echo-area + (if (or use-echo-area + (not (display-graphic-p))) (tooltip-show-help-non-mode text) (condition-case error (let ((params (copy-sequence tooltip-frame-parameters)) @@ -285,8 +286,13 @@ toolkit." "Hide a tooltip, if one is displayed. Value is non-nil if tooltip was open." (tooltip-cancel-delayed-tip) - (when (x-hide-tip) - (setq tooltip-hide-time (float-time)))) + (if (display-graphic-p) + (when (x-hide-tip) + (setq tooltip-hide-time (float-time))) + (let ((msg (current-message))) + (message "") + (when (not (or (null msg) (equal msg ""))) + (setq tooltip-hide-time (float-time)))))) ;;; Debugger-related functions @@ -386,11 +392,10 @@ It is also called if Tooltip mode is on, for text-only displays." (defun tooltip-show-help (msg) "Function installed as `show-help-function'. MSG is either a help string to display, or nil to cancel the display." - (if (and (display-graphic-p) - ;; Tooltips can't be displayed on top of the global menu - ;; bar on NS. - (or (not (eq window-system 'ns)) - (not (menu-or-popup-active-p)))) + (if ;; Tooltips can't be displayed on top of the global menu bar on + ;; NS. + (not (and (eq window-system 'ns) + (menu-or-popup-active-p))) (let ((previous-help tooltip-help-message)) (setq tooltip-help-message msg) (cond ((null msg) @@ -408,9 +413,7 @@ MSG is either a help string to display, or nil to cancel the display." ;; A different help. Remove a previous tooltip, and ;; display a new one, with some delay. (tooltip-hide) - (tooltip-start-delayed-tip)))) - ;; On text-only displays, try `tooltip-show-help-non-mode'. - (tooltip-show-help-non-mode msg))) + (tooltip-start-delayed-tip)))))) (defun tooltip-help-tips (_event) "Hook function to display a help tooltip. commit 503622a10151d2ec15e08d91b4f6aeec347fa855 Author: Eli Zaretskii Date: Sat Mar 1 10:09:16 2025 -0500 ; * etc/NEWS.30: Fix last merge. diff --git a/etc/NEWS.30 b/etc/NEWS.30 index 8369aa05423..906deb07212 100644 --- a/etc/NEWS.30 +++ b/etc/NEWS.30 @@ -15,6 +15,33 @@ in older Emacs versions. You can narrow news to a specific version by calling 'view-emacs-news' with a prefix argument or by typing 'C-u C-h C-n'. + +* Installation Changes in Emacs 30.2 + + +* Startup Changes in Emacs 30.2 + + +* Changes in Emacs 30.2 + + +* Editing Changes in Emacs 30.2 + + +* Changes in Specialized Modes and Packages in Emacs 30.2 + + +* New Modes and Packages in Emacs 30.2 + + +* Incompatible Lisp Changes in Emacs 30.2 + + +* Lisp Changes in Emacs 30.2 + + +* Changes in Emacs 30.2 on Non-Free Operating Systems + * Installation Changes in Emacs 30.1 @@ -184,6 +211,9 @@ expectations. * Changes in Emacs 30.1 +** Fix shell injection vulnerability in man.el (CVE-2025-1244). +We urge all users to upgrade immediately. + ** New user option 'trusted-content' to allow potentially dangerous features. This option lists those files and directories whose content Emacs should consider as sufficiently trusted to run any part of the code contained @@ -425,7 +455,7 @@ This user option controls outline visibility in the output buffer of 'describe-bindings' when 'describe-bindings-outline' is non-nil. *** 'describe-function' shows the function's inferred type when available. -For native-compiled Lisp functions, 'describe-function' prints (after +For native compiled Lisp functions, 'describe-function' prints (after the signature) the automatically inferred function type as well. If the function's type was explicitly declared (via the 'declare' form's 'ftype' property), 'describe-function' shows the declared type. This is commit 2095d0fcc686107c2ee25f75983710ca5f4abacf Merge: 5eb67a21008 0460177451d Author: Eli Zaretskii Date: Sat Mar 1 10:02:41 2025 -0500 Merge from origin/emacs-30 0460177451d ; * lisp/progmodes/java-ts-mode.el (treesit-node-end): De... 8481170eb29 Fix 'M-q' in 'makefile-mode' 44a770b8713 ; Improve documentation of 'rmail-movemail-program' # Conflicts: # lisp/progmodes/java-ts-mode.el commit 5eb67a210082a7800dbcd6828593c7328d0fb5b4 Merge: da584ad6fb1 3998dea566a Author: Eli Zaretskii Date: Sat Mar 1 10:01:54 2025 -0500 ; Merge from origin/emacs-30 The following commit was skipped: 3998dea566a ; Cleanup sexp things in 'lua-ts-mode' commit da584ad6fb1b6de72dee895d29ef680f54b76cf5 Merge: 4442cd5b7d7 b531bbf73ef Author: Eli Zaretskii Date: Sat Mar 1 10:01:54 2025 -0500 Merge from origin/emacs-30 b531bbf73ef Fix go-ts-mode const_spec highlighting (Bug#76330) bd1d6761f4c ; Document what happens when 'display' and 'invisible' pr... 526eeedf889 keymaps.texi: Move "Changing Key Bindings" section up 7ec6531c7bd keymaps.texi: Move "Key Sequences" section down 8b804011275 Improve process-get/process-put docstrings 73c646b7771 Merge branch 'emacs-30' of git.sv.gnu.org:/srv/git/emacs ... 0af5c574998 Fix recent change in diff-no-select c8cec840d79 Prevent rare freeze on Android 4.2 through 4.4 commit 4442cd5b7d7ec549a7b0d5839c5595ef64c4693a Merge: a7e75dbabdf c8cec840d79 Author: Eli Zaretskii Date: Sat Mar 1 10:01:53 2025 -0500 ; Merge from origin/emacs-30 The following commit was skipped: c8cec840d79 Prevent rare freeze on Android 4.2 through 4.4 commit a7e75dbabdf8b36c38e32bfedad23b25657c056e Merge: f7e1fa88a11 5247da2e3cd Author: Eli Zaretskii Date: Sat Mar 1 10:01:53 2025 -0500 Merge from origin/emacs-30 5247da2e3cd * lisp/proced.el (proced-<): Check, that NUM1 and NUM2 ar... commit f7e1fa88a11471f5f2846b0379236ea2e232e28d Merge: a242d9a48f2 0d89aa6b6c1 Author: Eli Zaretskii Date: Sat Mar 1 10:01:53 2025 -0500 ; Merge from origin/emacs-30 The following commits were skipped: 0d89aa6b6c1 ; * src/keymap.c: Fix last change (bug#75219). b3181a80712 Fix mouse-2 clicks on mode line and header line commit a242d9a48f2ad00f98230530aa2dc8eb0afcbc7e Merge: 7fde605d3d5 6f5c322f597 Author: Eli Zaretskii Date: Sat Mar 1 10:01:53 2025 -0500 Merge from origin/emacs-30 6f5c322f597 Recommend secure-hash in md5 docstring 1352b184f3f Improve docstring of add-hook and remove-hook commit 7fde605d3d593a3eb2a74fd7bf2c2c15f53b7a67 Merge: 095ba1b6742 dbae1fc69f8 Author: Eli Zaretskii Date: Sat Mar 1 10:01:53 2025 -0500 ; Merge from origin/emacs-30 The following commit was skipped: dbae1fc69f8 * lisp/subr.el (read-key): Add 'tab-line' (bug#76408). commit 095ba1b674256252c7849d55dca67846b129af95 Merge: 25dc3b2ddea 62b3d3136fa Author: Eli Zaretskii Date: Sat Mar 1 10:01:52 2025 -0500 Merge from origin/emacs-30 62b3d3136fa Fix fns-tests-collate-strings failure with musl 840c6824589 ; (completion-preview-complete): Fix bug#76606 fa42626a6a8 ; Fix indentation in cl.texi example 7ff806da496 ; Fix my last commit commit 25dc3b2ddea7180fdf84858e35cb51b0134b3ea4 Merge: 6c411de542d 706426f9669 Author: Eli Zaretskii Date: Sat Mar 1 10:01:52 2025 -0500 ; Merge from origin/emacs-30 The following commit was skipped: 706426f9669 Fix setup of coding-systems on MS-Windows commit 6c411de542d8499a7cc4cb9cf5a381fcf1381436 Merge: 140e7aebc01 f88dc0f2f9d Author: Eli Zaretskii Date: Sat Mar 1 10:01:09 2025 -0500 Merge from origin/emacs-30 f88dc0f2f9d ; Fix documentation of 'buffer-text-pixel-size' 734986349fd ; Minor Android documentation improvements a90da899034 ; Fix up emacs-lisp-mode docstring 58c7acb5554 ; Fix completion-fail-discreetly docstring typo. 02c830ba22b Fix ert-font-lock macro signatures 0c6b8643aec Fix a typo in 'window_text_pixel_size' 8a8c25eaccd ; Add Rudolf Schlatte to authors.el 94c0ea39a5a * doc/misc/efaq.texi (New in Emacs 30): Fix typo. (Bug#7... 0be5f9115ec ; * etc/images/README (Files): Add an entry for last-page... 63adf9dcf53 ; Reflow some cl-lib docstrings 99253f79703 ; * etc/TODO: New section "Make it easier to contribute". # Conflicts: # lisp/emacs-lisp/cl-macs.el commit 140e7aebc01205c5156c5b673fd065dde8fce259 Merge: 612b6df6081 d63b27a416b Author: Eli Zaretskii Date: Sat Mar 1 09:59:08 2025 -0500 ; Merge from origin/emacs-30 The following commit was skipped: d63b27a416b Upgrade out-of-date VC package dependencies commit 612b6df6081c7694525bc236040c4bf360571752 Merge: 27297d20d97 563b6f94511 Author: Eli Zaretskii Date: Sat Mar 1 09:59:08 2025 -0500 Merge from origin/emacs-30 563b6f94511 Constant highlighting no longer captures Java annotations e15dcb2db5c Improve wording of lsh docstring 0cc651acddb ; * admin/check-doc-strings: Add note for future developm... 3c9b1c3cd18 Don't document deleted xwidget functions 9e9b78dda94 ; Improve lsh and ash documented argument names commit 27297d20d979866f3c0c3fc6350cd2294df5421e Merge: b9c9bc20399 77441190252 Author: Eli Zaretskii Date: Sat Mar 1 09:59:08 2025 -0500 ; Merge from origin/emacs-30 The following commits were skipped: 77441190252 Use a persistent directory as default directory in diff ac7f2054b52 Sync build-aux/update-copyright from Gnulib commit b9c9bc203997ea1931ed10062981d72369349c99 Merge: 975567f987b e9c9ed1f468 Author: Eli Zaretskii Date: Sat Mar 1 09:59:08 2025 -0500 Merge from origin/emacs-30 e9c9ed1f468 Minor refactoring in admin/admin.el a8b1726487b ; * admin/make-tarball.txt: Copy edits. commit 975567f987b55fd70cc9811af858492c4b509a06 Merge: def890a0347 2db182ce0bd Author: Eli Zaretskii Date: Sat Mar 1 09:59:07 2025 -0500 ; Merge from origin/emacs-30 The following commit was skipped: 2db182ce0bd Bump Emacs version to 30.1.50 commit def890a034735cf3ccae95370082225bf22cc379 Merge: 0ab8955659c 8ac894e2246 Author: Eli Zaretskii Date: Sat Mar 1 09:59:07 2025 -0500 Merge from origin/emacs-30 8ac894e2246 Release Emacs 30.1 bcba098505e ; * ChangeLog.4: Update. commit 0ab8955659c15c73b24a63ddc9db9ac6ff6387fd Merge: 30cbeaba312 1cda0967b4d Author: Eli Zaretskii Date: Sat Mar 1 09:59:07 2025 -0500 ; Merge from origin/emacs-30 The following commit was skipped: 1cda0967b4d Mention CVE-2025-1244 in NEWS commit 30cbeaba312410cca0bd92988ffac8a3716ab6a4 Merge: 34362a2a1cc 2dbf7d0b1b2 Author: Eli Zaretskii Date: Sat Mar 1 09:59:06 2025 -0500 Merge from origin/emacs-30 2dbf7d0b1b2 Use character position for ranges in treesit_sync_visible... commit 0460177451d86460c0a028f07458e78087181f82 Author: Eli Zaretskii Date: Sat Mar 1 16:42:50 2025 +0200 ; * lisp/progmodes/java-ts-mode.el (treesit-node-end): Declare. diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el index 849ab23ef3e..a4f33948ae9 100644 --- a/lisp/progmodes/java-ts-mode.el +++ b/lisp/progmodes/java-ts-mode.el @@ -37,6 +37,7 @@ (declare-function treesit-node-type "treesit.c") (declare-function treesit-node-child-by-field-name "treesit.c") (declare-function treesit-node-child-by-field-name "treesit.c") +(declare-function treesit-node-end "treesit.c") (declare-function treesit-query-capture "treesit.c") (defcustom java-ts-mode-indent-offset 4 commit 8481170eb296780b404caea587d17ab33a24aaeb Author: Eli Zaretskii Date: Sat Mar 1 16:04:52 2025 +0200 Fix 'M-q' in 'makefile-mode' * lisp/progmodes/make-mode.el (makefile-mode-map): Bind 'M-q' to 'fill-paragraph', as 'prog-mode's default binding is not appropriate for Makefile's syntax. (Bug#76641) diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el index 37dc9a98506..3996284dd21 100644 --- a/lisp/progmodes/make-mode.el +++ b/lisp/progmodes/make-mode.el @@ -574,6 +574,7 @@ The function must satisfy this calling convention: "C-c RET C-p" #'makefile-makepp-mode "M-p" #'makefile-previous-dependency "M-n" #'makefile-next-dependency + "M-q" #'fill-paragraph "C-M-i" #'completion-at-point) (when makefile-electric-keys commit 44a770b87137c93f0c4af4d203bb071659a603a0 Author: Eli Zaretskii Date: Sat Mar 1 15:45:57 2025 +0200 ; Improve documentation of 'rmail-movemail-program' * lisp/mail/rmail.el (rmail-movemail-program): * doc/emacs/rmail.texi (Movemail): Document how to change the value of 'rmail-movemail-program' safely. (Bug#76595) diff --git a/doc/emacs/rmail.texi b/doc/emacs/rmail.texi index 402386684ae..229dc6e3e33 100644 --- a/doc/emacs/rmail.texi +++ b/doc/emacs/rmail.texi @@ -1527,7 +1527,10 @@ This is equivalent to specifying the @samp{file} protocol: absolute file name of the @command{movemail} executable. If it is @code{nil}, Rmail searches for @command{movemail} in the directories listed in @code{rmail-movemail-search-path}, then in @code{exec-path} -(@pxref{Shell}), then in @code{exec-directory}. +(@pxref{Shell}), then in @code{exec-directory}. This variable should be +customized before starting Rmail; if you customize it after starting +Rmail, you will need to set @code{rmail-movemail-variant-in-use} to the +@code{nil} value, and then restart Rmail. @node Remote Mailboxes @section Retrieving Mail from Remote Mailboxes diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index c9c8b0f298e..41d177baf32 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -177,7 +177,10 @@ Its name should end with a slash." :group 'rmail) (defcustom rmail-movemail-program nil - "If non-nil, the file name of the `movemail' program." + "If non-nil, the file name of the `movemail' program. +If you customize this after starting Rmail, reset the +variable `rmail-movemail-variant-in-use' to the nil value, +and then restart Rmail." :group 'rmail-retrieve :type '(choice (const nil) string)) commit 3998dea566aee807922e6edf8d1b20f3da89b4fc Author: john muhl Date: Mon Feb 24 15:21:38 2025 -0600 ; Cleanup sexp things in 'lua-ts-mode' * lisp/progmodes/lua-ts-mode.el (lua-ts-mode): Remove some nonsensical entries from 'treesit-thing-settings'. * test/lisp/progmodes/lua-ts-mode-resources/movement.erts: Add missing tests for 'backward-sexp'. (Bug#76534) diff --git a/lisp/progmodes/lua-ts-mode.el b/lisp/progmodes/lua-ts-mode.el index e99ab0ba825..f35bdff32b1 100644 --- a/lisp/progmodes/lua-ts-mode.el +++ b/lisp/progmodes/lua-ts-mode.el @@ -798,8 +798,7 @@ Calls REPORT-FN directly." `((lua (function ,(rx (or "function_declaration" "function_definition"))) - (keyword ,(regexp-opt lua-ts--keywords - 'symbols)) + (keyword ,(regexp-opt lua-ts--keywords 'symbols)) (loop-statement ,(rx (or "do_statement" "for_statement" "repeat_statement" @@ -817,18 +816,10 @@ Calls REPORT-FN directly." keyword loop-statement ,(rx (or "arguments" - "break_statement" - "expression_list" - "false" - "identifier" - "nil" - "number" "parameters" "parenthesized_expression" "string" - "table_constructor" - "true" - "vararg_expression")))) + "table_constructor")))) (text "comment")))) ;; Imenu/Outline/Which-function. diff --git a/test/lisp/progmodes/lua-ts-mode-resources/movement.erts b/test/lisp/progmodes/lua-ts-mode-resources/movement.erts index 11e86f12926..6e2ffb21d0e 100644 --- a/test/lisp/progmodes/lua-ts-mode-resources/movement.erts +++ b/test/lisp/progmodes/lua-ts-mode-resources/movement.erts @@ -436,9 +436,9 @@ function f(a, b)| end Name: forward-sexp moves over strings =-= -print("|1, 2, 3") +print(|"1, 2, 3") =-= -print("1, 2, 3|") +print("1, 2, 3"|) =-=-= Name: forward-sexp moves over tables @@ -557,9 +557,9 @@ function f|(a, b) end Name: backward-sexp moves over strings =-= -print("1, 2, 3|") +print("1, 2, 3"|) =-= -print("|1, 2, 3") +print(|"1, 2, 3") =-=-= Name: backward-sexp moves over tables @@ -601,3 +601,53 @@ end| end end =-=-= + +Name: backward-sexp moves over do statements + +=-= +do + print(a + 1) +end| +=-= +|do + print(a + 1) +end +=-=-= + +Name: backward-sexp moves over for statements + +=-= +for k,v in pairs({}) do + print(k, v) +end| +=-= +|for k,v in pairs({}) do + print(k, v) +end +=-=-= + +Name: backward-sexp moves over repeat statements + +=-= +repeat + n = n + 1 +until n > 10| +=-= +|repeat + n = n + 1 +until n > 10 +=-=-= + +Name: backward-sexp moves over while statements + +=-= +while n < 99 +do + n = n+1 +end| +=-= +|while n < 99 +do + n = n+1 +end +=-=-= commit 34362a2a1ccd229b486d87cbf4de2eed66e0010d Author: Tassilo Horn Date: Sun Feb 23 09:46:54 2025 +0100 doc-view: Fix error during revert in editing mode When in editing mode in a doc-view buffer and then reverting (which can happen automatically when editing OpenDocument contents), we errored in the advide function doc-view--revert-buffer because the local doc-view--buffer-file-name has been killed when switching to the editing mode. Also restore doc-view-minor-mode after reverting during being in the editing mode. * lisp/doc-view.el (doc-view--revert-buffer): Check that 'doc-view--buffer-file-name' is non-nil. (doc-view-minor-mode): Add re-enabling function to 'revert-buffer-restore-functions'. diff --git a/lisp/doc-view.el b/lisp/doc-view.el index 2fdcc111cab..9cc55529440 100644 --- a/lisp/doc-view.el +++ b/lisp/doc-view.el @@ -591,11 +591,15 @@ Typically \"page-%s.png\".") (cl-labels ((revert () (let ((revert-buffer-preserve-modes t)) (apply orig-fun args) - ;; Update the cached version of the pdf file, - ;; too. This is the one that's used when - ;; rendering (bug#26996). - (unless (equal buffer-file-name - doc-view--buffer-file-name) + ;; Update the cached version of the pdf file, too. + ;; This is the one that's used when rendering + ;; (bug#26996). doc-view--buffer-file-name is nil in + ;; the case where we've switched to the editing mode + ;; (bug#76478). In that case, we'll update the cached + ;; version when switching back to doc-view-mode. + (when (and doc-view--buffer-file-name + (not (equal buffer-file-name + doc-view--buffer-file-name))) ;; FIXME: Lars says he needed to recreate ;; the dir, we should figure out why. (doc-view-make-safe-dir doc-view-cache-directory) @@ -2443,7 +2447,20 @@ to the next best mode." See the command `doc-view-mode' for more information on this mode." :lighter " DocView" (when doc-view-minor-mode - (add-hook 'change-major-mode-hook (lambda () (doc-view-minor-mode -1)) nil t) + (add-hook 'change-major-mode-hook + (lambda () + (doc-view-minor-mode -1)) + nil t) + ;; OpenDocuments are archive files, so their editing mode is + ;; archive-mode. When editing and saving a file in that archive, + ;; it'll automatically revert the archive buffer. Take care to + ;; re-enable `doc-view-minor-mode' in that case. + (add-hook 'revert-buffer-restore-functions + (lambda () + (lambda () + (unless (derived-mode-p 'doc-view-mode) + (doc-view-minor-mode 1)))) + nil t) (message "%s" (substitute-command-keys commit b531bbf73ef91aca0a699ffc89e6b93dc49d0151 Author: Randy Taylor Date: Sun Feb 16 15:51:43 2025 -0500 Fix go-ts-mode const_spec highlighting (Bug#76330) * lisp/progmodes/go-ts-mode.el (go-ts-mode--font-lock-settings): Handle multiple const_spec identifiers. * test/lisp/progmodes/go-ts-mode-resources/font-lock.go: Add test case. diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index 5110ab890f3..eb5b93008eb 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -154,7 +154,8 @@ ,@(when (go-ts-mode--iota-query-supported-p) '((iota) @font-lock-constant-face)) (const_declaration - (const_spec name: (identifier) @font-lock-constant-face))) + (const_spec name: (identifier) @font-lock-constant-face + ("," name: (identifier) @font-lock-constant-face)*))) :language 'go :feature 'delimiter diff --git a/test/lisp/progmodes/go-ts-mode-resources/font-lock.go b/test/lisp/progmodes/go-ts-mode-resources/font-lock.go index 4e7a8e1710b..170bf9353c6 100644 --- a/test/lisp/progmodes/go-ts-mode-resources/font-lock.go +++ b/test/lisp/progmodes/go-ts-mode-resources/font-lock.go @@ -3,3 +3,9 @@ for idx, val := range arr {} // ^ font-lock-variable-name-face for idx := 0; idx < n; idx++ {} // ^ font-lock-variable-name-face + +const ( + zero, one = 0, 1 +// ^ font-lock-constant-face +// ^ font-lock-constant-face +) commit b6efedd66a08103e547266279419e646fc659339 Author: Trevor Murphy Date: Tue Feb 11 17:26:55 2025 -0800 Ignore dedicated windows in 'display-buffer-reuse-mode-window' Ignore the dedicated windows unless the dedicated window is already displaying the buffer-to-be-displayed. In that case, the window may be reused, according to the setting of 'inhibit-same-window'. * lisp/window.el (display-buffer-reuse-mode-window): Check 'window-dedicated-p' before pushing the candidate window onto the stack. (Bug#76216) diff --git a/lisp/window.el b/lisp/window.el index 7fdde3ee18c..4dbe4a9c4e3 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -8492,6 +8492,8 @@ indirectly called by the latter." (cond ((memq major-mode allowed-modes) 'same) ((derived-mode-p allowed-modes) 'derived))))) (when (and mode? + (or (not (window-dedicated-p window)) + (eq buffer (window-buffer window))) (not (and inhibit-same-window-p (eq window curwin)))) (push window (if (eq curframe (window-frame window)) commit bd1d6761f4cd6548731dcb80e0ee8e1a53d929cc Author: Eli Zaretskii Date: Sat Mar 1 12:59:32 2025 +0200 ; Document what happens when 'display' and 'invisible' props clash * doc/lispref/display.texi (Replacing Specs, Overlay Properties) (Invisible Text): Document that 'invisible' is ignored when 'display' property covers the same text. (Bug#76658) diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 8b1847cc4dc..95b17032a74 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -1210,6 +1210,12 @@ The function is called with two arguments: the first is the overlay, and the second is @code{nil} to make the overlay visible, or @code{t} to make it invisible again. +@cindex invisible text, and display properties + The @code{invisible} property is ignored in text that is covered by a +@dfn{replacing} @code{display} property, because such @code{display} +properties skip the text without processing its properties. +@xref{Replacing Specs}. + @node Selective Display @section Selective Display @c @cindex selective display Duplicates selective-display @@ -1918,7 +1924,9 @@ same as in the unhighlighted text. This property activates various features that change the way text is displayed. For example, it can make text appear taller or shorter, higher or lower, wider or narrower, or replaced with an image. -@xref{Display Property}. +@xref{Display Property}. Note that, if the @code{display} property is a +@dfn{replacing} one (@pxref{Replacing Specs}), the @code{invisible} +property of the same overlay will be ignored. @kindex help-echo @r{(overlay property)} @item help-echo @@ -1981,8 +1989,11 @@ conventions are the same as for the @code{modification-hooks} functions. @kindex invisible @r{(overlay property)} @item invisible The @code{invisible} property can make the text in the overlay -invisible, which means that it does not appear on the screen. -@xref{Invisible Text}, for details. +invisible, which means that it does not appear on the screen. However, +if the text covered by the overlay has a @dfn{replacing} @code{display} +property, the @code{invisible} property will be ignored, because a +replacing @code{display} property skips the text without examining its +properties. @xref{Invisible Text}, for details. @kindex intangible @r{(overlay property)} @item intangible @@ -5307,10 +5318,15 @@ instead of the text that has the property. These are called to interactively move point into the middle of buffer text that is replaced in this way. +@cindex display properties, and invisible text +@cindex composition property, and replacing display specs If a list of display specifications includes more than one replacing display specification, the first overrides the rest. Replacing display specifications make most other display specifications -irrelevant, since those don't apply to the replacement. +irrelevant, since those don't apply to the replacement. In addition, +any @code{invisible} and @code{composition} properties of the text that +is replaced are ignored, because the replaced text is skipped and its +properties are not processed. For replacing display specifications, @dfn{the text that has the property} means all the consecutive characters that have the same commit cabbb36ae1d089e34c501c54a682ea7121899565 Author: Eli Zaretskii Date: Sat Mar 1 10:27:17 2025 +0200 Save IELM input history on "C-c C-c" * lisp/ielm.el (ielm--write-history-on-interrupt): New function. (inferior-emacs-lisp-mode): Install it as buffer-local value of the 'interrupt-process-functions' hook. (Bug#76585) * etc/NEWS: Announce the behavior change. diff --git a/etc/NEWS b/etc/NEWS index 0867822a7d8..2a973b77827 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -918,6 +918,14 @@ for docstrings where symbols 'nil' and 't' are in quotes. In most cases, having it enabled leads to a large amount of false positives. +** IELM + +--- +*** IELM input history is now saved also when the IELM process is killed. +When you kill the IELM process with "C-c C-c", the input history is now +saved to the file specified by 'ielm-history-file-name', just like when +you exit the Emacs session or kill the IELM buffer. + ** DocView --- diff --git a/lisp/ielm.el b/lisp/ielm.el index b3cd02b4dc0..43529f36cd6 100644 --- a/lisp/ielm.el +++ b/lisp/ielm.el @@ -521,6 +521,12 @@ behavior of the indirect buffer." (with-current-buffer buf (comint-write-input-ring)))) +(defun ielm--write-history-on-interrupt (_proc _group) + "Save the IELM input history when the process is interrupted." + (funcall (ielm--input-history-writer (current-buffer))) + ;; Let the rest of the hook functions run as well. + nil) + ;;; Major mode (define-derived-mode inferior-emacs-lisp-mode comint-mode "IELM" @@ -658,7 +664,10 @@ Customized bindings may be defined in `ielm-map', which currently contains: '(rear-nonsticky t field output inhibit-line-move-field-capture t)))) (comint-output-filter (ielm-process) ielm-prompt-internal) (set-marker comint-last-input-start (ielm-pm)) - (set-process-filter (get-buffer-process (current-buffer)) 'comint-output-filter))) + (set-process-filter (get-buffer-process (current-buffer)) + 'comint-output-filter) + (add-hook 'interrupt-process-functions + #'ielm--write-history-on-interrupt -1 t))) (defun ielm-get-old-input nil ;; Return the previous input surrounding point commit 61320784ed2a8f5f3dcdeb401579d220e5dc05da Author: Eli Zaretskii Date: Sat Mar 1 10:12:21 2025 +0200 Add a portable test for ffap parsing path-style directory lists * test/lisp/ffap-tests.el (ffap-test-path-unix): Renamed from 'ffap-test-path'. (ffap-test-path-portable): New test, which should work on all systems. diff --git a/test/lisp/ffap-tests.el b/test/lisp/ffap-tests.el index b07a4c4fbc6..3c6e1e8e18e 100644 --- a/test/lisp/ffap-tests.el +++ b/test/lisp/ffap-tests.el @@ -165,7 +165,7 @@ left alone when opening a URL in an external browser." (let (kill-buffer-query-functions) (kill-buffer (call-interactively #'find-file-at-point))))))) -(ert-deftest ffap-test-path () +(ert-deftest ffap-test-path-unix () (skip-unless (file-exists-p "/bin")) (skip-unless (file-exists-p "/usr/bin")) (with-temp-buffer @@ -182,6 +182,32 @@ left alone when opening a URL in an external browser." (goto-char (point-min)) (should (equal (ffap-file-at-point) nil)))) +(ert-deftest ffap-test-path-portable () + ;; Why 'load-path' and not 'exec-path'? Because there are various + ;; complications when the test is run on Windows from MSYS Bash: the + ;; few first directories MSYS adds to the system PATH may not exist, + ;; and the very first one is ".", which ffap-file-at-point doesn't + ;; recognize as a file. + (skip-unless (> (length load-path) 2)) + (let ((dir1 (expand-file-name (car load-path))) + (dir2 (expand-file-name (nth 1 load-path)))) + (skip-unless (and (file-exists-p dir1) (file-exists-p dir2))) + (with-temp-buffer + (insert (format "%s%s%s" dir1 path-separator dir2)) + (goto-char (point-min)) + ;; Use 'file-equal-p' because PATH could have backslashes, "~", + ;; and other constructs that will make 'equal' fail. + (should (file-equal-p (ffap-file-at-point) dir1))) + (with-temp-buffer + (insert (format "%s%s%s" dir1 path-separator dir2)) + (goto-char (point-min)) + (search-forward path-separator) + (should (file-equal-p (ffap-file-at-point) dir2))) + (with-temp-buffer + (insert "%s%s" path-separator dir2) + (goto-char (point-min)) + (should (equal (ffap-file-at-point) nil))))) + (ert-deftest ffap-tests--c-path () (should (seq-every-p #'stringp (ffap--c-path))) (should (locate-file "stdio.h" (ffap--c-path))) commit 526eeedf88941daf2a77ac5a6c2ba8237ed4814d Author: Stefan Kangas Date: Sat Mar 1 06:34:00 2025 +0100 keymaps.texi: Move "Changing Key Bindings" section up * doc/lispref/keymaps.texi (Changing Key Bindings): Move section up. (Bug#52821) diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index ac63f296958..e1f11f9a138 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -15,6 +15,7 @@ is found. The whole process is called @dfn{key lookup}. @menu * Keymap Basics:: Basic concepts of keymaps. +* Changing Key Bindings:: Redefining a key in a keymap. * Format of Keymaps:: What a keymap looks like as a Lisp object. * Creating Keymaps:: Functions to create and copy keymaps. * Inheritance and Keymaps:: How one keymap can inherit the bindings @@ -28,7 +29,6 @@ is found. The whole process is called @dfn{key lookup}. A minor mode can also override them. * Key Lookup:: Finding a key's binding in one keymap. * Functions for Key Lookup:: How to request key lookup. -* Changing Key Bindings:: Redefining a key in a keymap. * Key Sequences:: Key sequences as Lisp objects. * Low-Level Key Binding:: Legacy key syntax description. * Remapping Commands:: A keymap can translate one command to another. @@ -90,303 +90,577 @@ precedence over) the corresponding global bindings. The minor mode keymaps shadow both local and global keymaps. @xref{Active Keymaps}, for details. -@node Format of Keymaps -@section Format of Keymaps -@cindex format of keymaps -@cindex keymap format -@cindex full keymap -@cindex sparse keymap +@node Changing Key Bindings +@section Changing Key Bindings +@cindex changing key bindings +@cindex rebinding - Each keymap is a list whose @sc{car} is the symbol @code{keymap}. The -remaining elements of the list define the key bindings of the keymap. -A symbol whose function definition is a keymap is also a keymap. Use -the function @code{keymapp} (see below) to test whether an object is a -keymap. + The way to rebind a key is to change its entry in a keymap. If you +change a binding in the global keymap, the change is effective in all +buffers (though it has no direct effect in buffers that shadow the +global binding with a local one). If you change the current buffer's +local map, that usually affects all buffers using the same major mode. +The @code{keymap-global-set} and @code{keymap-local-set} functions are +convenient interfaces for these operations (@pxref{Key Binding +Commands}). You can also use @code{keymap-set}, a more general +function; then you must explicitly specify the map to change. - Several kinds of elements may appear in a keymap, after the symbol -@code{keymap} that begins it: + When choosing the key sequences for Lisp programs to rebind, please +follow the Emacs conventions for use of various keys (@pxref{Key +Binding Conventions}). -@table @code -@item (@var{type} .@: @var{binding}) -This specifies one binding, for events of type @var{type}. Each -ordinary binding applies to events of a particular @dfn{event type}, -which is always a character or a symbol. @xref{Classifying Events}. -In this kind of binding, @var{binding} is a command. + The functions below signal an error if @var{keymap} is not a keymap, +or if @var{key} is not a valid key. -@item (@var{type} @var{item-name} .@: @var{binding}) -This specifies a binding which is also a simple menu item that -displays as @var{item-name} in the menu. @xref{Simple Menu Items}. +@var{key} is a string representing a single key or a series of key +strokes, and must satisfy @code{key-valid-p}. Key strokes are +separated by a single space character. -@item (@var{type} @var{item-name} @var{help-string} .@: @var{binding}) -This is a simple menu item with help string @var{help-string}. +Each key stroke is either a single character, or the name of an +event, surrounded by angle brackets. In addition, any key stroke +may be preceded by one or more modifier keys. Finally, a limited +number of characters have a special shorthand syntax. Here's some +example key sequences: -@item (@var{type} menu-item .@: @var{details}) -This specifies a binding which is also an extended menu item. This -allows use of other features. @xref{Extended Menu Items}. +@table @kbd +@item f +The key @kbd{f}. -@item (t .@: @var{binding}) -@cindex default key binding -This specifies a @dfn{default key binding}; any event not bound by other -elements of the keymap is given @var{binding} as its binding. Default -bindings allow a keymap to bind all possible event types without having -to enumerate all of them. A keymap that has a default binding -completely masks any lower-precedence keymap, except for events -explicitly bound to @code{nil} (see below). +@item S o m +A three key sequence of the keys @kbd{S}, @kbd{o} and @kbd{m}. -@item @var{char-table} -If an element of a keymap is a char-table, it counts as holding -bindings for all character events with no modifier bits -(@pxref{modifier bits}): the element whose index is @var{c} is the -binding for the character @var{c}. This is a compact way to record -lots of bindings. A keymap with such a char-table is called a -@dfn{full keymap}. Other keymaps are called @dfn{sparse keymaps}. +@item C-c o +A two key sequence of the keys @kbd{c} with the control modifier and +then the key @kbd{o} -@item @var{vector} -This kind of element is similar to a char-table: the element whose -index is @var{c} is the binding for the character @var{c}. Since the -range of characters that can be bound this way is limited by the -vector size, and vector creation allocates space for all character -codes from 0 up, this format should not be used except for creating -menu keymaps (@pxref{Menu Keymaps}), where the bindings themselves -don't matter. +@item H- +The key named @kbd{left} with the hyper modifier. -@item @var{string} -@cindex keymap prompt string -@cindex overall prompt string -@cindex prompt string of keymap -Aside from elements that specify bindings for keys, a keymap can also -have a string as an element. This is called the @dfn{overall prompt -string} and makes it possible to use the keymap as a menu. -@xref{Defining Menus}. +@item M-RET +The @kbd{return} key with a meta modifier. -@item (keymap @dots{}) -If an element of a keymap is itself a keymap, it counts as if this inner keymap -were inlined in the outer keymap. This is used for multiple-inheritance, such -as in @code{make-composed-keymap}. +@item C-M- +The @kbd{space} key with both the control and meta modifiers. @end table -When the binding is @code{nil}, it doesn't constitute a definition -but it does take precedence over a default binding or a binding in the -parent keymap. On the other hand, a binding of @code{nil} does -@emph{not} override lower-precedence keymaps; thus, if the local map -gives a binding of @code{nil}, Emacs uses the binding from the -global map. +The only keys that have a special shorthand syntax are @kbd{NUL}, +@kbd{RET}, @kbd{TAB}, @kbd{LFD}, @kbd{ESC}, @kbd{SPC} and @kbd{DEL}. -@cindex meta characters lookup - Keymaps do not directly record bindings for the meta characters. -Instead, meta characters are regarded for purposes of key lookup as -sequences of two characters, the first of which is @key{ESC} (or -whatever is currently the value of @code{meta-prefix-char}). Thus, the -key @kbd{M-a} is internally represented as @kbd{@key{ESC} a}, and its -global binding is found at the slot for @kbd{a} in @code{esc-map} -(@pxref{Prefix Keys}). +The modifiers have to be specified in alphabetical order: +@samp{A-C-H-M-S-s}, which is @samp{Alt-Control-Hyper-Meta-Shift-super}. - This conversion applies only to characters, not to function keys or -other input events; thus, @kbd{M-@key{end}} has nothing to do with -@kbd{@key{ESC} @key{end}}. +@findex keymap-set +@defun keymap-set keymap key binding +This function sets the binding for @var{key} in @var{keymap}. (If +@var{key} is more than one event long, the change is actually made +in another keymap reached from @var{keymap}.) The argument +@var{binding} can be any Lisp object, but only certain types are +meaningful. (For a list of meaningful types, see @ref{Key Lookup}.) +The value returned by @code{keymap-set} is @var{binding}. - Here as an example is the local keymap for Lisp mode, a sparse -keymap. It defines bindings for @key{DEL}, @kbd{C-c C-z}, -@kbd{C-M-q}, and @kbd{C-M-x} (the actual value also contains a menu -binding, which is omitted here for the sake of brevity). +If @var{key} is @kbd{}, this sets the default binding in +@var{keymap}. When an event has no binding of its own, the Emacs +command loop uses the keymap's default binding, if there is one. -@example +@cindex invalid prefix key error +@cindex key sequence error +Every prefix of @var{key} must be a prefix key (i.e., bound to a keymap) +or undefined; otherwise an error is signaled. If some prefix of +@var{key} is undefined, then @code{keymap-set} defines it as a prefix +key so that the rest of @var{key} can be defined as specified. + +If there was previously no binding for @var{key} in @var{keymap}, the +new binding is added at the beginning of @var{keymap}. The order of +bindings in a keymap makes no difference for keyboard input, but it +does matter for menu keymaps (@pxref{Menu Keymaps}). +@end defun + +@findex keymap-unset +@defun keymap-unset keymap key &optional remove +This function is the inverse of @code{keymap-set}, it unsets the +binding for @var{key} in @var{keymap}, which is the same as setting +the binding to @code{nil}. In order to instead remove the binding +completely, specify @var{remove} as non-@code{nil}. This only makes a +difference if @var{keymap} has a parent keymap: if you just unset a key +in a child map, it will still shadow the same key in the parent +keymap; using @var{remove} instead will allow the key in the parent keymap +to be used. +@end defun + +Note: using @code{keymap-unset} with @var{remove} non-@code{nil} is +intended for users to put in their init file; Emacs packages should +avoid using it if possible, since they have complete control over +their own keymaps anyway, and they should not be altering other +packages' keymaps. + + This example creates a sparse keymap and makes a number of +bindings in it: + +@smallexample @group -lisp-mode-map -@result{} +(setq map (make-sparse-keymap)) + @result{} (keymap) @end group @group -(keymap - (3 keymap - ;; @kbd{C-c C-z} - (26 . run-lisp)) +(keymap-set map "C-f" 'forward-char) + @result{} forward-char @end group @group - (27 keymap - ;; @r{@kbd{C-M-x}, treated as @kbd{@key{ESC} C-x}} - (24 . lisp-send-defun)) +map + @result{} (keymap (6 . forward-char)) @end group + @group - ;; @r{This part is inherited from @code{lisp-mode-shared-map}.} - keymap - ;; @key{DEL} - (127 . backward-delete-char-untabify) +;; @r{Build sparse submap for @kbd{C-x} and bind @kbd{f} in that.} +(keymap-set map "C-x f" 'forward-word) + @result{} forward-word @end group @group - (27 keymap - ;; @r{@kbd{C-M-q}, treated as @kbd{@key{ESC} C-q}} - (17 . indent-sexp))) +map +@result{} (keymap + (24 keymap ; @kbd{C-x} + (102 . forward-word)) ; @kbd{f} + (6 . forward-char)) ; @kbd{C-f} @end group -@end example -@defun keymapp object -This function returns @code{t} if @var{object} is a keymap, @code{nil} -otherwise. More precisely, this function tests for a list whose -@sc{car} is @code{keymap}, or for a symbol whose function definition -satisfies @code{keymapp}. - -@example @group -(keymapp '(keymap)) - @result{} t +;; @r{Bind @kbd{C-p} to the @code{ctl-x-map}.} +(keymap-set map "C-p" ctl-x-map) +;; @code{ctl-x-map} +@result{} [nil @dots{} find-file @dots{} backward-kill-sentence] @end group + @group -(fset 'foo '(keymap)) -(keymapp 'foo) - @result{} t +;; @r{Bind @kbd{C-f} to @code{foo} in the @code{ctl-x-map}.} +(keymap-set map "C-p C-f" 'foo) +@result{} 'foo @end group @group -(keymapp (current-global-map)) - @result{} t +map +@result{} (keymap ; @r{Note @code{foo} in @code{ctl-x-map}.} + (16 keymap [nil @dots{} foo @dots{} backward-kill-sentence]) + (24 keymap + (102 . forward-word)) + (6 . forward-char)) @end group -@end example -@end defun +@end smallexample -@node Creating Keymaps -@section Creating Keymaps -@cindex creating keymaps +@noindent +Note that storing a new binding for @kbd{C-p C-f} actually works by +changing an entry in @code{ctl-x-map}, and this has the effect of +changing the bindings of both @kbd{C-p C-f} and @kbd{C-x C-f} in the +default global map. - Here we describe the functions for creating keymaps. +@code{keymap-set} is the general work horse for defining a key in a +keymap. When writing modes, however, you frequently have to bind a +large number of keys at once, and using @code{keymap-set} on them all +can be tedious and error-prone. Instead you can use +@code{define-keymap}, which creates a keymap and binds a number of +keys. @xref{Creating Keymaps}, for details. -@defun make-sparse-keymap &optional prompt -This function creates and returns a new sparse keymap with no entries. -(A sparse keymap is the kind of keymap you usually want.) The new -keymap does not contain a char-table, unlike @code{make-keymap}, and -does not bind any events. +The function @code{substitute-key-definition} scans a keymap for +keys that have a certain binding and rebinds them with a different +binding. Another feature which is cleaner and can often produce the +same results is to remap one command into another (@pxref{Remapping +Commands}). -@example +@defun substitute-key-definition olddef newdef keymap &optional oldmap +@cindex replace bindings +This function replaces @var{olddef} with @var{newdef} for any keys in +@var{keymap} that were bound to @var{olddef}. In other words, +@var{olddef} is replaced with @var{newdef} wherever it appears. The +function returns @code{nil}. + +For example, this redefines @kbd{C-x C-f}, if you do it in an Emacs with +standard bindings: + +@smallexample @group -(make-sparse-keymap) - @result{} (keymap) +(substitute-key-definition + 'find-file 'find-file-read-only (current-global-map)) @end group -@end example +@end smallexample -If you specify @var{prompt}, that becomes the overall prompt string -for the keymap. You should specify this only for menu keymaps -(@pxref{Defining Menus}). A keymap with an overall prompt string will -always present a mouse menu or a keyboard menu if it is active for -looking up the next input event. Don't specify an overall prompt string -for the main map of a major or minor mode, because that would cause -the command loop to present a keyboard menu every time. -@end defun +If @var{oldmap} is non-@code{nil}, that changes the behavior of +@code{substitute-key-definition}: the bindings in @var{oldmap} determine +which keys to rebind. The rebindings still happen in @var{keymap}, not +in @var{oldmap}. Thus, you can change one map under the control of the +bindings in another. For example, -@defun make-keymap &optional prompt -This function creates and returns a new full keymap. That keymap -contains a char-table (@pxref{Char-Tables}) with slots for all -characters without modifiers. The new keymap initially binds all -these characters to @code{nil}, and does not bind any other kind of -event. The argument @var{prompt} specifies a -prompt string, as in @code{make-sparse-keymap}. +@smallexample +(substitute-key-definition + 'delete-backward-char 'my-funny-delete + my-map global-map) +@end smallexample -@c This example seems kind of pointless, but I guess it serves -@c to contrast the result with make-sparse-keymap above. -@example +@noindent +puts the special deletion command in @code{my-map} for whichever keys +are globally bound to the standard deletion command. + +Here is an example showing a keymap before and after substitution: + +@smallexample @group -(make-keymap) - @result{} (keymap #^[nil nil keymap nil nil nil @dots{}]) +(setq map (list 'keymap + (cons ?1 olddef-1) + (cons ?2 olddef-2) + (cons ?3 olddef-1))) +@result{} (keymap (49 . olddef-1) (50 . olddef-2) (51 . olddef-1)) @end group -@end example -A full keymap is more efficient than a sparse keymap when it holds -lots of bindings; for just a few, the sparse keymap is better. +@group +(substitute-key-definition 'olddef-1 'newdef map) +@result{} nil +@end group +@group +map +@result{} (keymap (49 . newdef) (50 . olddef-2) (51 . newdef)) +@end group +@end smallexample @end defun -@defun define-keymap &key options... &rest pairs... -You can create a keymap with the functions described above, and then -use @code{keymap-set} (@pxref{Changing Key Bindings}) to specify key -bindings in that map. When writing modes, however, you frequently -have to bind a large number of keys at once, and using -@code{keymap-set} on them all can be tedious and error-prone. Instead -you can use @code{define-keymap}, which creates a keymap and binds a -number of keys. Here's a very basic example: +@defun suppress-keymap keymap &optional nodigits +@cindex @code{self-insert-command} override +This function changes the contents of the full keymap @var{keymap} by +remapping @code{self-insert-command} to the command @code{undefined} +(@pxref{Remapping Commands}). This has the effect of undefining all +printing characters, thus making ordinary insertion of text impossible. +@code{suppress-keymap} returns @code{nil}. -@lisp -(define-keymap - "n" #'forward-line - "f" #'previous-line - "C-c C-c" #'quit-window) -@end lisp +If @var{nodigits} is @code{nil}, then @code{suppress-keymap} defines +digits to run @code{digit-argument}, and @kbd{-} to run +@code{negative-argument}. Otherwise it makes them undefined like the +rest of the printing characters. -This function creates a new sparse keymap, defines the keystrokes in -@var{pairs}, and returns the new keymap. It signals an error if there -are duplicate key bindings in @var{pairs}. +@cindex yank suppression +@cindex @code{quoted-insert} suppression +The @code{suppress-keymap} function does not make it impossible to +modify a buffer, as it does not suppress commands such as @code{yank} +and @code{quoted-insert}. To prevent any modification of a buffer, make +it read-only (@pxref{Read Only Buffers}). -@var{pairs} is a list of alternating key bindings and key definitions, -as accepted by @code{keymap-set}. In addition, the key can be the -special symbol @code{:menu}, in which case the definition should be a -menu definition as accepted by @code{easy-menu-define} (@pxref{Easy -Menu}). Here's a brief example of this usage: +Since this function modifies @var{keymap}, you would normally use it +on a newly created keymap. Operating on an existing keymap +that is used for some other purpose is likely to cause trouble; for +example, suppressing @code{global-map} would make it impossible to use +most of Emacs. -@lisp -(define-keymap :full t - "g" #'eww-reload - :menu '("Eww" - ["Exit" quit-window t] - ["Reload" eww-reload t])) -@end lisp +This function can be used to initialize the local keymap of a major +mode for which insertion of text is not desirable. But usually such a +mode should be derived from @code{special-mode} (@pxref{Basic Major +Modes}); then its keymap will automatically inherit from +@code{special-mode-map}, which is already suppressed. Here is how +@code{special-mode-map} is defined: -A number of keywords can be used before the key/definition pairs to -change features of the new keymap. If any of the feature keywords is -missing from the @code{define-keymap} call, the default value for that -feature is @code{nil}. Here's a list of the available feature -keywords: +@smallexample +@group +(defvar special-mode-map + (let ((map (make-sparse-keymap))) + (suppress-keymap map) + (keymap-set map "q" 'quit-window) + @dots{} + map)) +@end group +@end smallexample +@end defun -@table @code -@item :full -If non-@code{nil}, create a char-table keymap (as from -@code{make-keymap}) instead of a sparse keymap (as from -@code{make-sparse-keymap} (@pxref{Creating Keymaps}). A sparse keymap -is the default. +@node Format of Keymaps +@section Format of Keymaps +@cindex format of keymaps +@cindex keymap format +@cindex full keymap +@cindex sparse keymap -@item :parent -If non-@code{nil}, the value should be a keymap to use as the parent -(@pxref{Inheritance and Keymaps}). + Each keymap is a list whose @sc{car} is the symbol @code{keymap}. The +remaining elements of the list define the key bindings of the keymap. +A symbol whose function definition is a keymap is also a keymap. Use +the function @code{keymapp} (see below) to test whether an object is a +keymap. -@item :keymap -If non-@code{nil}, the value should be a keymap. Instead of creating -a new keymap, the specified keymap is modified instead. + Several kinds of elements may appear in a keymap, after the symbol +@code{keymap} that begins it: -@item :suppress -If non-@code{nil}, the keymap will be suppressed with -@code{suppress-keymap} (@pxref{Changing Key Bindings}). By default, -digits and the minus sign are exempt from suppressing, but if the -value is @code{nodigits}, this suppresses digits and minus-sign like -it does with other characters. +@table @code +@item (@var{type} .@: @var{binding}) +This specifies one binding, for events of type @var{type}. Each +ordinary binding applies to events of a particular @dfn{event type}, +which is always a character or a symbol. @xref{Classifying Events}. +In this kind of binding, @var{binding} is a command. -@item :name -If non-@code{nil}, the value should be a string to use as the menu for -the keymap if you use it as a menu with @code{x-popup-menu} -(@pxref{Pop-Up Menus}). +@item (@var{type} @var{item-name} .@: @var{binding}) +This specifies a binding which is also a simple menu item that +displays as @var{item-name} in the menu. @xref{Simple Menu Items}. -@item :prefix -If non-@code{nil}, the value should be a symbol to be used as a prefix -command (@pxref{Prefix Keys}). If this is the case, this symbol is -returned by @code{define-keymap} instead of the map itself. -@end table +@item (@var{type} @var{item-name} @var{help-string} .@: @var{binding}) +This is a simple menu item with help string @var{help-string}. -@end defun +@item (@var{type} menu-item .@: @var{details}) +This specifies a binding which is also an extended menu item. This +allows use of other features. @xref{Extended Menu Items}. -@defmac defvar-keymap name &key options... &rest pairs... -By far, the most common thing to do with a keymap is to bind it to a -variable. This is what virtually all modes do---a mode called -@code{foo} almost always has a variable called @code{foo-mode-map}. +@item (t .@: @var{binding}) +@cindex default key binding +This specifies a @dfn{default key binding}; any event not bound by other +elements of the keymap is given @var{binding} as its binding. Default +bindings allow a keymap to bind all possible event types without having +to enumerate all of them. A keymap that has a default binding +completely masks any lower-precedence keymap, except for events +explicitly bound to @code{nil} (see below). -This macro defines @var{name} as a variable, passes @var{options} -and @var{pairs} to @code{define-keymap}, and uses the result as the -default value for the variable. It signals an error if there are -duplicate key bindings in @var{pairs}. +@item @var{char-table} +If an element of a keymap is a char-table, it counts as holding +bindings for all character events with no modifier bits +(@pxref{modifier bits}): the element whose index is @var{c} is the +binding for the character @var{c}. This is a compact way to record +lots of bindings. A keymap with such a char-table is called a +@dfn{full keymap}. Other keymaps are called @dfn{sparse keymaps}. -@var{options} is like the keywords in @code{define-keymap}, but -there's an additional @code{:doc} keyword that provides the doc -string for the defined variable. +@item @var{vector} +This kind of element is similar to a char-table: the element whose +index is @var{c} is the binding for the character @var{c}. Since the +range of characters that can be bound this way is limited by the +vector size, and vector creation allocates space for all character +codes from 0 up, this format should not be used except for creating +menu keymaps (@pxref{Menu Keymaps}), where the bindings themselves +don't matter. -Here's an example: +@item @var{string} +@cindex keymap prompt string +@cindex overall prompt string +@cindex prompt string of keymap +Aside from elements that specify bindings for keys, a keymap can also +have a string as an element. This is called the @dfn{overall prompt +string} and makes it possible to use the keymap as a menu. +@xref{Defining Menus}. -@lisp -(defvar-keymap eww-textarea-map - :parent text-mode-map - :doc "Keymap for the eww text area." - "RET" #'forward-line +@item (keymap @dots{}) +If an element of a keymap is itself a keymap, it counts as if this inner keymap +were inlined in the outer keymap. This is used for multiple-inheritance, such +as in @code{make-composed-keymap}. +@end table + +When the binding is @code{nil}, it doesn't constitute a definition +but it does take precedence over a default binding or a binding in the +parent keymap. On the other hand, a binding of @code{nil} does +@emph{not} override lower-precedence keymaps; thus, if the local map +gives a binding of @code{nil}, Emacs uses the binding from the +global map. + +@cindex meta characters lookup + Keymaps do not directly record bindings for the meta characters. +Instead, meta characters are regarded for purposes of key lookup as +sequences of two characters, the first of which is @key{ESC} (or +whatever is currently the value of @code{meta-prefix-char}). Thus, the +key @kbd{M-a} is internally represented as @kbd{@key{ESC} a}, and its +global binding is found at the slot for @kbd{a} in @code{esc-map} +(@pxref{Prefix Keys}). + + This conversion applies only to characters, not to function keys or +other input events; thus, @kbd{M-@key{end}} has nothing to do with +@kbd{@key{ESC} @key{end}}. + + Here as an example is the local keymap for Lisp mode, a sparse +keymap. It defines bindings for @key{DEL}, @kbd{C-c C-z}, +@kbd{C-M-q}, and @kbd{C-M-x} (the actual value also contains a menu +binding, which is omitted here for the sake of brevity). + +@example +@group +lisp-mode-map +@result{} +@end group +@group +(keymap + (3 keymap + ;; @kbd{C-c C-z} + (26 . run-lisp)) +@end group +@group + (27 keymap + ;; @r{@kbd{C-M-x}, treated as @kbd{@key{ESC} C-x}} + (24 . lisp-send-defun)) +@end group +@group + ;; @r{This part is inherited from @code{lisp-mode-shared-map}.} + keymap + ;; @key{DEL} + (127 . backward-delete-char-untabify) +@end group +@group + (27 keymap + ;; @r{@kbd{C-M-q}, treated as @kbd{@key{ESC} C-q}} + (17 . indent-sexp))) +@end group +@end example + +@defun keymapp object +This function returns @code{t} if @var{object} is a keymap, @code{nil} +otherwise. More precisely, this function tests for a list whose +@sc{car} is @code{keymap}, or for a symbol whose function definition +satisfies @code{keymapp}. + +@example +@group +(keymapp '(keymap)) + @result{} t +@end group +@group +(fset 'foo '(keymap)) +(keymapp 'foo) + @result{} t +@end group +@group +(keymapp (current-global-map)) + @result{} t +@end group +@end example +@end defun + +@node Creating Keymaps +@section Creating Keymaps +@cindex creating keymaps + + Here we describe the functions for creating keymaps. + +@defun make-sparse-keymap &optional prompt +This function creates and returns a new sparse keymap with no entries. +(A sparse keymap is the kind of keymap you usually want.) The new +keymap does not contain a char-table, unlike @code{make-keymap}, and +does not bind any events. + +@example +@group +(make-sparse-keymap) + @result{} (keymap) +@end group +@end example + +If you specify @var{prompt}, that becomes the overall prompt string +for the keymap. You should specify this only for menu keymaps +(@pxref{Defining Menus}). A keymap with an overall prompt string will +always present a mouse menu or a keyboard menu if it is active for +looking up the next input event. Don't specify an overall prompt string +for the main map of a major or minor mode, because that would cause +the command loop to present a keyboard menu every time. +@end defun + +@defun make-keymap &optional prompt +This function creates and returns a new full keymap. That keymap +contains a char-table (@pxref{Char-Tables}) with slots for all +characters without modifiers. The new keymap initially binds all +these characters to @code{nil}, and does not bind any other kind of +event. The argument @var{prompt} specifies a +prompt string, as in @code{make-sparse-keymap}. + +@c This example seems kind of pointless, but I guess it serves +@c to contrast the result with make-sparse-keymap above. +@example +@group +(make-keymap) + @result{} (keymap #^[nil nil keymap nil nil nil @dots{}]) +@end group +@end example + +A full keymap is more efficient than a sparse keymap when it holds +lots of bindings; for just a few, the sparse keymap is better. +@end defun + +@defun define-keymap &key options... &rest pairs... +You can create a keymap with the functions described above, and then +use @code{keymap-set} (@pxref{Changing Key Bindings}) to specify key +bindings in that map. When writing modes, however, you frequently +have to bind a large number of keys at once, and using +@code{keymap-set} on them all can be tedious and error-prone. Instead +you can use @code{define-keymap}, which creates a keymap and binds a +number of keys. Here's a very basic example: + +@lisp +(define-keymap + "n" #'forward-line + "f" #'previous-line + "C-c C-c" #'quit-window) +@end lisp + +This function creates a new sparse keymap, defines the keystrokes in +@var{pairs}, and returns the new keymap. It signals an error if there +are duplicate key bindings in @var{pairs}. + +@var{pairs} is a list of alternating key bindings and key definitions, +as accepted by @code{keymap-set}. In addition, the key can be the +special symbol @code{:menu}, in which case the definition should be a +menu definition as accepted by @code{easy-menu-define} (@pxref{Easy +Menu}). Here's a brief example of this usage: + +@lisp +(define-keymap :full t + "g" #'eww-reload + :menu '("Eww" + ["Exit" quit-window t] + ["Reload" eww-reload t])) +@end lisp + +A number of keywords can be used before the key/definition pairs to +change features of the new keymap. If any of the feature keywords is +missing from the @code{define-keymap} call, the default value for that +feature is @code{nil}. Here's a list of the available feature +keywords: + +@table @code +@item :full +If non-@code{nil}, create a char-table keymap (as from +@code{make-keymap}) instead of a sparse keymap (as from +@code{make-sparse-keymap} (@pxref{Creating Keymaps}). A sparse keymap +is the default. + +@item :parent +If non-@code{nil}, the value should be a keymap to use as the parent +(@pxref{Inheritance and Keymaps}). + +@item :keymap +If non-@code{nil}, the value should be a keymap. Instead of creating +a new keymap, the specified keymap is modified instead. + +@item :suppress +If non-@code{nil}, the keymap will be suppressed with +@code{suppress-keymap} (@pxref{Changing Key Bindings}). By default, +digits and the minus sign are exempt from suppressing, but if the +value is @code{nodigits}, this suppresses digits and minus-sign like +it does with other characters. + +@item :name +If non-@code{nil}, the value should be a string to use as the menu for +the keymap if you use it as a menu with @code{x-popup-menu} +(@pxref{Pop-Up Menus}). + +@item :prefix +If non-@code{nil}, the value should be a symbol to be used as a prefix +command (@pxref{Prefix Keys}). If this is the case, this symbol is +returned by @code{define-keymap} instead of the map itself. +@end table + +@end defun + +@defmac defvar-keymap name &key options... &rest pairs... +By far, the most common thing to do with a keymap is to bind it to a +variable. This is what virtually all modes do---a mode called +@code{foo} almost always has a variable called @code{foo-mode-map}. + +This macro defines @var{name} as a variable, passes @var{options} +and @var{pairs} to @code{define-keymap}, and uses the result as the +default value for the variable. It signals an error if there are +duplicate key bindings in @var{pairs}. + +@var{options} is like the keywords in @code{define-keymap}, but +there's an additional @code{:doc} keyword that provides the doc +string for the defined variable. + +Here's an example: + +@lisp +(defvar-keymap eww-textarea-map + :parent text-mode-map + :doc "Keymap for the eww text area." + "RET" #'forward-line "TAB" #'shr-next-link) @end lisp @@ -1200,436 +1474,162 @@ macro, a symbol that leads to one of them, or @code{nil}. Here are the functions and variables pertaining to key lookup. @defun keymap-lookup keymap key &optional accept-defaults no-remap position -This function returns the definition of @var{key} in @var{keymap}. All -the other functions described in this chapter that look up keys use -@code{keymap-lookup}. Here are examples: - -@example -@group -(keymap-lookup (current-global-map) "C-x C-f") - @result{} find-file -@end group -@group -(keymap-lookup (current-global-map) "C-x C-f 1 2 3 4 5") - @result{} 2 -@end group -@end example - -If the string or vector @var{key} is not a valid key sequence according -to the prefix keys specified in @var{keymap}, it must be too long -and have extra events at the end that do not fit into a single key -sequence. Then the value is a number, the number of events at the front -of @var{key} that compose a complete key. - -If @var{accept-defaults} is non-@code{nil}, then @code{keymap-lookup} -considers default bindings as well as bindings for the specific events -in @var{key}. Otherwise, @code{keymap-lookup} reports only bindings for -the specific sequence @var{key}, ignoring default bindings except when -you explicitly ask about them. (To do this, supply @code{t} as an -element of @var{key}; see @ref{Format of Keymaps}.) - -If @var{key} contains a meta character (not a function key), that -character is implicitly replaced by a two-character sequence: the value -of @code{meta-prefix-char}, followed by the corresponding non-meta -character. Thus, the first example below is handled by conversion into -the second example. - -@example -@group -(keymap-lookup (current-global-map) "M-f") - @result{} forward-word -@end group -@group -(keymap-lookup (current-global-map) "ESC f") - @result{} forward-word -@end group -@end example - -The @var{keymap} argument can be @code{nil}, meaning to look up -@var{key} in the current keymaps (as returned by -@code{current-active-maps}, @pxref{Active Keymaps}); or it can be a -keymap or a list of keymaps, meaning to look up @var{key} only in the -specified keymaps. - -Unlike @code{read-key-sequence}, this function does not modify the -specified events in ways that discard information (@pxref{Key Sequence -Input}). In particular, it does not convert letters to lower case and -it does not change drag events to clicks. - -Like the normal command loop, @code{keymap-lookup} will remap the -command resulting from looking up @var{key} by looking up the command -in the current keymaps. However, if the optional third argument -@var{no-remap} is non-@code{nil}, @code{keymap-lookup} returns the -command without remapping. - -If the optional argument @var{position} is non-@code{nil}, it -specifies a mouse position as returned by @code{event-start} and -@code{event-end}, and the lookup occurs in the keymaps associated with -that position, instead of in @var{keymap}. @var{position} can also be -a number or a marker, in which case it is interpreted as a buffer -position, and the function uses the keymap properties at that position -instead of at point. -@end defun - -@deffn Command undefined -Used in keymaps to undefine keys. It calls @code{ding}, but does -not cause an error. -@end deffn - -@defun keymap-local-lookup key &optional accept-defaults -This function returns the binding for @var{key} in the current -local keymap, or @code{nil} if it is undefined there. - -The argument @var{accept-defaults} controls checking for default bindings, -as in @code{keymap-lookup} (above). -@end defun - -@defun keymap-global-lookup key &optional accept-defaults -This function returns the binding for command @var{key} in the -current global keymap, or @code{nil} if it is undefined there. - -The argument @var{accept-defaults} controls checking for default bindings, -as in @code{keymap-lookup} (above). -@end defun - -@defun minor-mode-key-binding key &optional accept-defaults -This function returns a list of all the active minor mode bindings of -@var{key}. More precisely, it returns an alist of pairs -@code{(@var{modename} . @var{binding})}, where @var{modename} is the -variable that enables the minor mode, and @var{binding} is @var{key}'s -binding in that mode. If @var{key} has no minor-mode bindings, the -value is @code{nil}. - -If the first binding found is not a prefix definition (a keymap or a -symbol defined as a keymap), all subsequent bindings from other minor -modes are omitted, since they would be completely shadowed. Similarly, -the list omits non-prefix bindings that follow prefix bindings. - -The argument @var{accept-defaults} controls checking for default -bindings, as in @code{keymap-lookup} (above). -@end defun - -@defopt meta-prefix-char -@cindex @key{ESC} -This variable is the meta-prefix character code. It is used for -translating a meta character to a two-character sequence so it can be -looked up in a keymap. For useful results, the value should be a -prefix event (@pxref{Prefix Keys}). The default value is 27, which is -the @acronym{ASCII} code for @key{ESC}. - -As long as the value of @code{meta-prefix-char} remains 27, key lookup -translates @kbd{M-b} into @kbd{@key{ESC} b}, which is normally defined -as the @code{backward-word} command. However, if you were to set -@code{meta-prefix-char} to 24, the code for @kbd{C-x}, then Emacs will -translate @kbd{M-b} into @kbd{C-x b}, whose standard binding is the -@code{switch-to-buffer} command. (Don't actually do this!) Here is an -illustration of what would happen: - -@smallexample -@group -meta-prefix-char ; @r{The default value.} - @result{} 27 -@end group -@group -(key-binding "\M-b") - @result{} backward-word -@end group -@group -?\C-x ; @r{The print representation} - @result{} 24 ; @r{of a character.} -@end group -@group -(setq meta-prefix-char 24) - @result{} 24 -@end group -@group -(key-binding "\M-b") - @result{} switch-to-buffer ; @r{Now, typing @kbd{M-b} is} - ; @r{like typing @kbd{C-x b}.} - -(setq meta-prefix-char 27) ; @r{Avoid confusion!} - @result{} 27 ; @r{Restore the default value!} -@end group -@end smallexample - -This translation of one event into two happens only for characters, not -for other kinds of input events. Thus, @kbd{M-@key{F1}}, a function -key, is not converted into @kbd{@key{ESC} @key{F1}}. -@end defopt - -@node Changing Key Bindings -@section Changing Key Bindings -@cindex changing key bindings -@cindex rebinding - - The way to rebind a key is to change its entry in a keymap. If you -change a binding in the global keymap, the change is effective in all -buffers (though it has no direct effect in buffers that shadow the -global binding with a local one). If you change the current buffer's -local map, that usually affects all buffers using the same major mode. -The @code{keymap-global-set} and @code{keymap-local-set} functions are -convenient interfaces for these operations (@pxref{Key Binding -Commands}). You can also use @code{keymap-set}, a more general -function; then you must explicitly specify the map to change. - - When choosing the key sequences for Lisp programs to rebind, please -follow the Emacs conventions for use of various keys (@pxref{Key -Binding Conventions}). - - The functions below signal an error if @var{keymap} is not a keymap, -or if @var{key} is not a valid key. - -@var{key} is a string representing a single key or a series of key -strokes, and must satisfy @code{key-valid-p}. Key strokes are -separated by a single space character. - -Each key stroke is either a single character, or the name of an -event, surrounded by angle brackets. In addition, any key stroke -may be preceded by one or more modifier keys. Finally, a limited -number of characters have a special shorthand syntax. Here's some -example key sequences: - -@table @kbd -@item f -The key @kbd{f}. - -@item S o m -A three key sequence of the keys @kbd{S}, @kbd{o} and @kbd{m}. - -@item C-c o -A two key sequence of the keys @kbd{c} with the control modifier and -then the key @kbd{o} - -@item H- -The key named @kbd{left} with the hyper modifier. - -@item M-RET -The @kbd{return} key with a meta modifier. - -@item C-M- -The @kbd{space} key with both the control and meta modifiers. -@end table - -The only keys that have a special shorthand syntax are @kbd{NUL}, -@kbd{RET}, @kbd{TAB}, @kbd{LFD}, @kbd{ESC}, @kbd{SPC} and @kbd{DEL}. - -The modifiers have to be specified in alphabetical order: -@samp{A-C-H-M-S-s}, which is @samp{Alt-Control-Hyper-Meta-Shift-super}. - -@findex keymap-set -@defun keymap-set keymap key binding -This function sets the binding for @var{key} in @var{keymap}. (If -@var{key} is more than one event long, the change is actually made -in another keymap reached from @var{keymap}.) The argument -@var{binding} can be any Lisp object, but only certain types are -meaningful. (For a list of meaningful types, see @ref{Key Lookup}.) -The value returned by @code{keymap-set} is @var{binding}. - -If @var{key} is @kbd{}, this sets the default binding in -@var{keymap}. When an event has no binding of its own, the Emacs -command loop uses the keymap's default binding, if there is one. - -@cindex invalid prefix key error -@cindex key sequence error -Every prefix of @var{key} must be a prefix key (i.e., bound to a keymap) -or undefined; otherwise an error is signaled. If some prefix of -@var{key} is undefined, then @code{keymap-set} defines it as a prefix -key so that the rest of @var{key} can be defined as specified. - -If there was previously no binding for @var{key} in @var{keymap}, the -new binding is added at the beginning of @var{keymap}. The order of -bindings in a keymap makes no difference for keyboard input, but it -does matter for menu keymaps (@pxref{Menu Keymaps}). -@end defun - -@findex keymap-unset -@defun keymap-unset keymap key &optional remove -This function is the inverse of @code{keymap-set}, it unsets the -binding for @var{key} in @var{keymap}, which is the same as setting -the binding to @code{nil}. In order to instead remove the binding -completely, specify @var{remove} as non-@code{nil}. This only makes a -difference if @var{keymap} has a parent keymap: if you just unset a key -in a child map, it will still shadow the same key in the parent -keymap; using @var{remove} instead will allow the key in the parent keymap -to be used. -@end defun - -Note: using @code{keymap-unset} with @var{remove} non-@code{nil} is -intended for users to put in their init file; Emacs packages should -avoid using it if possible, since they have complete control over -their own keymaps anyway, and they should not be altering other -packages' keymaps. - - This example creates a sparse keymap and makes a number of -bindings in it: +This function returns the definition of @var{key} in @var{keymap}. All +the other functions described in this chapter that look up keys use +@code{keymap-lookup}. Here are examples: -@smallexample -@group -(setq map (make-sparse-keymap)) - @result{} (keymap) -@end group +@example @group -(keymap-set map "C-f" 'forward-char) - @result{} forward-char +(keymap-lookup (current-global-map) "C-x C-f") + @result{} find-file @end group @group -map - @result{} (keymap (6 . forward-char)) +(keymap-lookup (current-global-map) "C-x C-f 1 2 3 4 5") + @result{} 2 @end group +@end example + +If the string or vector @var{key} is not a valid key sequence according +to the prefix keys specified in @var{keymap}, it must be too long +and have extra events at the end that do not fit into a single key +sequence. Then the value is a number, the number of events at the front +of @var{key} that compose a complete key. + +If @var{accept-defaults} is non-@code{nil}, then @code{keymap-lookup} +considers default bindings as well as bindings for the specific events +in @var{key}. Otherwise, @code{keymap-lookup} reports only bindings for +the specific sequence @var{key}, ignoring default bindings except when +you explicitly ask about them. (To do this, supply @code{t} as an +element of @var{key}; see @ref{Format of Keymaps}.) + +If @var{key} contains a meta character (not a function key), that +character is implicitly replaced by a two-character sequence: the value +of @code{meta-prefix-char}, followed by the corresponding non-meta +character. Thus, the first example below is handled by conversion into +the second example. +@example @group -;; @r{Build sparse submap for @kbd{C-x} and bind @kbd{f} in that.} -(keymap-set map "C-x f" 'forward-word) +(keymap-lookup (current-global-map) "M-f") @result{} forward-word @end group @group -map -@result{} (keymap - (24 keymap ; @kbd{C-x} - (102 . forward-word)) ; @kbd{f} - (6 . forward-char)) ; @kbd{C-f} +(keymap-lookup (current-global-map) "ESC f") + @result{} forward-word @end group +@end example -@group -;; @r{Bind @kbd{C-p} to the @code{ctl-x-map}.} -(keymap-set map "C-p" ctl-x-map) -;; @code{ctl-x-map} -@result{} [nil @dots{} find-file @dots{} backward-kill-sentence] -@end group +The @var{keymap} argument can be @code{nil}, meaning to look up +@var{key} in the current keymaps (as returned by +@code{current-active-maps}, @pxref{Active Keymaps}); or it can be a +keymap or a list of keymaps, meaning to look up @var{key} only in the +specified keymaps. -@group -;; @r{Bind @kbd{C-f} to @code{foo} in the @code{ctl-x-map}.} -(keymap-set map "C-p C-f" 'foo) -@result{} 'foo -@end group -@group -map -@result{} (keymap ; @r{Note @code{foo} in @code{ctl-x-map}.} - (16 keymap [nil @dots{} foo @dots{} backward-kill-sentence]) - (24 keymap - (102 . forward-word)) - (6 . forward-char)) -@end group -@end smallexample +Unlike @code{read-key-sequence}, this function does not modify the +specified events in ways that discard information (@pxref{Key Sequence +Input}). In particular, it does not convert letters to lower case and +it does not change drag events to clicks. -@noindent -Note that storing a new binding for @kbd{C-p C-f} actually works by -changing an entry in @code{ctl-x-map}, and this has the effect of -changing the bindings of both @kbd{C-p C-f} and @kbd{C-x C-f} in the -default global map. +Like the normal command loop, @code{keymap-lookup} will remap the +command resulting from looking up @var{key} by looking up the command +in the current keymaps. However, if the optional third argument +@var{no-remap} is non-@code{nil}, @code{keymap-lookup} returns the +command without remapping. -@code{keymap-set} is the general work horse for defining a key in a -keymap. When writing modes, however, you frequently have to bind a -large number of keys at once, and using @code{keymap-set} on them all -can be tedious and error-prone. Instead you can use -@code{define-keymap}, which creates a keymap and binds a number of -keys. @xref{Creating Keymaps}, for details. +If the optional argument @var{position} is non-@code{nil}, it +specifies a mouse position as returned by @code{event-start} and +@code{event-end}, and the lookup occurs in the keymaps associated with +that position, instead of in @var{keymap}. @var{position} can also be +a number or a marker, in which case it is interpreted as a buffer +position, and the function uses the keymap properties at that position +instead of at point. +@end defun -The function @code{substitute-key-definition} scans a keymap for -keys that have a certain binding and rebinds them with a different -binding. Another feature which is cleaner and can often produce the -same results is to remap one command into another (@pxref{Remapping -Commands}). +@deffn Command undefined +Used in keymaps to undefine keys. It calls @code{ding}, but does +not cause an error. +@end deffn -@defun substitute-key-definition olddef newdef keymap &optional oldmap -@cindex replace bindings -This function replaces @var{olddef} with @var{newdef} for any keys in -@var{keymap} that were bound to @var{olddef}. In other words, -@var{olddef} is replaced with @var{newdef} wherever it appears. The -function returns @code{nil}. +@defun keymap-local-lookup key &optional accept-defaults +This function returns the binding for @var{key} in the current +local keymap, or @code{nil} if it is undefined there. -For example, this redefines @kbd{C-x C-f}, if you do it in an Emacs with -standard bindings: +The argument @var{accept-defaults} controls checking for default bindings, +as in @code{keymap-lookup} (above). +@end defun -@smallexample -@group -(substitute-key-definition - 'find-file 'find-file-read-only (current-global-map)) -@end group -@end smallexample +@defun keymap-global-lookup key &optional accept-defaults +This function returns the binding for command @var{key} in the +current global keymap, or @code{nil} if it is undefined there. -If @var{oldmap} is non-@code{nil}, that changes the behavior of -@code{substitute-key-definition}: the bindings in @var{oldmap} determine -which keys to rebind. The rebindings still happen in @var{keymap}, not -in @var{oldmap}. Thus, you can change one map under the control of the -bindings in another. For example, +The argument @var{accept-defaults} controls checking for default bindings, +as in @code{keymap-lookup} (above). +@end defun -@smallexample -(substitute-key-definition - 'delete-backward-char 'my-funny-delete - my-map global-map) -@end smallexample +@defun minor-mode-key-binding key &optional accept-defaults +This function returns a list of all the active minor mode bindings of +@var{key}. More precisely, it returns an alist of pairs +@code{(@var{modename} . @var{binding})}, where @var{modename} is the +variable that enables the minor mode, and @var{binding} is @var{key}'s +binding in that mode. If @var{key} has no minor-mode bindings, the +value is @code{nil}. -@noindent -puts the special deletion command in @code{my-map} for whichever keys -are globally bound to the standard deletion command. +If the first binding found is not a prefix definition (a keymap or a +symbol defined as a keymap), all subsequent bindings from other minor +modes are omitted, since they would be completely shadowed. Similarly, +the list omits non-prefix bindings that follow prefix bindings. -Here is an example showing a keymap before and after substitution: +The argument @var{accept-defaults} controls checking for default +bindings, as in @code{keymap-lookup} (above). +@end defun + +@defopt meta-prefix-char +@cindex @key{ESC} +This variable is the meta-prefix character code. It is used for +translating a meta character to a two-character sequence so it can be +looked up in a keymap. For useful results, the value should be a +prefix event (@pxref{Prefix Keys}). The default value is 27, which is +the @acronym{ASCII} code for @key{ESC}. + +As long as the value of @code{meta-prefix-char} remains 27, key lookup +translates @kbd{M-b} into @kbd{@key{ESC} b}, which is normally defined +as the @code{backward-word} command. However, if you were to set +@code{meta-prefix-char} to 24, the code for @kbd{C-x}, then Emacs will +translate @kbd{M-b} into @kbd{C-x b}, whose standard binding is the +@code{switch-to-buffer} command. (Don't actually do this!) Here is an +illustration of what would happen: @smallexample @group -(setq map (list 'keymap - (cons ?1 olddef-1) - (cons ?2 olddef-2) - (cons ?3 olddef-1))) -@result{} (keymap (49 . olddef-1) (50 . olddef-2) (51 . olddef-1)) +meta-prefix-char ; @r{The default value.} + @result{} 27 @end group - @group -(substitute-key-definition 'olddef-1 'newdef map) -@result{} nil +(key-binding "\M-b") + @result{} backward-word @end group @group -map -@result{} (keymap (49 . newdef) (50 . olddef-2) (51 . newdef)) +?\C-x ; @r{The print representation} + @result{} 24 ; @r{of a character.} @end group -@end smallexample -@end defun - -@defun suppress-keymap keymap &optional nodigits -@cindex @code{self-insert-command} override -This function changes the contents of the full keymap @var{keymap} by -remapping @code{self-insert-command} to the command @code{undefined} -(@pxref{Remapping Commands}). This has the effect of undefining all -printing characters, thus making ordinary insertion of text impossible. -@code{suppress-keymap} returns @code{nil}. - -If @var{nodigits} is @code{nil}, then @code{suppress-keymap} defines -digits to run @code{digit-argument}, and @kbd{-} to run -@code{negative-argument}. Otherwise it makes them undefined like the -rest of the printing characters. - -@cindex yank suppression -@cindex @code{quoted-insert} suppression -The @code{suppress-keymap} function does not make it impossible to -modify a buffer, as it does not suppress commands such as @code{yank} -and @code{quoted-insert}. To prevent any modification of a buffer, make -it read-only (@pxref{Read Only Buffers}). - -Since this function modifies @var{keymap}, you would normally use it -on a newly created keymap. Operating on an existing keymap -that is used for some other purpose is likely to cause trouble; for -example, suppressing @code{global-map} would make it impossible to use -most of Emacs. - -This function can be used to initialize the local keymap of a major -mode for which insertion of text is not desirable. But usually such a -mode should be derived from @code{special-mode} (@pxref{Basic Major -Modes}); then its keymap will automatically inherit from -@code{special-mode-map}, which is already suppressed. Here is how -@code{special-mode-map} is defined: - -@smallexample @group -(defvar special-mode-map - (let ((map (make-sparse-keymap))) - (suppress-keymap map) - (keymap-set map "q" 'quit-window) - @dots{} - map)) +(setq meta-prefix-char 24) + @result{} 24 +@end group +@group +(key-binding "\M-b") + @result{} switch-to-buffer ; @r{Now, typing @kbd{M-b} is} + ; @r{like typing @kbd{C-x b}.} + +(setq meta-prefix-char 27) ; @r{Avoid confusion!} + @result{} 27 ; @r{Restore the default value!} @end group @end smallexample -@end defun + +This translation of one event into two happens only for characters, not +for other kinds of input events. Thus, @kbd{M-@key{F1}}, a function +key, is not converted into @kbd{@key{ESC} @key{F1}}. +@end defopt @node Key Sequences @section Key Sequences commit 7ec6531c7bd99ff13e73b9cc2f00d49d2472565f Author: Stefan Kangas Date: Sat Mar 1 06:28:17 2025 +0100 keymaps.texi: Move "Key Sequences" section down * doc/lispref/keymaps.texi (Key Sequences): Move section down. (Bug#52821) diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index 56bfb550974..ac63f296958 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -14,7 +14,6 @@ used to look up the next input event; this continues until a command is found. The whole process is called @dfn{key lookup}. @menu -* Key Sequences:: Key sequences as Lisp objects. * Keymap Basics:: Basic concepts of keymaps. * Format of Keymaps:: What a keymap looks like as a Lisp object. * Creating Keymaps:: Functions to create and copy keymaps. @@ -30,6 +29,7 @@ is found. The whole process is called @dfn{key lookup}. * Key Lookup:: Finding a key's binding in one keymap. * Functions for Key Lookup:: How to request key lookup. * Changing Key Bindings:: Redefining a key in a keymap. +* Key Sequences:: Key sequences as Lisp objects. * Low-Level Key Binding:: Legacy key syntax description. * Remapping Commands:: A keymap can translate one command to another. * Translation Keymaps:: Keymaps for translating sequences of events. @@ -38,72 +38,6 @@ is found. The whole process is called @dfn{key lookup}. * Menu Keymaps:: Defining a menu as a keymap. @end menu -@node Key Sequences -@section Key Sequences -@cindex key -@cindex keystroke -@cindex key sequence - - A @dfn{key sequence}, or @dfn{key} for short, is a sequence of one -or more input events that form a unit. Input events include -characters, function keys, mouse actions, or system events external to -Emacs, such as @code{iconify-frame} (@pxref{Input Events}). -The Emacs Lisp representation for a key sequence is a string or -vector. Unless otherwise stated, any Emacs Lisp function that accepts -a key sequence as an argument can handle both representations. - - In the string representation, alphanumeric characters ordinarily -stand for themselves; for example, @code{"a"} represents @kbd{a} -and @code{"2"} represents @kbd{2}. Control character events are -prefixed by the substring @code{"\C-"}, and meta characters by -@code{"\M-"}; for example, @code{"\C-x"} represents the key @kbd{C-x}. -In addition, the @key{TAB}, @key{RET}, @key{ESC}, and @key{DEL} events -are represented by @code{"\t"}, @code{"\r"}, @code{"\e"}, and -@code{"\d"} respectively. The string representation of a complete key -sequence is the concatenation of the string representations of the -constituent events; thus, @code{"\C-xl"} represents the key sequence -@kbd{C-x l}. - - Key sequences containing function keys, mouse button events, system -events, or non-@acronym{ASCII} characters such as @kbd{C-=} or -@kbd{H-a} cannot be represented as strings; they have to be -represented as vectors. - - In the vector representation, each element of the vector represents -an input event, in its Lisp form. @xref{Input Events}. For example, -the vector @code{[?\C-x ?l]} represents the key sequence @kbd{C-x l}. - - For examples of key sequences written in string and vector -representations, @ref{Init Rebinding,,, emacs, The GNU Emacs Manual}. - -@defun kbd keyseq-text -This function converts the text @var{keyseq-text} (a string constant) -into a key sequence (a string or vector constant). The contents of -@var{keyseq-text} should use the same syntax as in the buffer invoked -by the @kbd{C-x C-k @key{RET}} (@code{kmacro-edit-macro}) command; in -particular, you must surround function key names with -@samp{<@dots{}>}. @xref{Edit Keyboard Macro,,, emacs, The GNU Emacs -Manual}. - -@example -(kbd "C-x") @result{} "\C-x" -(kbd "C-x C-f") @result{} "\C-x\C-f" -(kbd "C-x 4 C-f") @result{} "\C-x4\C-f" -(kbd "X") @result{} "X" -(kbd "RET") @result{} "^M" -(kbd "C-c SPC") @result{} "\C-c@ " -(kbd " SPC") @result{} [f1 32] -(kbd "C-M-") @result{} [C-M-down] -@end example - -@findex key-valid-p -The @code{kbd} function is very permissive, and will try to return -something sensible even if the syntax used isn't completely -conforming. To check whether the syntax is actually valid, use the -@code{key-valid-p} function. -@end defun - - @node Keymap Basics @section Keymap Basics @cindex key binding @@ -1697,6 +1631,71 @@ Modes}); then its keymap will automatically inherit from @end smallexample @end defun +@node Key Sequences +@section Key Sequences +@cindex key +@cindex keystroke +@cindex key sequence + + A @dfn{key sequence}, or @dfn{key} for short, is a sequence of one +or more input events that form a unit. Input events include +characters, function keys, mouse actions, or system events external to +Emacs, such as @code{iconify-frame} (@pxref{Input Events}). +The Emacs Lisp representation for a key sequence is a string or +vector. Unless otherwise stated, any Emacs Lisp function that accepts +a key sequence as an argument can handle both representations. + + In the string representation, alphanumeric characters ordinarily +stand for themselves; for example, @code{"a"} represents @kbd{a} +and @code{"2"} represents @kbd{2}. Control character events are +prefixed by the substring @code{"\C-"}, and meta characters by +@code{"\M-"}; for example, @code{"\C-x"} represents the key @kbd{C-x}. +In addition, the @key{TAB}, @key{RET}, @key{ESC}, and @key{DEL} events +are represented by @code{"\t"}, @code{"\r"}, @code{"\e"}, and +@code{"\d"} respectively. The string representation of a complete key +sequence is the concatenation of the string representations of the +constituent events; thus, @code{"\C-xl"} represents the key sequence +@kbd{C-x l}. + + Key sequences containing function keys, mouse button events, system +events, or non-@acronym{ASCII} characters such as @kbd{C-=} or +@kbd{H-a} cannot be represented as strings; they have to be +represented as vectors. + + In the vector representation, each element of the vector represents +an input event, in its Lisp form. @xref{Input Events}. For example, +the vector @code{[?\C-x ?l]} represents the key sequence @kbd{C-x l}. + + For examples of key sequences written in string and vector +representations, @ref{Init Rebinding,,, emacs, The GNU Emacs Manual}. + +@defun kbd keyseq-text +This function converts the text @var{keyseq-text} (a string constant) +into a key sequence (a string or vector constant). The contents of +@var{keyseq-text} should use the same syntax as in the buffer invoked +by the @kbd{C-x C-k @key{RET}} (@code{kmacro-edit-macro}) command; in +particular, you must surround function key names with +@samp{<@dots{}>}. @xref{Edit Keyboard Macro,,, emacs, The GNU Emacs +Manual}. + +@example +(kbd "C-x") @result{} "\C-x" +(kbd "C-x C-f") @result{} "\C-x\C-f" +(kbd "C-x 4 C-f") @result{} "\C-x4\C-f" +(kbd "X") @result{} "X" +(kbd "RET") @result{} "^M" +(kbd "C-c SPC") @result{} "\C-c@ " +(kbd " SPC") @result{} [f1 32] +(kbd "C-M-") @result{} [C-M-down] +@end example + +@findex key-valid-p +The @code{kbd} function is very permissive, and will try to return +something sensible even if the syntax used isn't completely +conforming. To check whether the syntax is actually valid, use the +@code{key-valid-p} function. +@end defun + @node Low-Level Key Binding @section Low-Level Key Binding @cindex low-level key bindings commit 8b804011275f9f7b5dda1f03e1d6118cae2846c5 Author: Stefan Kangas Date: Sat Mar 1 02:01:30 2025 +0100 Improve process-get/process-put docstrings * lisp/subr.el (process-get, process-put): Explain the purpose of these functions in the docstring. diff --git a/lisp/subr.el b/lisp/subr.el index dfd91825363..37a3f9efe6b 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3263,13 +3263,19 @@ process." (defun process-get (process propname) "Return the value of PROCESS' PROPNAME property. -This is the last value stored with `(process-put PROCESS PROPNAME VALUE)'." +This is the last value stored with `(process-put PROCESS PROPNAME VALUE)'. + +Together with `process-put', this can be used to store and retrieve +miscellaneous values associated with the process." (declare (side-effect-free t)) (plist-get (process-plist process) propname)) (defun process-put (process propname value) "Change PROCESS' PROPNAME property to VALUE. -It can be retrieved with `(process-get PROCESS PROPNAME)'." +It can be retrieved with `(process-get PROCESS PROPNAME)'. + +Together with `process-get', this can be used to store and retrieve +miscellaneous values associated with the process." (set-process-plist process (plist-put (process-plist process) propname value))) commit 73c646b7771bc81e622933443b5b336d40f8d8c2 Merge: 0af5c574998 c8cec840d79 Author: Michael Albinus Date: Fri Feb 28 18:04:35 2025 +0100 Merge branch 'emacs-30' of git.sv.gnu.org:/srv/git/emacs into emacs-30 commit 0af5c5749988180c6a2f7c50b7e1c8163b4c5bf1 Author: Michael Albinus Date: Fri Feb 28 18:03:54 2025 +0100 Fix recent change in diff-no-select * lisp/vc/diff.el (diff-no-select): Keep initial default directory in *Diff* buffer. diff --git a/lisp/vc/diff.el b/lisp/vc/diff.el index 555ad80d1dd..fa12f1677eb 100644 --- a/lisp/vc/diff.el +++ b/lisp/vc/diff.el @@ -187,7 +187,8 @@ returns the buffer used." (prin1-to-string new)))) (list (or old-alt old) (or new-alt new))))) - " "))) + " ")) + (thisdir default-directory)) (with-current-buffer buf (setq buffer-read-only t) (buffer-disable-undo (current-buffer)) @@ -198,14 +199,15 @@ returns the buffer used." (setq-local revert-buffer-function (lambda (_ignore-auto _noconfirm) (diff-no-select old new switches no-async (current-buffer)))) - (setq default-directory temporary-file-directory) + (setq default-directory thisdir) (setq diff-default-directory default-directory) (let ((inhibit-read-only t)) (insert command "\n")) (with-file-modes #o600 (if (and (not no-async) (fboundp 'make-process)) - (let ((proc (start-process "Diff" buf shell-file-name - shell-command-switch command))) + (let* ((default-directory temporary-file-directory) + (proc (start-process "Diff" buf shell-file-name + shell-command-switch command))) (set-process-filter proc #'diff-process-filter) (set-process-sentinel proc (lambda (proc _msg) @@ -213,7 +215,8 @@ returns the buffer used." (diff-sentinel (process-exit-status proc) old-alt new-alt))))) ;; Async processes aren't available. - (let ((inhibit-read-only t)) + (let* ((default-directory temporary-file-directory) + (inhibit-read-only t)) (diff-sentinel (call-process shell-file-name nil buf nil shell-command-switch command) commit c8cec840d7972d5cca0c255a19fd521703c7628c Author: Po Lu Date: Fri Feb 28 22:36:08 2025 +0800 Prevent rare freeze on Android 4.2 through 4.4 * src/android.c (android_run_select_thread, android_init_events) (android_select): Enable self-pipes on all Android versions <= 21. The Android C library provides a functioning pselect on these systems, but it does not apply the signal mask atomically. (android_run_select_thread): Correct typo. This never produced any adverse consequences, as the relevant signals would already have been blocked by `setupSystemThread'. Do not merge to master. diff --git a/src/android.c b/src/android.c index c20730460be..bcd48e300ff 100644 --- a/src/android.c +++ b/src/android.c @@ -304,7 +304,7 @@ static struct android_event_queue event_queue; /* Semaphores used to signal select completion and start. */ static sem_t android_pselect_sem, android_pselect_start_sem; -#if __ANDROID_API__ < 16 +#if __ANDROID_API__ < 21 /* Select self-pipe. */ static int select_pipe[2]; @@ -363,7 +363,7 @@ android_run_select_thread (void *data) JNI_STACK_ALIGNMENT_PROLOGUE; int rc; -#if __ANDROID_API__ < 16 +#if __ANDROID_API__ < 21 int nfds; fd_set readfds; char byte; @@ -375,7 +375,7 @@ android_run_select_thread (void *data) /* Set the name of this thread's LWP for debugging purposes. */ android_set_task_name ("`android_select'"); -#if __ANDROID_API__ < 16 +#if __ANDROID_API__ < 21 /* A completely different implementation is used when building for Android versions earlier than 16, because pselect with a signal mask does not work there. Instead of blocking SIGUSR1 and @@ -451,12 +451,12 @@ android_run_select_thread (void *data) sem_post (&android_pselect_sem); } #else + sigfillset (&signals); if (pthread_sigmask (SIG_BLOCK, &signals, NULL)) __android_log_print (ANDROID_LOG_FATAL, __func__, "pthread_sigmask: %s", strerror (errno)); - sigfillset (&signals); sigdelset (&signals, SIGUSR1); sigemptyset (&waitset); sigaddset (&waitset, SIGUSR1); @@ -514,7 +514,7 @@ android_run_select_thread (void *data) return NULL; } -#if __ANDROID_API__ >= 16 +#if __ANDROID_API__ >= 21 static void android_handle_sigusr1 (int sig, siginfo_t *siginfo, void *arg) @@ -569,7 +569,7 @@ android_init_events (void) main_thread_id = pthread_self (); -#if __ANDROID_API__ >= 16 +#if __ANDROID_API__ >= 21 /* Before starting the select thread, make sure the disposition for SIGUSR1 is correct. */ @@ -762,7 +762,7 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timespec *timeout) { int nfds_return; -#if __ANDROID_API__ < 16 +#if __ANDROID_API__ < 21 static char byte; #endif @@ -818,7 +818,7 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds, /* Start waiting for the event queue condition to be set. */ pthread_cond_wait (&event_queue.read_var, &event_queue.mutex); -#if __ANDROID_API__ >= 16 +#if __ANDROID_API__ >= 21 /* Interrupt the select thread now, in case it's still in pselect. */ pthread_kill (event_queue.select_thread, SIGUSR1); commit 5247da2e3cd2705278bb68e0c5313a6972a6d43c Author: Michael Albinus Date: Fri Feb 28 15:32:35 2025 +0100 * lisp/proced.el (proced-<): Check, that NUM1 and NUM2 are numbers. (Bug#76549) diff --git a/lisp/proced.el b/lisp/proced.el index 51fc39328b7..a60f70c949e 100644 --- a/lisp/proced.el +++ b/lisp/proced.el @@ -1423,10 +1423,12 @@ a certain refinement, consider defining a new filter in `proced-filter-alist'." (defun proced-< (num1 num2) "Return t if NUM1 less than NUM2. -Return `equal' if NUM1 equals NUM2. Return nil if NUM1 greater than NUM2." - (if (= num1 num2) - 'equal - (< num1 num2))) +Return `equal' if NUM1 equals NUM2. Return nil if NUM1 greater than NUM2. +If either NUM1 or NUM2 is not a number, return nil." + (when (and (numberp num1) (numberp num2)) + (if (= num1 num2) + 'equal + (< num1 num2)))) (defun proced-string-lessp (s1 s2) "Return t if string S1 is less than S2 in lexicographic order. commit 0d89aa6b6c11cb97a0df78dd31b8fa12b7710f82 Author: Eli Zaretskii Date: Sun Jan 12 08:24:39 2025 +0200 ; * src/keymap.c: Fix last change (bug#75219). (cherry picked from commit 412c1a4f0e1df8c82bd94f02e21c1ef62b3d53d5) diff --git a/src/keymap.c b/src/keymap.c index 634c4e33bbd..6b266bb5736 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -1740,7 +1740,6 @@ like in the respective argument of `key-binding'. */) if (CONSP (string) && STRINGP (XCAR (string))) { Lisp_Object pos = XCDR (string); - Lisp_Object pos_area = POSN_POSN (position); string = XCAR (string); if (FIXNUMP (pos) && XFIXNUM (pos) >= 0 @@ -1748,6 +1747,7 @@ like in the respective argument of `key-binding'. */) { Lisp_Object map = Fget_text_property (pos, Qlocal_map, string); + Lisp_Object pos_area = POSN_POSN (position); /* For clicks on mode line or header line, override the maps we found at POSITION unconditionally, even if the corresponding properties of the mode- or commit b3181a807124d5c6226fdcf1e42bf4b6fcdc4ad2 Author: Eli Zaretskii Date: Sun Jan 12 08:22:24 2025 +0200 Fix mouse-2 clicks on mode line and header line * src/keymap.c (Fcurrent_active_maps): For clicks on mode-line and header-line, always override the keymaps at buffer position. (Bug#75219) (cherry picked from commit c41ea047a434710c4b7bc8280695c83fbe5fff35) diff --git a/src/keymap.c b/src/keymap.c index 720eb5c32a4..634c4e33bbd 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -1740,17 +1740,27 @@ like in the respective argument of `key-binding'. */) if (CONSP (string) && STRINGP (XCAR (string))) { Lisp_Object pos = XCDR (string); + Lisp_Object pos_area = POSN_POSN (position); string = XCAR (string); if (FIXNUMP (pos) && XFIXNUM (pos) >= 0 && XFIXNUM (pos) < SCHARS (string)) { - Lisp_Object map = Fget_text_property (pos, Qlocal_map, string); - if (!NILP (map)) + Lisp_Object map = Fget_text_property (pos, Qlocal_map, + string); + /* For clicks on mode line or header line, override + the maps we found at POSITION unconditionally, even + if the corresponding properties of the mode- or + header-line string are nil, because propertries at + point are not relevant in that case. */ + if (!NILP (map) + || EQ (pos_area, Qmode_line) + || EQ (pos_area, Qheader_line)) local_map = map; - map = Fget_text_property (pos, Qkeymap, string); - if (!NILP (map)) + if (!NILP (map) + || EQ (pos_area, Qmode_line) + || EQ (pos_area, Qheader_line)) keymap = map; } } commit 6f5c322f5974786290b1b3e68b5a0685ddec3410 Author: Stefan Kangas Date: Fri Feb 28 05:21:48 2025 +0100 Recommend secure-hash in md5 docstring * src/fns.c (Fmd5): Repeat explanation from manual about md5 being "semi-obsolete", and recommend using secure-hash instead. diff --git a/src/fns.c b/src/fns.c index a37c651c793..8444a9edb00 100644 --- a/src/fns.c +++ b/src/fns.c @@ -6385,6 +6385,11 @@ command `prefer-coding-system') is used. If NOERROR is non-nil, silently assume the `raw-text' coding if the guesswork fails. Normally, an error is signaled in such case. +This function is semi-obsolete, since for most purposes it is equivalent +to calling `secure-hash` with the symbol `md5' as the ALGORITHM +argument. The OBJECT, START and END arguments have the same meanings as +in `secure-hash'. + Note that MD5 is not collision resistant and should not be used for anything security-related. See `secure-hash' for alternatives. */) (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror) commit 1352b184f3f7bd1e31ee71ee4b60491dacaf347b Author: Tomas Nordin Date: Thu Feb 27 22:06:25 2025 +0100 Improve docstring of add-hook and remove-hook * lisp/subr.el (add-hook, remove-hook): Remove detail about setting to nil and talk about functions instead of hooks. (Bug#72915) diff --git a/lisp/subr.el b/lisp/subr.el index 0394a333b44..dfd91825363 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2090,6 +2090,9 @@ instead; it will indirectly limit the specpdl stack size as well.") "Add to the value of HOOK the function FUNCTION. FUNCTION is not added if already present. +HOOK should be a symbol. If HOOK is void, or if HOOK's value is a +single function, it is changed to a list of functions. + The place where the function is added depends on the DEPTH parameter. DEPTH defaults to 0. By convention, it should be a number between -100 and 100 where 100 means that the function @@ -2108,10 +2111,6 @@ This makes the hook buffer-local, and it makes t a member of the buffer-local value. That acts as a flag to run the hook functions of the global value as well as in the local value. -HOOK should be a symbol. If HOOK is void, it is first set to -nil. If HOOK's value is a single function, it is changed to a -list of functions. - FUNCTION may be any valid function, but it's recommended to use a function symbol and not a lambda form. Using a symbol will ensure that the function is not re-added if the function is @@ -2176,10 +2175,11 @@ performance impact when running `add-hook' and `remove-hook'." (set-default hook hook-value)))) (defun remove-hook (hook function &optional local) - "Remove from the value of HOOK the function FUNCTION. -HOOK should be a symbol, and FUNCTION may be any valid function. If -FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the -list of hooks to run in HOOK, then nothing is done. See `add-hook'. + "Remove FUNCTION from HOOK's functions. +HOOK should be a symbol, and FUNCTION may be any valid function. +Do nothing if HOOK does not currently contain FUNCTION. +Compare functions with `equal`, which means that it can be +slow if FUNCTION is not a symbol. See `add-hook'. The optional third argument, LOCAL, if non-nil, says to modify the hook's buffer-local value rather than its default value. commit dbae1fc69f82ff481d1591d60a0c44cad354c3b3 Author: Jared Finder Date: Wed Feb 19 09:41:44 2025 +0200 * lisp/subr.el (read-key): Add 'tab-line' (bug#76408). Backport: (cherry picked from commit 0c8abe8bb5072c46a93585cb325c249f85f3d9c2) diff --git a/lisp/subr.el b/lisp/subr.el index 7552378a781..0394a333b44 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3377,7 +3377,7 @@ only unbound fallback disabled is downcasing of the last event." nil nil t))) (key (aref keys 0))) (if (and (> (length keys) 1) - (memq key '(mode-line header-line + (memq key '(mode-line header-line tab-line left-fringe right-fringe))) (aref keys 1) key))) commit 62b3d3136fae8830d63f69143b09e99b5173c537 Author: Paul Eggert Date: Thu Feb 27 10:57:19 2025 -0800 Fix fns-tests-collate-strings failure with musl * test/src/fns-tests.el (fns-tests-collate-strings): Don’t assume "en_XY.UTF-8", or any particular string, is an invalid locale, as they all seem to be valid in musl. Instead, simply test that a non-string is invalid. (Bug#76550) diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el index 9e134c24e05..2ca67f14539 100644 --- a/test/src/fns-tests.el +++ b/test/src/fns-tests.el @@ -277,7 +277,7 @@ (should (string-collate-equalp "xyzzy" "XYZZY" nil t)) ;; Locale must be valid. - (should-error (string-collate-equalp "xyzzy" "xyzzy" "en_XY.UTF-8"))) + (should-error (string-collate-equalp "xyzzy" "xyzzy" 'not-a-locale))) ;; There must be a check for valid codepoints. (Check not implemented yet) ; (should-error commit 840c6824589c9a82deedc5112891d8014d134746 Author: Eshel Yaron Date: Thu Feb 27 15:34:24 2025 +0100 ; (completion-preview-complete): Fix bug#76606 * lisp/completion-preview.el (completion-preview-complete): Dismiss completion preview before calling ':exit-function'. This eliminates potential flicker with slow exit functions and avoids the broken preview update reported in bug#76606. diff --git a/lisp/completion-preview.el b/lisp/completion-preview.el index 4928d9a8824..505cf45f48d 100644 --- a/lisp/completion-preview.el +++ b/lisp/completion-preview.el @@ -520,6 +520,10 @@ completions list." ;; hook update the completion preview in case the candidate ;; can be completed further. (when (functionp efn) + ;; Remove stale preview since `efn' can make arbitrary + ;; text and point modifications that might interfere with + ;; a subsequent preview update. See bug#76606. + (completion-preview-active-mode -1) (funcall efn (concat base com) (if (cdr all) 'exact 'finished))) ;; Otherwise, remove the common prefix from the preview. (completion-preview--inhibit-update) commit fa42626a6a8d60c9ab313f39b64c12be32054442 Author: Stefan Kangas Date: Wed Feb 26 18:31:48 2025 +0100 ; Fix indentation in cl.texi example diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi index c210b711a98..91ebf2b3862 100644 --- a/doc/misc/cl.texi +++ b/doc/misc/cl.texi @@ -640,7 +640,7 @@ For example: @example (cl-defmacro dolist ((var listform &optional resultform) - &rest body) + &rest body) @dots{}) @end example commit 7ff806da496619f9109b2075c3ff5b803506d258 Author: Stefan Kangas Date: Wed Feb 26 17:49:56 2025 +0100 ; Fix my last commit diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index bde6b030335..79e32b5f43b 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -335,8 +335,8 @@ mouse-1: Enable lexical-binding mode" mouse-face mode-line-highlight local-map ,elisp--dynlex-modeline-map))) "Major mode for editing Lisp code to run in Emacs. - -- Delete converts tabs to spaces as it moves back. +\\ +- \\[backward-delete-char-untabify] converts tabs to spaces as it moves back. - Blank lines separate paragraphs. - Semicolons start comments. @@ -1330,8 +1330,8 @@ Like Lisp mode except that \\[eval-print-last-sexp] evals the Lisp expression before point, and prints its value into the buffer, advancing point. Note that printing is controlled by `eval-expression-print-length' and `eval-expression-print-level'. - -- Delete converts tabs to spaces as it moves back. +\\ +- \\[backward-delete-char-untabify] converts tabs to spaces as it moves back. - Paragraphs are separated only by blank lines. - Semicolons start comments. commit 706426f96698fb8e6aeaa1a21c2cac1f76f5851c Author: Eli Zaretskii Date: Sun Jan 5 07:56:27 2025 +0200 Fix setup of coding-systems on MS-Windows * src/emacs.c (main) [HAVE_PDUMPER] [WINDOWSNT]: Call 'w32_init_file_name_codepage' again after loading the pdumper file. * src/w32.c (w32_init_file_name_codepage) [HAVE_PDUMPER]: Reinitialize additional variables. (Bug#75207) (cherry picked from commit cc5cd4de93d1e5ba205cbf0c370aef4559bc342b) diff --git a/src/emacs.c b/src/emacs.c index 1e07b2c8638..1beb295c9b1 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1430,7 +1430,18 @@ main (int argc, char **argv) #ifdef HAVE_PDUMPER if (attempt_load_pdump) - initial_emacs_executable = load_pdump (argc, argv, dump_file); + { + initial_emacs_executable = load_pdump (argc, argv, dump_file); +#ifdef WINDOWSNT + /* Reinitialize the codepage for file names, needed to decode + non-ASCII file names during startup. This is needed because + loading the pdumper file above assigns to those variables values + from the dump stage, which might be incorrect, if dumping was done + on a different system. */ + if (dumped_with_pdumper_p ()) + w32_init_file_name_codepage (); +#endif + } #else ptrdiff_t bufsize; initial_emacs_executable = find_emacs_executable (argv[0], &bufsize); diff --git a/src/w32.c b/src/w32.c index 1135462ba8c..4107751951c 100644 --- a/src/w32.c +++ b/src/w32.c @@ -1685,6 +1685,19 @@ w32_init_file_name_codepage (void) { file_name_codepage = CP_ACP; w32_ansi_code_page = CP_ACP; +#ifdef HAVE_PDUMPER + /* If we were dumped with pdumper, this function will be called after + loading the pdumper file, and needs to reset the following + variables that come from the dump stage, which could be on a + different system with different default codepages. Then, the + correct value of w32-ansi-code-page will be assigned by + globals_of_w32fns, which is called from 'main'. Until that call + happens, w32-ansi-code-page will have the value of CP_ACP, which + stands for the default ANSI codepage. The other variables will be + computed by codepage_for_filenames below. */ + Vdefault_file_name_coding_system = Qnil; + Vfile_name_coding_system = Qnil; +#endif } /* Produce a Windows ANSI codepage suitable for encoding file names. commit f88dc0f2f9d28d0988cca54c5b9fc1ba85ce3d7e Author: Eli Zaretskii Date: Wed Feb 26 14:52:26 2025 +0200 ; Fix documentation of 'buffer-text-pixel-size' * doc/lispref/display.texi (Size of Displayed Text): Fix arguments of 'buffer-text-pixel-size'. (Bug#76519) diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index e896b8198af..8b1847cc4dc 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -2377,7 +2377,7 @@ though when this function is run from an idle timer with a delay of zero seconds. @end defun -@defun buffer-text-pixel-size &optional buffer-or-name window from to x-limit y-limit +@defun buffer-text-pixel-size &optional buffer-or-name window x-limit y-limit This is much like @code{window-text-pixel-size}, but can be used when the buffer isn't shown in a window. (@code{window-text-pixel-size} is faster when it is, so this function shouldn't be used in that case.) @@ -2388,10 +2388,14 @@ live window and defaults to the selected one; the function will compute the text dimensions as if @var{buffer} is displayed in @var{window}. The return value is a cons of the maximum pixel-width of any text line and the pixel-height of all the text lines of the -buffer specified by @var{buffer-or-name}. +accessible portion of the buffer specified by @var{buffer-or-name}. The optional arguments @var{x-limit} and @var{y-limit} have the same meaning as with @code{window-text-pixel-size}. + +If you want to measure dimensions of some part of the buffer text, +narrow the buffer to that part before calling this function +(@pxref{Narrowing}). @end defun @defun string-pixel-width string commit 734986349fd460e5c1f65f315e16817320026444 Author: Po Lu Date: Wed Feb 26 15:10:27 2025 +0800 ; Minor Android documentation improvements * doc/emacs/android.texi (Android Startup, Android File System) (Android Document Providers): Improve phrasing. diff --git a/doc/emacs/android.texi b/doc/emacs/android.texi index a1801d378ea..568fd8022d1 100644 --- a/doc/emacs/android.texi +++ b/doc/emacs/android.texi @@ -145,8 +145,8 @@ attempts to open the file with the wrapper will fail. @cindex /content/by-authority directory, android @cindex /content/by-authority-named directory, android Some files are given to Emacs as ``content identifiers'' that the -system provides access to outside the normal filesystem APIs. Emacs -uses pseudo-directories named @file{/content/by-authority} and +system provides access to independently of the normal filesystem APIs. +Emacs uses pseudo-directories named @file{/content/by-authority} and @file{/content/by-authority-named} to access those files. Do not make any assumptions about the contents of these directories, or try to open files in it yourself. @@ -227,9 +227,9 @@ system settings. @item Directories provided by @dfn{document providers} on Android 5.0 and -later. These directories exist outside the normal Unix filesystem, -containing files provided by external programs (@pxref{Android -Document Providers}.) +later. These directories exist independently of the Unix virtual +filesystem, containing files provided by external programs +(@pxref{Android Document Providers}.) @end itemize Despite ordinary installations of Android not having files within @@ -324,9 +324,8 @@ its name to the command @code{android-relinquish-directory-access}. The same limitations applied to the @file{/assets} directory (@pxref{Android File System}) are applied when creating sub-processes within those directories, because they do not exist within the Unix -file-system. In addition, although Emacs can normally write and -create files inside these directories, it cannot create symlinks or -hard links. +file-system. In addition, although Emacs can normally write and create +files inside these directories, it cannot create symlinks or hard links. Since document providers are allowed to perform expensive network operations to obtain file contents, a file access operation within one commit a90da8990342c7fc0aa51ae92a0849de346a8d8b Author: Stefan Kangas Date: Wed Feb 26 03:31:57 2025 +0100 ; Fix up emacs-lisp-mode docstring * lisp/progmodes/elisp-mode.el (emacs-lisp-mode, lisp-interaction-mode): Fix up docstring slightly by removing redundant and misplaced word "Commands", and prefix list with dashes. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index a573d9ef864..bde6b030335 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -335,9 +335,10 @@ mouse-1: Enable lexical-binding mode" mouse-face mode-line-highlight local-map ,elisp--dynlex-modeline-map))) "Major mode for editing Lisp code to run in Emacs. -Commands: -Delete converts tabs to spaces as it moves back. -Blank lines separate paragraphs. Semicolons start comments. + +- Delete converts tabs to spaces as it moves back. +- Blank lines separate paragraphs. +- Semicolons start comments. When editing Lisp data (as opposed to code), `lisp-data-mode' can be used instead. @@ -367,7 +368,7 @@ be used instead. #'elisp-completion-at-point nil 'local) (add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t) (add-hook 'flymake-diagnostic-functions - #'elisp-flymake-byte-compile nil t) + #'elisp-flymake-byte-compile nil t) (add-hook 'context-menu-functions #'elisp-context-menu 10 t)) ;; Font-locking support. @@ -1330,10 +1331,9 @@ before point, and prints its value into the buffer, advancing point. Note that printing is controlled by `eval-expression-print-length' and `eval-expression-print-level'. -Commands: -Delete converts tabs to spaces as it moves back. -Paragraphs are separated only by blank lines. -Semicolons start comments. +- Delete converts tabs to spaces as it moves back. +- Paragraphs are separated only by blank lines. +- Semicolons start comments. \\{lisp-interaction-mode-map}" :abbrev-table nil commit 58c7acb55543bddf4280e90c219ee5023d4898f9 Author: Basil L. Contovounesios Date: Tue Feb 25 11:26:11 2025 +0100 ; Fix completion-fail-discreetly docstring typo. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index f19fe241bfb..cfce7de8df1 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1455,7 +1455,7 @@ pair of a group title string and a list of group candidate strings." (defvar completion-tab-width nil) (defvar completion-fail-discreetly nil - "If non-nil, stay quiet when there is no match.") + "If non-nil, stay quiet when there is no match.") (defun completion--message (msg) (if completion-show-inline-help commit 02c830ba22b0564f6725cd403beba4accb836061 Author: Basil L. Contovounesios Date: Thu Feb 20 10:29:54 2025 +0100 Fix ert-font-lock macro signatures * doc/misc/ert.texi (Syntax Highlighting Tests): * test/lisp/emacs-lisp/ert-font-lock-tests.el (test-line-comment-p--emacs-lisp, test-line-comment-p--shell-script) (test-line-comment-p--javascript, test-line-comment-p--python) (test-line-comment-p--c, test-macro-test--correct-highlighting) (test-macro-test--docstring, test-macro-test--failing) (test-macro-test--file, test-macro-test--file-no-asserts) (test-macro-test--file-failing): Reindent macro calls. (with-temp-buffer-str-mode): Evaluate macro arguments left-to-right. (ert-font-lock--wrap-begin-end): Use rx for more robust composition. (test-line-comment-p--php): Require that php-mode is callable, not already loaded. * lisp/emacs-lisp/ert-font-lock.el (ert-font-lock-deftest) (ert-font-lock-deftest-file): NAME is not followed by an empty list like in ert-deftest, so the optional DOCSTRING is actually the second argument. Adapt calling convention in docstring, and debug, doc-string, and indent properties accordingly (bug#76372). Fix docstring grammar, document MAJOR-MODE, and avoid referring to a file name as a path. diff --git a/doc/misc/ert.texi b/doc/misc/ert.texi index 9e60647f3ba..e0cc415fa93 100644 --- a/doc/misc/ert.texi +++ b/doc/misc/ert.texi @@ -955,7 +955,7 @@ checking face assignment. Test assertions are included in code-level comments directly and can be read either from inline strings or files. The parser expects the input string to contain at least one assertion. -Test assertion parser extracts tests from comment-only lines. Every +The test assertion parser extracts tests from comment-only lines. Every comment assertion line starts either with a caret (@samp{^}) or an arrow (@samp{<-}). A single caret/arrow or carets should be followed immediately by the name of a face or a list of faces to be checked @@ -977,7 +977,7 @@ var variable = 11; @end example Both symbol-only @code{:face} property values and assertion face values -are normalized to single element lists so assertions below are +are normalized to single element lists so the assertions below are equivalent: @example @@ -1054,7 +1054,7 @@ definition: @lisp (ert-font-lock-deftest test-macro-test--inline - emacs-lisp-mode + emacs-lisp-mode " (defun fun ()) ;; ^ font-lock-keyword-face @@ -1068,13 +1068,13 @@ file: @lisp (ert-font-lock-deftest-file test-macro-test--file - "Test reading correct assertions from a file" + "Test reading correct assertions from a file." javascript-mode "correct.js") @end lisp The @code{ert-font-lock-deftest} and @code{ert-font-lock-deftest-file} -macros accept the same keyword parameters as @code{ert-deftest} i.e., +macros accept the same keyword arguments as @code{ert-deftest}, i.e., @code{:tag} and @code{:expected-result}. @node How to Debug Tests diff --git a/lisp/emacs-lisp/ert-font-lock.el b/lisp/emacs-lisp/ert-font-lock.el index e584eb679fd..80f4a6d5467 100644 --- a/lisp/emacs-lisp/ert-font-lock.el +++ b/lisp/emacs-lisp/ert-font-lock.el @@ -27,8 +27,8 @@ ;; highlighting provided by font-lock. ;; ;; ert-font-lock entry points are functions -;; `ert-font-lock-test-string' and `ert-font-lock-test-file' and -;; convenience macros: `ert-font-lock-deftest' and +;; `ert-font-lock-test-string' and `ert-font-lock-test-file', and +;; convenience macros `ert-font-lock-deftest' and ;; `ert-font-lock-deftest-file'. ;; ;; See unit tests in ert-font-lock-tests.el for usage examples. @@ -124,19 +124,21 @@ Argument TEST-NAME - name of the currently running ert test." (defmacro ert-font-lock-deftest (name &rest docstring-keys-mode-and-str) "Define test NAME (a symbol) using assertions from TEST-STR. -Other than MAJOR-MODE and TEST-STR parameters, this macro accepts -the same parameters and keywords as `ert-deftest' and is intended -to be used through `ert'. +The MAJOR-MODE symbol determines the syntax and font lock of TEST-STR. -\(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] \ +Except for the MAJOR-MODE and TEST-STR parameters, this macro accepts +the same arguments and keywords as `ert-deftest' and is intended to be +used through `ert'. + +\(fn NAME [DOCSTRING] [:expected-result RESULT-TYPE] \ [:tags \\='(TAG...)] MAJOR-MODE TEST-STR)" (declare (debug (&define [&name "test@" symbolp] - sexp [&optional stringp] + [&optional stringp] [&rest keywordp sexp] symbolp stringp)) - (doc-string 3) - (indent 2)) + (doc-string 2) + (indent 1)) (pcase-let ((`(,documentation ,documentation-supplied-p ,keys ,mode ,arg) @@ -159,22 +161,23 @@ to be used through `ert'. (defmacro ert-font-lock-deftest-file (name &rest docstring-keys-mode-and-file) "Define test NAME (a symbol) using assertions from FILE. -FILE - path to a file with assertions in ERT resource director as -return by `ert-resource-directory'. +FILE names a file with assertions in the ERT resource directory, as +returned by `ert-resource-directory'. The MAJOR-MODE symbol determines +the syntax and font lock of FILE's contents. -Other than MAJOR-MODE and FILE parameters, this macro accepts the -same parameters and keywords as `ert-deftest' and is intended to -be used through `ert'. +Except for the MAJOR-MODE and FILE parameters, this macro accepts the +same arguments and keywords as `ert-deftest' and is intended to be used +through `ert'. -\(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] \ +\(fn NAME [DOCSTRING] [:expected-result RESULT-TYPE] \ [:tags \\='(TAG...)] MAJOR-MODE FILE)" (declare (debug (&define [&name "test@" symbolp] - sexp [&optional stringp] + [&optional stringp] [&rest keywordp sexp] symbolp stringp)) - (doc-string 3) - (indent 2)) + (doc-string 2) + (indent 1)) (pcase-let ((`(,documentation ,documentation-supplied-p diff --git a/test/lisp/emacs-lisp/ert-font-lock-tests.el b/test/lisp/emacs-lisp/ert-font-lock-tests.el index e410cf5fa13..0c3e4405562 100644 --- a/test/lisp/emacs-lisp/ert-font-lock-tests.el +++ b/test/lisp/emacs-lisp/ert-font-lock-tests.el @@ -39,13 +39,13 @@ "Create a buffer with STR contents and MODE. " (declare (indent 1) (debug t)) `(with-temp-buffer - (insert ,str) (,mode) + (insert ,str) (goto-char (point-min)) ,@body)) (defun ert-font-lock--wrap-begin-end (re) - (concat "^" re "$")) + (rx bol (regexp re) eol)) ;;; Regexp tests ;;; @@ -97,89 +97,89 @@ (ert-deftest test-line-comment-p--emacs-lisp () (with-temp-buffer-str-mode emacs-lisp-mode - "not comment + "not comment ;; comment " - (should-not (ert-font-lock--line-comment-p)) - (forward-line) - (should (ert-font-lock--line-comment-p)) - (forward-line) - (should-not (ert-font-lock--line-comment-p)))) + (should-not (ert-font-lock--line-comment-p)) + (forward-line) + (should (ert-font-lock--line-comment-p)) + (forward-line) + (should-not (ert-font-lock--line-comment-p)))) (ert-deftest test-line-comment-p--shell-script () (with-temp-buffer-str-mode shell-script-mode - "echo Not a comment + "echo Not a comment # comment " - (should-not (ert-font-lock--line-comment-p)) - (forward-line) - (should (ert-font-lock--line-comment-p)))) + (should-not (ert-font-lock--line-comment-p)) + (forward-line) + (should (ert-font-lock--line-comment-p)))) (declare-function php-mode "php-mode") (ert-deftest test-line-comment-p--php () - (skip-unless (featurep 'php-mode)) + (skip-unless (fboundp 'php-mode)) (with-temp-buffer-str-mode php-mode - "echo 'Not a comment' + "echo 'Not a comment' // comment /* comment */ " - (should-not (ert-font-lock--line-comment-p)) - (forward-line) - (should (ert-font-lock--line-comment-p)) - (forward-line) - (should (ert-font-lock--line-comment-p)))) + (should-not (ert-font-lock--line-comment-p)) + (forward-line) + (should (ert-font-lock--line-comment-p)) + (forward-line) + (should (ert-font-lock--line-comment-p)))) (ert-deftest test-line-comment-p--javascript () (with-temp-buffer-str-mode javascript-mode - "// comment + "// comment // comment, after a blank line var abc = function(d) {}; " - (should (ert-font-lock--line-comment-p)) + (should (ert-font-lock--line-comment-p)) - (forward-line) - (should-not (ert-font-lock--line-comment-p)) + (forward-line) + (should-not (ert-font-lock--line-comment-p)) - (forward-line) - (should (ert-font-lock--line-comment-p)) + (forward-line) + (should (ert-font-lock--line-comment-p)) - (forward-line) - (should-not (ert-font-lock--line-comment-p)) + (forward-line) + (should-not (ert-font-lock--line-comment-p)) - (forward-line) - (should-not (ert-font-lock--line-comment-p)))) + (forward-line) + (should-not (ert-font-lock--line-comment-p)))) (ert-deftest test-line-comment-p--python () (with-temp-buffer-str-mode python-mode - "# comment + "# comment # comment print(\"Hello, world!\")" - (should (ert-font-lock--line-comment-p)) + (should (ert-font-lock--line-comment-p)) - (forward-line) - (should-not (ert-font-lock--line-comment-p)) + (forward-line) + (should-not (ert-font-lock--line-comment-p)) - (forward-line) - (should (ert-font-lock--line-comment-p)) + (forward-line) + (should (ert-font-lock--line-comment-p)) - (forward-line) - (should-not (ert-font-lock--line-comment-p)))) + (forward-line) + (should-not (ert-font-lock--line-comment-p)))) (ert-deftest test-line-comment-p--c () (with-temp-buffer-str-mode c-mode - "// comment + "// comment /* also comment */" - (should (ert-font-lock--line-comment-p)) + (should (ert-font-lock--line-comment-p)) - (forward-line) - (should (ert-font-lock--line-comment-p)))) + (forward-line) + (should (ert-font-lock--line-comment-p)))) (ert-deftest test-parse-comments--no-assertion-error () (let* ((str " @@ -568,14 +568,14 @@ var abc = function(d) { ;; (ert-font-lock-deftest test-macro-test--correct-highlighting - emacs-lisp-mode + emacs-lisp-mode " (defun fun ()) ;; ^ font-lock-keyword-face ;; ^ font-lock-function-name-face") (ert-font-lock-deftest test-macro-test--docstring - "A test with a docstring." + "A test with a docstring." emacs-lisp-mode " (defun fun ()) @@ -583,7 +583,7 @@ var abc = function(d) { ) (ert-font-lock-deftest test-macro-test--failing - "A failing test." + "A failing test." :expected-result :failed emacs-lisp-mode " @@ -591,18 +591,18 @@ var abc = function(d) { ;; ^ wrong-face") (ert-font-lock-deftest-file test-macro-test--file - "Test reading correct assertions from a file" + "Test reading correct assertions from a file." javascript-mode "correct.js") (ert-font-lock-deftest-file test-macro-test--file-no-asserts - "Check failing on files without assertions" + "Check failing on files without assertions." :expected-result :failed javascript-mode "no-asserts.js") (ert-font-lock-deftest-file test-macro-test--file-failing - "Test reading wrong assertions from a file" + "Test reading wrong assertions from a file." :expected-result :failed javascript-mode "broken.js") commit 0c6b8643aec24935f82c63d43219f26378e3e578 Author: Eli Zaretskii Date: Mon Feb 24 21:02:14 2025 +0200 Fix a typo in 'window_text_pixel_size' This typo caused strange mis-behaviors in buffers with non-ASCII characters. * src/xdisp.c (window_text_pixel_size): Fix typo. (Bug#76519) diff --git a/src/xdisp.c b/src/xdisp.c index f11a8aa6d55..eb00c510aaa 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -11546,6 +11546,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, it.bidi_p = false; int start_x; + ptrdiff_t start_bpos = BYTEPOS (startp); if (vertical_offset != 0) { int last_y; @@ -11578,6 +11579,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, it.current_y = (WINDOW_TAB_LINE_HEIGHT (w) + WINDOW_HEADER_LINE_HEIGHT (w)); start = clip_to_bounds (BEGV, IT_CHARPOS (it), ZV); + start_bpos = CHAR_TO_BYTE (start); start_y = it.current_y; start_x = it.current_x; } @@ -11639,7 +11641,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, it.current_y = start_y; /* If FROM is on a newline, pretend that we start at the beginning of the next line, because the newline takes no place on display. */ - if (FETCH_BYTE (start) == '\n') + if (FETCH_BYTE (start_bpos) == '\n') it.current_x = 0, it.wrap_prefix_width = 0; if (!NILP (x_limit)) { commit 8a8c25eaccd7adee45a291ba97e828528083f4d9 Author: Stefan Kangas Date: Mon Feb 24 18:26:14 2025 +0100 ; Add Rudolf Schlatte to authors.el * admin/authors.el (authors-aliases): Add Rudolf Schlatte. diff --git a/admin/authors.el b/admin/authors.el index 946b1598f37..96a102b3f67 100644 --- a/admin/authors.el +++ b/admin/authors.el @@ -249,6 +249,7 @@ files.") ("Rodney J. Whitby" "Rod Whitby") ("Roland B. Roberts" "Roland B Roberts" "Roland Roberts") ("Ron Schnell" "Ronnie Schnell") + ("Rudolf Schlatte" "Rudi Schlatte") ("Rui-Tao Dong" "Rui-Tao Dong ~{6-HpLN~}") ("Ryan Thompson" "Ryan .*rct@thompsonclan") (nil "rvs314") commit 94c0ea39a5af6f0979e769fc8a053ac60b561367 Author: Ulrich Müller Date: Mon Feb 24 10:32:47 2025 +0100 * doc/misc/efaq.texi (New in Emacs 30): Fix typo. (Bug#76518) diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi index 4f936014ed1..56eccfd9456 100644 --- a/doc/misc/efaq.texi +++ b/doc/misc/efaq.texi @@ -943,7 +943,7 @@ Emacs has been ported to the Android operating system. See the file to build it. @item -New user option @code{trusted-contents} to allow potentially dangerous +New user option @code{trusted-content} to allow potentially dangerous Emacs features which could execute arbitrary Lisp code. Use this variable to list files and directories whose contents Emacs should trust, thus allowing those potentially dangerous features when those commit 0be5f9115ec8828bcc50389ca30f76fa1ad5f364 Author: Sean Whitton Date: Mon Feb 24 14:20:44 2025 +0800 ; * etc/images/README (Files): Add an entry for last-page.xpm diff --git a/etc/images/README b/etc/images/README index cc8966d7800..66b489d555d 100644 --- a/etc/images/README +++ b/etc/images/README @@ -83,6 +83,7 @@ Emacs images and their source in the GNOME icons stock/ directory: lock-ok.xpm data/stock_lock-ok lock.xpm data/stock_lock next-page.xpm navigation/stock_next-page + last-page.xpm mirrored from navigation/stock_next-page redo.xpm generic/stock_redo refresh.xpm generic/stock_refresh search-replace.xpm slightly modified generic/stock_search-and-replace commit 63adf9dcf53ac64585803fe5f9ad0acb107a9f9f Author: Stefan Kangas Date: Mon Feb 24 03:45:18 2025 +0100 ; Reflow some cl-lib docstrings * lisp/emacs-lisp/cl-macs.el (cl-flet, cl-labels): Reflow docstrings. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index b07a881ba48..555b4f018ad 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -2067,15 +2067,15 @@ a `let' form, except that the list of symbols can be computed at run-time." ;;;###autoload (defmacro cl-flet (bindings &rest body) "Make local function definitions. -Each definition can take the form (FUNC EXP) where -FUNC is the function name, and EXP is an expression that returns the -function value to which it should be bound, or it can take the more common -form (FUNC ARGLIST BODY...) which is a shorthand -for (FUNC (lambda ARGLIST BODY)). -FUNC is defined only within FORM, not BODY, so you can't write -recursive function definitions. Use `cl-labels' for that. See -info node `(cl) Function Bindings' for details. +Each definition can take the form (FUNC EXP) where FUNC is the function +name, and EXP is an expression that returns the function value to which +it should be bound, or it can take the more common form (FUNC ARGLIST +BODY...) which is a shorthand for (FUNC (lambda ARGLIST BODY)). + +FUNC is defined only within FORM, not BODY, so you can't write recursive +function definitions. Use `cl-labels' for that. See Info node +`(cl) Function Bindings' for details. \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" (declare (indent 1) @@ -2250,12 +2250,14 @@ Like `cl-flet' but the definitions can refer to previous ones. ;;;###autoload (defmacro cl-labels (bindings &rest body) "Make local (recursive) function definitions. -BINDINGS is a list of definitions of the form (FUNC ARGLIST BODY...) where -FUNC is the function name, ARGLIST its arguments, and BODY the -forms of the function body. FUNC is defined in any BODY, as well -as FORM, so you can write recursive and mutually recursive -function definitions. See info node `(cl) Function Bindings' for -details. + +BINDINGS is a list of definitions of the form (FUNC ARGLIST BODY...) +where FUNC is the function name, ARGLIST its arguments, and BODY the +forms of the function body. + +FUNC is defined in any BODY, as well as FORM, so you can write recursive +and mutually recursive function definitions. See Info node +`(cl) Function Bindings' for details. \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" (declare (indent 1) (debug cl-flet)) commit d63b27a416b1677bfb1e96194ce009f1609b2e10 Author: Joseph Turner Date: Sun Oct 13 01:10:02 2024 +0200 Upgrade out-of-date VC package dependencies * lisp/emacs-lisp/package-vc.el (package-vc-install-dependencies): Pass the specified package version when checking if a package is installed. (Bug#73781) (cherry picked from commit 71a4670a9fa238f920ce88b938f703b605ad2f48) diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index 29602c30e13..ac78c5af4e4 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -465,7 +465,7 @@ this function successfully installs all given dependencies)." "Attempt to find all dependencies for PKG." (cond ((assq (car pkg) to-install)) ;inhibit cycles - ((package-installed-p (car pkg))) + ((package-installed-p (car pkg) (cadr pkg))) ((let* ((pac package-archive-contents) (desc (cadr (assoc (car pkg) pac)))) (if desc commit 99253f79703535ab7bd500fc39b33dc0a966333d Author: Stefan Kangas Date: Sun Feb 23 06:19:26 2025 +0100 ; * etc/TODO: New section "Make it easier to contribute". diff --git a/etc/TODO b/etc/TODO index 95c2167645a..3c628c60bd7 100644 --- a/etc/TODO +++ b/etc/TODO @@ -222,6 +222,31 @@ https://lists.gnu.org/r/emacs-devel/2008-08/msg00456.html * Important features +** Make it easier to contribute + +*** New script to catch common mistakes in patches. +Examples of things to catch are missing or malformed ChangeLog, style +issues in C, Lisp, and Texinfo, etc. There is no need to be overly +ambitious in a first draft, making a start is better than nothing. It +could draw inspiration from checkpatch.pl used by the Linux kernel. + +*** New make target or script to run tests for changed files. +This might require some kind of data structure mapping a source file to +the tests which exercise some of the code in that source file. The +first approximation is to run FOO-tests when you modify a file FOO, but +some FOO's get used in many places in the test suite, so this is not a +simple 1:1 relation. Then we could ask contributors to run the relevant +tests as part of the submission process. + +*** Automated emails to contributors when their commits make tests fail +Having EMBA or something similar email the guilty parties in case of +new test failures (or maybe even warnings) would be great. + +*** Automated testing of patches submitted to the bug tracker +Create a bot that can run the above "check patch" script, and perhaps +even run unit tests, for every patch submitted to the bug tracker, and +then send an automated email with the results. Can EMBA help with this? + ** Speed up Elisp execution *** Speed up function calls commit 563b6f94511b76266984bc6764ec2a9391448138 Author: Vincenzo Pupillo Date: Wed Jan 22 16:14:41 2025 +0100 Constant highlighting no longer captures Java annotations * lisp/progmodes/java-ts-mode.el (java-ts-mode--fontify-constant): New function. (java-ts-mode--font-lock-settings): Use it. diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el index 6823cb4f38a..849ab23ef3e 100644 --- a/lisp/progmodes/java-ts-mode.el +++ b/lisp/progmodes/java-ts-mode.el @@ -164,6 +164,23 @@ the available version of Tree-sitter for Java." (error `((string_literal) @font-lock-string-face)))) +(defun java-ts-mode--fontify-constant (node override start end &rest _) + "Fontify a Java constant. +In Java the names of variables declared class constants and of ANSI +constants should be all uppercase with words separated by underscores. +This function also prevents annotations from being highlighted as if +they were constants. +For NODE, OVERRIDE, START, and END, see `treesit-font-lock-rules'." + (let ((node-start (treesit-node-start node)) + (case-fold-search nil)) + (when (and + (not (equal (char-before node-start) ?@)) ;; skip annotations + (string-match "\\`[A-Z_][0-9A-Z_]*\\'" (treesit-node-text node))) + (treesit-fontify-with-override + node-start (treesit-node-end node) + 'font-lock-constant-face override + start end)))) + (defvar java-ts-mode--font-lock-settings (treesit-font-lock-rules :language 'java @@ -174,8 +191,7 @@ the available version of Tree-sitter for Java." :language 'java :override t :feature 'constant - `(((identifier) @font-lock-constant-face - (:match "\\`[A-Z_][0-9A-Z_]*\\'" @font-lock-constant-face)) + `((identifier) @java-ts-mode--fontify-constant [(true) (false)] @font-lock-constant-face) :language 'java :override t commit 77441190252ce3a147e9535e422f15c1f6e38241 Author: Michael Albinus Date: Fri Feb 21 14:47:15 2025 +0100 Use a persistent directory as default directory in diff * lisp/vc/diff.el (diff-no-select): Use `temporary-file-directory' as default directory. Set default file permissions temporarily to #o600. (Bug#69606) (cherry picked from commit ae439cc1b9f428a8247548f4ef3b992608a3c09b) diff --git a/lisp/vc/diff.el b/lisp/vc/diff.el index 8f8ed69cfd9..555ad80d1dd 100644 --- a/lisp/vc/diff.el +++ b/lisp/vc/diff.el @@ -187,8 +187,7 @@ returns the buffer used." (prin1-to-string new)))) (list (or old-alt old) (or new-alt new))))) - " ")) - (thisdir default-directory)) + " "))) (with-current-buffer buf (setq buffer-read-only t) (buffer-disable-undo (current-buffer)) @@ -199,25 +198,26 @@ returns the buffer used." (setq-local revert-buffer-function (lambda (_ignore-auto _noconfirm) (diff-no-select old new switches no-async (current-buffer)))) - (setq default-directory thisdir) + (setq default-directory temporary-file-directory) (setq diff-default-directory default-directory) (let ((inhibit-read-only t)) (insert command "\n")) - (if (and (not no-async) (fboundp 'make-process)) - (let ((proc (start-process "Diff" buf shell-file-name - shell-command-switch command))) - (set-process-filter proc #'diff-process-filter) - (set-process-sentinel - proc (lambda (proc _msg) - (with-current-buffer (process-buffer proc) - (diff-sentinel (process-exit-status proc) - old-alt new-alt))))) - ;; Async processes aren't available. - (let ((inhibit-read-only t)) - (diff-sentinel - (call-process shell-file-name nil buf nil - shell-command-switch command) - old-alt new-alt)))) + (with-file-modes #o600 + (if (and (not no-async) (fboundp 'make-process)) + (let ((proc (start-process "Diff" buf shell-file-name + shell-command-switch command))) + (set-process-filter proc #'diff-process-filter) + (set-process-sentinel + proc (lambda (proc _msg) + (with-current-buffer (process-buffer proc) + (diff-sentinel (process-exit-status proc) + old-alt new-alt))))) + ;; Async processes aren't available. + (let ((inhibit-read-only t)) + (diff-sentinel + (call-process shell-file-name nil buf nil + shell-command-switch command) + old-alt new-alt))))) buf)) (defun diff-process-filter (proc string) commit e9c9ed1f46853793cb4b064718c990cc2cd17f59 Author: Stefan Kangas Date: Thu Feb 20 02:13:29 2025 +0100 Minor refactoring in admin/admin.el * admin/admin.el (admin--read-root-directory): (admin--read-version): New functions. (add-release-logs, set-version, set-copyright, make-manuals) (make-manuals-dist, make-news-html-file): Use above new function. diff --git a/admin/admin.el b/admin/admin.el index 131b8574029..8fc970ed430 100644 --- a/admin/admin.el +++ b/admin/admin.el @@ -28,12 +28,19 @@ (defvar add-log-time-format) ; in add-log +(defun admin--read-root-directory () + (read-directory-name "Emacs root directory: " + source-directory nil t)) + +(defun admin--read-version () + (read-string "Version number: " emacs-version)) + (defun add-release-logs (root version &optional date) "Add \"Version VERSION released.\" change log entries in ROOT. Also update the etc/HISTORY file. Root must be the root of an Emacs source tree. Optional argument DATE is the release date, default today." - (interactive (list (read-directory-name "Emacs root directory: ") + (interactive (list (admin--read-root-directory) (read-string "Version number: " (format "%s.%s" emacs-major-version emacs-minor-version)) @@ -94,9 +101,8 @@ Optional argument DATE is the release date, default today." (defun set-version (root version) "Set Emacs version to VERSION in relevant files under ROOT. Root must be the root of an Emacs source tree." - (interactive (list - (read-directory-name "Emacs root directory: " source-directory) - (read-string "Version number: " emacs-version))) + (interactive (list (admin--read-root-directory) + (admin--read-version))) (unless (file-exists-p (expand-file-name "src/emacs.c" root)) (user-error "%s doesn't seem to be the root of an Emacs source tree" root)) (unless admin-git-command @@ -213,9 +219,9 @@ Documentation changes might not have been completed!")))) (dolist (s '("Installation Changes" "Startup Changes" "Changes" "Editing Changes" "Changes in Specialized Modes and Packages" - "New Modes and Packages" - "Incompatible Lisp Changes" - "Lisp Changes")) + "New Modes and Packages" + "Incompatible Lisp Changes" + "Lisp Changes")) (insert (format "\n \n* %s in Emacs %s\n" s newshort))) (insert (format "\n \n* Changes in Emacs %s on \ Non-Free Operating Systems\n" newshort))) @@ -230,7 +236,7 @@ Non-Free Operating Systems\n" newshort))) "Set Emacs short copyright to COPYRIGHT in relevant files under ROOT. Root must be the root of an Emacs source tree." (interactive (list - (read-directory-name "Emacs root directory: " nil nil t) + (admin--read-root-directory) (read-string "Short copyright string: " (format "Copyright (C) %s Free Software Foundation, Inc." @@ -289,8 +295,7 @@ Optional argument TYPE is type of output (nil means all)." (if noninteractive (or (pop command-line-args-left) default-directory) - (read-directory-name "Emacs root directory: " - source-directory nil t)))) + (admin--read-root-directory)))) (list root (if current-prefix-arg (completing-read @@ -772,8 +777,7 @@ Optional argument TYPE is type of output (nil means all)." (if noninteractive (or (pop command-line-args-left) default-directory) - (read-directory-name "Emacs root directory: " - source-directory nil t)))) + (admin--read-root-directory)))) (list root (if current-prefix-arg (completing-read @@ -861,8 +865,7 @@ $Date: %s $ (if noninteractive (or (pop command-line-args-left) default-directory) - (read-directory-name "Emacs root directory: " - source-directory nil t)))) + (admin--read-root-directory)))) (list root (read-string "Major version number: " (number-to-string emacs-major-version))))) commit e15dcb2db5c40e90ea2a21391af5addb9e778779 Author: Stefan Kangas Date: Sat Feb 22 18:15:37 2025 +0100 Improve wording of lsh docstring * lisp/subr.el (lsh): Improve wording of docstring. diff --git a/lisp/subr.el b/lisp/subr.el index 7aca542dab4..7552378a781 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -571,10 +571,10 @@ If COUNT is negative, shifting is actually to the right. In this case, if VALUE is a negative fixnum treat it as unsigned, i.e., subtract 2 * `most-negative-fixnum' from VALUE before shifting it. -Most uses of this function turn out to be mistakes. We recommend -to use `ash' instead, unless COUNT could ever be negative, and -if, when COUNT is negative, your program really needs the special -treatment of negative COUNT provided by this function." +Most uses of this function turn out to be mistakes. We recommend using +`ash' instead, unless COUNT could ever be negative, in which case your +program should only use this function if it specifically requires the +special handling of negative COUNT." (declare (ftype (function (integer integer) integer)) (compiler-macro (lambda (form) commit ac7f2054b52d5105007b004dd229674e58472f7c Author: Stefan Kangas Date: Thu Feb 20 11:14:35 2025 +0100 Sync build-aux/update-copyright from Gnulib * build-aux/update-copyright: Copy from Gnulib. This fixes a bug where troff markers were introduced in ChangeLog files. (Do not merge to master.) diff --git a/build-aux/update-copyright b/build-aux/update-copyright index 413a0c4a731..124c7d2e423 100755 --- a/build-aux/update-copyright +++ b/build-aux/update-copyright @@ -47,8 +47,8 @@ # Each file's copyright statement must be formatted correctly in # order to be recognized. For example, each of these is fine: # -# Copyright @copyright{} 1990-2005, 2007-2009, 2025 Free Software -# Foundation, Inc. +# Copyright @copyright{} 1990-2005, 2007-2009, 2025 Free Software Foundation, +# Inc. # # # Copyright (C) 1990-2005, 2007-2009 Free Software # # Foundation, Inc. @@ -138,7 +138,7 @@ eval 'exec perl -wSx -0777 -pi "$0" "$@"' if 0; -my $VERSION = '2024-01-15.18:30'; # UTC +my $VERSION = '2025-01-01.07:36'; # UTC # The definition above must lie within the first 8 lines in order # for the Emacs time-stamp write hook (at end) to update it. # If you change this file with Emacs, please let the write hook @@ -235,7 +235,7 @@ while (/(^|\n)(.{0,$prefix_max})$copyright_re/cg) else { my $ndash = ($ARGV =~ /\.tex(i(nfo)?)?$/ ? "--" - : $ARGV =~ /\.(\d[a-z]*|man)$/ ? "\\(en" + : $ARGV =~ /\.(\d[a-z]*|man)(\.in)?$/ && $ARGV !~ /ChangeLog\./ ? "\\(en" : "-"); $stmt =~ @@ -298,7 +298,7 @@ if (!$found) # coding: utf-8 # mode: perl # indent-tabs-mode: nil -# eval: (add-hook 'before-save-hook 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp nil t) # time-stamp-line-limit: 200 # time-stamp-start: "my $VERSION = '" # time-stamp-format: "%:y-%02m-%02d.%02H:%02M" commit a8b1726487b85aa6822431af1a213e1d15713d93 Author: Stefan Kangas Date: Thu Feb 20 01:53:57 2025 +0100 ; * admin/make-tarball.txt: Copy edits. diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt index 858f381cb61..22e76a0ac2e 100644 --- a/admin/make-tarball.txt +++ b/admin/make-tarball.txt @@ -1,8 +1,16 @@ Instructions to create pretest or release tarballs. -*- coding: utf-8 -*- --- originally written by Gerd Moellmann, amended by Francesco Potortì +-- originally written by Gerd Möllmann, amended by Francesco Potortì with the initial help of Eli Zaretskii +Preparations: + +0. In order to upload to the GNU FTP server, you must be registered as + an Emacs maintainer and have your GPG key acknowledged by the FTP + people. Do this as soon as possible to avoid lead time. For + instructions, see: + . + Steps to take before starting on the first pretest in any release sequence: 0. The release branch (e.g. emacs-28) should already have been made @@ -18,7 +26,7 @@ Steps to take before starting on the first pretest in any release sequence: the release branch, see admin/release-branch.txt, but it can't hurt to double check its value.) Commit cus-edit.el if changed. -3. Remove any old pretests from https://alpha.gnu.org/gnu/emacs/pretest. +3. Remove any old pretests from . You can use 'gnupload --delete' (see below for more gnupload details). (We currently don't bother with this.) @@ -224,12 +232,12 @@ General steps (for each step, check for possible errors): against the previous release (if this is the first pretest) or the previous pretest. If you did not make the previous pretest yourself, find it at . - Releases are of course at . + Releases are at . ./admin/diff-tar-files emacs-OLD.tar emacs-NEW.tar - Alternatively, if you want to use the compressed tarballs (which - diff-tar-files doesn't understand): + Alternatively, if you want to do this manually using the compressed + tarballs: tar tJf emacs-OLD.tar.xz | sed -e 's,^[^/]*,,' | sort > old_tmp tar tJf emacs-NEW.tar.xz | sed -e 's,^[^/]*,,' | sort > new_tmp @@ -289,14 +297,12 @@ General steps (for each step, check for possible errors): xz -c emacs-NEW.tar > emacs-NEW.tar.xz For pretests, just xz is probably fine (saves bandwidth). - Now you should upload the files to the GNU ftp server. In order to - do that, you must be registered as an Emacs maintainer and have your - GPG key acknowledged by the ftp people. For instructions, see - https://www.gnu.org/prep/maintain/html_node/Automated-Upload-Registration.html - The simplest method to upload is to use the gnulib + Now you should upload the files to the GNU FTP server; your + GPG key must already be accepted as described above. + The simplest method of uploading is with the gnulib script "build-aux/gnupload": - For a pretest: + For a pretest or release candidate: gnupload [--user your@gpg.key.email] --to alpha.gnu.org:emacs/pretest \ FILE.gz FILE.xz ... @@ -325,11 +331,11 @@ General steps (for each step, check for possible errors): FILE.sig, FILE.directive.asc. For a release, place the files in the /incoming/ftp directory. For a pretest, place the files in /incoming/alpha instead, so that - they appear on https://alpha.gnu.org/. + they appear on . 11. After five minutes, verify that the files are visible at - https://alpha.gnu.org/gnu/emacs/pretest/ for a pretest, or - https://ftp.gnu.org/gnu/emacs/ for a release. + for a pretest, or + for a release. Download them and check the signatures and SHA1/SHA256 checksums. Check they build (./configure --with-native-compilation). @@ -353,7 +359,7 @@ General steps (for each step, check for possible errors): sha1sum emacs-NEW.tar.xz sha256sum emacs-NEW.tar.xz - You can optionally sign the announcement email, preferably using + You can optionally sign the announcement email using the same PGP key that you used for signing the tarball. (Use e.g. `M-x mml-secure-message-sign' in `message-mode' to sign an email.) @@ -371,7 +377,7 @@ General steps (for each step, check for possible errors): UPDATING THE EMACS WEB PAGES AFTER A RELEASE As soon as possible after a release, the Emacs web pages at -https://www.gnu.org/software/emacs/ should be updated. + should be updated. (See admin/notes/www for general information.) The pages to update are: commit 0cc651acddb87180357ab8ff4adcbac8d6174e50 Author: Stefan Kangas Date: Sat Feb 22 14:41:34 2025 +0100 ; * admin/check-doc-strings: Add note for future development. diff --git a/admin/check-doc-strings b/admin/check-doc-strings index b119b50885b..dee7ded8237 100755 --- a/admin/check-doc-strings +++ b/admin/check-doc-strings @@ -5,6 +5,18 @@ eval 'exec perl -S $0 "$@"' # Portability kludge # Author: Martin Buchholz # This program is in the public domain. +# NOTE ADDED 2025-02-22: +# +# This is an old script that doesn't necessarily work very well with +# today's sources. If anyone wants to fix it up, it might be worth the +# effort, as it could help catch some mistakes that we have overlooked. +# +# If you want to work on this, consider fundamentally rethinking the +# approach. Instead of flagging anything that *might* be an error, +# maybe it should flag only things that we are *sure* are an error. +# That would make it possible to run this as a matter of routine, just +# as we already do with codespell (see "admin/run-codespell"). + use strict; use warnings; use POSIX; commit 3c9b1c3cd18f42dd0cced43b0f1d4c2df9e5cc2d Author: Stefan Kangas Date: Sat Feb 22 04:16:21 2025 +0100 Don't document deleted xwidget functions * doc/lispref/display.texi (Xwidgets): Don't document deleted function xwidget-webkit-execute-script-rv. Fix name of deleted and then re-added function xwidget-webkit-title. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index c13c908d3f8..e896b8198af 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -7602,15 +7602,7 @@ This function causes the browser widget specified by @var{xwidget} to execute the specified JavaScript @code{script}. @end defun -@defun xwidget-webkit-execute-script-rv xwidget script &optional default -This function executes the specified @var{script} like -@code{xwidget-webkit-execute-script} does, but it also returns the -script's return value as a string. If @var{script} doesn't return a -value, this function returns @var{default}, or @code{nil} if -@var{default} was omitted. -@end defun - -@defun xwidget-webkit-get-title xwidget +@defun xwidget-webkit-title xwidget This function returns the title of @var{xwidget} as a string. @end defun commit 9e9b78dda94fb1fe0b68f23fc004f87a94e633b5 Author: Stefan Kangas Date: Sat Feb 22 03:41:41 2025 +0100 ; Improve lsh and ash documented argument names * doc/lispref/numbers.texi (Bitwise Operations): Improve lsh and ash argument names. diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index fc52f11cf4a..00f47f283b3 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi @@ -892,13 +892,13 @@ reproducing the same pattern moved over. The bitwise operations in Emacs Lisp apply only to integers. -@defun ash integer1 count +@defun ash integer count @cindex arithmetic shift -@code{ash} (@dfn{arithmetic shift}) shifts the bits in @var{integer1} +@code{ash} (@dfn{arithmetic shift}) shifts the bits in @var{integer} to the left @var{count} places, or to the right if @var{count} is negative. Left shifts introduce zero bits on the right; right shifts discard the rightmost bits. Considered as an integer operation, -@code{ash} multiplies @var{integer1} by +@code{ash} multiplies @var{integer} by @ifnottex 2**@var{count}, @end ifnottex @@ -967,20 +967,20 @@ Here are examples of shifting left or right by two bits: @end smallexample @end defun -@defun lsh integer1 count +@defun lsh integer count @cindex logical shift @code{lsh}, which is an abbreviation for @dfn{logical shift}, shifts the -bits in @var{integer1} to the left @var{count} places, or to the right +bits in @var{integer} to the left @var{count} places, or to the right if @var{count} is negative, bringing zeros into the vacated bits. If -@var{count} is negative, then @var{integer1} must be either a fixnum +@var{count} is negative, then @var{integer} must be either a fixnum or a positive bignum, and @code{lsh} treats a negative fixnum as if it were unsigned by subtracting twice @code{most-negative-fixnum} before shifting, producing a nonnegative result. This quirky behavior dates back to when Emacs supported only fixnums; nowadays @code{ash} is a better choice. -As @code{lsh} behaves like @code{ash} except when @var{integer1} and -@var{count1} are both negative, the following examples focus on these +As @code{lsh} behaves like @code{ash} except when @var{integer} and +@var{count} are both negative, the following examples focus on these exceptional cases. These examples assume 30-bit fixnums. @smallexample commit 2db182ce0bd1c4fca0344c81eaebc442c98d3caf Author: Stefan Kangas Date: Sun Feb 23 20:39:42 2025 +0100 Bump Emacs version to 30.1.50 * README: * configure.ac: * etc/NEWS: * exec/configure.ac: * msdos/sed2v2.inp: * nt/README.W32: Bump Emacs version to 30.1.50. diff --git a/README b/README index c70f9197ca8..1902137d0c9 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ Copyright (C) 2001-2025 Free Software Foundation, Inc. See the end of the file for license conditions. -This directory tree holds version 30.1 of GNU Emacs, the extensible, +This directory tree holds version 30.1.50 of GNU Emacs, the extensible, customizable, self-documenting real-time display editor. The file INSTALL in this directory says how to build and install GNU diff --git a/configure.ac b/configure.ac index cf274c0cffd..49b91d801e5 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ dnl along with GNU Emacs. If not, see . AC_PREREQ([2.65]) dnl Note this is parsed by (at least) make-dist and lisp/cedet/ede/emacs.el. -AC_INIT([GNU Emacs], [30.1], [bug-gnu-emacs@gnu.org], [], +AC_INIT([GNU Emacs], [30.1.50], [bug-gnu-emacs@gnu.org], [], [https://www.gnu.org/software/emacs/]) if test "$XCONFIGURE" = "android"; then diff --git a/etc/NEWS b/etc/NEWS index 1a68e70ce48..906deb07212 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -15,6 +15,33 @@ in older Emacs versions. You can narrow news to a specific version by calling 'view-emacs-news' with a prefix argument or by typing 'C-u C-h C-n'. + +* Installation Changes in Emacs 30.2 + + +* Startup Changes in Emacs 30.2 + + +* Changes in Emacs 30.2 + + +* Editing Changes in Emacs 30.2 + + +* Changes in Specialized Modes and Packages in Emacs 30.2 + + +* New Modes and Packages in Emacs 30.2 + + +* Incompatible Lisp Changes in Emacs 30.2 + + +* Lisp Changes in Emacs 30.2 + + +* Changes in Emacs 30.2 on Non-Free Operating Systems + * Installation Changes in Emacs 30.1 diff --git a/exec/configure.ac b/exec/configure.ac index c0a10124bc7..317872caa28 100644 --- a/exec/configure.ac +++ b/exec/configure.ac @@ -22,7 +22,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with GNU Emacs. If not, see . AC_PREREQ([2.65]) -AC_INIT([libexec], [30.1], [bug-gnu-emacs@gnu.org], [], +AC_INIT([libexec], [30.1.50], [bug-gnu-emacs@gnu.org], [], [https://www.gnu.org/software/emacs/]) AH_TOP([/* Copyright (C) 2024-2025 Free Software Foundation, Inc. diff --git a/msdos/sed2v2.inp b/msdos/sed2v2.inp index 164d4f31219..c564fa8ae15 100644 --- a/msdos/sed2v2.inp +++ b/msdos/sed2v2.inp @@ -67,7 +67,7 @@ /^#undef PACKAGE_NAME/s/^.*$/#define PACKAGE_NAME ""/ /^#undef PACKAGE_STRING/s/^.*$/#define PACKAGE_STRING ""/ /^#undef PACKAGE_TARNAME/s/^.*$/#define PACKAGE_TARNAME ""/ -/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "30.1"/ +/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "30.1.50"/ /^#undef SYSTEM_TYPE/s/^.*$/#define SYSTEM_TYPE "ms-dos"/ /^#undef HAVE_DECL_GETENV/s/^.*$/#define HAVE_DECL_GETENV 1/ /^#undef SYS_SIGLIST_DECLARED/s/^.*$/#define SYS_SIGLIST_DECLARED 1/ diff --git a/nt/README.W32 b/nt/README.W32 index b05239f762b..abe0784ccfc 100644 --- a/nt/README.W32 +++ b/nt/README.W32 @@ -1,7 +1,7 @@ Copyright (C) 2001-2025 Free Software Foundation, Inc. See the end of the file for license conditions. - Emacs version 30.1 for MS-Windows + Emacs version 30.1.50 for MS-Windows This README file describes how to set up and run a precompiled distribution of the latest version of GNU Emacs for MS-Windows. You commit 8ac894e2246f25d2a2a97d866b10e6e0b0fede5a (tag: refs/tags/emacs-30.1) Author: Stefan Kangas Date: Sun Feb 23 17:29:57 2025 +0100 Release Emacs 30.1 * ChangeLog.5: New file. * Makefile.in (CHANGELOG_HISTORY_INDEX_MAX): Bump. * etc/HISTORY: Add Emacs 30.1. diff --git a/ChangeLog.5 b/ChangeLog.5 new file mode 100644 index 00000000000..af0dc0e5f10 --- /dev/null +++ b/ChangeLog.5 @@ -0,0 +1,29 @@ +2025-02-23 Stefan Kangas + + * Version 30.1 released. + +This file records repository revisions from +commit 1cda0967b4d3c815fc610794ad6a8fc2b913a3c5 (exclusive) to +commit bcba098505e4f80eef41e4be9726f1f9868223f3 (inclusive). +See ChangeLog.4 for earlier changes. + +;; Local Variables: +;; coding: utf-8 +;; End: + + Copyright (C) 2025 Free Software Foundation, Inc. + + This file is part of GNU Emacs. + + GNU Emacs is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + GNU Emacs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Emacs. If not, see . diff --git a/Makefile.in b/Makefile.in index b8f714bb7ea..a89836dca2c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1303,7 +1303,7 @@ emacslog = build-aux/gitlog-to-emacslog # The ChangeLog history files are called ChangeLog.1, ChangeLog.2, ..., # ChangeLog.$(CHANGELOG_HISTORY_INDEX_MAX). $(CHANGELOG_N) stands for # the newest (highest-numbered) ChangeLog history file. -CHANGELOG_HISTORY_INDEX_MAX = 4 +CHANGELOG_HISTORY_INDEX_MAX = 5 CHANGELOG_N = ChangeLog.$(CHANGELOG_HISTORY_INDEX_MAX) # Convert git commit log to ChangeLog file. make-dist uses this. diff --git a/etc/HISTORY b/etc/HISTORY index d3d2bd7981d..bb8155de112 100644 --- a/etc/HISTORY +++ b/etc/HISTORY @@ -239,6 +239,8 @@ GNU Emacs 29.3 (2024-03-24) emacs-29.3 GNU Emacs 29.4 (2024-06-22) emacs-29.4 +GNU Emacs 30.1 (2025-02-23) emacs-30.1 + ---------------------------------------------------------------------- This file is part of GNU Emacs. commit bcba098505e4f80eef41e4be9726f1f9868223f3 Author: Stefan Kangas Date: Sun Feb 23 17:19:47 2025 +0100 ; * ChangeLog.4: Update. diff --git a/ChangeLog.4 b/ChangeLog.4 index 8eaed786a75..0271c67981a 100644 --- a/ChangeLog.4 +++ b/ChangeLog.4 @@ -1,3 +1,44 @@ +2025-02-23 Stefan Kangas + + Mention CVE-2025-1244 in NEWS + + * etc/NEWS: Document CVE-2025-1244. + + For anyone looking to backport this, the fix is in commit + 820f0793f0b46448928905552726c1f1b999062f. + +2025-02-23 Yuan Fu + + Use character position for ranges in treesit_sync_visible_region + + * src/treesit.c (treesit_sync_visible_region): Use character position + instead of byte position when comparing to ranges, because the + ranges are in character position. + +2025-02-21 Po Lu + + Fix reported Haiku build error in emacs-30.1-rc1 + + * src/haiku_support.cc (keysym_from_raw_char): Don't define + duplicate cases on the previous release. + +2025-02-20 Stefan Kangas + + Bump Emacs version to 30.1 + + * README: + * configure.ac: + * exec/configure.ac: + * msdos/sed2v2.inp: + * nt/README.W32: Bump Emacs version to 30.1. + +2025-02-20 Stefan Kangas + + Update files for Emacs 30.1 + + * ChangeLog.4: + * etc/AUTHORS: Update for Emacs 30.1. + 2025-02-19 Po Lu Fix remaining Android bugs reported over the past months @@ -203580,7 +203621,7 @@ This file records repository revisions from commit f2ae39829812098d8269eafbc0fcb98959ee5bb7 (exclusive) to -commit 375c3622e2dac090c62d99baaaac1314f6c9c5e7 (inclusive). +commit 1cda0967b4d3c815fc610794ad6a8fc2b913a3c5 (inclusive). See ChangeLog.3 for earlier changes. ;; Local Variables: commit 1cda0967b4d3c815fc610794ad6a8fc2b913a3c5 Author: Stefan Kangas Date: Sun Feb 23 16:25:37 2025 +0100 Mention CVE-2025-1244 in NEWS * etc/NEWS: Document CVE-2025-1244. For anyone looking to backport this, the fix is in commit 820f0793f0b46448928905552726c1f1b999062f. diff --git a/etc/NEWS b/etc/NEWS index ec14e447859..1a68e70ce48 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -184,6 +184,9 @@ expectations. * Changes in Emacs 30.1 +** Fix shell injection vulnerability in man.el (CVE-2025-1244). +We urge all users to upgrade immediately. + ** New user option 'trusted-content' to allow potentially dangerous features. This option lists those files and directories whose content Emacs should consider as sufficiently trusted to run any part of the code contained commit 2dbf7d0b1b26a9676fbdb56a5955f3f24f521cc4 Author: Yuan Fu Date: Sat Feb 22 23:24:38 2025 -0800 Use character position for ranges in treesit_sync_visible_region * src/treesit.c (treesit_sync_visible_region): Use character position instead of byte position when comparing to ranges, because the ranges are in character position. diff --git a/src/treesit.c b/src/treesit.c index 655eab8af8a..f234698defd 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -1072,12 +1072,12 @@ treesit_sync_visible_region (Lisp_Object parser) ptrdiff_t beg = XFIXNUM (XCAR (range)); ptrdiff_t end = XFIXNUM (XCDR (range)); - if (end <= visible_beg) - /* Even the end is before visible_beg, discard this range. */ + if (end <= BUF_BEGV (buffer)) + /* Even the end is before BUF_BEGV (buffer), discard this range. */ new_ranges_head = XCDR (new_ranges_head); - else if (beg >= visible_end) + else if (beg >= BUF_ZV (buffer)) { - /* Even the beg is after visible_end, discard this range and all + /* Even the beg is after BUF_ZV (buffer), discard this range and all the ranges after it. */ if (NILP (prev_cons)) new_ranges_head = Qnil; @@ -1090,10 +1090,10 @@ treesit_sync_visible_region (Lisp_Object parser) /* At this point, the range overlaps with the visible portion of the buffer in some way (in front / in back / completely encased / completely encases). */ - if (beg < visible_beg) - XSETCAR (range, make_fixnum (visible_beg)); - if (end > visible_end) - XSETCDR (range, make_fixnum (visible_end)); + if (beg < BUF_BEGV (buffer)) + XSETCAR (range, make_fixnum (BUF_BEGV (buffer))); + if (end > BUF_ZV (buffer)) + XSETCDR (range, make_fixnum (BUF_ZV (buffer))); } prev_cons = lisp_ranges; } @@ -1103,8 +1103,8 @@ treesit_sync_visible_region (Lisp_Object parser) options, so just throw the towel: just give the parser a zero range. (Perfect filling!!) */ if (NILP (new_ranges_head)) - new_ranges_head = Fcons (Fcons (make_fixnum (visible_beg), - make_fixnum (visible_beg)), + new_ranges_head = Fcons (Fcons (make_fixnum (BUF_BEGV (buffer)), + make_fixnum (BUF_BEGV (buffer))), Qnil); XTS_PARSER (parser)->last_set_ranges = new_ranges_head;