commit 94ba1b097ed12b9b77ecef4899c18b46b7e2dd36 (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Mon Mar 10 12:44:26 2025 +0800 Reenable mmap-based dump allocation on wide int configurations * src/pdumper.c (VM_SUPPORTED): Don't define to 0 when !USE_LSB_TAG if WIDE_EMACS_INT. diff --git a/src/pdumper.c b/src/pdumper.c index 166ba32eab7..de213130756 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -77,7 +77,7 @@ along with GNU Emacs. If not, see . */ #define VM_POSIX 1 #define VM_MS_WINDOWS 2 -#if !USE_LSB_TAG +#if !USE_LSB_TAG && !defined WIDE_EMACS_INT # define VM_SUPPORTED 0 #elif defined (HAVE_MMAP) && defined (MAP_FIXED) # define VM_SUPPORTED VM_POSIX commit ab5bfcebddf4c0613ef352231628d4034c8cb178 Author: Po Lu Date: Mon Mar 10 12:41:12 2025 +0800 Fix bug#76805 * src/xterm.c (x_fast_mouse_position): Clear the mouse_moved flag whether or not mouse motion is reported, to avoid repeated polling for mouse movement. (bug#76806) diff --git a/src/xterm.c b/src/xterm.c index 2ccf267bbd3..b21efd5a2a2 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -14878,6 +14878,14 @@ x_fast_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, return; } + FOR_EACH_FRAME (tail, frame) + { + if (FRAME_X_P (XFRAME (frame)) + && (FRAME_DISPLAY_INFO (XFRAME (frame)) + == dpyinfo)) + XFRAME (frame)->mouse_moved = false; + } + if (!EQ (Vx_use_fast_mouse_position, Qreally_fast)) { /* This means that Emacs should select a frame and report the @@ -14886,14 +14894,6 @@ x_fast_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, window beneath the pointer, and was borrowed from haiku_mouse_position in haikuterm.c. */ - FOR_EACH_FRAME (tail, frame) - { - if (FRAME_X_P (XFRAME (frame)) - && (FRAME_DISPLAY_INFO (XFRAME (frame)) - == dpyinfo)) - XFRAME (frame)->mouse_moved = false; - } - if (gui_mouse_grabbed (dpyinfo) && !EQ (track_mouse, Qdropping) && !EQ (track_mouse, Qdrag_source)) @@ -14952,8 +14952,8 @@ x_fast_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, } else { - /* This means Emacs should only report the coordinates of the - last mouse motion. */ + /* This means Emacs should only report the coordinates of the last + mouse motion. */ if (dpyinfo->last_mouse_motion_frame) { @@ -14963,15 +14963,6 @@ x_fast_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, *y = make_fixnum (dpyinfo->last_mouse_motion_y); *bar_window = Qnil; *part = scroll_bar_nowhere; - - FOR_EACH_FRAME (tail, frame) - { - if (FRAME_X_P (XFRAME (frame)) - && (FRAME_DISPLAY_INFO (XFRAME (frame)) - == dpyinfo)) - XFRAME (frame)->mouse_moved = false; - } - dpyinfo->last_mouse_motion_frame->mouse_moved = false; } } commit d343a80e6e1854ffdbea1378f0bc4f836fd01ea4 Author: Po Lu Date: Mon Mar 10 11:31:50 2025 +0800 ; Fix function declarations in frame.el * lisp/frame.el (widget-field-text-end, widget-field-start) (widget-get): Correct function declarations. diff --git a/lisp/frame.el b/lisp/frame.el index 3eccb9a5848..cf8aff826c1 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -94,8 +94,9 @@ handles the corresponding kind of display.") "vertical-scroll-bars" "visibility" "wait-for-wm" "width" "z-group") "List of special frame parameters that makes sense to customize.") -(declare-function "widget-field-text-end" "wid-edit") -(declare-function "widget-field-start" "wid-edit") +(declare-function widget-field-text-end "wid-edit") +(declare-function widget-field-start "wid-edit") +(declare-function widget-get "wid-edit") (defun frame--complete-parameter-value (widget) "Provide completion for WIDGET, which holds frame parameter's values." commit 02681b0fbf02913cd474e082f67649f14115e4a6 Author: Po Lu Date: Mon Mar 10 11:28:38 2025 +0800 Don't claim that xftfont is being considered for deletion * configure.ac: Don't claim that Xft is being considered for deletion or that recent releases are buggy, or imply that HarfBuzz support is exclusive to Cairo. diff --git a/configure.ac b/configure.ac index 9cd19bb6ae6..a3fc4e9fe5b 100644 --- a/configure.ac +++ b/configure.ac @@ -7865,9 +7865,8 @@ fi if test "${HAVE_XFT}" = yes; then AC_MSG_WARN([This configuration uses libXft, which has a number of - font rendering issues, and is being considered for removal in the - next release of Emacs. Please consider using Cairo graphics + - HarfBuzz text shaping instead (they are auto-detected if the + font rendering issues in its earlier releases. Please consider + using Cairo graphics instead (they are auto-detected if the relevant development headers are installed).]) fi commit c4a282316633bdc6a21077350650ecd97868934c Author: Stefan Monnier Date: Sun Mar 9 22:07:39 2025 -0400 (makefile-dependency-regex): Fix bug#76759 * lisp/progmodes/make-mode.el (makefile-dependency-regex): Decompose the regexp to be more understandable, and then change it so the target part can't accidentally match a TAB. * test/lisp/progmodes/make-mode-tests.el (make-mode-tests--bug17400): New test. diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el index 782e0168ed8..d5fdd063825 100644 --- a/lisp/progmodes/make-mode.el +++ b/lisp/progmodes/make-mode.el @@ -225,8 +225,18 @@ not be enclosed in { } or ( )." ;; that if you change this regexp you might have to fix the imenu ;; index in makefile-imenu-generic-expression. (defvar makefile-dependency-regex - ;; Allow for two nested levels $(v1:$(v2:$(v3:a=b)=c)=d) - "^\\(\\(?:\\$\\(?:[({]\\(?:\\$\\(?:[({]\\(?:\\$\\(?:[^({]\\|.[^\n$#})]+?[})]\\)\\|[^\n$#)}]\\)+?[})]\\|[^({]\\)\\|[^\n$#)}]\\)+?[})]\\|[^({]\\)\\|[^\n$#:=]\\)+?\\)\\(:\\)\\(?:[ \t]*$\\|[^=\n]\\(?:[^#\n]*?;[ \t]*\\(.+\\)\\)?\\)" + (letrec ((elems-re + (lambda (n &optional outer) + (if (< n 1) + "[^\n$#})]+?" + (concat "\\(?:\\$\\(?:" + "[({]" (funcall elems-re (- n 1)) "[})]" + "\\|[^({]\\)" + "\\|[^\n$#" (if outer "\t:=" ")}") "]\\)+?"))))) + (concat + ;; Allow for two nested levels $(v1:$(v2:$(v3:a=b)=c)=d) + "^\\(" (funcall elems-re 3 'outer) + "\\)\\(:\\)\\(?:[ \t]*$\\|[^=\n]\\(?:[^#\n]*?;[ \t]*\\(.+\\)\\)?\\)")) "Regex used to find dependency lines in a makefile.") (defconst makefile-bsdmake-dependency-regex diff --git a/test/lisp/progmodes/make-mode-tests.el b/test/lisp/progmodes/make-mode-tests.el new file mode 100644 index 00000000000..07b5572b315 --- /dev/null +++ b/test/lisp/progmodes/make-mode-tests.el @@ -0,0 +1,42 @@ +;;; make-mode-tests.el --- tests for make-mode.el -*- lexical-binding: t -*- + +;; 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 . + +;;; Code: + +(require 'ert) + +(ert-deftest make-mode-tests--bug17400 () + (let ((code " +foo: + bar; : baz")) + (with-temp-buffer + (insert code "\n") + (makefile-mode) + (font-lock-ensure) + (re-search-backward "bar") + (let ((bar-pos (point))) + (re-search-backward "foo") + (let ((foo-pos (point))) + ;; Make sure we don't confuse "bar;:" for a target! + (should-not (equal (get-text-property bar-pos 'face) + (get-text-property foo-pos 'face)))))))) + +(provide 'make-mode-tests) + +;;; make-mode-tests.el ends here commit 5176eeb3003a4d31053b07a9c6045da723fa257d Author: Po Lu Date: Mon Mar 10 09:43:13 2025 +0800 ; Correct typos in commentary and error messages * src/lisp.h (USE_LSB_TAG): * src/pdumper.c (pdumper_load): Correct typos in commentary and error messages. diff --git a/src/lisp.h b/src/lisp.h index 22c822ad12f..243e8cc7f36 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -257,9 +257,9 @@ DEFINE_GDB_SYMBOL_BEGIN (bool, USE_LSB_TAG) && !defined __alignas_is_defined \ && __STDC_VERSION__ < 202311 && __cplusplus < 201103) #define USE_LSB_TAG 0 -#else /* EMACS_INT_WIDTH >= GCALIGNMENT || defined alignas ... */ +#else /* ALIGNOF_EMACS_INT >= IDEAL_GCALIGNMENT || defined alignas ... */ #define USE_LSB_TAG (VAL_MAX / 2 < INTPTR_MAX) -#endif /* EMACS_INT_WIDTH >= GCALIGNMENT || defined alignas ... */ +#endif /* ALIGNOF_EMACS_INT >= IDEAL_GCALIGNMENT || defined alignas ... */ DEFINE_GDB_SYMBOL_END (USE_LSB_TAG) /* Mask for the value (as opposed to the type bits) of a Lisp object. */ diff --git a/src/pdumper.c b/src/pdumper.c index 8e10e561bcf..166ba32eab7 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -5810,7 +5810,7 @@ pdumper_load (const char *dump_filename, char *argv0) if ((dump_base + dump_size) & ~VALMASK) { fprintf (stderr, - "Failed to load dump file: 0x%p+0x%p & 0x%p != 0\n", + "Failed to load dump file: 0x%p+0x%p & ~0x%p != 0\n", (void *) dump_base, (void *) dump_size, (void *) (uintptr_t) VALMASK); goto out; commit 0861da138b91b936a1b307fd59622d98f9b22cc6 Author: Mauro Aranda Date: Sun Mar 9 19:07:40 2025 -0300 Provide better completion for customizing frame parameters * lisp/frame.el (frame--special-parameters): New const. (frame--complete-parameter-value): New function. (initial-frame-alist, minibuffer-frame-alist): Use them in :type. (Bug#39143) * lisp/cus-start.el (default-frame-alist): Use them here as well. * src/frame.c (frame_parms): Add comment to try to keep frame--special-parameters updated. diff --git a/lisp/cus-start.el b/lisp/cus-start.el index b4c20caccc1..7d17249f78d 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -317,10 +317,13 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of (vertical-centering-font-regexp display (choice (const nil) regexp)) ;; frame.c - (default-frame-alist frames - (repeat (cons :format "%v" - (symbol :tag "Parameter") - (sexp :tag "Value")))) + (default-frame-alist + frames + (repeat (cons :format "%v" + (symbol :tag "Parameter" + :completions ,frame--special-parameters) + (sexp :tag "Value" + :complete frame--complete-parameter-value)))) (mouse-highlight mouse (choice (const :tag "disabled" nil) (const :tag "always shown" t) (other :tag "hidden by keypress" 1)) diff --git a/lisp/frame.el b/lisp/frame.el index e66270130d2..3eccb9a5848 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -60,6 +60,78 @@ The car of each entry is a regular expression matching a display name string. The cdr is a symbol giving the window-system that handles the corresponding kind of display.") +;; If you're adding a new frame parameter to `frame_parms' in frame.c, +;; consider if it makes sense for the user to customize it via +;; `initial-frame-alist' and the like. +;; If it does, add it here, in order to provide completion for +;; that parameter in the Customize UI. +;; If the parameter has some special values, modify +;; `frame--complete-parameter-value' to provide completion for those +;; values as well. +(defconst frame--special-parameters + '("alpha" "alpha-background" "auto-hide-function" "auto-lower" + "auto-raise" "background-color" "background-mode" "border-color" + "border-width" "bottom-divider-width" "bottom-visible" "buffer-list" + "buffer-predicate" "child-frame-border-width" "cursor-color" + "cursor-type" "delete-before" "display" "display-type" + "drag-internal-border" "drag-with-header-line" "drag-with-mode-line" + "drag-with-tab-line" "explicit-name" "fit-frame-to-buffer-margins" + "fit-frame-to-buffer-sizes" "font" "font-backend" "foreground-color" + "fullscreen" "fullscreen-restore" "height" "horizontal-scroll-bars" + "icon-left" "icon-name" "icon-top" "icon-type" + "inhibit-double-buffering" "internal-border-width" "keep-ratio" + "left" "left-fringe" "line-spacing" "menu-bar-lines" "min-height" + "min-width" "minibuffer" "minibuffer-exit" "mouse-color" + "mouse-wheel-frame" "name" "no-accept-focus" "no-focus-on-map" + "no-other-frame" "no-special-glyphs" "ns-appearance" + "ns-transparent-titlebar" "outer-window-id" "override-redirect" + "parent-frame" "right-fringe" "rigth-divider-width" "screen-gamma" + "scroll-bar-background" "scroll-bar-foreground" "scroll-bar-height" + "scroll-bar-width" "shaded" "skip-taskbar" "snap-width" "sticky" + "tab-bar-lines" "title" "tool-bar-lines" "tool-bar-position" "top" + "top-visible" "tty-color-mode" "undecorated" "unspittable" + "use-frame-synchronization" "user-position" "user-size" + "vertical-scroll-bars" "visibility" "wait-for-wm" "width" "z-group") + "List of special frame parameters that makes sense to customize.") + +(declare-function "widget-field-text-end" "wid-edit") +(declare-function "widget-field-start" "wid-edit") + +(defun frame--complete-parameter-value (widget) + "Provide completion for WIDGET, which holds frame parameter's values." + (let* ((parameter (widget-value + (nth 0 + (widget-get (widget-get widget :parent) :children)))) + (comps (cond ((eq parameter 'display-type) + '("color" "grayscale" "mono")) + ((eq parameter 'z-group) '("nil" "above" "below")) + ((memq parameter '(fullscreen fullscreen-restore)) + '("fullwidth" "fullheight" "fullboth" "maximized")) + ((eq parameter 'cursor-type) + '("t" "nil" "box" "hollow" "bar" "hbar")) + ((eq parameter 'vertical-scroll-bars) + '("nil" "left" "right")) + ((eq parameter 'tool-bar-position) + '("top" "bottom" "left" "right")) + ((eq parameter 'minibuffer) + '("t" "nil" "only")) + ((eq parameter 'minibuffer-exit) + '("nil" "t" "iconify-frame" "delete-frame")) + ((eq parameter 'visibility) '("nil" "t" "icon")) + ((memq parameter '(ns-appearance background-mode)) + '("dark" "light")) + ((eq parameter 'font-backend) + '("x" "xft" "xfthb" "ftcr" "ftcrhb" "gdi" + "uniscribe" "harfbuzz")) + ((memq parameter '(buffer-predicate auto-hide-function)) + (apply-partially + #'completion-table-with-predicate + obarray #'fboundp 'strict)) + (t nil)))) + (completion-in-region (widget-field-start widget) + (max (point) (widget-field-text-end widget)) + comps))) + ;; The initial value given here used to ask for a minibuffer. ;; But that's not necessary, because the default is to have one. ;; By not specifying it here, we let an X resource specify it. @@ -91,9 +163,11 @@ process: * Set `initial-frame-alist' in your normal init file in a way that matches the X resources, to override what you put in `default-frame-alist'." - :type '(repeat (cons :format "%v" - (symbol :tag "Parameter") - (sexp :tag "Value"))) + :type `(repeat (cons :format "%v" + (symbol :tag "Parameter" + :completions ,frame--special-parameters) + (sexp :tag "Value" + :complete frame--complete-parameter-value))) :group 'frames) (defcustom minibuffer-frame-alist '((width . 80) (height . 2)) @@ -110,9 +184,11 @@ You can set this in your init file; for example, It is not necessary to include (minibuffer . only); that is appended when the minibuffer frame is created." - :type '(repeat (cons :format "%v" - (symbol :tag "Parameter") - (sexp :tag "Value"))) + :type `(repeat (cons :format "%v" + (symbol :tag "Parameter" + :completions ,frame--special-parameters) + (sexp :tag "Value" + :complete frame--complete-parameter-value))) :group 'frames) (defun frame-deletable-p (&optional frame) diff --git a/src/frame.c b/src/frame.c index 1a5c2f5c3d4..b386839f34c 100644 --- a/src/frame.c +++ b/src/frame.c @@ -4392,6 +4392,10 @@ struct frame_parm_table { int sym; }; +/* If you're adding a new frame parameter here, consider if it makes sense + for the user to customize it via `initial-frame-alist' and the like. + If it does, add it to `frame--special-parameters' in frame.el, in order + to provide completion in the Customize UI for the new parameter. */ static const struct frame_parm_table frame_parms[] = { {"auto-raise", SYMBOL_INDEX (Qauto_raise)}, commit 731af8747cb07aea532d9e9fd246857a88625a44 Author: Stefan Kangas Date: Sun Mar 9 18:28:53 2025 +0100 ; Fix byte-compiler warning diff --git a/test/lisp/vc/log-edit-tests.el b/test/lisp/vc/log-edit-tests.el index 6a312c6dac7..fdc9a0b41b9 100644 --- a/test/lisp/vc/log-edit-tests.el +++ b/test/lisp/vc/log-edit-tests.el @@ -364,7 +364,7 @@ Report color and/or grayscale properly. "Helper function for the log-edit-done-strip-cvs-lines tests. Tests that running log-edit-done-strip-cvs-lines as a log-edit-done-hook produces the WANTED string when run on INITIAL-TEXT with -'log-edit-vc-backend' set to VC-BACKEND.\"" +\\='log-edit-vc-backend' set to VC-BACKEND.\"" (with-temp-buffer (let ((log-edit-done-hook 'log-edit-done-strip-cvs-lines) (log-edit-vc-backend vc-backend)) commit ce03bf252ae9bff28a6def163cb3f4fa102e691a Author: Stefan Kangas Date: Sat Mar 8 18:24:26 2025 +0100 Make second arg to defvar-local optional This change allows declaring a variable both special and buffer-local like so: (defvar-local foo) * lisp/subr.el (defvar-local): Make second argument optional. * test/lisp/subr-tests.el (subr-test-defvar-local): New test. * doc/lispref/variables.texi (Creating Buffer-Local): Document above change. * etc/NEWS: * lisp/mb-depth.el (minibuffer-depth-overlay): * lisp/minibuf-eldef.el (minibuf-eldef-initial-input) (minibuf-eldef-initial-buffer-length) (minibuf-eldef-showing-default-in-prompt, minibuf-eldef-overlay): * lisp/misc.el (list-dynamic-libraries--loaded-only-p): * lisp/simple.el (minibuffer-history-isearch-message-overlay): Use above new one-argument form of 'defvar-local'. diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi index 46027edb041..f8a361aa7ce 100644 --- a/doc/lispref/variables.texi +++ b/doc/lispref/variables.texi @@ -1649,7 +1649,7 @@ on having separate values in separate buffers, then using @code{make-variable-buffer-local} can be the best solution. @end deffn -@defmac defvar-local variable value &optional docstring +@defmac defvar-local variable &optional value docstring This macro defines @var{variable} as a variable with initial value @var{value} and @var{docstring}, and marks it as automatically buffer-local. It is equivalent to calling @code{defvar} followed by diff --git a/etc/NEWS b/etc/NEWS index 4f0d052f1c3..926d426eaae 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1565,6 +1565,11 @@ and signal an error if they are given a non-number. They return non-nil if an integer is odd or even, respectively, and signal an error if they are given a non-integer. ++++ +** The 'defvar-local' macro second argument is now optional. +This means that you can now call it with just one argument, like +'defvar', to declare a variable both special, and buffer-local. + ** ERT *** Some experimental ERT macros are now considered stable. diff --git a/lisp/mb-depth.el b/lisp/mb-depth.el index 7c00f5b1989..5fc66a8c8db 100644 --- a/lisp/mb-depth.el +++ b/lisp/mb-depth.el @@ -50,8 +50,7 @@ the `minibuffer-depth-indicator' face." ;; An overlay covering the prompt. This is a buffer-local variable in ;; each affected minibuffer. ;; -(defvar minibuffer-depth-overlay) -(make-variable-buffer-local 'minibuffer-depth-overlay) +(defvar-local minibuffer-depth-overlay) ;; This function goes on minibuffer-setup-hook (defun minibuffer-depth-setup () diff --git a/lisp/minibuf-eldef.el b/lisp/minibuf-eldef.el index 4b72cd9511c..50ab2354214 100644 --- a/lisp/minibuf-eldef.el +++ b/lisp/minibuf-eldef.el @@ -88,19 +88,16 @@ should be displayed in its place.") ;;; The following are all local variables in the minibuffer ;; Input pre-inserted into the minibuffer before the user can edit it. -(defvar minibuf-eldef-initial-input) -(make-variable-buffer-local 'minibuf-eldef-initial-input) +(defvar-local minibuf-eldef-initial-input) + ;; and the length of the buffer with it inserted. -(defvar minibuf-eldef-initial-buffer-length) -(make-variable-buffer-local 'minibuf-eldef-initial-buffer-length) +(defvar-local minibuf-eldef-initial-buffer-length) ;; True if the current minibuffer prompt contains the default spec. -(defvar minibuf-eldef-showing-default-in-prompt) -(make-variable-buffer-local 'minibuf-eldef-showing-default-in-prompt) +(defvar-local minibuf-eldef-showing-default-in-prompt) ;; An overlay covering the default portion of the prompt -(defvar minibuf-eldef-overlay) -(make-variable-buffer-local 'minibuf-eldef-overlay) +(defvar-local minibuf-eldef-overlay) ;;; Hook functions diff --git a/lisp/misc.el b/lisp/misc.el index 85ba1649d21..b2422648744 100644 --- a/lisp/misc.el +++ b/lisp/misc.el @@ -262,8 +262,7 @@ variation of `C-x M-c M-butterfly' from url `https://xkcd.com/378/'." ;; A command to list dynamically loaded libraries. This useful in ;; environments where dynamic-library-alist is used, i.e., Windows -(defvar list-dynamic-libraries--loaded-only-p) -(make-variable-buffer-local 'list-dynamic-libraries--loaded-only-p) +(defvar-local list-dynamic-libraries--loaded-only-p) (defun list-dynamic-libraries--loaded (from) "Compute the \"Loaded from\" column. diff --git a/lisp/simple.el b/lisp/simple.el index 2d36062e9c2..32479f3c092 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -3235,8 +3235,7 @@ Return 0 if current buffer is not a minibuffer." ;; isearch minibuffer history (add-hook 'minibuffer-setup-hook 'minibuffer-history-isearch-setup) -(defvar minibuffer-history-isearch-message-overlay) -(make-variable-buffer-local 'minibuffer-history-isearch-message-overlay) +(defvar-local minibuffer-history-isearch-message-overlay) (defun minibuffer-history-isearch-setup () "Set up a minibuffer for using isearch to search the minibuffer history. diff --git a/lisp/subr.el b/lisp/subr.el index 110bebed789..932a22d3250 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -192,14 +192,20 @@ pair. (setq pairs (cdr (cdr pairs)))) (macroexp-progn (nreverse expr)))) -(defmacro defvar-local (var val &optional docstring) - "Define VAR as a buffer-local variable with default value VAL. +(defmacro defvar-local (symbol &rest args) + "Define SYMBOL as a buffer-local variable with default value VALUE. Like `defvar' but additionally marks the variable as being automatically -buffer-local wherever it is set." +buffer-local wherever it is set. +\n(fn symbol &optional value docstring)" (declare (debug defvar) (doc-string 3) (indent 2)) ;; Can't use backquote here, it's too early in the bootstrap. - (list 'progn (list 'defvar var val docstring) - (list 'make-variable-buffer-local (list 'quote var)))) + (let ((value (car-safe args)) + (docstring (car-safe (cdr-safe args)))) + (list 'progn + (if (zerop (length args)) + (list 'defvar symbol) + (list 'defvar symbol value docstring)) + (list 'make-variable-buffer-local (list 'quote symbol))))) (defun buffer-local-boundp (symbol buffer) "Return non-nil if SYMBOL is bound in BUFFER. diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 98fd1cad894..df330bf60fc 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -30,6 +30,16 @@ (require 'ert-x) (eval-when-compile (require 'cl-lib)) +(defvar-local subr-tests--local-var1) +(defvar-local subr-tests--local-var2 'hello) +(defvar-local subr-tests--local-var3 nil "Doc.") +(ert-deftest subr-test-defvar-local () + (should (local-variable-if-set-p 'subr-tests--local-var1)) + (should (local-variable-if-set-p 'subr-tests--local-var2)) + (should (eq subr-tests--local-var2 'hello)) + (should (local-variable-if-set-p 'subr-tests--local-var3)) + (should (get 'subr-tests--local-var3 'variable-documentation))) + (ert-deftest subr-test-apply-partially () (should (functionp (apply-partially #'identity))) (should (functionp (apply-partially #'list 1 2 3))) commit a6523599f985eae5f884834bf15bd714c1cf557b Author: Stefan Kangas Date: Sat Mar 8 14:00:42 2025 +0100 Use lisp-data-mode in recentf-save-file * lisp/recentf.el (recentf-save-file-header): Add cookie to use lisp-data-mode in recentf-save-file. diff --git a/lisp/recentf.el b/lisp/recentf.el index 70e01907a0e..172ce704d93 100644 --- a/lisp/recentf.el +++ b/lisp/recentf.el @@ -1316,7 +1316,7 @@ Optional argument N must be a valid digit number. It defaults to 1. ;;; Save/load/cleanup the recent list ;; (defconst recentf-save-file-header - ";;; Automatically generated by `recentf' on %s.\n" + ";;; Automatically generated by `recentf' on %s. -*- mode: lisp-data -*-\n" "Header to be written into the `recentf-save-file'.") (defconst recentf-save-file-coding-system @@ -1344,7 +1344,7 @@ Write data into the file specified by `recentf-save-file'." (point-max) (expand-file-name recentf-save-file) nil (unless (or (called-interactively-p 'interactive) - recentf-show-messages) + recentf-show-messages) 'quiet)) (when recentf-save-file-modes (set-file-modes recentf-save-file recentf-save-file-modes)) commit 3396f0e5678cf1edb0056917182b30927a35335b Author: Stefan Kangas Date: Sat Mar 8 13:41:22 2025 +0100 Use .eld for some relevant cache and data files * lisp/bookmark.el (bookmark-default-file): * lisp/net/nsm.el (nsm-settings-file): * lisp/progmodes/project.el (project-list-file): * lisp/saveplace.el (save-place-file): Rename files to have the file suffix ".eld". This change is backwards-compatible. diff --git a/lisp/bookmark.el b/lisp/bookmark.el index 42b6187d917..99bb26e83cc 100644 --- a/lisp/bookmark.el +++ b/lisp/bookmark.el @@ -81,12 +81,13 @@ To specify the file in which to save them, modify the variable 'bookmark-default-file "27.1") (define-obsolete-variable-alias 'bookmark-file 'bookmark-default-file "27.1") (defcustom bookmark-default-file - (locate-user-emacs-file "bookmarks" ".emacs.bmk") + (locate-user-emacs-file '("bookmarks.eld" "bookmarks") ".emacs.bmk") "File in which to save bookmarks by default." ;; The current default file is defined via the internal variable ;; `bookmark-bookmarks-timestamp'. This does not affect the value ;; of `bookmark-default-file'. - :type 'file) + :type 'file + :version "31.1") (defcustom bookmark-watch-bookmark-file t "If non-nil reload the default bookmark file if it was changed. diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el index faff22304dc..1f910242666 100644 --- a/lisp/net/nsm.el +++ b/lisp/net/nsm.el @@ -79,9 +79,10 @@ option." (const :tag "Off" nil) (function :tag "Custom function"))) -(defcustom nsm-settings-file (locate-user-emacs-file "network-security.data") +(defcustom nsm-settings-file + (locate-user-emacs-file '("network-security.eld" "network-security.data")) "The file the security manager settings will be stored in." - :version "25.1" + :version "31.1" :type 'file) (defcustom nsm-save-host-names nil diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index a077e647db3..4eac541167a 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1831,10 +1831,11 @@ Also see the `project-kill-buffers-display-buffer-list' variable." ;;; Project list -(defcustom project-list-file (locate-user-emacs-file "projects") +(defcustom project-list-file + (locate-user-emacs-file '("projects.eld" "projects")) "File in which to save the list of known projects." :type 'file - :version "28.1" + :version "31.1" :group 'project) (defcustom project-list-exclude nil diff --git a/lisp/recentf.el b/lisp/recentf.el index e9173c406b7..70e01907a0e 100644 --- a/lisp/recentf.el +++ b/lisp/recentf.el @@ -82,10 +82,11 @@ See the command `recentf-save-list'." (const :tag "No Limit" nil)) :version "31.1") -(defcustom recentf-save-file (locate-user-emacs-file "recentf" ".recentf") +(defcustom recentf-save-file + (locate-user-emacs-file '("recentf.eld" "recentf") ".recentf") "File to save the recent list into." :group 'recentf - :version "24.4" + :version "31.1" :type 'file :initialize 'custom-initialize-default :set (lambda (symbol value) diff --git a/lisp/saveplace.el b/lisp/saveplace.el index 19075d8c7ea..0cb81ebaf55 100644 --- a/lisp/saveplace.el +++ b/lisp/saveplace.el @@ -62,9 +62,10 @@ when the place in that buffer was recorded. This alist is saved between Emacs sessions.") -(defcustom save-place-file (locate-user-emacs-file "places" ".emacs-places") +(defcustom save-place-file + (locate-user-emacs-file '("places.eld" "places") ".emacs-places") "Name of the file that records `save-place-alist' value." - :version "24.4" ; added locate-user-emacs-file + :version "31.1" :type 'file) (defcustom save-place-version-control nil commit 87db670d045bea2d90139b1f741eea8db7c193ea Author: Stefan Kangas Date: Sat Mar 8 13:02:58 2025 +0100 Make locate-user-emacs-file accept a list too This can be used to migrate to a new name, while also keeping backwards-compatible support for an old name. * lisp/files.el (locate-user-emacs-file): Accept a list as the NEW-NAME argument. * test/lisp/files-tests.el (files-test-locate-user-emacs-file): New test for the above. diff --git a/lisp/files.el b/lisp/files.el index bf05939ebeb..aa4da83bfe0 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -1242,12 +1242,24 @@ inaccessible location." If NEW-NAME exists in `user-emacs-directory', return it. Else if OLD-NAME is non-nil and ~/OLD-NAME exists, return ~/OLD-NAME. Else return NEW-NAME in `user-emacs-directory', creating the -directory if it does not exist." +directory if it does not exist. + +NEW-NAME can also be a list, in which case consider all names in that +list, from last to first, and use the first name that exists. If none +of them exists, use the `car' of that list." (convert-standard-filename (let* ((home (concat "~" (or init-file-user ""))) (at-home (and old-name (expand-file-name old-name home))) (bestname (abbreviate-file-name - (expand-file-name new-name user-emacs-directory)))) + (if (listp new-name) + (or (car (seq-filter + #'file-exists-p + (mapcar + (lambda (f) + (expand-file-name f user-emacs-directory)) + (reverse new-name)))) + (expand-file-name (car new-name) user-emacs-directory)) + (expand-file-name new-name user-emacs-directory))))) (if (and at-home (not (file-readable-p bestname)) (file-readable-p at-home)) at-home diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el index ed63b6f6fb4..9f17747da1f 100644 --- a/test/lisp/files-tests.el +++ b/test/lisp/files-tests.el @@ -68,7 +68,18 @@ (should (equal (locate-user-emacs-file basename) in-edir)) (should (equal (locate-user-emacs-file basename "anything") - in-edir))))))) + in-edir))) + ;; NEW-FILE is a list. + (should (equal (locate-user-emacs-file '("first" "second")) + (expand-file-name "first" user-emacs-directory))) + (should (equal (locate-user-emacs-file '("first" "second") "never") + (expand-file-name "first" user-emacs-directory))) + (let ((exists (expand-file-name "exists" user-emacs-directory))) + (write-region "data" nil exists nil 'quietly) + (should (equal (locate-user-emacs-file '("missing" "exists")) + exists)) + (should (equal (locate-user-emacs-file '("missing1" "exists") "missing2") + exists))))))) ;; Test combinations: ;; `enable-local-variables' t, nil, :safe, :all, or something else. commit 9c6e8589ee5eae0f793994c96d434b77f54749de Author: Stefan Kangas Date: Sat Mar 8 12:23:50 2025 +0100 Add test for 'locate-user-emacs-file' * test/lisp/files-tests.el (files-test-locate-user-emacs-file): New test. diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el index 0e4f649d3d1..ed63b6f6fb4 100644 --- a/test/lisp/files-tests.el +++ b/test/lisp/files-tests.el @@ -37,6 +37,39 @@ (defun files-test-fun1 () (setq files-test-result t)) +(ert-deftest files-test-locate-user-emacs-file () + (ert-with-temp-directory home + (with-environment-variables (("HOME" home)) + (let* ((user-emacs-directory (expand-file-name ".emacs.d/" home))) + (make-directory user-emacs-directory 'parents) + (should-error (locate-user-emacs-file nil "any-file") + :type 'wrong-type-argument) + ;; No file exists. + (should (equal (locate-user-emacs-file "always") + (expand-file-name "always" user-emacs-directory))) + (should (equal (locate-user-emacs-file "always" "never") + (expand-file-name "always" user-emacs-directory))) + ;; Only the file in $HOME/.conf exists. + (let ((exists (expand-file-name "exists" home))) + (write-region "data" nil exists nil 'quietly) + (should (equal (locate-user-emacs-file "missing" "exists") + exists))) + ;; Only the file in ~/.emacs.d/ exists. + (let ((exists (expand-file-name "exists" user-emacs-directory))) + (write-region "data" nil exists nil 'quietly) + (should (equal (locate-user-emacs-file "exists" "missing") + exists))) + ;; Both files exist. + (let* ((basename "testconfig") + (in-home (expand-file-name basename home)) + (in-edir (expand-file-name basename user-emacs-directory))) + (write-region "data" nil in-home nil 'quietly) + (write-region "data" nil in-edir nil 'quietly) + (should (equal (locate-user-emacs-file basename) + in-edir)) + (should (equal (locate-user-emacs-file basename "anything") + in-edir))))))) + ;; Test combinations: ;; `enable-local-variables' t, nil, :safe, :all, or something else. ;; `enable-local-eval' t, nil, or something else. commit a5f8ce9f1eae29f87fe13adb61bd4e15faa628a2 Author: Po Lu Date: Sun Mar 9 23:02:21 2025 +0800 Re-port to 32-bit systems without alignment primitives * configure.ac (ALIGNOF_INT, ALIGNOF_LONG, ALIGNOF_LONG_LONG): New variables. (emacs_cv_alignas_unavailable): Define if alignas and structure alignment primitives are unavailable. In such an environment, the MSB tagging scheme must be enabled, as must the GNU malloc. * msdos/sed2v2.inp: Adjust correspondingly. * src/alloc.c (union emacs_align_type): Remove types which contain flexible array members. The address of a field subsequent to an aggregate with flexible array members cannot validly be taken. (mark_memory) [!USE_LSB_TAG && !WIDE_EMACS_INT]: Strip type bits before scanning memory. * src/emacs.c (main): * src/eval.c (Fautoload_do_load): * src/fns.c (Frequire): Rename a number of illogically named fields. * src/lisp.h (ALIGNOF_EMACS_INT): Define to the natural alignment of EMACS_INT. (IDEAL_GCALIGNMENT): New macro. (USE_LSB_TAG): Disable if no alignment specifiers are available, WIDE_EMACS_INT is undefined, and the natural alignment of EMACS_INT falls short of LSB tagging's requirements. (gflags): Rename illogically named fields and don't define them as bitfields, which runs afoul of certain compiler issues. (will_dump_p, will_bootstrap_p, will_dump_with_pdumper_p) (dumped_with_pdumper_p): Adjust accordingly. * src/pdumper.c (VM_SUPPORTED): Define to 0 when !USE_LSB_TAG. It is better to read dump files into the heap by hand than to be supplied with an address that is not representable. (_dump_object_start_pseudovector): Rename to dump_object_start_pseudovector, to avoid encroaching on reserved names. (START_DUMP_PVEC): Adjust correspondingly. (dump_mmap_contiguous_vm): Preserve errno around failure cleanup. (dump_bitset_bit_set_p): Work around certain compiler issues. (pdumper_load) [!USE_LSB_TAG]: Reject dump file allocations that are not representable as Lisp_Objects. Tested on i386-unknown-solaris2.10, sparc-sun-solaris2.10. diff --git a/configure.ac b/configure.ac index 13e2d7e16ad..9cd19bb6ae6 100644 --- a/configure.ac +++ b/configure.ac @@ -3218,8 +3218,68 @@ AC_CACHE_CHECK( fi]) doug_lea_malloc=$emacs_cv_var_doug_lea_malloc +AC_CHECK_ALIGNOF([int]) +AC_CHECK_ALIGNOF([long]) +AC_CHECK_ALIGNOF([long long]) +AC_CHECK_SIZEOF([long]) + +AC_CACHE_CHECK([for struct alignment], + [emacs_cv_struct_alignment], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include + struct s { char c; } __attribute__ ((aligned (8))); + struct t { char c; struct s s; }; + char verify[offsetof (struct t, s) == 8 ? 1 : -1]; + ]])], + [emacs_cv_struct_alignment=yes], + [emacs_cv_struct_alignment=no])]) +if test "$emacs_cv_struct_alignment" = yes; then + AC_DEFINE([HAVE_STRUCT_ATTRIBUTE_ALIGNED], [1], + [Define to 1 if 'struct __attribute__ ((aligned (N)))' aligns the + structure to an N-byte boundary.]) +fi + system_malloc=yes +# If it appears as if the system malloc can't be trusted to return +# adequately positioned memory, enable the GNU malloc, which more +# consistently provides allocations at low addresses, as is required for +# the pdumper to load dump files at a representable location. +AS_IF([test "$with_pdumper" = "yes" && test "$with_wide_int" != "yes"], + AC_CHECK_HEADERS([stdalign.h]) + [AC_CACHE_CHECK([whether alignas is required yet unavailable], + [emacs_cv_alignas_unavailable], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_STDALIGN_H +#include +#endif + #include + ]], [[ +#define IDEAL_GCALIGNMENT 8 +#if INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT +# define ALIGNOF_EMACS_INT ALIGNOF_INT +# elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT +# define ALIGNOF_EMACS_INT ALIGNOF_LONG +# elif INTPTR_MAX <= LLONG_MAX +# define ALIGNOF_EMACS_INT ALIGNOF_LONG_LONG +# else +# error "INTPTR_MAX too large" +#endif + +#if (ALIGNOF_EMACS_INT < IDEAL_GCALIGNMENT && !defined alignas \ + && !defined HAVE_STRUCT_ATTRIBUTE_ALIGNED \ + && !defined __alignas_is_defined \ + && __STDC_VERSION__ < 202311 && __cplusplus < 201103) +#error "!USE_LSB_TAG required" +#endif + ]])], [emacs_cv_alignas_unavailable=no], + [emacs_cv_alignas_unavailable=yes])]) + AS_IF([test "$emacs_cv_alignas_unavailable" = "yes"], + [system_malloc=no + AC_MSG_WARN([The GNU memory manager will be enabled as your system +does not guarantee that the portable dumper can allocate memory at a suitably +low address.])])]) + dnl This must be before the test of $ac_cv_func_sbrk below. AC_CHECK_FUNCS_ONCE([sbrk]) @@ -5823,7 +5883,6 @@ AC_SUBST([HAVE_LIBSECCOMP]) AC_SUBST([LIBSECCOMP_LIBS]) AC_SUBST([LIBSECCOMP_CFLAGS]) -AC_CHECK_SIZEOF([long]) SIZEOF_LONG="$ac_cv_sizeof_long" AC_SUBST([SIZEOF_LONG]) @@ -7186,22 +7245,6 @@ else fi AC_SUBST([LIBXMENU]) -AC_CACHE_CHECK([for struct alignment], - [emacs_cv_struct_alignment], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[#include - struct s { char c; } __attribute__ ((aligned (8))); - struct t { char c; struct s s; }; - char verify[offsetof (struct t, s) == 8 ? 1 : -1]; - ]])], - [emacs_cv_struct_alignment=yes], - [emacs_cv_struct_alignment=no])]) -if test "$emacs_cv_struct_alignment" = yes; then - AC_DEFINE([HAVE_STRUCT_ATTRIBUTE_ALIGNED], [1], - [Define to 1 if 'struct __attribute__ ((aligned (N)))' aligns the - structure to an N-byte boundary.]) -fi - AC_C_RESTRICT AC_C_TYPEOF diff --git a/msdos/sed2v2.inp b/msdos/sed2v2.inp index ff6eca0f625..6a6a3c2d9a8 100644 --- a/msdos/sed2v2.inp +++ b/msdos/sed2v2.inp @@ -140,6 +140,9 @@ s/^#undef HAVE_DECL_STRTOIMAX *$/#define HAVE_DECL_STRTOIMAX 1/ s/^#undef HAVE_PDUMPER *$/#define HAVE_PDUMPER 1/ s/^#undef HAVE_STRTOLL *$/#define HAVE_STRTOLL 1/ s/^#undef HAVE_STRTOULL *$/#define HAVE_STRTOULL 1/ +s/^#undef ALIGNOF_INT *$/s/^.*$/#define ALIGNOF_INT 4/ +s/^#undef ALIGNOF_LONG *$/s/^.*$/#define ALIGNOF_LONG 4/ +s/^#undef ALIGNOF_LONG_LONG *$/s/^.*$/#define ALIGNOF_LONG_LONG 4/ /^#undef HAVE_STRUCT_DIRENT_D_TYPE *$/c\ #if __DJGPP__ + (__DJGPP_MINOR__ >= 5) >= 3\ #define HAVE_STRUCT_DIRENT_D_TYPE 1/\ diff --git a/src/alloc.c b/src/alloc.c index 7fa05e54202..c0d68e6c964 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -150,8 +150,6 @@ union emacs_align_type { struct frame frame; struct Lisp_Bignum Lisp_Bignum; - struct Lisp_Bool_Vector Lisp_Bool_Vector; - struct Lisp_Char_Table Lisp_Char_Table; struct Lisp_CondVar Lisp_CondVar; struct Lisp_Finalizer Lisp_Finalizer; struct Lisp_Float Lisp_Float; @@ -160,21 +158,25 @@ union emacs_align_type struct Lisp_Misc_Ptr Lisp_Misc_Ptr; struct Lisp_Mutex Lisp_Mutex; struct Lisp_Overlay Lisp_Overlay; - struct Lisp_Sub_Char_Table Lisp_Sub_Char_Table; struct Lisp_Subr Lisp_Subr; struct Lisp_Sqlite Lisp_Sqlite; struct Lisp_User_Ptr Lisp_User_Ptr; - struct Lisp_Vector Lisp_Vector; struct terminal terminal; struct thread_state thread_state; struct window window; /* Omit the following since they would require including process.h - etc. In practice their alignments never exceed that of the - structs already listed. */ + etc, or because they are defined with flexible array members, which + are rejected by some C99 compilers when this union subsequently + appears in an `alignof' expression. In practice their alignments + never exceed that of the structs already listed. */ #if 0 + struct Lisp_Bool_Vector Lisp_Bool_Vector; + struct Lisp_Char_Table Lisp_Char_Table; + struct Lisp_Sub_Char_Table Lisp_Sub_Char_Table; struct Lisp_Module_Function Lisp_Module_Function; struct Lisp_Process Lisp_Process; + struct Lisp_Vector Lisp_Vector; struct save_window_data save_window_data; struct scroll_bar scroll_bar; struct xwidget_view xwidget_view; @@ -5167,14 +5169,20 @@ mark_memory (void const *start, void const *end) for (pp = start; (void const *) pp < end; pp += GC_POINTER_ALIGNMENT) { void *p = *(void *const *) pp; + intptr_t ip; + +#if !USE_LSB_TAG && !defined WIDE_EMACS_INT + ip = (intptr_t) p; + mark_maybe_pointer ((void *) (ip & VALMASK), false); +#else /* USE_LSB_TAG || WIDE_EMACS_INT */ mark_maybe_pointer (p, false); +#endif /* USE_LSB_TAG || WIDE_EMACS_INT */ /* Unmask any struct Lisp_Symbol pointer that make_lisp_symbol previously disguised by adding the address of 'lispsym'. On a host with 32-bit pointers and 64-bit Lisp_Objects, a Lisp_Object might be split into registers saved into non-adjacent words and P might be the low-order word's value. */ - intptr_t ip; ckd_add (&ip, (intptr_t) p, (intptr_t) lispsym); mark_maybe_pointer ((void *) ip, true); } diff --git a/src/emacs.c b/src/emacs.c index dc7041c2338..6ff7b632c0f 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1311,13 +1311,11 @@ android_emacs_init (int argc, char **argv, char *dump_file) if (!initialized && temacs) { #ifdef HAVE_PDUMPER - if (strcmp (temacs, "pdump") == 0 || - strcmp (temacs, "pbootstrap") == 0) - gflags.will_dump_with_pdumper_ = true; - if (strcmp (temacs, "pbootstrap") == 0) - gflags.will_bootstrap_ = true; - gflags.will_dump_ = - will_dump_with_pdumper_p (); + if (!strcmp (temacs, "pdump") || !strcmp (temacs, "pbootstrap")) + gflags.will_dump_with_pdumper = true; + if (!strcmp (temacs, "pbootstrap")) + gflags.will_bootstrap = true; + gflags.will_dump = will_dump_with_pdumper_p (); if (will_dump_p ()) dump_mode = temacs; #endif diff --git a/src/eval.c b/src/eval.c index a514bb4b8f9..5de723cf3bc 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2389,7 +2389,7 @@ it defines a macro. */) { /* Avoid landing here recursively while outputting the backtrace from the error. */ - gflags.will_dump_ = false; + gflags.will_dump = false; error ("Attempt to autoload %s while preparing to dump", SDATA (SYMBOL_NAME (funname))); } diff --git a/src/fns.c b/src/fns.c index 62283e92eb7..dcbcd2aa40e 100644 --- a/src/fns.c +++ b/src/fns.c @@ -3780,7 +3780,7 @@ FILENAME are suppressed. */) { /* Avoid landing here recursively while outputting the backtrace from the error. */ - gflags.will_dump_ = false; + gflags.will_dump = false; error ("(require %s) while preparing to dump", SDATA (SYMBOL_NAME (feature))); } diff --git a/src/lisp.h b/src/lisp.h index 24e4fe0f84d..22c822ad12f 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -89,18 +89,21 @@ DEFINE_GDB_SYMBOL_END (GCTYPEBITS) typedef int EMACS_INT; typedef unsigned int EMACS_UINT; enum { EMACS_INT_WIDTH = INT_WIDTH, EMACS_UINT_WIDTH = UINT_WIDTH }; +# define ALIGNOF_EMACS_INT ALIGNOF_INT # define EMACS_INT_MAX INT_MAX # define pI "" # elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT typedef long int EMACS_INT; typedef unsigned long EMACS_UINT; enum { EMACS_INT_WIDTH = LONG_WIDTH, EMACS_UINT_WIDTH = ULONG_WIDTH }; +# define ALIGNOF_EMACS_INT ALIGNOF_LONG # define EMACS_INT_MAX LONG_MAX # define pI "l" # elif INTPTR_MAX <= LLONG_MAX typedef long long int EMACS_INT; typedef unsigned long long int EMACS_UINT; enum { EMACS_INT_WIDTH = LLONG_WIDTH, EMACS_UINT_WIDTH = ULLONG_WIDTH }; +# define ALIGNOF_EMACS_INT ALIGNOF_LONG_LONG # define EMACS_INT_MAX LLONG_MAX /* MinGW supports %lld only if __USE_MINGW_ANSI_STDIO is non-zero, which is arranged by config.h, and (for mingw.org) if GCC is 6.0 or @@ -237,13 +240,26 @@ DEFINE_GDB_SYMBOL_END (INTTYPEBITS) expression involving VAL_MAX. */ #define VAL_MAX (EMACS_INT_MAX >> (GCTYPEBITS - 1)) +/* The alignment ideally required of objects subject to garbage + collection. (In the sense that it would be ideal for such an + alignment to be available to enable LSB tagging.) */ +#define IDEAL_GCALIGNMENT 8 + /* Whether the least-significant bits of an EMACS_INT contain the tag. On hosts where pointers-as-ints do not exceed VAL_MAX / 2, USE_LSB_TAG is: a. unnecessary, because the top bits of an EMACS_INT are unused, and b. slower, because it typically requires extra masking. So, USE_LSB_TAG is true only on hosts where it might be useful. */ DEFINE_GDB_SYMBOL_BEGIN (bool, USE_LSB_TAG) +#if (ALIGNOF_EMACS_INT < IDEAL_GCALIGNMENT && !defined alignas \ + && !defined WIDE_EMACS_INT \ + && !defined HAVE_STRUCT_ATTRIBUTE_ALIGNED \ + && !defined __alignas_is_defined \ + && __STDC_VERSION__ < 202311 && __cplusplus < 201103) +#define USE_LSB_TAG 0 +#else /* EMACS_INT_WIDTH >= GCALIGNMENT || defined alignas ... */ #define USE_LSB_TAG (VAL_MAX / 2 < INTPTR_MAX) +#endif /* EMACS_INT_WIDTH >= GCALIGNMENT || defined alignas ... */ DEFINE_GDB_SYMBOL_END (USE_LSB_TAG) /* Mask for the value (as opposed to the type bits) of a Lisp object. */ @@ -262,7 +278,7 @@ DEFINE_GDB_SYMBOL_END (VALMASK) USE_LSB_TAG, 1 otherwise. It must be a literal integer constant, for older versions of GCC (through at least 4.9). */ #if USE_LSB_TAG -# define GCALIGNMENT 8 +# define GCALIGNMENT IDEAL_GCALIGNMENT # if GCALIGNMENT != 1 << GCTYPEBITS # error "GCALIGNMENT and GCTYPEBITS are inconsistent" # endif @@ -629,15 +645,15 @@ extern bool initialized; extern struct gflags { /* True means this Emacs instance was born to dump. */ - bool will_dump_ : 1; - bool will_bootstrap_ : 1; + bool will_dump; + bool will_bootstrap; #ifdef HAVE_PDUMPER /* Set in an Emacs process that will likely dump with pdumper; all Emacs processes may dump with pdumper, however. */ - bool will_dump_with_pdumper_ : 1; + bool will_dump_with_pdumper; /* Set in an Emacs process that has been restored from a portable dump. */ - bool dumped_with_pdumper_ : 1; + bool dumped_with_pdumper; #endif } gflags; @@ -645,7 +661,7 @@ INLINE bool will_dump_p (void) { #if HAVE_PDUMPER - return gflags.will_dump_; + return gflags.will_dump; #else return false; #endif @@ -655,7 +671,7 @@ INLINE bool will_bootstrap_p (void) { #if HAVE_PDUMPER - return gflags.will_bootstrap_; + return gflags.will_bootstrap; #else return false; #endif @@ -665,7 +681,7 @@ INLINE bool will_dump_with_pdumper_p (void) { #if HAVE_PDUMPER - return gflags.will_dump_with_pdumper_; + return gflags.will_dump_with_pdumper; #else return false; #endif @@ -675,7 +691,7 @@ INLINE bool dumped_with_pdumper_p (void) { #if HAVE_PDUMPER - return gflags.dumped_with_pdumper_; + return gflags.dumped_with_pdumper; #else return false; #endif diff --git a/src/pdumper.c b/src/pdumper.c index 342c37b5e62..8e10e561bcf 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -77,7 +77,9 @@ along with GNU Emacs. If not, see . */ #define VM_POSIX 1 #define VM_MS_WINDOWS 2 -#if defined (HAVE_MMAP) && defined (MAP_FIXED) +#if !USE_LSB_TAG +# define VM_SUPPORTED 0 +#elif defined (HAVE_MMAP) && defined (MAP_FIXED) # define VM_SUPPORTED VM_POSIX # if !defined (MAP_POPULATE) && defined (MAP_PREFAULT_READ) # define MAP_POPULATE MAP_PREFAULT_READ @@ -1964,9 +1966,9 @@ dump_field_emacs_ptr (struct dump_context *ctx, } static void -_dump_object_start_pseudovector (struct dump_context *ctx, - union vectorlike_header *out_hdr, - const union vectorlike_header *in_hdr) +dump_object_start_pseudovector (struct dump_context *ctx, + union vectorlike_header *out_hdr, + const union vectorlike_header *in_hdr) { eassert (in_hdr->size & PSEUDOVECTOR_FLAG); ptrdiff_t vec_size = vectorlike_nbytes (in_hdr); @@ -1976,9 +1978,9 @@ _dump_object_start_pseudovector (struct dump_context *ctx, /* Need a macro for alloca. */ #define START_DUMP_PVEC(ctx, hdr, type, out) \ - const union vectorlike_header *_in_hdr = (hdr); \ - type *out = alloca (vectorlike_nbytes (_in_hdr)); \ - _dump_object_start_pseudovector (ctx, &out->header, _in_hdr) + const union vectorlike_header *in_hdr = (hdr); \ + type *out = alloca (vectorlike_nbytes (in_hdr)); \ + dump_object_start_pseudovector (ctx, &out->header, in_hdr) static dump_off finish_dump_pvec (struct dump_context *ctx, @@ -3994,14 +3996,14 @@ dump_do_fixup (struct dump_context *ctx, Lisp_Object fixup, Lisp_Object prev_fixup) { - enum dump_fixup_type type = - (enum dump_fixup_type) XFIXNUM (dump_pop (&fixup)); + enum dump_fixup_type type + = (enum dump_fixup_type) XFIXNUM (dump_pop (&fixup)); dump_off dump_fixup_offset = dump_off_from_lisp (dump_pop (&fixup)); #ifdef ENABLE_CHECKING if (!NILP (prev_fixup)) { - dump_off prev_dump_fixup_offset = - dump_off_from_lisp (XCAR (XCDR (prev_fixup))); + dump_off prev_dump_fixup_offset + = dump_off_from_lisp (XCAR (XCDR (prev_fixup))); eassert (dump_fixup_offset - prev_dump_fixup_offset >= sizeof (void *)); } @@ -4618,23 +4620,8 @@ dump_anonymous_allocate_posix (void *base, } #endif -/* Perform anonymous memory allocation. */ -static void * -dump_anonymous_allocate (void *base, - const size_t size, - enum dump_memory_protection protection) -{ -#if VM_SUPPORTED == VM_POSIX - return dump_anonymous_allocate_posix (base, size, protection); -#elif VM_SUPPORTED == VM_MS_WINDOWS - return dump_anonymous_allocate_w32 (base, size, protection); -#else - errno = ENOSYS; - return NULL; -#endif -} +/* Undo the effect of `dump_reserve_address_space'. */ -/* Undo the effect of dump_reserve_address_space(). */ static void dump_anonymous_release (void *addr, size_t size) { @@ -4653,6 +4640,26 @@ dump_anonymous_release (void *addr, size_t size) #endif } +/* Perform anonymous memory allocation. */ +static void * +dump_anonymous_allocate (void *base, + const size_t size, + enum dump_memory_protection protection) +{ + void *val; + +#if VM_SUPPORTED == VM_POSIX + val = dump_anonymous_allocate_posix (base, size, protection); +#elif VM_SUPPORTED == VM_MS_WINDOWS + val = dump_anonymous_allocate_w32 (base, size, protection); +#else + errno = ENOSYS; + val = NULL; +#endif + + return val; +} + #if VM_SUPPORTED == VM_MS_WINDOWS static void * dump_map_file_w32 (void *base, int fd, off_t offset, size_t size, @@ -4824,20 +4831,20 @@ static void dump_discard_mem (void *mem, size_t size) { #if VM_SUPPORTED == VM_MS_WINDOWS - /* Discard COWed pages. */ - (void) VirtualFree (mem, size, MEM_DECOMMIT); - /* Release the commit charge for the mapping. */ - DWORD old_prot; - (void) VirtualProtect (mem, size, PAGE_NOACCESS, &old_prot); + /* Discard COWed pages. */ + (void) VirtualFree (mem, size, MEM_DECOMMIT); + /* Release the commit charge for the mapping. */ + DWORD old_prot; + (void) VirtualProtect (mem, size, PAGE_NOACCESS, &old_prot); #elif VM_SUPPORTED == VM_POSIX # ifdef HAVE_POSIX_MADVISE - /* Discard COWed pages. */ - (void) posix_madvise (mem, size, POSIX_MADV_DONTNEED); + /* Discard COWed pages. */ + (void) posix_madvise (mem, size, POSIX_MADV_DONTNEED); # elif defined HAVE_MADVISE - (void) madvise (mem, size, MADV_DONTNEED); + (void) madvise (mem, size, MADV_DONTNEED); #endif - /* Release the commit charge for the mapping. */ - (void) mprotect (mem, size, PROT_NONE); + /* Release the commit charge for the mapping. */ + (void) mprotect (mem, size, PROT_NONE); #endif } @@ -4959,21 +4966,23 @@ dump_mmap_release_vm (struct dump_memory_map *map) static bool needs_mmap_retry_p (void) { -#if defined CYGWIN || VM_SUPPORTED == VM_MS_WINDOWS || defined _AIX +#if defined CYGWIN || VM_SUPPORTED == VM_MS_WINDOWS \ + || defined _AIX return true; -#else +#else /* !CYGWIN && VM_SUPPORTED != VM_MS_WINDOWS && !_AIX */ return false; -#endif +#endif /* !CYGWIN && VM_SUPPORTED != VM_MS_WINDOWS && !_AIX */ } static bool dump_mmap_contiguous_vm (struct dump_memory_map *maps, int nr_maps, size_t total_size) { + int save_errno; bool ret = false; void *resv = NULL; bool retry = false; - const bool need_retry = needs_mmap_retry_p (); + bool need_retry = needs_mmap_retry_p (); do { @@ -4986,11 +4995,10 @@ dump_mmap_contiguous_vm (struct dump_memory_map *maps, int nr_maps, } eassert (resv == NULL); - resv = dump_anonymous_allocate (NULL, - total_size, + resv = dump_anonymous_allocate (NULL, total_size, DUMP_MEMORY_ACCESS_NONE); if (!resv) - goto out; + goto out; char *mem = resv; @@ -5039,6 +5047,7 @@ dump_mmap_contiguous_vm (struct dump_memory_map *maps, int nr_maps, ret = true; resv = NULL; out: + save_errno = errno; if (resv) dump_anonymous_release (resv, total_size); if (!ret) @@ -5051,6 +5060,7 @@ dump_mmap_contiguous_vm (struct dump_memory_map *maps, int nr_maps, dump_mmap_release (&maps[i]); } } + errno = save_errno; return ret; } @@ -5058,8 +5068,8 @@ dump_mmap_contiguous_vm (struct dump_memory_map *maps, int nr_maps, Each dump_memory_map structure describes how to fill the corresponding range of memory. On input, all members except MAPPING - are valid. On output, MAPPING contains the location of the given - chunk of memory. The MAPPING for MAPS[N] is MAPS[N-1].mapping + + are valid. On output, MAPPING contains the location of the given + chunk of memory. The MAPPING for MAPS[N] is MAPS[N-1].mapping + MAPS[N-1].size. Each mapping SIZE must be a multiple of the system page size except @@ -5085,8 +5095,10 @@ dump_mmap_contiguous (struct dump_memory_map *maps, int nr_maps) total_size += maps[i].spec.size; } - return (VM_SUPPORTED ? dump_mmap_contiguous_vm : dump_mmap_contiguous_heap) - (maps, nr_maps, total_size); + if (VM_SUPPORTED) + return dump_mmap_contiguous_vm (maps, nr_maps, total_size); + else + return dump_mmap_contiguous_heap (maps, nr_maps, total_size); } typedef uint_fast32_t dump_bitset_word; @@ -5129,7 +5141,7 @@ dump_bitset_bit_set_p (const struct dump_bitset *bitset, { dump_bitset_word bit = 1; bit <<= bit_number % DUMP_BITSET_WORD_WIDTH; - return *dump_bitset__bit_slot (bitset, bit_number) & bit; + return (*dump_bitset__bit_slot (bitset, bit_number) & bit) != 0; } static void @@ -5548,8 +5560,8 @@ dump_do_dump_relocation (const uintptr_t dump_base, struct bignum_reload_info reload_info; static_assert (sizeof (reload_info) <= sizeof (*bignum_val (bignum))); memcpy (&reload_info, bignum_val (bignum), sizeof (reload_info)); - const mp_limb_t *limbs = - dump_ptr (dump_base, reload_info.data_location); + const mp_limb_t *limbs = dump_ptr (dump_base, + reload_info.data_location); mpz_roinit_n (bignum->value, limbs, reload_info.nlimbs); break; } @@ -5790,15 +5802,29 @@ pdumper_load (const char *dump_filename, char *argv0) goto out; err = PDUMPER_LOAD_ERROR; - mark_bits_needed = - divide_round_up (header->discardable_start, DUMP_ALIGNMENT); + dump_base = (uintptr_t) sections[DS_HOT].mapping; + +#if !USE_LSB_TAG + /* The dump may have been mapped at a location that does not admit of + representation as Lisp_Objects. Abort in this case. */ + if ((dump_base + dump_size) & ~VALMASK) + { + fprintf (stderr, + "Failed to load dump file: 0x%p+0x%p & 0x%p != 0\n", + (void *) dump_base, (void *) dump_size, + (void *) (uintptr_t) VALMASK); + goto out; + } +#endif /* !USE_LSB_TAG */ + + mark_bits_needed + = divide_round_up (header->discardable_start, DUMP_ALIGNMENT); if (!dump_bitsets_init (mark_bits, mark_bits_needed)) goto out; /* Point of no return. */ err = PDUMPER_LOAD_SUCCESS; - dump_base = (uintptr_t) sections[DS_HOT].mapping; - gflags.dumped_with_pdumper_ = true; + gflags.dumped_with_pdumper = true; dump_private.header = *header; dump_private.mark_bits = mark_bits[0]; dump_private.last_mark_bits = mark_bits[1]; @@ -5815,8 +5841,8 @@ pdumper_load (const char *dump_filename, char *argv0) Lisp_Object hashes = zero_vector; if (header->hash_list) { - struct Lisp_Vector *hash_tables = - (struct Lisp_Vector *) (dump_base + header->hash_list); + struct Lisp_Vector *hash_tables + = (struct Lisp_Vector *) (dump_base + header->hash_list); hashes = make_lisp_ptr (hash_tables, Lisp_Vectorlike); } @@ -5852,7 +5878,6 @@ pdumper_load (const char *dump_filename, char *argv0) dump_mmap_release (§ions[i]); if (dump_fd >= 0) emacs_close (dump_fd); - return err; } commit 57cef07710d91988b6332ad3ed2f5c4b4b371585 Author: Sean Whitton Date: Sun Mar 9 21:49:44 2025 +0800 Restore find-function-mode-map (bug#76700) * lisp/emacs-lisp/find-func.el (find-function-mode-lower-precedence): New option. (find-function-mode-map): Restore. (find-function-mode): Don't unconditionally bind keys into the global map. Instead respond to the new user option (bug#76700). * etc/NEWS: Mention the new option in existing entry. diff --git a/etc/NEWS b/etc/NEWS index 7223d8700c1..4f0d052f1c3 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -135,6 +135,9 @@ usual minibuffer history commands. Each command has a separate history. --- ** New minor mode 'find-function-mode' replaces 'find-function-setup-keys'. +The new minor mode defines the keys at a higher precedence level than +the old function, one more usual for a minor mode. To restore the old +behavior, customize 'find-function-mode-lower-precedence' to non-nil. ** Minibuffer and Completions diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el index 6b7b5083620..92cd22a544b 100644 --- a/lisp/emacs-lisp/find-func.el +++ b/lisp/emacs-lisp/find-func.el @@ -187,6 +187,21 @@ for completion." :version "29.1" :group 'find-function) +(defcustom find-function-mode-lower-precedence nil + "If non-nil, `find-function-mode' defines keys in the global map. +This is for compatibility with the historical behavior of +the old `find-function-setup-keys'." + :type 'boolean + :version "31.1" + :group 'find-function + :set (lambda (symbol value) + ;; Toggle the mode off before changing this setting in order to + ;; avoid getting into an inconsistent state. + (let ((already-on find-function-mode)) + (when already-on (find-function-mode -1)) + (set-default symbol value) + (when already-on (find-function-mode 1))))) + ;;; Functions: (defun find-library-suffixes () @@ -812,30 +827,47 @@ See `find-function-on-key'." (when (and symb (not (equal symb 0))) (find-variable-other-window symb)))) +(defvar-keymap find-function-mode-map + :doc "Keymap for `find-function-mode'." + "C-x F" #'find-function + "C-x 4 F" #'find-function-other-window + "C-x 5 F" #'find-function-other-frame + + "C-x K" #'find-function-on-key + "C-x 4 K" #'find-function-on-key-other-window + "C-x 5 K" #'find-function-on-key-other-frame + + "C-x V" #'find-variable + "C-x 4 V" #'find-variable-other-window + "C-x 5 V" #'find-variable-other-frame + + "C-x L" #'find-library + "C-x 4 L" #'find-library-other-window + "C-x 5 L" #'find-library-other-frame) + ;;;###autoload (define-minor-mode find-function-mode "Enable some key bindings for the `find-function' family of functions." :group 'find-function :version "31.1" :global t :lighter nil - ;; For compatibility with the historical behavior of the old - ;; `find-function-setup-keys', define our bindings at the precedence - ;; level of the global map. - :keymap nil - (pcase-dolist (`(,map ,key ,cmd) - `((,ctl-x-map "F" find-function) - (,ctl-x-4-map "F" find-function-other-window) - (,ctl-x-5-map "F" find-function-other-frame) - (,ctl-x-map "K" find-function-on-key) - (,ctl-x-4-map "K" find-function-on-key-other-window) - (,ctl-x-5-map "K" find-function-on-key-other-frame) - (,ctl-x-map "V" find-variable) - (,ctl-x-4-map "V" find-variable-other-window) - (,ctl-x-5-map "V" find-variable-other-frame) - (,ctl-x-map "L" find-library) - (,ctl-x-4-map "L" find-library-other-window) - (,ctl-x-5-map "L" find-library-other-frame))) - (if find-function-mode - (keymap-set map key cmd) - (keymap-unset map key t)))) + (when find-function-mode-lower-precedence + (rplacd (assq 'find-function-mode minor-mode-map-alist) + (if find-function-mode + (make-sparse-keymap) + find-function-mode-map)) + (named-let define-keys ((from find-function-mode-map) + (into (current-global-map)) + (prefix [])) + (map-keymap (lambda (event binding) + (let* ((key (vector event)) + (prefixed (vconcat prefix key))) + (if-let* (((keymapp binding)) + (ninto (lookup-key into key)) + ((keymapp ninto))) + (define-keys binding ninto prefixed) + (if find-function-mode + (global-set-key prefixed binding) + (global-unset-key prefixed))))) + from)))) ;;;###autoload (defun find-function-setup-keys () commit 203747b87fbf976fda887d0652b05685447b8d65 Author: Mauro Aranda Date: Sun Mar 9 09:22:29 2025 -0300 Allow changing theme settings without reloading it * lisp/custom.el (custom--should-apply-setting): Return non-nil for an enabled theme. Provide docstring. This allows for users to reevaluate a custom-theme-set-* function and see the settings applied right away. (Bug#76685) (custom--inhibit-theme-enable): Adapt docstring. * etc/NEWS: Announce the new behavior. diff --git a/etc/NEWS b/etc/NEWS index ca9669b66e9..7223d8700c1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -384,6 +384,11 @@ to wrong results in some cases. We believe that it is no longer useful; please contact us if you still need it for some reason. ** 'byte-compile-cond-use-jump-table' is now obsolete. +--- +** Modified settings for an enabled theme now apply immediately. +Evaluating a custom-theme-set-faces or custom-theme-set-variables +call for an enabled theme causes the settings to apply immediately, +without a need to re-load the theme. * Editing Changes in Emacs 31.1 diff --git a/lisp/custom.el b/lisp/custom.el index 5360c397c59..d309754ab9b 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -901,7 +901,15 @@ to the front of this list.") (error "Unknown theme `%s'" theme))) (defun custom--should-apply-setting (theme) - (or (null custom--inhibit-theme-enable) + "Non-nil if settings for the theme THEME should apply immediately. + +Theme settings apply immediately if: +- THEME is already enabled. +- THEME is being enabled via `enable-theme' or an interactive call to + `load-theme'. +- THEME is the `user' theme." + (or (memq theme custom-enabled-themes) + (null custom--inhibit-theme-enable) (and (eq custom--inhibit-theme-enable 'apply-only-user) (eq theme 'user)))) @@ -1235,6 +1243,10 @@ external packages). For manual user customizations, use (defvar custom--inhibit-theme-enable 'apply-only-user "Whether the custom-theme-set-* functions act immediately. + +If the theme argument for those functions is an already enabled theme, +the theme settings always apply immediately, ignoring this variable. + If nil, `custom-theme-set-variables' and `custom-theme-set-faces' change the current values of the given variable or face. If t, they just make a record of the theme settings. If the commit 5890ee840e65fee2b730079d18faa34c35316368 Merge: ee789d3d278 eb03969846f Author: Michael Albinus Date: Sun Mar 9 12:42:06 2025 +0100 Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs commit ee789d3d27824eaca42fed02659e7b712a6f8c66 Author: Michael Albinus Date: Sun Mar 9 12:41:40 2025 +0100 * admin/notes/jargon: Add AFK and OOO. diff --git a/admin/notes/jargon b/admin/notes/jargon index aa214b289e0..3f709af7d28 100644 --- a/admin/notes/jargon +++ b/admin/notes/jargon @@ -39,6 +39,7 @@ AFAICT - as far as I can tell AFAIK - as far as I know AFAIR - as far as I remember AFAIU - as far as I understand +AFK - away from keyboard AKA - also known as ASAP - as soon as possible BTW - by the way @@ -61,6 +62,7 @@ IMO - in my opinion IOW - in other words LGTM - looks good to me LMK - let me know +OOO - out of office OOTB - out of the box OTOH - on the other hand SNAFU - situation normal, all fouled up commit eb03969846fe8c3afb315f7a9c30980f1b669e2b Merge: 7f655b11885 35c7837c661 Author: Eli Zaretskii Date: Sun Mar 9 07:33:14 2025 -0400 Merge from origin/emacs-30 35c7837c661 Fix TAGS regeneration with Universal Ctags commit 7f655b11885f29ac9f1665d74312e385bfea908d Merge: bcfa9692f05 b1a9a4a48e2 Author: Eli Zaretskii Date: Sun Mar 9 07:33:14 2025 -0400 ; Merge from origin/emacs-30 The following commit was skipped: b1a9a4a48e2 Fix crash in daemon when "C-x C-c" while a client frame s... commit bcfa9692f05ccc61c6816da249ea540c3fee297a Merge: 6fb68f4310d af8017b23f6 Author: Eli Zaretskii Date: Sun Mar 9 07:33:13 2025 -0400 Merge from origin/emacs-30 af8017b23f6 Explicitly document read-string return value cf03c2b6093 Improve docstrings of python.el import management 01bcc6961a6 ; Improve doc strings of Speedbar bd9c76ab175 Avoid warnings about 'image-scaling-factor' in builds --w... commit 6fb68f4310d808827b83da053fbc112b316b7757 Author: Gerd Möllmann Date: Sun Mar 9 10:04:41 2025 +0100 Fix drawing to the bottom-right corner of terminals * src/term.c (tty_write_glyphs_1): Renamed from tty_write_glyphs. Don't check if writing the bottom-right corner. (tty_write_glyphs): New function handling case of writing to the bottom-right corner, and otherwise calling tty_write_glyphs_1. diff --git a/src/term.c b/src/term.c index 6990978ecfb..bc7a9c78f0d 100644 --- a/src/term.c +++ b/src/term.c @@ -750,19 +750,13 @@ encode_terminal_code (struct glyph *src, int src_len, /* An implementation of write_glyphs for termcap frames. */ static void -tty_write_glyphs (struct frame *f, struct glyph *string, int len) +tty_write_glyphs_1 (struct frame *f, struct glyph *string, int len) { struct tty_display_info *tty = FRAME_TTY (f); tty_turn_off_insert (tty); tty_hide_cursor (tty); - /* Don't dare write in last column of bottom line, if Auto-Wrap, - since that would scroll the whole frame on some terminals. */ - if (AutoWrap (tty) - && curY (tty) + 1 == FRAME_TOTAL_LINES (f) - && (curX (tty) + len) == FRAME_COLS (f)) - len --; - if (len <= 0) + if (len == 0) return; cmplus (tty, len); @@ -968,6 +962,30 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len) cmcheckmagic (tty); } +static void +tty_write_glyphs (struct frame *f, struct glyph *string, int len) +{ + struct tty_display_info *tty = FRAME_TTY (f); + /* Don't dare write in last column of bottom line, if Auto-Wrap, + since that would scroll the whole frame on some terminals. */ + if (AutoWrap (tty) + && curY (tty) + 1 == FRAME_TOTAL_LINES (f) + && curX (tty) + len == FRAME_COLS (f) + && curX (tty) < FRAME_COLS (f) - 1 + && len > 0) + { + /* Write glyphs except the first. */ + int old_x = curX (tty), old_y = curY (tty); + tty_write_glyphs_1 (f, string + 1, len - 1); + + /* Insert the first glyph, shifting the rest right. */ + cmgoto (tty, old_y, old_x); + tty_insert_glyphs (f, string, 1); + } + else + tty_write_glyphs_1 (f, string, len); +} + /* An implementation of delete_glyphs for termcap frames. */ static void commit d01b7c85fea3e177df112513af150cead4bbb3e5 Author: Mauro Aranda Date: Sun Mar 9 08:10:17 2025 -0300 Guard against user saving ediff-meta-diff-buffer * lisp/vc/ediff-mult.el (ediff-collect-custom-diffs): If the diff buffer is visiting a file, create a new buffer. (Bug#3348) * test/lisp/vc/ediff-mult-tests.el: New test file. diff --git a/lisp/vc/ediff-mult.el b/lisp/vc/ediff-mult.el index 493e98f76b7..ade20a4a299 100644 --- a/lisp/vc/ediff-mult.el +++ b/lisp/vc/ediff-mult.el @@ -1719,7 +1719,14 @@ multifile patches. For `ediff-directory-revisions', we insist that all marked sessions must be active." (interactive) (let ((coding-system-for-read ediff-coding-system-for-read)) - (or (ediff-buffer-live-p ediff-meta-diff-buffer) + (unless (and (ediff-buffer-live-p ediff-meta-diff-buffer) + ;; We assume `ediff-meta-diff-buffer' doesn't + ;; visit any file. But if the user saves the + ;; `ediff-meta-diff-buffer' to a file, that + ;; assumption isn't right anymore. (Bug#3348) + ;; So, if `ediff-meta-diff-buffer' is visiting some + ;; file, create a new buffer rather than reusing it. + (not (buffer-file-name ediff-meta-diff-buffer))) (setq ediff-meta-diff-buffer (get-buffer-create (ediff-unique-buffer-name "*Ediff Multifile Diffs" "*")))) diff --git a/test/lisp/vc/ediff-mult-tests.el b/test/lisp/vc/ediff-mult-tests.el new file mode 100644 index 00000000000..525088bf856 --- /dev/null +++ b/test/lisp/vc/ediff-mult-tests.el @@ -0,0 +1,54 @@ +;;; ediff-mult-tests.el --- Tests for ediff-mult.el -*- lexical-binding:t -*- + +;; 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 . + +;;; Code: + +(require 'ert) +(require 'ediff-mult) + +(ert-deftest ediff-test-bug3348 () + "After saving `ediff-meta-diff-buffer' to a file, we should not reuse it." + (let ((test-dir + (expand-file-name "bug-3348-testdir" temporary-file-directory))) + (make-directory test-dir t) + (cd test-dir) + + (make-directory "dir-a" t) + (make-directory "dir-b" t) + + (with-temp-file "dir-a/file" + (insert "aaa\n")) + (with-temp-file "dir-b/file" + (insert "bbb\n")) + + (ediff-directories "dir-a" "dir-b" nil) + (switch-to-buffer "*Ediff Session Group Panel*") + + (ediff-next-meta-item 1) + (ediff-mark-for-operation-at-pos nil) + (ediff-collect-custom-diffs) + + (with-current-buffer "*Ediff Multifile Diffs*" + (write-file "foo.patch")) + + (with-temp-file "dir-b/file" + (insert "BBB\n")) + (ediff-collect-custom-diffs) + + (should-not (equal ediff-meta-diff-buffer (get-buffer "foo.patch"))))) commit ba20f73d8e0173a37fbdd2efe72a7a3b0d62dfa5 Author: Gerd Möllmann Date: Sun Mar 9 11:47:35 2025 +0100 macOS: Don't constrainFrameRect for child frames * src/nsterm.m ([EmacsWindow constrainFrameRect:toScreen:]): Don't do anything for child frames. diff --git a/src/nsterm.m b/src/nsterm.m index f6fd43a1889..46bb3f5dd7a 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -9790,6 +9790,13 @@ - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen NSTRACE ("[EmacsWindow constrainFrameRect:" NSTRACE_FMT_RECT " toScreen:]", NSTRACE_ARG_RECT (frameRect)); + /* Don't do anything for child frames because that leads to weird + child frame placement in some cases involving Dock placement and + Dock Hiding. */ + struct frame *f = ((EmacsView *) [self delegate])->emacsframe; + if (FRAME_PARENT_FRAME (f)) + return frameRect; + #ifdef NS_IMPL_COCOA #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 // If separate spaces is on, it is like each screen is independent. There is commit 41c1c6ffac3bc3db9818ed8e0cc857c72b06d806 Author: Rudolf Adamkovič Date: Fri Feb 28 14:54:14 2025 +0100 Make sure Comint minibuffer password prompts end with space * lisp/comint.el (comint-watch-for-password-prompt): Add a trailing space character to the minibuffer password prompt, if it does not contain one already, per the minibuffer UI conventions. Bug#76604 diff --git a/lisp/comint.el b/lisp/comint.el index c1028bc93dc..f0305e4de3c 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -2601,8 +2601,14 @@ This function could be in the list `comint-output-filter-functions'." prompt) (when (let ((case-fold-search t)) (string-match comint-password-prompt-regexp string)) - (setq prompt (string-trim (match-string 0 string) - "[ \n\r\t\v\f\b\a]+" "\n+")) + (setq prompt + (let ((content (string-trim (match-string 0 string) + "[ \n\r\t\v\f\b\a]+" "\n+")) + (suffix " ")) + (concat content + (and (not (string-empty-p content)) + (not (string-suffix-p suffix content)) + suffix)))) ;; Use `run-at-time' in order not to pause execution of the ;; process filter with a minibuffer (run-at-time commit 7e89ef2ced2d06f49705aff679f1962af94d0973 Author: Eli Zaretskii Date: Sun Mar 9 11:20:33 2025 +0200 ; Fix documentation of previous change. * lisp/display-fill-column-indicator.el (display-fill-column-indicator-warning) (display-fill-column-indicator-warning-face): Doc fixes. * etc/NEWS: Announce 'display-fill-column-indicator-warning'. (Bug#76494). diff --git a/etc/NEWS b/etc/NEWS index 6cfed2932d4..ca9669b66e9 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1446,6 +1446,13 @@ commands. When nil, clicking on an inactive Emacs frame will only activate it. When t (the default), the click will both activate the frame and be interpreted as a command. +--- +*** New user option 'display-fill-column-indicator-warning'. +Customize it to a non-nil value to have the fill-column indicators +change their face if the current line exceeds the 'fill-column'. The +new face 'display-fill-column-indicator-warning-face' is used to +highlight the fill-column indicators. By default this is disabled. + * New Modes and Packages in Emacs 31.1 diff --git a/lisp/display-fill-column-indicator.el b/lisp/display-fill-column-indicator.el index e2395bb1f01..dbd067f5f3d 100644 --- a/lisp/display-fill-column-indicator.el +++ b/lisp/display-fill-column-indicator.el @@ -43,7 +43,7 @@ :link '(info-link "(emacs)Displaying Boundaries")) (defcustom display-fill-column-indicator-warning nil - "Highlight fill-column-indicator when current column is too long. + "Highlight fill-column-indicator when current line is too long. Non-nil means highlight fill-column-indicator when current column exceeds `display-fill-column-indicator-column'." :type 'boolean @@ -51,7 +51,7 @@ Non-nil means highlight fill-column-indicator when current column exceeds (defface display-fill-column-indicator-warning-face '((t :inherit error :stipple nil)) - "Face used to highlight `display-fill-column-indicator' when column is too long." + "Face used to highlight `display-fill-column-indicator' when lines are too long." :version "31.1") (defun fill-indicator--set-warning () commit 2322dea77cc2f3e1f1eb08a5b03f97afdd3a4cde Author: Elías Gabriel Pérez Date: Sat Feb 22 12:19:07 2025 -0600 Highlight fill-column-indicator when current line is too long * lisp/display-fill-column-indicator.el (display-fill-column-indicator-warning): New user option. (display-fill-column-indicator-warning-face): New face. (display-fill-column-indicator-mode): Add post-command-hook if `display-fill-column-indicator-warning' is ON. (Bug#76494) diff --git a/lisp/display-fill-column-indicator.el b/lisp/display-fill-column-indicator.el index c55a03533bd..e2395bb1f01 100644 --- a/lisp/display-fill-column-indicator.el +++ b/lisp/display-fill-column-indicator.el @@ -42,6 +42,30 @@ :group 'display :link '(info-link "(emacs)Displaying Boundaries")) +(defcustom display-fill-column-indicator-warning nil + "Highlight fill-column-indicator when current column is too long. +Non-nil means highlight fill-column-indicator when current column exceeds +`display-fill-column-indicator-column'." + :type 'boolean + :version "31.1") + +(defface display-fill-column-indicator-warning-face + '((t :inherit error :stipple nil)) + "Face used to highlight `display-fill-column-indicator' when column is too long." + :version "31.1") + +(defun fill-indicator--set-warning () + "Set the warning face for the fill column indicator." + (if-let* ((column (if (integerp display-fill-column-indicator-column) + display-fill-column-indicator-column + fill-column)) + ((> (save-excursion (end-of-line) (current-column)) + column))) + (progn + (face-remap-set-base + 'fill-column-indicator + 'display-fill-column-indicator-warning-face)) + (face-remap-reset-base 'fill-column-indicator))) ;;;###autoload (define-minor-mode display-fill-column-indicator-mode @@ -68,7 +92,11 @@ See Info node `Displaying Boundaries' for details." (eq (aref (query-font (car (internal-char-font nil ?\u2502))) 0) (face-font 'default)))) ?\u2502 - ?|)))) + ?|))) + (if display-fill-column-indicator-warning + (add-hook 'post-command-hook #'fill-indicator--set-warning nil t))) + (if display-fill-column-indicator-warning + (remove-hook 'post-command-hook #'fill-indicator--set-warning t)) (setq display-fill-column-indicator nil))) (defun display-fill-column-indicator--turn-on () commit 31ebc00ece7d7234868a2a1e95f138473ea6646c Author: Arash Esbati Date: Sun Mar 9 09:12:37 2025 +0100 ; Add debug spec * lisp/textmodes/reftex-parse.el (reftex-with-special-syntax): Add debug spec and docstring. diff --git a/lisp/textmodes/reftex-parse.el b/lisp/textmodes/reftex-parse.el index 0acf91ebe20..7795c583076 100644 --- a/lisp/textmodes/reftex-parse.el +++ b/lisp/textmodes/reftex-parse.el @@ -29,6 +29,8 @@ (require 'reftex) (defmacro reftex-with-special-syntax (&rest body) + "Evaluate BODY with syntax table set to `reftex-syntax-table'." + (declare (debug t)) `(let ((saved-syntax (syntax-table))) (unwind-protect (progn commit 35c7837c6616b3a2b845ba06d3ed797bb12fb749 Author: Ben Scuron Date: Fri Mar 7 22:29:36 2025 -0500 Fix TAGS regeneration with Universal Ctags * lisp/progmodes/etags-regen.el (etags-regen--append-tags): Move the "-o" option to before the filename, as Ctags doesn't allow it to follow the file name. (Bug#76855) Copyright-paperwork-exempt: yes diff --git a/lisp/progmodes/etags-regen.el b/lisp/progmodes/etags-regen.el index 14791c944ef..7994303284b 100644 --- a/lisp/progmodes/etags-regen.el +++ b/lisp/progmodes/etags-regen.el @@ -381,7 +381,7 @@ File extensions to generate the tags for." ;; Like 10ms vs 20ms here. But `shell-command' makes it easy to ;; direct stderr to a separate buffer. (shell-command - (format "%s %s %s -o -" + (format "%s %s -o - %s" etags-regen-program (mapconcat #'identity options " ") (mapconcat #'identity file-names " ")) t etags-regen--errors-buffer-name)) commit b1a9a4a48e24fd69cf94338d83b221698ba8af11 Author: Eli Zaretskii Date: Sat Mar 8 11:31:22 2025 +0200 Fix crash in daemon when "C-x C-c" while a client frame shows tooltip * src/frame.c (delete_frame): Ignore tooltip frames when looking for other frames on the same terminal. (Bug#76842) (cherry picked from commit d2445c8c23595efdd444fce6f0c33ba66b596812) diff --git a/src/frame.c b/src/frame.c index b21ff73c9ef..d0446279db7 100644 --- a/src/frame.c +++ b/src/frame.c @@ -2410,17 +2410,19 @@ delete_frame (Lisp_Object frame, Lisp_Object force) struct frame *f1 = XFRAME (frame1); /* Set frame_on_same_kboard to frame1 if it is on the same - keyboard. Set frame_with_minibuf to frame1 if it also - has a minibuffer. Leave the loop immediately if frame1 - is also minibuffer-only. + keyboard and is not a tooltip frame. Set + frame_with_minibuf to frame1 if it also has a minibuffer. + Leave the loop immediately if frame1 is also + minibuffer-only. - Emacs 26 does _not_ set frame_on_same_kboard here when it - finds a minibuffer-only frame and subsequently fails to + Emacs 26 did _not_ set frame_on_same_kboard here when it + found a minibuffer-only frame, and subsequently failed to set default_minibuffer_frame below. Not a great deal and - never noticed since make_frame_without_minibuffer creates - a new minibuffer frame in that case (which can be a minor - annoyance though). To consider for Emacs 26.3. */ - if (kb == FRAME_KBOARD (f1)) + never noticed since make_frame_without_minibuffer created a + new minibuffer frame in that case (which can be a minor + annoyance though). */ + if (!FRAME_TOOLTIP_P (f1) + && kb == FRAME_KBOARD (f1)) { frame_on_same_kboard = frame1; if (FRAME_HAS_MINIBUF_P (f1)) commit af8017b23f6d94266dd05dcd084c8d7656393db8 Author: Stefan Kangas Date: Fri Mar 7 18:10:53 2025 +0100 Explicitly document read-string return value * src/minibuf.c (Fread_string): Document return value explicitly. Better document PROMPT argument, and reflow docstring. (Bug#76797) diff --git a/src/minibuf.c b/src/minibuf.c index bf9fad48d88..026a8f4271e 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1402,20 +1402,28 @@ and some related functions, which use zero-indexing for POSITION. */) /* Functions that use the minibuffer to read various things. */ DEFUN ("read-string", Fread_string, Sread_string, 1, 5, 0, - doc: /* Read a string from the minibuffer, prompting with string PROMPT. -If non-nil, second arg INITIAL-INPUT is a string to insert before reading. - This argument has been superseded by DEFAULT-VALUE and should normally be nil - in new code. It behaves as INITIAL-CONTENTS in `read-from-minibuffer' (which - see). -The third arg HISTORY, if non-nil, specifies a history list - and optionally the initial position in the list. + doc: /* Read and return a string from the minibuffer, prompting with PROMPT. + +PROMPT is a string, which should normally end with the string ": ". + +If non-nil, second arg INITIAL-INPUT is a string to insert before +reading. This argument has been superseded by DEFAULT-VALUE and should +normally be nil in new code. It behaves as INITIAL-CONTENTS in +`read-from-minibuffer' (which see). + +The third arg HISTORY, if non-nil, specifies a history list and +optionally the initial position in the list. + See `read-from-minibuffer' for details of HISTORY argument. -Fourth arg DEFAULT-VALUE is the default value or the list of default values. - If non-nil, it is used for history commands, and as the value (or the first - element of the list of default values) to return if the user enters the - empty string. -Fifth arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits - the current input method and the setting of `enable-multibyte-characters'. */) + +Fourth arg DEFAULT-VALUE is the default value or the list of default +values. If non-nil, it is used for history commands, and as the value +(or the first element of the list of default values) to return if the +user enters the empty string. + +Fifth arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer +inherits the current input method and the setting of +`enable-multibyte-characters'. */) (Lisp_Object prompt, Lisp_Object initial_input, Lisp_Object history, Lisp_Object default_value, Lisp_Object inherit_input_method) { Lisp_Object val; commit cf03c2b6093d3b555f758f033610a6015378de57 Author: kobarity Date: Sun Mar 2 17:37:36 2025 +0900 Improve docstrings of python.el import management Added notes that when adding import statements for a file that does not belong to a project, it may take some time to find candidate import statements in the default directory. * lisp/progmodes/python.el (python-add-import) (python-fix-imports): Improve docstring. (Bug#74894) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 7f329f91e4f..f966190ea6d 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -6911,6 +6911,12 @@ argument, restrict the suggestions to imports defining the symbol at point. If there is only one such suggestion, act without asking. +If the buffer does not belong to a project, the import statement is +searched under the buffer's default directory. For example, if the file +is located directly under the home directory, all files under the home +directory will be searched. Please note that this can take a long time +and may appear to hang. + When calling from Lisp, use a non-nil NAME to restrict the suggestions to imports defining NAME." (interactive (list (when current-prefix-arg (thing-at-point 'symbol)))) @@ -6955,7 +6961,17 @@ asking." ;;;###autoload (defun python-fix-imports () - "Add missing imports and remove unused ones from the current buffer." + "Add missing imports and remove unused ones from the current buffer. + +If there are missing imports, ask for an import statement using all +imports found in the current project as suggestions. If there is only +one such suggestion, act without asking. + +If the buffer does not belong to a project, the import statement is +searched under the buffer's default directory. For example, if the file +is located directly under the home directory, all files under the home +directory will be searched. Please note that this can take a long time +and may appear to hang." (interactive) (let ((buffer (current-buffer)) undefined unused add remove) commit 01bcc6961a6b0db36c371c9016d6eb00a1ae8ea2 Author: Eli Zaretskii Date: Fri Mar 7 10:45:50 2025 +0200 ; Improve doc strings of Speedbar * lisp/speedbar.el (speedbar-extension-list-to-regex) (speedbar-query-confirmation-method) (speedbar-show-unknown-files, speedbar-use-imenu-flag) (speedbar-track-mouse-flag, speedbar-default-position) (speedbar-sort-tags, speedbar-directory-button-trim-method) (speedbar-smart-directory-expand-flag) (speedbar-hide-button-brackets-flag, speedbar-vc-do-check) (speedbar-vc-indicator, speedbar-obj-do-check) (speedbar-frame-mode, speedbar-handle-delete-frame) (speedbar-show-info-under-mouse, speedbar-item-info) (speedbar-item-rename, speedbar-item-delete) (speedbar-initial-keymap, speedbar-insert-files-at-point) (speedbar-generic-list-positioned-group-p) (speedbar-generic-list-tag-p, speedbar-check-read-only) (speedbar-tag-file, speedbar-tag-expand) (speedbar-find-file-in-frame, speedbar-parse-tex-string) (speedbar-buffer-click): Doc fixes. diff --git a/lisp/speedbar.el b/lisp/speedbar.el index 4c563d87da8..3a233588ae8 100644 --- a/lisp/speedbar.el +++ b/lisp/speedbar.el @@ -220,9 +220,9 @@ frame." :type 'boolean) (defcustom speedbar-query-confirmation-method 'all - "Query control for file operations. -The `all' flag means to always query before file operations. -The `none-but-delete' flag means to not query before any file + "Control querying for file operations. +The value `all' means to always query before file operations. +The value `none-but-delete' means to not query before any file operations, except before a file deletion." :group 'speedbar :type '(radio (const :tag "Always Query before some file operations." @@ -284,7 +284,7 @@ The default buffer is the buffer in the selected window in the attached frame." :type 'hook) (defcustom speedbar-show-unknown-files nil - "Non-nil show files we can't expand with a ? in the expand button. + "Non-nil means show files we can't expand with a ? in the expand button. A nil value means don't show the file in the list." :group 'speedbar :type 'boolean) @@ -309,7 +309,8 @@ attached to and added to this list before the new frame is initialized." :version "30.1") (defcustom speedbar-use-imenu-flag t - "Non-nil means use imenu for file parsing, nil to use etags. + "Whether to use imenu or etags for file parsing. +Non-nil means use imenu for file parsing, nil means use etags. Etags support is not as robust as imenu support." ; See Bug#51102 :tag "Use Imenu for tags" :group 'speedbar @@ -335,12 +336,12 @@ display is used instead." :type 'boolean) (defcustom speedbar-track-mouse-flag (not speedbar-use-tool-tips-flag) - "Non-nil means to display info about the line under the mouse." + "Non-nil means to display info about the line under the mouse pointer." :group 'speedbar :type 'boolean) (defcustom speedbar-default-position 'left-right - "Default position of the speedbar frame. + "Default position of the speedbar frame relative to the attached frame. Possible values are `left', `right' or `left-right'. If value is `left-right', the most suitable location is determined automatically." @@ -350,8 +351,8 @@ determined automatically." (const :tag "Right" right))) (defcustom speedbar-sort-tags nil - "If non-nil, sort tags in the speedbar display. *Obsolete*. -Use `speedbar-tag-hierarchy-method' instead." + "If non-nil, sort tags in the speedbar display. +This option is obsolete; use `speedbar-tag-hierarchy-method' instead." :group 'speedbar :type 'boolean) @@ -405,7 +406,7 @@ items is reached." :type 'integer) (defcustom speedbar-directory-button-trim-method 'span - "Indicates how the directory button will be displayed. + "Control how the directory button in speedbar will be displayed. Possible values are: `span' - span large directories over multiple lines. `trim' - trim large directories to only show the last few. @@ -419,7 +420,7 @@ Possible values are: (defcustom speedbar-smart-directory-expand-flag t "Non-nil means speedbar should use smart expansion. -Smart expansion only affects when speedbar wants to display a +Smart expansion is only in effect when speedbar wants to display a directory for a file in the attached frame. When smart expansion is enabled, new directories which are children of a displayed directory are expanded in the current framework. If nil, then the current @@ -433,7 +434,7 @@ hierarchy would be replaced with the new directory." :type 'integer) (defcustom speedbar-hide-button-brackets-flag nil - "Non-nil means speedbar will hide the brackets around the + or -." + "If non-nil, speedbar will hide the brackets around the + or -." :group 'speedbar :type 'boolean) @@ -474,14 +475,14 @@ hierarchy would be replaced with the new directory." "String separating file text from indicator characters.") (defcustom speedbar-vc-do-check t - "Non-nil check all files in speedbar to see if they have been checked out. + "If non-nil, check all files in speedbar to see if they have been checked out. Any file checked out is marked with `speedbar-vc-indicator'." :group 'speedbar-vc :type 'boolean) (defvar speedbar-vc-indicator "*" "Text used to mark files which are currently checked out. -Other version control systems can be added by examining the function +Other version control systems can be added by examining the functions `speedbar-vc-directory-enable-hook' and `speedbar-vc-in-control-hook'.") (defcustom speedbar-vc-directory-enable-hook nil @@ -502,7 +503,7 @@ current file, and the FILENAME of the file being checked." "Local variable maintaining the current version control check position.") (defcustom speedbar-obj-do-check t - "Non-nil check all files in speedbar to see if they have an object file. + "If non-nil, check all files in speedbar to see if they have an object file. Any file checked out is marked with `speedbar-obj-indicator', and the marking is based on `speedbar-obj-alist'." :group 'speedbar-vc @@ -561,7 +562,7 @@ state data." (repeat :tag "List of modes" (symbol :tag "Major mode")))) (defun speedbar-extension-list-to-regex (extlist) - "Takes EXTLIST, a list of extensions and transforms it into regexp. + "Take EXTLIST, a list of extensions and transform it into regexp. All the preceding `.' are stripped for an optimized expression starting with `.' followed by extensions, followed by full-filenames." (let ((regex1 nil) (regex2 nil)) @@ -894,10 +895,10 @@ directories.") (defalias 'speedbar 'speedbar-frame-mode) ;;;###autoload (defun speedbar-frame-mode (&optional arg) - "Enable or disable speedbar. Positive ARG means turn on, negative turn off. -A nil ARG means toggle. Once the speedbar frame is activated, a buffer in -`speedbar-mode' will be displayed. Currently, only one speedbar is -supported at a time. + "Enable or disable speedbar. +Positive ARG means turn on, negative turn off. A nil ARG means toggle. +Once the speedbar frame is activated, a buffer in `speedbar-mode' will +be displayed. Currently, only one speedbar is supported at a time. `speedbar-before-popup-hook' is called before popping up the speedbar frame. `speedbar-before-delete-hook' is called before the frame is deleted." (interactive "P") @@ -956,7 +957,7 @@ supported at a time. (dframe-current-frame 'speedbar-frame 'speedbar-mode)) (defun speedbar-handle-delete-frame (e) - "Handle a delete frame event E. + "Handle a delete-frame event E. If the deleted frame is the frame speedbar is attached to, we need to delete speedbar also." (when (and speedbar-frame @@ -1177,7 +1178,7 @@ and the existence of packages." (error (dframe-message nil))))))) (defun speedbar-show-info-under-mouse () - "Call the info function for the line under the mouse." + "Call the info function for the line under the mouse pointer." (let ((pos (mouse-position))) ; we ignore event until I use it later. (if (equal (car pos) speedbar-frame) (save-excursion @@ -1360,7 +1361,7 @@ File style information is displayed with `speedbar-item-info'." (point) (line-end-position))))) (defun speedbar-item-info () - "Display info in the minibuffer about the button the mouse is over. + "Display info in the minibuffer about the button the mouse pointer is over. This function can be replaced in `speedbar-mode-functions-list' as `speedbar-item-info'." (interactive) @@ -1479,7 +1480,7 @@ Files can be copied to new names or places." )))))) (defun speedbar-item-rename () - "Rename the item under the cursor or mouse. + "Rename the item under the cursor or the mouse pointer. Files can be renamed to new names or moved to new directories." (interactive) (let ((f (speedbar-line-file))) @@ -1524,7 +1525,8 @@ Files can be renamed to new names or moved to new directories." (error "Not a file")))) (defun speedbar-item-delete () - "Delete the item under the cursor. Files are removed from disk." + "Delete the item under the cursor. +Files are removed from disk." (interactive) (let ((f (speedbar-line-file))) (if (not f) (error "Not a file")) @@ -1679,7 +1681,7 @@ This is based on `speedbar-initial-expansion-list-name' referencing speedbar-initial-expansion-mode-alist))))) (defun speedbar-initial-keymap () - "Return the current default menu data. + "Return the current default keymap data. This is based on `speedbar-initial-expansion-list-name' referencing `speedbar-initial-expansion-mode-alist'." (symbol-value @@ -1956,7 +1958,7 @@ position to insert a new item, and that the new item will end with a CR." ;;; Build button lists ;; (defun speedbar-insert-files-at-point (files level) - "Insert list of FILES starting at point, and indenting all files to LEVEL. + "Insert list of FILES starting at point, and indent all files to LEVEL. Tag expandable items with a +, otherwise a ?. Don't highlight ? as we don't know how to manage them. The input parameter FILES is a cons cell of the form (DIRLIST . FILELIST)." @@ -2028,7 +2030,7 @@ Groups may optionally contain a position." ))) (defun speedbar-generic-list-positioned-group-p (sublst) - "Non-nil if SUBLST is a group with a position." + "Return non-nil if SUBLST is a group with a position." (and (stringp (car-safe sublst)) (number-or-marker-p (car-safe (cdr-safe sublst))) (listp (cdr-safe (cdr-safe sublst))) @@ -2039,7 +2041,7 @@ Groups may optionally contain a position." )))) (defun speedbar-generic-list-tag-p (sublst) - "Non-nil if SUBLST is a tag." + "Return non-nil if SUBLST is a tag." (and (stringp (car-safe sublst)) (or (and (number-or-marker-p (cdr-safe sublst)) (not (cdr-safe (cdr-safe sublst)))) @@ -2744,7 +2746,7 @@ indicator, then do not add a space." )))) (defun speedbar-check-read-only () - "Scan all the files in a directory, and for each see if it is read only." + "Scan all the files in a directory, and for each see if it is read-only." ;; Check for to-do to be reset. If reset but no RCS is available ;; then set to nil (do nothing) otherwise, start at the beginning (save-excursion @@ -3296,7 +3298,7 @@ INDENT is the current indentation level and is unused." (speedbar-set-timer dframe-update-speed)) (defun speedbar-tag-file (text token indent) - "The cursor is on a selected line. Expand the tags in the specified file. + "Expand tags in file given by TOKEN when button TEXT was clicked. The parameter TEXT and TOKEN are required, where TEXT is the button clicked, and TOKEN is the file to expand. INDENT is the current indentation level." @@ -3338,7 +3340,8 @@ INDENT is the current indentation level." )) (defun speedbar-tag-expand (text token indent) - "Expand a tag sublist. Imenu will return sub-lists of specialized tag types. + "Expand a tag sublist TOKEN for button TEXT and indentation level INDENT. +Imenu will return sub-lists of specialized tag types. Etags does not support this feature. TEXT will be the button string. TOKEN will be the list, and INDENT is the current indentation level." (cond ((string-search "+" text) ;we have to expand this file @@ -3365,7 +3368,7 @@ the attached frame (the frame that speedbar was started from)." :type '(choice integer (other :tag "attached" attached))) (defun speedbar-find-file-in-frame (file) - "This will load FILE into the speedbar attached frame. + "Load FILE into the frame attached to speedbar. If the file is being displayed in a different frame already, then raise that frame instead." (let* ((buff (find-file-noselect file)) @@ -3388,18 +3391,13 @@ frame instead." "Recenter a speedbar buffer so the current indentation level is all visible. This assumes that the cursor is on a file, or tag of a file which the user is interested in." - (save-selected-window - (select-window (get-buffer-window speedbar-buffer t)) - (set-buffer speedbar-buffer) - (if (<= (count-lines (point-min) (point-max)) (1- (window-height))) ;; whole buffer fits (let ((cp (point))) - (goto-char (point-min)) (recenter 0) (goto-char cp)) @@ -3659,7 +3657,8 @@ regular expression EXPR." ))) (defun speedbar-parse-tex-string () - "Parse a Tex string. Only find data which is relevant." + "Parse a Tex string. +Only finds data which is relevant." (save-excursion (let ((bound (line-end-position))) (cond ((re-search-forward "\\(\\(sub\\)*section\\|chapter\\|cite\\)\\s-*{[^\C-?}]*}?" bound t) @@ -3803,8 +3802,8 @@ Optional argument DEPTH specifies the current depth of the back search." (buffer-file-name buffer)))))))) (defun speedbar-buffer-click (text token _indent) - "When the users clicks on a buffer-button in speedbar. -TEXT is the buffer's name, TOKEN and INDENT are unused." + "Select frame when the users clicks on a buffer-button in speedbar. +TEXT is the buffer's name, INDENT is unused." (if dframe-power-click (let ((pop-up-frames t)) (select-window (display-buffer text))) (dframe-select-attached-frame speedbar-frame) commit bd9c76ab175cde67fc98849d9d216c2ee4373042 Author: Eli Zaretskii Date: Thu Mar 6 15:49:27 2025 +0200 Avoid warnings about 'image-scaling-factor' in builds --without-x * lisp/cus-start.el (standard): Exclude 'image-*' options if Emacs was built without GUI support. (Bug#76716) diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 0f7d7c3c020..91cc6e22152 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -908,6 +908,8 @@ since it could result in memory overflow and make Emacs crash." (fboundp 'x-create-frame)) ((string-match "tab-bar-" (symbol-name symbol)) (fboundp 'x-create-frame)) + ((string-match "image-" (symbol-name symbol)) + (fboundp 'x-create-frame)) ((equal "vertical-centering-font-regexp" (symbol-name symbol)) ;; Any function from fontset.c will do.