commit 069c8ff6d5860486ca8b97060002e80c3c4bdbc0 (HEAD, refs/remotes/origin/master) Author: Stefan Kangas Date: Thu Feb 13 08:34:24 2025 +0100 Improve read-directory-name docstring * lisp/files.el (read-directory-name): Improve docstring to be more similar to that of 'read-file-name', and refer back to it where appropriate. diff --git a/lisp/files.el b/lisp/files.el index 79b744f80df..499f062932f 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -877,22 +877,30 @@ See Info node `(elisp)Standard File Names' for more details." (defun read-directory-name (prompt &optional dir default-dirname mustmatch initial predicate) "Read directory name, prompting with PROMPT and completing in directory DIR. -Value is not expanded---you must call `expand-file-name' yourself. -Default name to DEFAULT-DIRNAME if user exits with the same -non-empty string that was inserted by this function. +The return value is not expanded---you must call `expand-file-name' +yourself. + +DIR is the directory to use for completing relative file names. +It should be an absolute directory name, or nil (which means the +current buffer's value of `default-directory'). + +DEFAULT-DIRNAME specifies the default directory name to return if user +exits with the same non-empty string that was inserted by this function. (If DEFAULT-DIRNAME is omitted, DIR combined with INITIAL is used, or just DIR if INITIAL is nil.) -If the user exits with an empty minibuffer, this function returns -an empty string. (This can happen only if the user erased the -pre-inserted contents or if `insert-default-directory' is nil.) -Fourth arg MUSTMATCH non-nil means require existing directory's name. - Non-nil and non-t means also require confirmation after completion. + +If the user exits with an empty minibuffer, return an empty +string. (This can happen only if the user erased the pre-inserted +contents or if `insert-default-directory' is nil.) + +Fourth arg MUSTMATCH, is like for `read-file-name', which see. + Fifth arg INITIAL specifies text to start with. -DIR should be an absolute directory name. It defaults to -the value of `default-directory'. -When sixth arg PREDICATE is non-nil, the union of PREDICATE and -`file-directory-p' is passed as the PREDICATE argument to -`read-file-name'. Otherwise, only `file-directory-p' is passed." + +Sixth arg PREDICATE, if non-nil, should be a function of one +argument; then a directory is considered an acceptable completion +alternative only if PREDICATE returns non-nil with the file name +as its argument." (unless dir (setq dir default-directory)) (read-file-name prompt dir (or default-dirname commit 3f1d84d593bf864b72043ff2a598b18b5e9b05be Author: Joseph Turner Date: Thu Sep 28 20:27:47 2023 -0700 Add optional PREDICATE argument to read-directory-name * lisp/files.el (read-directory-name): Add optional PREDICATE argument. * doc/lispref/minibuf.texi (Reading File Names): Document above change. (Bug#66224) diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index 42189b9d0d7..3cc206d2e1d 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -1715,7 +1715,7 @@ If this variable is non-@code{nil}, @code{read-file-name} ignores case when performing completion. @end defopt -@defun read-directory-name prompt &optional directory default require-match initial +@defun read-directory-name prompt &optional directory default require-match initial predicate This function is like @code{read-file-name} but allows only directory names as completion alternatives. diff --git a/etc/NEWS b/etc/NEWS index 33f5df84d4b..9b2558d14d7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1183,6 +1183,9 @@ runs its body, and removes the current buffer from ** The 'rx' category name 'chinese-two-byte' must now be spelled correctly. An old alternative name (without the first 'e') has been removed. ++++ +** 'read-directory-name' now accepts an optional PREDICATE argument. + --- ** All the digit characters now have the 'digit' category. All the characters whose Unicode general-category is Nd now have the diff --git a/lisp/files.el b/lisp/files.el index e5fde17513f..79b744f80df 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -875,7 +875,7 @@ See Info node `(elisp)Standard File Names' for more details." (dos-convert-standard-filename filename)) (t filename))) -(defun read-directory-name (prompt &optional dir default-dirname mustmatch initial) +(defun read-directory-name (prompt &optional dir default-dirname mustmatch initial predicate) "Read directory name, prompting with PROMPT and completing in directory DIR. Value is not expanded---you must call `expand-file-name' yourself. Default name to DEFAULT-DIRNAME if user exits with the same @@ -889,14 +889,21 @@ Fourth arg MUSTMATCH non-nil means require existing directory's name. Non-nil and non-t means also require confirmation after completion. Fifth arg INITIAL specifies text to start with. DIR should be an absolute directory name. It defaults to -the value of `default-directory'." +the value of `default-directory'. +When sixth arg PREDICATE is non-nil, the union of PREDICATE and +`file-directory-p' is passed as the PREDICATE argument to +`read-file-name'. Otherwise, only `file-directory-p' is passed." (unless dir (setq dir default-directory)) (read-file-name prompt dir (or default-dirname (if initial (expand-file-name initial dir) dir)) mustmatch initial - 'file-directory-p)) + (if predicate + (lambda (filename) + (and (file-directory-p filename) + (funcall predicate filename))) + #'file-directory-p))) (defun pwd (&optional insert) commit 2e9413255fb8cbd0c8481ca6f863b37df3e9008d Author: Stefan Kangas Date: Thu Feb 13 06:23:17 2025 +0100 Increase recentf-max-saved-items to 25 * lisp/recentf.el (recentf-max-saved-items): Increase default to 25. diff --git a/lisp/recentf.el b/lisp/recentf.el index a282fbee3b1..8862fea9926 100644 --- a/lisp/recentf.el +++ b/lisp/recentf.el @@ -73,13 +73,14 @@ You should define the options of your own filters in this group." :group 'recentf) -(defcustom recentf-max-saved-items 20 +(defcustom recentf-max-saved-items 25 "Maximum number of items of the recent list that will be saved. A nil value means to save the whole list. See the command `recentf-save-list'." :group 'recentf - :type '(choice (integer :tag "Entries" :value 1) - (const :tag "No Limit" nil))) + :type '(choice (natnum :tag "Entries") + (const :tag "No Limit" nil)) + :version "31.1") (defcustom recentf-save-file (locate-user-emacs-file "recentf" ".recentf") "File to save the recent list into." commit ab43d956cad94da7bf3c325821666e408af4c73d Author: Stefan Kangas Date: Thu Feb 13 03:59:30 2025 +0100 ; Properly quote some functions in cl-lib as such diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index 2759fc0a028..20d2c8d6a68 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el @@ -185,8 +185,8 @@ to an element already in the list stored in PLACE. ;;; Blocks and exits. -(defalias 'cl--block-wrapper 'identity) -(defalias 'cl--block-throw 'throw) +(defalias 'cl--block-wrapper #'identity) +(defalias 'cl--block-throw #'throw) ;;; Multiple values. @@ -232,7 +232,7 @@ right when EXPRESSION calls an ordinary Emacs Lisp function that returns just one value." (apply function expression)) -(defalias 'cl-multiple-value-call 'apply +(defalias 'cl-multiple-value-call #'apply "Apply FUNCTION to ARGUMENTS, taking multiple values into account. This implementation only handles the case where there is only one argument.") @@ -354,7 +354,7 @@ Call `cl-float-limits' to set this.") ;;; Sequence functions. -(cl--defalias 'cl-copy-seq 'copy-sequence) +(cl--defalias 'cl-copy-seq #'copy-sequence) (declare-function cl--mapcar-many "cl-extra" (cl-func cl-seqs &optional acc)) @@ -374,13 +374,13 @@ SEQ, this is like `mapcar'. With several, it is like the Common Lisp (nreverse cl-res))) (mapcar cl-func cl-x))) -(cl--defalias 'cl-svref 'aref) +(cl--defalias 'cl-svref #'aref) ;;; List functions. -(cl--defalias 'cl-first 'car) -(cl--defalias 'cl-second 'cadr) -(cl--defalias 'cl-rest 'cdr) +(cl--defalias 'cl-first #'car) +(cl--defalias 'cl-second #'cadr) +(cl--defalias 'cl-rest #'cdr) (cl--defalias 'cl-third #'caddr "Return the third element of the list X.") (cl--defalias 'cl-fourth #'cadddr "Return the fourth element of the list X.") @@ -415,30 +415,30 @@ SEQ, this is like `mapcar'. With several, it is like the Common Lisp (declare (gv-setter (lambda (store) `(setcar (nthcdr 9 ,x) ,store)))) (nth 9 x)) -(defalias 'cl-caaar 'caaar) -(defalias 'cl-caadr 'caadr) -(defalias 'cl-cadar 'cadar) -(defalias 'cl-caddr 'caddr) -(defalias 'cl-cdaar 'cdaar) -(defalias 'cl-cdadr 'cdadr) -(defalias 'cl-cddar 'cddar) -(defalias 'cl-cdddr 'cdddr) -(defalias 'cl-caaaar 'caaaar) -(defalias 'cl-caaadr 'caaadr) -(defalias 'cl-caadar 'caadar) -(defalias 'cl-caaddr 'caaddr) -(defalias 'cl-cadaar 'cadaar) -(defalias 'cl-cadadr 'cadadr) -(defalias 'cl-caddar 'caddar) -(defalias 'cl-cadddr 'cadddr) -(defalias 'cl-cdaaar 'cdaaar) -(defalias 'cl-cdaadr 'cdaadr) -(defalias 'cl-cdadar 'cdadar) -(defalias 'cl-cdaddr 'cdaddr) -(defalias 'cl-cddaar 'cddaar) -(defalias 'cl-cddadr 'cddadr) -(defalias 'cl-cdddar 'cdddar) -(defalias 'cl-cddddr 'cddddr) +(defalias 'cl-caaar #'caaar) +(defalias 'cl-caadr #'caadr) +(defalias 'cl-cadar #'cadar) +(defalias 'cl-caddr #'caddr) +(defalias 'cl-cdaar #'cdaar) +(defalias 'cl-cdadr #'cdadr) +(defalias 'cl-cddar #'cddar) +(defalias 'cl-cdddr #'cdddr) +(defalias 'cl-caaaar #'caaaar) +(defalias 'cl-caaadr #'caaadr) +(defalias 'cl-caadar #'caadar) +(defalias 'cl-caaddr #'caaddr) +(defalias 'cl-cadaar #'cadaar) +(defalias 'cl-cadadr #'cadadr) +(defalias 'cl-caddar #'caddar) +(defalias 'cl-cadddr #'cadddr) +(defalias 'cl-cdaaar #'cdaaar) +(defalias 'cl-cdaadr #'cdaadr) +(defalias 'cl-cdadar #'cdadar) +(defalias 'cl-cdaddr #'cdaddr) +(defalias 'cl-cddaar #'cddaar) +(defalias 'cl-cddadr #'cddadr) +(defalias 'cl-cdddar #'cdddar) +(defalias 'cl-cddddr #'cddddr) ;;(defun last* (x &optional n) ;; "Returns the last link in the list LIST. commit 6077bbfc3d4a4aa042b364d31dd681e9f7ab7f30 Author: Ship Mints Date: Thu Feb 13 02:14:57 2025 +0200 project-(remember|forget)-projects-under: Improve docstrings * lisp/progmodes/project.el (project-forget-projects-under) (project-remember-projects-under): Clarify docstrings (bug#76234). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index a429c1d2c42..35bf66c9ffb 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -2056,11 +2056,13 @@ bindings from `project-prefix-map'." (project-any-command project-prefix-map "[execute in %s]:")) (defun project-remember-projects-under (dir &optional recursive) - "Index all projects below a directory DIR. -If RECURSIVE is non-nil, recurse into all subdirectories to find -more projects. After finishing, a message is printed summarizing -the progress. The function returns the number of detected -projects." + "Remember projects below a directory DIR. +Interactively, prompt for DIR. +Optional argument RECURSIVE, if non-nil (interactively, the prefix +argument) means recurse into subdirectories of DIR to find more +projects. +Display a message at the end summarizing what was found. +Return the number of detected projects." (interactive "DDirectory: \nP") (project--ensure-read-project-list) (let ((dirs (if recursive @@ -2097,10 +2099,12 @@ projects." (defun project-forget-projects-under (dir &optional recursive) "Forget all known projects below a directory DIR. -If RECURSIVE is non-nil, recurse into all subdirectories to -remove all known projects. After finishing, a message is printed -summarizing the progress. The function returns the number of -forgotten projects." +Interactively, prompt for DIR. +Optional argument RECURSIVE, if non-nil (interactively, the prefix +argument), means recurse into subdirectories under DIR +to remove those projects from the index. +Display a message at the end summarizing what was forgotten. +Return the number of forgotten projects." (interactive "DDirectory: \nP") (let ((count 0)) (if recursive commit 86e17fbcbddb57b0653b7046202e54624c477836 Author: shipmints Date: Thu Feb 13 00:29:37 2025 +0200 Change the project-switch-project prompt to include the dir name * lisp/progmodes/project.el: (project--switch-project-command): Add new argument DIR. Change the prompt to "Command in `xxx': ..." (bug#76235). (project-switch-project): Pass DIR to the above function. diff --git a/etc/NEWS b/etc/NEWS index 5a29cd0a582..33f5df84d4b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -278,6 +278,10 @@ docstring for arguments passed to a help-text function. *** New command 'project-root-find-file'. It is equivalent to running ‘project-any-command’ with ‘find-file’. +--- +*** Improved prompt for 'project-switch-project'. +The prompt now displays the chosen project on which to invoke a command. + --- *** The MAYBE-PROMPT argument of 'project-current' can be a string. When such value is used, the 'project-prompter' is called with it as the diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index ff707437e95..a429c1d2c42 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -2211,7 +2211,7 @@ Otherwise, use the face `help-key-binding' in the prompt." project-switch-commands " ")) -(defun project--switch-project-command () +(defun project--switch-project-command (&optional dir) (let* ((commands-menu (mapcar (lambda (row) @@ -2241,7 +2241,14 @@ Otherwise, use the face `help-key-binding' in the prompt." (propertize "Unrecognized input" 'face 'warning) (help-key-description choice nil))))) - (setq choice (read-key-sequence (concat "Choose: " prompt))) + (setq choice (read-key-sequence (concat + (if dir + (format-message "Command in `%s': " + (propertize + dir 'face + 'font-lock-string-face)) + "Command: ") + prompt))) (when (setq command (lookup-key commands-map choice)) (when (numberp command) (setq command nil)) (unless (or project-switch-use-entire-map @@ -2266,7 +2273,7 @@ to directory DIR." (project--remember-dir dir) (let ((command (if (symbolp project-switch-commands) project-switch-commands - (project--switch-project-command))) + (project--switch-project-command dir))) (buffer (current-buffer))) (unwind-protect (progn commit b93cdeb04769fde8e553a03ed4c68b442f9c43b4 Author: Stefan Kangas Date: Wed Feb 12 19:55:34 2025 +0100 Consolidate side-effect-free decls in cl-lib * lisp/emacs-lisp/cl-macs.el: Consolidate two identical loops with side-effect-free declarations into one. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index c6e7833a6d0..9b76c8c80a0 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -3725,19 +3725,17 @@ macro that returns its `&whole' argument." `(cl-getf (symbol-plist ,sym) ,prop ,def) `(get ,sym ,prop))) -(dolist (y '(cl-first cl-second cl-third cl-fourth - cl-fifth cl-sixth cl-seventh - cl-eighth cl-ninth cl-tenth - cl-rest cl-endp cl-plusp cl-minusp)) - (put y 'side-effect-free t)) - ;;; Things that are inline. (cl-proclaim '(inline cl-acons cl-map cl-notany cl-notevery cl-revappend cl-nreconc)) ;;; Things that are side-effect-free. (mapc (lambda (x) (function-put x 'side-effect-free t)) - '(cl-oddp cl-evenp cl-signum cl-ldiff cl-pairlis cl-gcd + '(cl-first cl-second cl-third cl-fourth + cl-fifth cl-sixth cl-seventh + cl-eighth cl-ninth cl-tenth + cl-rest cl-endp cl-plusp cl-minusp + cl-oddp cl-evenp cl-signum cl-ldiff cl-pairlis cl-gcd cl-lcm cl-isqrt cl-floor cl-ceiling cl-truncate cl-round cl-mod cl-rem cl-subseq cl-list-length cl-get cl-getf)) commit a669e6a37610f78115f473176f3914cea4c20fb2 Author: Stefan Kangas Date: Wed Feb 12 18:33:59 2025 +0100 Avoid cl-caaar etc. compatibility macros in Org * lisp/org/ob-core.el (org-babel-process-params): * lisp/org/org-agenda.el (org-agenda-span-to-ndays): * lisp/org/org-capture.el (org-capture-set-target-location): * lisp/org/org.el (org-set-effort): Don't use cl-caaar, cl-caadr, etc. compatibility macros in Org. We don't need to use them, since Org requires Emacs 26.1. diff --git a/lisp/org/ob-core.el b/lisp/org/ob-core.el index 88d2f26df05..7d5677da5da 100644 --- a/lisp/org/ob-core.el +++ b/lisp/org/ob-core.el @@ -1822,7 +1822,7 @@ HEADER-ARGUMENTS is an alist of all the arguments." (cons :colname-names (or (cdr (assq :colname-names params)) (cadr vars-and-names))) (cons :rowname-names (or (cdr (assq :rowname-names params)) - (cl-caddr vars-and-names))) + (caddr vars-and-names))) (cons :result-params result-params) (cons :result-type (cond ((member "output" result-params) 'output) ((member "value" result-params) 'value) diff --git a/lisp/org/org-agenda.el b/lisp/org/org-agenda.el index 8fdd998fc52..50dbb6dbed6 100644 --- a/lisp/org/org-agenda.el +++ b/lisp/org/org-agenda.el @@ -4603,10 +4603,10 @@ START-DAY is an absolute time value." ((eq span 'fortnight) 14) ((eq span 'month) (let ((date (calendar-gregorian-from-absolute start-day))) - (calendar-last-day-of-month (car date) (cl-caddr date)))) + (calendar-last-day-of-month (car date) (caddr date)))) ((eq span 'year) (let ((date (calendar-gregorian-from-absolute start-day))) - (if (calendar-leap-year-p (cl-caddr date)) 366 365))))) + (if (calendar-leap-year-p (caddr date)) 366 365))))) (defun org-agenda-span-name (span) "Return a SPAN name." diff --git a/lisp/org/org-capture.el b/lisp/org/org-capture.el index 9c4a4619bbd..0720ad53cc7 100644 --- a/lisp/org/org-capture.el +++ b/lisp/org/org-capture.el @@ -1100,7 +1100,7 @@ Store them in the capture property list." (org-encode-time (apply #'list 0 0 org-extend-today-until - (cl-cdddr (decode-time prompt-time)))))) + (cdddr (decode-time prompt-time)))))) (time-to-days prompt-time))) (t ;; Current date, possibly corrected for late night diff --git a/lisp/org/org.el b/lisp/org/org.el index ab5316a0b13..56a8d11e1ab 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -12800,7 +12800,7 @@ variables is set." (cond (increment (unless allowed (user-error "Allowed effort values are not set")) - (or (cl-caadr (member (list current) allowed)) + (or (caadr (member (list current) allowed)) (user-error "Unknown value %S among allowed values" current))) (value (if (stringp value) value commit d5f788e016131421df8bdc1c5c7e0378d5143729 Author: Stefan Kangas Date: Wed Feb 12 18:26:43 2025 +0100 ; * etc/symbol-releases.eld: Add caaar, caadr, etc. diff --git a/etc/symbol-releases.eld b/etc/symbol-releases.eld index 0609dd1467f..21bbe3c793c 100644 --- a/etc/symbol-releases.eld +++ b/etc/symbol-releases.eld @@ -13,6 +13,30 @@ ("26.1" fun when-let*) ("26.1" fun and-let*) ("26.1" fun if-let*) + ("26.1" fun caaar) + ("26.1" fun caadr) + ("26.1" fun cadar) + ("26.1" fun caddr) + ("26.1" fun cdaar) + ("26.1" fun cdadr) + ("26.1" fun cddar) + ("26.1" fun cdddr) + ("26.1" fun caaaar) + ("26.1" fun caaadr) + ("26.1" fun caadar) + ("26.1" fun caaddr) + ("26.1" fun cadaar) + ("26.1" fun cadadr) + ("26.1" fun caddar) + ("26.1" fun cadddr) + ("26.1" fun cdaaar) + ("26.1" fun cdaadr) + ("26.1" fun cdadar) + ("26.1" fun cdaddr) + ("26.1" fun cddaar) + ("26.1" fun cddadr) + ("26.1" fun cdddar) + ("26.1" fun cddddr) ("24.4" fun set-transient-map) ("22.1" fun clear-string) ("22.1" fun version=) commit 816b9b4a0bf7c37883b9bceb8da196bba1855608 Author: Stefan Kangas Date: Wed Feb 12 18:11:59 2025 +0100 Delete comments about obsolete cl--compiler-macro-cXXr * lisp/emacs-lisp/cl-macs.el: * lisp/subr.el: Delete obsolete comments about compatibility alias cl--compiler-macro-cXXr. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 2cf2b3b06e9..c6e7833a6d0 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -70,9 +70,6 @@ (setq form `(cons ,(car args) ,form))) form)) -;; Note: `cl--compiler-macro-cXXr' has been copied to -;; `internal--compiler-macro-cXXr' in subr.el. If you amend either -;; one, you may want to amend the other, too. ;;;###autoload (define-obsolete-function-alias 'cl--compiler-macro-cXXr #'internal--compiler-macro-cXXr "25.1") diff --git a/lisp/subr.el b/lisp/subr.el index cda33ba6a29..77e909d1bf6 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -590,9 +590,6 @@ treatment of negative COUNT provided by this function." ;;;; List functions. -;; Note: `internal--compiler-macro-cXXr' was copied from -;; `cl--compiler-macro-cXXr' in cl-macs.el. If you amend either one, -;; you may want to amend the other, too. (defun internal--compiler-macro-cXXr (form x) (let* ((head (car form)) (n (symbol-name head)) commit f478d2d1b935f609b6c390c0ef961c00b295bbd7 Author: Stefan Kangas Date: Wed Feb 12 18:05:11 2025 +0100 Declare caar, cadr, etc. as side-effect-free * lisp/subr.el (caar, cadr, cdar, cddr, caaar, caadr, cadar, caddr) (cdaar, cdadr, cddar, cdddr, caaaar, caaadr, caadar, caaddr, cadaar) (cadadr, caddar, cadddr, cdaaar, cdaadr, cdadar, cdaddr, cddaar) (cddadr, cdddar, cddddr): Declare side-effect-free. * lisp/emacs-lisp/cl-macs.el: Remove redundant declarations of compatibility aliases for the above functions as side-effect-free. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 7559c58e77a..2cf2b3b06e9 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -3731,15 +3731,7 @@ macro that returns its `&whole' argument." (dolist (y '(cl-first cl-second cl-third cl-fourth cl-fifth cl-sixth cl-seventh cl-eighth cl-ninth cl-tenth - cl-rest cl-endp cl-plusp cl-minusp - cl-caaar cl-caadr cl-cadar - cl-caddr cl-cdaar cl-cdadr - cl-cddar cl-cdddr cl-caaaar - cl-caaadr cl-caadar cl-caaddr - cl-cadaar cl-cadadr cl-caddar - cl-cadddr cl-cdaaar cl-cdaadr - cl-cdadar cl-cdaddr cl-cddaar - cl-cddadr cl-cdddar cl-cddddr)) + cl-rest cl-endp cl-plusp cl-minusp)) (put y 'side-effect-free t)) ;;; Things that are inline. diff --git a/lisp/subr.el b/lisp/subr.el index 12f4ec38b78..cda33ba6a29 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -609,142 +609,170 @@ treatment of negative COUNT provided by this function." (defun caar (x) "Return the car of the car of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (car x))) (defun cadr (x) "Return the car of the cdr of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (cdr x))) (defun cdar (x) "Return the cdr of the car of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (car x))) (defun cddr (x) "Return the cdr of the cdr of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (cdr x))) (defun caaar (x) "Return the `car' of the `car' of the `car' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (car (car x)))) (defun caadr (x) "Return the `car' of the `car' of the `cdr' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (car (cdr x)))) (defun cadar (x) "Return the `car' of the `cdr' of the `car' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (cdr (car x)))) (defun caddr (x) "Return the `car' of the `cdr' of the `cdr' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (cdr (cdr x)))) (defun cdaar (x) "Return the `cdr' of the `car' of the `car' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (car (car x)))) (defun cdadr (x) "Return the `cdr' of the `car' of the `cdr' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (car (cdr x)))) (defun cddar (x) "Return the `cdr' of the `cdr' of the `car' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (cdr (car x)))) (defun cdddr (x) "Return the `cdr' of the `cdr' of the `cdr' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (cdr (cdr x)))) (defun caaaar (x) "Return the `car' of the `car' of the `car' of the `car' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (car (car (car x))))) (defun caaadr (x) "Return the `car' of the `car' of the `car' of the `cdr' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (car (car (cdr x))))) (defun caadar (x) "Return the `car' of the `car' of the `cdr' of the `car' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (car (cdr (car x))))) (defun caaddr (x) "Return the `car' of the `car' of the `cdr' of the `cdr' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (car (cdr (cdr x))))) (defun cadaar (x) "Return the `car' of the `cdr' of the `car' of the `car' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (cdr (car (car x))))) (defun cadadr (x) "Return the `car' of the `cdr' of the `car' of the `cdr' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (cdr (car (cdr x))))) (defun caddar (x) "Return the `car' of the `cdr' of the `cdr' of the `car' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (cdr (cdr (car x))))) (defun cadddr (x) "Return the `car' of the `cdr' of the `cdr' of the `cdr' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (car (cdr (cdr (cdr x))))) (defun cdaaar (x) "Return the `cdr' of the `car' of the `car' of the `car' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (car (car (car x))))) (defun cdaadr (x) "Return the `cdr' of the `car' of the `car' of the `cdr' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (car (car (cdr x))))) (defun cdadar (x) "Return the `cdr' of the `car' of the `cdr' of the `car' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (car (cdr (car x))))) (defun cdaddr (x) "Return the `cdr' of the `car' of the `cdr' of the `cdr' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (car (cdr (cdr x))))) (defun cddaar (x) "Return the `cdr' of the `cdr' of the `car' of the `car' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (cdr (car (car x))))) (defun cddadr (x) "Return the `cdr' of the `cdr' of the `car' of the `cdr' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (cdr (car (cdr x))))) (defun cdddar (x) "Return the `cdr' of the `cdr' of the `cdr' of the `car' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (cdr (cdr (car x))))) (defun cddddr (x) "Return the `cdr' of the `cdr' of the `cdr' of the `cdr' of X." - (declare (compiler-macro internal--compiler-macro-cXXr)) + (declare (side-effect-free t) + (compiler-macro internal--compiler-macro-cXXr)) (cdr (cdr (cdr (cdr x))))) (defun last (list &optional n) commit 31381f982dd6f17132a77bc41735a2fcf7cf5d6b Author: Stefan Kangas Date: Wed Feb 12 17:59:45 2025 +0100 Add compiler macros for cl-oddp and cl-evenp * lisp/emacs-lisp/cl-lib.el (cl-oddp, cl-evenp): Add compiler macros. diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index 3f7ca28d2bb..2759fc0a028 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el @@ -280,10 +280,12 @@ so that they are registered at compile-time as well as run-time." (defun cl-oddp (integer) "Return t if INTEGER is odd." + (declare (compiler-macro (lambda (_) `(eq (logand ,integer 1) 1)))) (eq (logand integer 1) 1)) (defun cl-evenp (integer) "Return t if INTEGER is even." + (declare (compiler-macro (lambda (_) `(eq (logand ,integer 1) 0)))) (eq (logand integer 1) 0)) (defconst cl-digit-char-table commit 44c11cd4241ffc8636135bc41ac718101666d34d Author: Juri Linkov Date: Wed Feb 12 20:31:22 2025 +0200 Fix treesit-outline related settings * lisp/treesit.el (treesit-outline-level): Use level 1 by default since treesit-outline--at-point now always returns the current node. * lisp/progmodes/ruby-ts-mode.el (ruby-ts-mode): Use 'bos' instead of 'bol'. Add "singleton_class" to 'treesit-outline-predicate'. Use new condition 'named' in 'treesit-outline-predicate' (bug#74963). diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el index 15394f28b27..551271275d7 100644 --- a/lisp/progmodes/ruby-ts-mode.el +++ b/lisp/progmodes/ruby-ts-mode.el @@ -1168,7 +1168,7 @@ leading double colon is not added." (setq-local treesit-thing-settings `((ruby (sexp ,(cons (rx - bol + bos (or "class" "singleton_class" @@ -1211,49 +1211,48 @@ leading double colon is not added." "instance_variable" "global_variable" ) - eol) + eos) #'ruby-ts--sexp-p)) - (list - ,(cons (rx - bol - (or - "begin_block" - "end_block" - "method" - "singleton_method" - "method_parameters" - "parameters" - "block_parameters" - "class" - "singleton_class" - "module" - "do" - "case" - "case_match" - "array_pattern" - "find_pattern" - "hash_pattern" - "parenthesized_pattern" - "expression_reference_pattern" - "if" - "unless" - "begin" - "parenthesized_statements" - "argument_list" - "do_block" - "block" - "destructured_left_assignment" - "interpolation" - "string" - "string_array" - "symbol_array" - "delimited_symbol" - "regex" - "heredoc_body" - "array" - "hash") - eol) - #'ruby-ts--list-p)) + (list ,(cons (rx + bos + (or + "begin_block" + "end_block" + "method" + "singleton_method" + "method_parameters" + "parameters" + "block_parameters" + "class" + "singleton_class" + "module" + "do" + "case" + "case_match" + "array_pattern" + "find_pattern" + "hash_pattern" + "parenthesized_pattern" + "expression_reference_pattern" + "if" + "unless" + "begin" + "parenthesized_statements" + "argument_list" + "do_block" + "block" + "destructured_left_assignment" + "interpolation" + "string" + "string_array" + "symbol_array" + "delimited_symbol" + "regex" + "heredoc_body" + "array" + "hash") + eos) + #'ruby-ts--list-p)) (text ,(lambda (node) (or (member (treesit-node-type node) '("comment" "string_content" "heredoc_content")) @@ -1275,12 +1274,14 @@ leading double colon is not added." ;; Outline minor mode. (setq-local treesit-outline-predicate - (rx bos (or "singleton_method" - "method" - "alias" - "class" - "module") - eos)) + `(and ,(rx bos (or "singleton_method" + "method" + "alias" + "singleton_class" + "class" + "module") + eos) + named)) ;; Restore default values of outline variables ;; to use `treesit-outline-predicate'. (kill-local-variable 'outline-regexp) diff --git a/lisp/treesit.el b/lisp/treesit.el index 49b81a2c87f..e67e2cc43f6 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -3501,7 +3501,7 @@ when a major mode sets it.") treesit-simple-imenu-settings)) (defun treesit-outline--at-point () - "Return the outline heading at the current line." + "Return the outline heading node at the current line." (let* ((pred treesit-outline-predicate) (bol (pos-bol)) (eol (pos-eol)) @@ -3551,8 +3551,7 @@ For BOUND, MOVE, BACKWARD, LOOKING-AT, see the descriptions in (defun treesit-outline-level () "Return the depth of the current outline heading." (let* ((node (treesit-outline--at-point)) - (level (if (treesit-node-match-p node treesit-outline-predicate) - 1 0))) + (level 1)) (while (setq node (treesit-parent-until node treesit-outline-predicate)) (setq level (1+ level))) (if (zerop level) 1 level))) commit b514ec87b618e4ee9a95b248eb55c5e0cc69949c Author: Juri Linkov Date: Wed Feb 12 19:41:12 2025 +0200 ; * lisp/treesit.el: Remove TODO for integration with thing-at-point. At this point, thing-at-point with all standard things is already supported by treesit, for example: "(thing-at-point 'defun)" by treesit-beginning-of-defun, "(thing-at-point 'sexp)" by treesit-forward-sexp, "(thing-at-point 'list)" by treesit-up-list, "(thing-at-point 'sentence)" by treesit-forward-sentence, "(thing-at-point 'comment)" by treesit-forward-comment. https://lists.gnu.org/archive/html/emacs-devel/2025-02/msg00384.html diff --git a/lisp/treesit.el b/lisp/treesit.el index 90426534842..49b81a2c87f 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -2789,9 +2789,6 @@ friends." ;; ;; There are also some defun-specific functions, like ;; treesit-defun-name, treesit-add-log-current-defun. -;; -;; TODO: Integration with thing-at-point: once our thing interface is -;; stable. (defvar-local treesit-defun-type-regexp nil "A regexp that matches the node type of defun nodes. @@ -3258,7 +3255,6 @@ function is called recursively." ;; Counter equal to 0 means we successfully stepped ARG steps. (if (eq counter 0) pos nil))) -;; TODO: In corporate into thing-at-point. (defun treesit-thing-at-point (thing tactic) "Return the THING at point, or nil if none is found. commit 82da36286265bb34baf39425a880dc11285648f2 Author: Dmitry Gutov Date: Wed Feb 12 19:17:29 2025 +0200 New command project-find-matching-file * lisp/progmodes/project.el (project--read-project-list): Ensure that the directory has a trailing '/' (bug#75983). diff --git a/etc/NEWS b/etc/NEWS index ac26b595339..5a29cd0a582 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -284,6 +284,12 @@ When such value is used, the 'project-prompter' is called with it as the first argument. This is a way for the callers to indicate, for example, the reason or the context why the project is asked for. +--- +*** New command 'project-find-matching-file' +It can be used when switching between projects with similar file trees +(such as Git worktrees of the same repository). It supports being +invoked standalone or from the 'project-switch-commands' dispatch menu. + ** Registers *** New functions 'buffer-to-register' and 'file-to-register'. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index fe8a765d194..ff707437e95 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1284,6 +1284,34 @@ directories listed in `vc-directory-exclusion-list'." (user-error "You didn't specify the file") (find-file file)))) +;;;###autoload +(defun project-find-matching-file () + "Visit the file that matches the current one, in another project. +It will skip to the same line number as well. +A matching file has the same file name relative to the project root. +When called during switching to another project, this command will +detect it and use the override. Otherwise, it prompts for the project +to use from the known list." + (interactive) + (let* ((pr (project-current)) + (line (line-number-at-pos nil t)) + relative-name mirror-name) + (if project-current-directory-override + (let* (project-current-directory-override + (real-project (project-current t))) + (setq relative-name (file-relative-name buffer-file-name + (project-root real-project)))) + (setq relative-name (file-relative-name buffer-file-name (project-root pr))) + (setq pr (project-read-project))) + (setq mirror-name (expand-file-name relative-name (project-root pr))) + (if (not (file-exists-p mirror-name)) + (user-error "File `%s' not found in `%s'" relative-name (project-root pr)) + (find-file mirror-name) + (save-restriction + (widen) + (goto-char (point-min)) + (forward-line (1- line)))))) + (defun project--completing-read-strict (prompt collection &optional predicate hist mb-default commit b9552ad8442ad20ed47b2d312a666585e23958fa Author: Stefan Kangas Date: Wed Feb 12 17:40:51 2025 +0100 Fix recently introduced test failure * test/lisp/progmodes/go-ts-mode-tests.el (go-mod-ts-mode-test-indentation): Fix test. diff --git a/test/lisp/progmodes/go-ts-mode-tests.el b/test/lisp/progmodes/go-ts-mode-tests.el index 7a4d7453799..abd0f5f94eb 100644 --- a/test/lisp/progmodes/go-ts-mode-tests.el +++ b/test/lisp/progmodes/go-ts-mode-tests.el @@ -36,7 +36,7 @@ ;; go-mod-ts-mode -(ert-deftest go-work-ts-mode-test-indentation () +(ert-deftest go-mod-ts-mode-test-indentation () (skip-unless (treesit-ready-p 'gomod)) (ert-test-erts-file (ert-resource-file "indent-mod.erts"))) commit 5d4927192a23bceb1403bd0170d5b4849162262d Author: Stefan Kangas Date: Wed Feb 12 17:33:52 2025 +0100 Mark package-x.el as obsolete * lisp/obsolete/package-x.el: Add "Obsolete-since" header. (Bug#76194) * doc/lispref/package.texi (Package Archives): Don't document package-x. diff --git a/doc/lispref/package.texi b/doc/lispref/package.texi index 0d8dc6db0eb..fd64f89e531 100644 --- a/doc/lispref/package.texi +++ b/doc/lispref/package.texi @@ -333,12 +333,6 @@ and associated files, are stored. If you want the archive to be reachable via HTTP, this directory must be accessible to a web server; @xref{Archive Web Server}. - A convenient way to set up and update a package archive is via the -@code{package-x} library. This is included with Emacs, but not loaded -by default; type @kbd{M-x load-library @key{RET} package-x @key{RET}} to -load it, or add @code{(require 'package-x)} to your init file. -@xref{Lisp Libraries,, Lisp Libraries, emacs, The GNU Emacs Manual}. - @noindent After you create an archive, remember that it is not accessible in the Package Menu interface unless it is in @code{package-archives}. diff --git a/etc/NEWS b/etc/NEWS index 53bc6ff2aaa..ac26b595339 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1130,6 +1130,9 @@ will not prompt the user for confirmation before installing packages. Refreshing the package index will no longer block when invoked interactively. ++++ +*** package-x.el is now obsolete. + ** Xref --- diff --git a/lisp/obsolete/package-x.el b/lisp/obsolete/package-x.el index 68a62df90f7..ff7d1022e4d 100644 --- a/lisp/obsolete/package-x.el +++ b/lisp/obsolete/package-x.el @@ -6,6 +6,7 @@ ;; Created: 10 Mar 2007 ;; Keywords: tools ;; Package: package +;; Obsolete-since: 31.1 ;; This file is part of GNU Emacs. commit f7867e685659ede4fafa8691381cfe08becc6ad6 Author: Stefan Kangas Date: Wed Feb 12 17:32:33 2025 +0100 Move package-x.el to lisp/obsolete * lisp/emacs-lisp/package-x.el: Move from here... * lisp/obsolete/package-x.el: ...to here. (Bug#76194) diff --git a/lisp/emacs-lisp/package-x.el b/lisp/obsolete/package-x.el similarity index 100% rename from lisp/emacs-lisp/package-x.el rename to lisp/obsolete/package-x.el commit cdf9f3ae19d9b5f82a3677f4a9b7585e956cded6 Author: Stefan Kangas Date: Wed Feb 12 17:32:03 2025 +0100 ; Fix indentation to appease git hooks * lisp/emacs-lisp/package-x.el (package-upload-buffer-internal): Fix indentation. diff --git a/lisp/emacs-lisp/package-x.el b/lisp/emacs-lisp/package-x.el index 31996662c38..68a62df90f7 100644 --- a/lisp/emacs-lisp/package-x.el +++ b/lisp/emacs-lisp/package-x.el @@ -245,9 +245,9 @@ if it exists." ;; If there is a commentary section, write it. (when commentary (write-region commentary nil - (expand-file-name - (concat (symbol-name pkg-name) "-readme.txt") - package-archive-upload-base))) + (expand-file-name + (concat (symbol-name pkg-name) "-readme.txt") + package-archive-upload-base))) (set-buffer (if (eq file-type 'tar) tar-data-buffer pkg-buffer)) (write-region (point-min) (point-max) commit 2bb38cc46dfedfb1547746d9123d6b433ccdaca4 Author: Ship Mints Date: Wed Feb 12 18:02:28 2025 +0200 Make reading project--list safer * lisp/progmodes/project.el (project--read-project-list): Ensure that each directory has a trailing '/' (bug#75983). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 5dd10071a1c..fe8a765d194 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1824,7 +1824,8 @@ With some possible metadata (to be decided).") (lambda (elem) (let ((name (car elem))) (list (if (file-remote-p name) name - (abbreviate-file-name name))))) + (file-name-as-directory + (abbreviate-file-name name)))))) (condition-case nil (read (current-buffer)) (end-of-file commit 8eef8907392942a8ececc0f989fa0bb031f4af18 Author: Martin Rudalics Date: Wed Feb 12 10:54:28 2025 +0100 Handle negative frame position values in xterm.c (Bug#76190) * src/xterm.c (x_calc_absolute_position): Always handle negative positions when XNegative or YNegative were set (Bug#76190). diff --git a/src/xterm.c b/src/xterm.c index c3047c4098b..2ccf267bbd3 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -27512,7 +27512,7 @@ x_calc_absolute_position (struct frame *f) /* Treat negative positions as relative to the leftmost bottommost position that fits on the screen. */ - if ((flags & XNegative) && (f->left_pos <= 0)) + if (flags & XNegative) { int width = FRAME_PIXEL_WIDTH (f); @@ -27539,7 +27539,7 @@ x_calc_absolute_position (struct frame *f) } - if ((flags & YNegative) && (f->top_pos <= 0)) + if (flags & YNegative) { int height = FRAME_PIXEL_HEIGHT (f); commit b5404a205c1a1aa858dc430ffaa32a35c744e244 Author: Tassilo Horn Date: Wed Feb 12 10:33:08 2025 +0100 Allow URL-FORMAT as string and function in bug-reference-setup-from-vc-alist That's a slight simplification resulting from bug#72735. * lisp/progmodes/bug-reference.el (bug-reference-setup-from-vc-alist): Rename URL-FORMAT-FN to URL-FORMAT and mention it may be string or function. * (bug-reference-maybe-setup-from-vc): Handle the new case where bug-url-fmt is just a string rather than a function. diff --git a/lisp/progmodes/bug-reference.el b/lisp/progmodes/bug-reference.el index 2b2858739cb..a4147bca05e 100644 --- a/lisp/progmodes/bug-reference.el +++ b/lisp/progmodes/bug-reference.el @@ -225,10 +225,14 @@ subexpression 10." (when (string-match url-rx url) (setq-local bug-reference-bug-regexp bug-rx) (setq-local bug-reference-url-format - (let (groups) - (dotimes (i (/ (length (match-data)) 2)) - (push (match-string i url) groups)) - (funcall bug-url-fmt (nreverse groups)))))) + (if (functionp bug-url-fmt) + ;; Collect the regex matches in a list and call + ;; bug-url-fmt with it. + (let (groups) + (dotimes (i (/ (length (match-data)) 2)) + (push (match-string i url) groups)) + (funcall bug-url-fmt (nreverse groups))) + bug-url-fmt)))) (defvar bug-reference--setup-from-vc-alist nil "An alist for setting up `bug-reference-mode' based on VC URL. @@ -366,13 +370,14 @@ generated from `bug-reference-forge-alist'." (defvar bug-reference-setup-from-vc-alist nil "An alist for setting up `bug-reference-mode' based on VC URL. -Each element has the form (URL-REGEXP BUG-REGEXP URL-FORMAT-FN). +Each element has the form (URL-REGEXP BUG-REGEXP URL-FORMAT). -URL-REGEXP is matched against the version control URL of the -current buffer's file. If it matches, BUG-REGEXP is set as -`bug-reference-bug-regexp'. URL-FORMAT-FN is a function of one -argument that receives a list of the groups 0 to N of matching -URL-REGEXP against the VCS URL and returns the value to be set as +URL-REGEXP is matched against the version control URL of the current +buffer's file. If it matches, BUG-REGEXP is set as +`bug-reference-bug-regexp'. URL-FORMAT is either a string, the +`bug-reference-url-format' to be used, or a function of one argument +that receives a list of the groups 0 to N of matching URL-REGEXP against +the VCS URL and returns the value to be set as `bug-reference-url-format'.") (defun bug-reference-try-setup-from-vc () commit 2254f7159813c345021896605be177e43c7ccb6d Author: Stefan Kangas Date: Wed Feb 12 09:17:37 2025 +0100 ; Fix up last commit * lisp/emulation/cua-base.el (cua--copy-or-cut-handler): Extract function from... (cua-cut-handler, cua-copy-handler): ...here. (cua-cut-to-global-mark, cua-copy-to-global-mark): Declare. diff --git a/lisp/emulation/cua-base.el b/lisp/emulation/cua-base.el index e2bc710c788..baee1a6965f 100644 --- a/lisp/emulation/cua-base.el +++ b/lisp/emulation/cua-base.el @@ -703,21 +703,25 @@ Repeating prefix key when region is active works as a single prefix key." ;; correct keys when generating menus. Also, when cua--prefix-override-handler ;; is nil, allow C-x C-c to cut/copy immediately without waiting for ;; cua--prefix-override-timer to expire. -(defun cua-cut-handler () - (interactive) +(declare-function cua-cut-to-global-mark "cua-gmrk") +(declare-function cua-copy-to-global-mark "cua-gmrk") +(defun cua--copy-or-cut-handler (&optional cut) (if (or (not (numberp cua-prefix-override-inhibit-delay)) (<= cua-prefix-override-inhibit-delay 0)) - (cond (cua--global-mark-active (cua-cut-to-global-mark)) - (t (call-interactively 'kill-region))) + (cond ((and (bound-and-true-p cua--global-mark-active)) + (funcall (if cut #'cua-cut-to-global-mark + #'cua-copy-to-global-mark))) + (t (call-interactively (if cut #'kill-region + #'copy-region-as-kill)))) (cua--prefix-override-handler))) +(defun cua-cut-handler () + (interactive) + (cua--copy-or-cut-handler t)) + (defun cua-copy-handler () (interactive) - (if (or (not (numberp cua-prefix-override-inhibit-delay)) - (<= cua-prefix-override-inhibit-delay 0)) - (cond (cua--global-mark-active (cua-copy-to-global-mark)) - (t (call-interactively 'copy-region-as-kill))) - (cua--prefix-override-handler))) + (cua--copy-or-cut-handler)) (defun cua--prefix-repeat-handler () "Repeating prefix key when region is active works as a single prefix key." commit 1fdfcad924a9dfaf5858624bb86cc34bd050a0de Author: Siyuan Chen Date: Tue May 28 00:29:50 2024 +0800 Fix 'C-x C-c' with cua-prefix-override-inhibit-delay nil * lisp/emulation/cua-base.el (cua-cut-handler, cua-copy-handler): New functions to fix cut and paste when 'cua-prefix-override-inhibit-delay' is nil. (Bug#71230) Copyright-paperwork-exempt: yes diff --git a/lisp/emulation/cua-base.el b/lisp/emulation/cua-base.el index 56c4085804b..e2bc710c788 100644 --- a/lisp/emulation/cua-base.el +++ b/lisp/emulation/cua-base.el @@ -699,10 +699,25 @@ Repeating prefix key when region is active works as a single prefix key." (interactive) (cua--prefix-override-replay 0)) -;; These aliases are so that we can look up the commands and find the -;; correct keys when generating menus. -(defalias 'cua-cut-handler #'cua--prefix-override-handler) -(defalias 'cua-copy-handler #'cua--prefix-override-handler) +;; These two functions are so that we can look up the commands and find the +;; correct keys when generating menus. Also, when cua--prefix-override-handler +;; is nil, allow C-x C-c to cut/copy immediately without waiting for +;; cua--prefix-override-timer to expire. +(defun cua-cut-handler () + (interactive) + (if (or (not (numberp cua-prefix-override-inhibit-delay)) + (<= cua-prefix-override-inhibit-delay 0)) + (cond (cua--global-mark-active (cua-cut-to-global-mark)) + (t (call-interactively 'kill-region))) + (cua--prefix-override-handler))) + +(defun cua-copy-handler () + (interactive) + (if (or (not (numberp cua-prefix-override-inhibit-delay)) + (<= cua-prefix-override-inhibit-delay 0)) + (cond (cua--global-mark-active (cua-copy-to-global-mark)) + (t (call-interactively 'copy-region-as-kill))) + (cua--prefix-override-handler))) (defun cua--prefix-repeat-handler () "Repeating prefix key when region is active works as a single prefix key." commit fa4260594fd2aae1c7d3e829b3cb15e344bc25ff Author: Po Lu Date: Wed Feb 12 15:49:12 2025 +0800 X11 drag-and-drop corrections * lisp/x-dnd.el (x-dnd-handle-drag-n-drop-event): Take cdddr of client-message, skipping the selection information. (x-dnd-do-direct-save): Do not erase the local copy of a remote file if it was not in fact copied on behalf of the recipient. (x-dnd-handle-xds-drop): Return proper action. * src/xterm.c (x_term_init): Remove unused variable on non-GTK builds. diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el index fc48a8290f3..760dd0a42bf 100644 --- a/lisp/x-dnd.el +++ b/lisp/x-dnd.el @@ -469,13 +469,15 @@ Currently XDND, Motif and old KDE 1.x protocols are recognized." (progn (let ((action (cdr (assoc (symbol-name (cadr client-message)) x-dnd-xdnd-to-action))) - (targets (cddr client-message)) + (targets (cdddr client-message)) (local-value (nth 2 client-message))) (when (windowp window) (select-window window)) - (x-dnd-save-state window nil nil - (apply #'vector targets)) - (x-dnd-maybe-call-test-function window action) + ;; Remove XdndDirectSave0 from this list--Emacs does not + ;; support this protocol for internal drops. + (setq targets (delete 'XdndDirectSave0 targets)) + (x-dnd-save-state window nil nil (apply #'vector targets)) + (x-dnd-maybe-call-test-function window action nil) (unwind-protect (x-dnd-drop-data event (if (framep window) window (window-frame window)) @@ -1542,43 +1544,46 @@ was taken, or the direct save failed." (x-dnd-use-offix-drop nil) (x-dnd-use-unsupported-drop nil) (prop-deleted nil) + (action nil) encoded-name) (unwind-protect - (progn - (when (file-remote-p file) - (setq file-name (file-local-copy file)) - (setq dnd-last-dragged-remote-file file-name) - (add-hook 'kill-emacs-hook - #'dnd-remove-last-dragged-remote-file)) - (setq encoded-name - (encode-coding-string name - (or file-name-coding-system - default-file-name-coding-system))) - (setq x-dnd-xds-current-file file-name) - (x-change-window-property "XdndDirectSave0" encoded-name - frame "text/plain" 8 nil) - (gui-set-selection 'XdndSelection (concat "file://" file-name)) - ;; FIXME: this does not work with GTK file managers, since - ;; they always reach for `text/uri-list' first, contrary to - ;; the spec. - (let ((action (x-begin-drag '("XdndDirectSave0" "text/uri-list" - "application/octet-stream") - 'XdndActionDirectSave - frame nil allow-same-frame))) - (if (not x-dnd-xds-performed) - action - (let ((property (x-window-property "XdndDirectSave0" frame - "AnyPropertyType" nil t))) - (setq prop-deleted t) - ;; "System-G" deletes the property upon success. - (and (or (null property) - (and (stringp property) - (not (equal property "")))) - action))))) + (setq action + (progn + (when (file-remote-p file) + (setq file-name (file-local-copy file)) + (setq dnd-last-dragged-remote-file file-name) + (add-hook 'kill-emacs-hook + #'dnd-remove-last-dragged-remote-file)) + (setq encoded-name + (encode-coding-string name + (or file-name-coding-system + default-file-name-coding-system))) + (setq x-dnd-xds-current-file file-name) + (x-change-window-property "XdndDirectSave0" encoded-name + frame "text/plain" 8 nil) + (gui-set-selection 'XdndSelection (concat "file://" file-name)) + ;; FIXME: this does not work with GTK file managers, + ;; since they always reach for `text/uri-list' first, + ;; contrary to the spec. + (let ((action (x-begin-drag '("XdndDirectSave0" "text/uri-list" + "application/octet-stream") + 'XdndActionDirectSave + frame nil allow-same-frame))) + (if (not x-dnd-xds-performed) + action + (let ((property (x-window-property "XdndDirectSave0" frame + "AnyPropertyType" nil t))) + (setq prop-deleted t) + ;; "System-G" deletes the property upon success. + (and (or (null property) + (and (stringp property) + (not (equal property "")))) + action)))))) (unless prop-deleted (x-delete-window-property "XdndDirectSave0" frame)) ;; Delete any remote copy that was made. - (when (not (equal file-name original-file-name)) + (when (and (not (equal file-name original-file-name)) + x-dnd-xds-performed) (delete-file file-name))))) (defun x-dnd-save-direct (need-name filename) @@ -1717,7 +1722,7 @@ VERSION is the version of the XDND protocol understood by SOURCE." (if (or (not success) (< version 5)) 0 - "XdndDirectSave0"))))))) + "XdndActionDirectSave"))))))) ;; Internal wheel movement. diff --git a/src/xterm.c b/src/xterm.c index 0a877e9edf9..c3047c4098b 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -30591,7 +30591,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) block_input (); +#ifdef USE_GTK bool was_initialized = x_initialized; +#endif /* USE_GTK */ if (!x_initialized) { x_initialize (); commit aade1b707c6b4932ed023f387d49324c6a7123eb Author: Gabriel Santos Date: Wed Nov 20 23:07:28 2024 -0300 Add go-work-ts-mode for Go workspace files * lisp/progmodes/eglot.el (eglot-server-programs): Add go-work-ts-mode. * lisp/progmodes/go-ts-mode.el (Commentary): Add the repositories for the grammars. (go-work-ts-mode--indent-rules, go-work-ts-mode--keywords) (go-work-ts-mode--font-lock-settings): New variables. (go-work-ts-mode--directive-matcher, go-work-ts-mode): New functions. (go-mod-ts-mode--directive-matcher): Rename from go-mod-ts-mode--in-directive-p. Be more specific on the directive location (modules). Replace mention of nil with function. Use member instead of pcase to check node types. * admin/notes/tree-sitter/build-module/batch.sh * admin/notes/tree-sitter/build-module/build.sh: Add go-work support. * test/lisp/progmodes/go-ts-mode-resources/font-lock-package.go: * test/lisp/progmodes/go-ts-mode-resources/indent-mod.erts: * test/lisp/progmodes/go-ts-mode-resources/indent-work.erts: New files for testing indentation and font-locking for Go module and workspace files. * test/lisp/progmodes/go-ts-mode-tests.el: Add tests for Go module and workspace files. (Bug#74461) * etc/NEWS: Announce go-work-ts-mode. diff --git a/admin/notes/tree-sitter/build-module/batch.sh b/admin/notes/tree-sitter/build-module/batch.sh index 012b5882e83..1b5214267f5 100755 --- a/admin/notes/tree-sitter/build-module/batch.sh +++ b/admin/notes/tree-sitter/build-module/batch.sh @@ -11,6 +11,7 @@ languages=( 'elixir' 'go' 'go-mod' + 'go-work' 'heex' 'html' 'java' diff --git a/admin/notes/tree-sitter/build-module/build.sh b/admin/notes/tree-sitter/build-module/build.sh index 9a567bb094d..4f3c6da3c5f 100755 --- a/admin/notes/tree-sitter/build-module/build.sh +++ b/admin/notes/tree-sitter/build-module/build.sh @@ -39,6 +39,11 @@ case "${lang}" in lang="gomod" org="camdencheek" ;; + "go-work") + # The parser is called "gowork". + lang="gowork" + org="omertuc" + ;; "heex") org="phoenixframework" ;; diff --git a/etc/NEWS b/etc/NEWS index 8434c1e893f..53bc6ff2aaa 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1474,6 +1474,12 @@ means of the GDI+ library. In addition to ':file FILE' for playing a sound from a file, ':data DATA' can now be used to play a sound from memory. +--- +** New major mode 'go-work-ts-mode'. +A major mode based on the tree-sitter library for editing "go.work" +files. If tree-sitter is properly set-up by the user, it can be +enabled for files named "go.work". + ---------------------------------------------------------------------- This file is part of GNU Emacs. diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index dbdb45d08cd..900a0e60513 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -279,7 +279,7 @@ automatically)." (elm-mode . ("elm-language-server")) (mint-mode . ("mint" "ls")) ((kotlin-mode kotlin-ts-mode) . ("kotlin-language-server")) - ((go-mode go-dot-mod-mode go-dot-work-mode go-ts-mode go-mod-ts-mode) + ((go-mode go-dot-mod-mode go-dot-work-mode go-ts-mode go-mod-ts-mode go-work-ts-mode) . ("gopls")) ((R-mode ess-r-mode) . ("R" "--slave" "-e" "languageserver::run()")) diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index ef2af3cd5af..6526ffe0c7c 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -26,6 +26,8 @@ ;; ;; go-ts-mode is known to work with the following languages and version: ;; - tree-sitter-go: v0.23.4-1-g12fe553 +;; - tree-sitter-go-mod: v1.1.0-3b01edce +;; - tree-sitter-go-work: 949a8a47 ;; ;; We try our best to make builtin modes work with latest grammar ;; versions, so a more recent grammar version has a good chance to work. @@ -33,6 +35,9 @@ ;;; Commentary: ;; +;; Go uses tabs as a convention for indentation: +;; https://go.dev/doc/effective_go#formatting +;; so `indent-tabs-mode' is enabled for the modes. ;;; Code: @@ -478,7 +483,7 @@ be run." default-directory (go-ts-mode--get-test-flags)))) -;; go.mod support. +;;;; go.mod support. (defvar go-mod-ts-mode--syntax-table (let ((table (make-syntax-table))) @@ -495,12 +500,12 @@ be run." ((parent-is "replace_directive") parent-bol go-ts-mode-indent-offset) ((parent-is "require_directive") parent-bol go-ts-mode-indent-offset) ((parent-is "retract_directive") parent-bol go-ts-mode-indent-offset) - ((go-mod-ts-mode--in-directive-p) no-indent go-ts-mode-indent-offset) + ((go-mod-ts-mode--directive-matcher) no-indent go-ts-mode-indent-offset) (no-node no-indent 0))) "Tree-sitter indent rules for `go-mod-ts-mode'.") -(defun go-mod-ts-mode--in-directive-p () - "Return non-nil if point is inside a directive. +(defun go-mod-ts-mode--directive-matcher () + "Return a function for determining if point is inside a Go module directive. When entering an empty directive or adding a new entry to one, no node will be present meaning none of the indentation rules will match, because there is no parent to match against. This function determines @@ -510,12 +515,12 @@ what the parent of the node would be if it were a node." (save-excursion (backward-up-list) (back-to-indentation) - (pcase (treesit-node-type (treesit-node-at (point))) - ("exclude" t) - ("module" t) - ("replace" t) - ("require" t) - ("retract" t)))))) + (member (treesit-node-type (treesit-node-at (point))) + '("exclude" + "module" + "replace" + "require" + "retract")))))) (defvar go-mod-ts-mode--keywords '("exclude" "go" "module" "replace" "require" "retract") @@ -582,6 +587,94 @@ what the parent of the node would be if it were a node." (if (treesit-ready-p 'gomod) (add-to-list 'auto-mode-alist '("/go\\.mod\\'" . go-mod-ts-mode))) +;;;; go.work support. + +(defvar go-work-ts-mode--indent-rules + `((gowork + ((node-is ")") parent-bol 0) + ((parent-is "replace_directive") parent-bol go-ts-mode-indent-offset) + ((parent-is "use_directive") parent-bol go-ts-mode-indent-offset) + ((go-work-ts-mode--directive-matcher) no-indent go-ts-mode-indent-offset) + (no-node no-indent 0))) + "Tree-sitter indent rules for `go-work-ts-mode'.") + +(defun go-work-ts-mode--directive-matcher () + "Return a function for determining if point is inside a Go workspace directive. +When entering an empty directive or adding a new entry to one, no node +will be present meaning none of the indentation rules will match, +because there is no parent to match against. This function determines +what the parent of the node would be if it were a node." + (lambda (node _ _ &rest _) + (unless (treesit-node-type node) + (save-excursion + (backward-up-list) + (back-to-indentation) + (member (treesit-node-type (treesit-node-at (point))) + '("replace" + "use")))))) + +(defvar go-work-ts-mode--keywords + '("go" "replace" "use") + "go.work keywords for tree-sitter font-locking.") + +(defvar go-work-ts-mode--font-lock-settings + (treesit-font-lock-rules + :language 'gowork + :feature 'bracket + '((["(" ")"]) @font-lock-bracket-face) + + :language 'gowork + :feature 'comment + '((comment) @font-lock-comment-face) + + :language 'gowork + :feature 'keyword + `([,@go-work-ts-mode--keywords] @font-lock-keyword-face) + + :language 'gowork + :feature 'number + '([(go_version) (version)] @font-lock-number-face) + + :language 'gowork + :feature 'operator + '((["=>"]) @font-lock-operator-face) + + :language 'gowork + :feature 'error + :override t + '((ERROR) @font-lock-warning-face)) + "Tree-sitter font-lock settings for `go-work-ts-mode'.") + +;;;###autoload +(define-derived-mode go-work-ts-mode prog-mode "Go Work" + "Major mode for editing go.work files, powered by tree-sitter." + :group 'go + + (when (treesit-ready-p 'gowork) + (setq treesit-primary-parser (treesit-parser-create 'gowork)) + + ;; Comments. + (setq-local comment-start "// ") + (setq-local comment-end "") + (setq-local comment-start-skip (rx "//" (* (syntax whitespace)))) + + ;; Indent. + (setq-local indent-tabs-mode t + treesit-simple-indent-rules go-work-ts-mode--indent-rules) + + ;; Font-lock. + (setq-local treesit-font-lock-settings go-work-ts-mode--font-lock-settings) + (setq-local treesit-font-lock-feature-list + '((comment) + (keyword) + (number) + (bracket error operator))) + + (treesit-major-mode-setup))) + +;;;###autoload +(add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode)) + (provide 'go-ts-mode) ;;; go-ts-mode.el ends here diff --git a/test/lisp/progmodes/go-ts-mode-resources/font-lock-package.go b/test/lisp/progmodes/go-ts-mode-resources/font-lock-package.go new file mode 100644 index 00000000000..7bee6848810 --- /dev/null +++ b/test/lisp/progmodes/go-ts-mode-resources/font-lock-package.go @@ -0,0 +1,4 @@ +replace gnu.org/go/package1 v1.0.0 => gnu.org/go/package2 v1.0.0 +// ^ font-lock-keyword-face +// ^ font-lock-number-face +// ^ font-lock-operator-face diff --git a/test/lisp/progmodes/go-ts-mode-resources/indent-mod.erts b/test/lisp/progmodes/go-ts-mode-resources/indent-mod.erts new file mode 100644 index 00000000000..2f7bfd9030b --- /dev/null +++ b/test/lisp/progmodes/go-ts-mode-resources/indent-mod.erts @@ -0,0 +1,16 @@ +Code: + (lambda () + (go-mod-ts-mode) + (indent-region (point-min) (point-max))) + +Point-Char: | + +Name: Basic + +=-= +require ( + gnu.org/go/package1 v1.0.0 + gnu.org/go/package2 v1.0.0 +) + +=-=-= diff --git a/test/lisp/progmodes/go-ts-mode-resources/indent-work.erts b/test/lisp/progmodes/go-ts-mode-resources/indent-work.erts new file mode 100644 index 00000000000..b210974cedc --- /dev/null +++ b/test/lisp/progmodes/go-ts-mode-resources/indent-work.erts @@ -0,0 +1,16 @@ +Code: + (lambda () + (go-work-ts-mode) + (indent-region (point-min) (point-max))) + +Point-Char: | + +Name: Basic + +=-= +use ( + ./package1 + ./package2 +) + +=-=-= diff --git a/test/lisp/progmodes/go-ts-mode-tests.el b/test/lisp/progmodes/go-ts-mode-tests.el index 2837d5d23d2..7a4d7453799 100644 --- a/test/lisp/progmodes/go-ts-mode-tests.el +++ b/test/lisp/progmodes/go-ts-mode-tests.el @@ -23,6 +23,8 @@ (require 'ert-x) (require 'treesit) +;; go-ts-mode + (ert-deftest go-ts-mode-test-indentation () (skip-unless (treesit-ready-p 'go)) (ert-test-erts-file (ert-resource-file "indent.erts"))) @@ -32,5 +34,27 @@ (let ((treesit-font-lock-level 4)) (ert-font-lock-test-file (ert-resource-file "font-lock.go") 'go-ts-mode))) +;; go-mod-ts-mode + +(ert-deftest go-work-ts-mode-test-indentation () + (skip-unless (treesit-ready-p 'gomod)) + (ert-test-erts-file (ert-resource-file "indent-mod.erts"))) + +(ert-deftest go-mod-ts-test-font-lock () + (skip-unless (treesit-ready-p 'gomod)) + (let ((treesit-font-lock-level 4)) + (ert-font-lock-test-file (ert-resource-file "font-lock-package.go") 'go-mod-ts-mode))) + +;; go-work-ts-mode + +(ert-deftest go-work-ts-mode-test-indentation () + (skip-unless (treesit-ready-p 'gowork)) + (ert-test-erts-file (ert-resource-file "indent-work.erts"))) + +(ert-deftest go-work-ts-test-font-lock () + (skip-unless (treesit-ready-p 'gowork)) + (let ((treesit-font-lock-level 4)) + (ert-font-lock-test-file (ert-resource-file "font-lock-package.go") 'go-work-ts-mode))) + (provide 'go-ts-mode-tests) ;;; go-ts-mode-tests.el ends here commit 7aa42917288829406d12c6d5c537ef9a720326a2 Author: Gabriel Santos Date: Mon Jan 6 16:56:31 2025 -0300 image-dired: Add extra keybinds for navigation * lisp/image/image-dired.el (image-dired-thumbnail-mode-map): Bind previously unused keys for alternative navigation. (Bug#75410) diff --git a/etc/NEWS b/etc/NEWS index 9fe46d818bd..8434c1e893f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -430,6 +430,11 @@ default is nil, which retains the old format. This allows passing a string with wildcards, or a cons cell where the first element is a list and the rest is a list of files. +*** Bound unused letters in 'image-dired-thumbnail-mode-map' +For a more comfortable navigation experience (as in, no modifier keys), +the keys "f", "b", "n", "p", "a" and "e" are now bound to the +same functions as their C- counterparts. + ** Browse URL *** New user option 'browse-url-transform-alist'. diff --git a/lisp/image/image-dired.el b/lisp/image/image-dired.el index 3b550fbc35a..906e3521a61 100644 --- a/lisp/image/image-dired.el +++ b/lisp/image/image-dired.el @@ -950,6 +950,15 @@ You probably want to use this together with (defvar-keymap image-dired-thumbnail-mode-map :doc "Keymap for `image-dired-thumbnail-mode'." + + ;; Regular navigation + "f" #'image-dired-forward-image + "b" #'image-dired-backward-image + "n" #'image-dired-next-line + "p" #'image-dired-previous-line + "a" #'image-dired-move-beginning-of-line + "e" #'image-dired-move-end-of-line + "d" #'image-dired-flag-thumb-original-file "" #'image-dired-flag-thumb-original-file "m" #'image-dired-mark-thumb-original-file commit dcc4cec04ada100d4389393500bdc94018e180c8 Author: Basil L. Contovounesios Date: Wed Oct 18 15:33:51 2023 +0200 Print bare symbols for EMACS_GENERATE_DYNVARS * lisp/emacs-lisp/bytecomp.el (byte-compile--load-dynvars): Remove redundant goto-char. (byte-compile-file): Bind print-symbols-bare around .dynvars file generation. (Bug#66628) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index f8c2f8c7219..931b155313e 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2132,7 +2132,6 @@ If compilation is needed, this functions returns the result of (and file (not (equal file "")) (with-temp-buffer (insert-file-contents file) - (goto-char (point-min)) (let ((vars nil) var) (while (ignore-errors (setq var (read (current-buffer)))) @@ -2355,7 +2354,8 @@ See also `emacs-lisp-byte-compile-and-load'." (let ((gen-dynvars (getenv "EMACS_GENERATE_DYNVARS"))) (when (and gen-dynvars (not (equal gen-dynvars "")) byte-compile--seen-defvars) - (let ((dynvar-file (concat target-file ".dynvars"))) + (let ((dynvar-file (concat target-file ".dynvars")) + (print-symbols-bare t)) (message "Generating %s" dynvar-file) (with-temp-buffer (dolist (var (delete-dups byte-compile--seen-defvars)) commit a73a1e00523c55942b953b55c3baaeb335e07e45 Author: Lin Jian Date: Tue Jan 30 06:11:26 2024 +0800 Substitute all emacsclient occurrences in emacsclient.desktop After commit "From .desktop files, reuse a frame or start a new Emacs as required" on 2021-06-30, there are two emacsclient occurrences for the Exec key of etc/emacsclient.desktop. Before this change, only the first occurrence is substituted. * Makefile.in (install-etc): Substitute all emacsclient occurrences in emacsclient.desktop. (Bug#68803) Copyright-paperwork-exempt: yes diff --git a/Makefile.in b/Makefile.in index 8579cea3e89..57cfcfd1605 100644 --- a/Makefile.in +++ b/Makefile.in @@ -859,7 +859,7 @@ install-etc: rm -f $${tmp} tmp=etc/emacsclient.tmpdesktop; rm -f $${tmp}; \ client_name=`echo emacsclient | sed '$(TRANSFORM)'`${EXEEXT}; \ - sed -e "/^Exec=/ s|emacsclient|${bindir}/$${client_name}|" \ + sed -e "/^Exec=/ s|emacsclient|${bindir}/$${client_name}|g" \ -e "/^Icon=emacs/ s/emacs/${EMACS_NAME}/" \ $(USE_STARTUP_NOTIFICATION_SED_CMD) \ $(USE_WAYLAND_DISPLAY_SED_CMD) \ commit 9e3359475f167ad8b18e5259a6585700ab135953 Author: Lin Jian Date: Tue Jan 30 06:12:43 2024 +0800 Remove an unneeded sed command for emacs.service After commit e5348f125ff03ac70713e5b227f9e51f759a587b on 2020-12-14, there is no ExecStop in etc/emacs.service. * Makefile.in (install-etc): Remove an unneeded sed command for etc/emacs.service. Copyright-paperwork-exempt: yes diff --git a/Makefile.in b/Makefile.in index 342bec11d81..8579cea3e89 100644 --- a/Makefile.in +++ b/Makefile.in @@ -888,11 +888,9 @@ install-etc: rm -f $${tmp} umask 022; $(MKDIR_P) "$(DESTDIR)$(systemdunitdir)" tmp=etc/emacs.tmpservice; rm -f $${tmp}; \ - client_name=`echo emacsclient | sed '$(TRANSFORM)'`${EXEEXT}; \ sed -e '/^##/d' \ -e "/^Documentation/ s/emacs(1)/${EMACS_NAME}(1)/" \ -e "/^ExecStart/ s|emacs|${bindir}/${EMACS}|" \ - -e "/^ExecStop/ s|emacsclient|${bindir}/$${client_name}|" \ ${srcdir}/etc/emacs.service > $${tmp}; \ $(INSTALL_DATA) $${tmp} "$(DESTDIR)$(systemdunitdir)/${EMACS_NAME}.service"; \ rm -f $${tmp} commit 02485d2982875b309ef93708c3b2d6aa59a1195b Merge: 82384aaef0e 32700f38fdd Author: Po Lu Date: Wed Feb 12 11:16:54 2025 +0800 Merge remote-tracking branch 'savannah/master' into master-android-1 commit 82384aaef0eb2317fd8249a42a3521aa2c479b08 Merge: 288339e62e7 ea3a937176f Author: Po Lu Date: Wed Feb 12 11:16:20 2025 +0800 Merge from savannah/emacs-30 ea3a937176f ; Add a utility script for retrieving Android port depend... commit 288339e62e72b5de04d8c5c2e1e3ec1e04f548ce Merge: fb4daf4aa07 13608ad64d1 Author: Po Lu Date: Wed Feb 12 11:16:20 2025 +0800 ; Merge from savannah/emacs-30 The following commit was skipped: 13608ad64d1 Eglot: mention ocaml-ts-mode in eglot-server-programs commit fb4daf4aa07b6fa060b64548ff5c75819f77515c Merge: 3fd0b802de2 19791839cfb Author: Po Lu Date: Wed Feb 12 11:16:20 2025 +0800 Merge from savannah/emacs-30 19791839cfb ; Don't document a complicated default 88bc748f52f Fix minibuffer-next-completion in completing-read-multiple 737f249aa2c ; Document 'completing-read-multiple' in the ELisp manual 37f25514602 ; * lisp/gnus/nnweb.el (nnweb-type): Doc fix. commit 32700f38fdd279cb79e3b78b35cb8666f5cd08a7 Author: Thuna Date: Fri Nov 18 15:56:38 2022 +0100 Highlight multiple symbols in single quotes in CL strings * lisp/emacs-lisp/lisp-mode.el (lisp-cl-font-lock-keywords-2): When multiple space-delimited symbols are single quoted together (e.g "`foo bar'"), highlight them. (Bug#59360) diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 1349a5212ed..9bed4374dff 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -559,7 +559,9 @@ This will generate compile-time constants from BINDINGS." (,(concat "(" cl-errs-re "\\_>") (1 font-lock-warning-face)) ;; Words inside ‘’ and `' tend to be symbol names. - (,(concat "[`‘]\\(" (rx lisp-mode-symbol) "\\)['’]") + (,(concat "[`‘]\\(" + (rx (* lisp-mode-symbol (+ space)) lisp-mode-symbol) + "\\)['’]") (1 font-lock-constant-face prepend)) ;; Uninterned symbols, e.g., (defpackage #:my-package ...) ;; must come before keywords below to have effect commit ea3a937176fbf038a6f6f5cc7b47fb8cecdd894a Author: Po Lu Date: Wed Feb 12 11:14:29 2025 +0800 ; Add a utility script for retrieving Android port dependencies * admin/download-android-deps.sh: New file. diff --git a/admin/download-android-deps.sh b/admin/download-android-deps.sh new file mode 100644 index 00000000000..e40392381d7 --- /dev/null +++ b/admin/download-android-deps.sh @@ -0,0 +1,133 @@ +#!/bin/sh + +# This script downloads and extracts dependencies from +# https://sourceforge.net/projects/android-ports-for-gnu-emacs/ and +# Android source code repositories for the convenience of packagers. +# +# See https://forum.f-droid.org/t/emacs-packaging/30424/12 for +# context. + +set -e + +bits_64=no + +if [ "$1" == "64" ]; then + bits_64=yes +fi + +ndk_path= + +mirror=${2-https://master.dl.sourceforge.net/project/android-ports-for-gnu-emacs} + +download_tarball () +{ + echo "Downloading $mirror/$1" + curl -OL $mirror/$1 + hash=`shasum $1 | cut -d " " -f 1` + if test "$hash" != "$3"; then + echo "Hash mismatch detected with archive $1:\ + expected $3, but received $hash." + exit 1 + fi + tar xfz $1 $2 + + if test ! -d "$2"; then + echo "\`$1' was extracted but without producing the directory \`$2'." >&2 + exit 1 + fi + + ndk_path="$ndk_path $PWD/$2" +} + +# 31e74492a49cde9e420e2c71f6d6de0f2b9d6fd3 cairo-1.16.0-emacs.tar.gz +# 98de96764c64f31a6df23adec65425e1813f571b gdk-pixbuf-2.22.1-emacs.tar.gz +# a407c568961d729bb2d0175a34e0d4ed4a269978 giflib-5.2.1-emacs.tar.gz +# e63bc0a628cec770a3a5124c00873d4a44c8c1ac glib-2.33.14-emacs.tar.gz +# 66518ea7905cdb42a22b6f003551ca3f73d249f0 gmp-6.3.0-emacs.tar.gz +# 4e92fb479c96f1c0e9eb3577262f1ebe609a752e gnutls-3.8.5-emacs-armv7a.tar.gz +# 0491c778a81e42490789db9b30a9b7c69b650618 gnutls-3.8.5-emacs.tar.gz +# 22dc71d503ab2eb263dc8411de9da1db144520f5 harfbuzz-7.1.0-emacs.tar.gz +# 590f6c6c06dfe19a8190f526b5b76de34b999a07 libcroco-0.6.13-emacs.tar.gz +# 23508b52a8d9fc3f3750c0187e4141b0d06f79c9 libffi-3.4.5-emacs.tar.gz +# b9398f30e882b140ec790a761663e829ba9bce31 libiconv-1.17-emacs.tar.gz +# 5091fe6f8b368ea2dcc92e2fd003add7bbc63a0a libjpeg-turbo-3.0.2-emacs.tar.gz +# 85e10d1d289d7fd4621cb9648533a0cc69f352a8 libpng-1.6.41-emacs.tar.gz +# 8361966e19fe25ae987b08799f1442393ae6366b libselinux-3.6-emacs.tar.gz +# fdc827211075d9b70a8ba6ceffa02eb48d6741e9 libtasn1-4.19.0-emacs.tar.gz +# 73c3174f7b22d3cfedad9eb58db916199575eea4 libxml2-2.12.4-emacs.tar.gz +# 94882f5494e5435f885d64b57e3e7b3ee5345a3b nettle-3.8-emacs.tar.gz +# b4680fcfec66220a09618489584c8f3270cc16fd p11-kit-0.24.1-emacs.tar.gz +# 89bb17b09d4381835b32291a65107dc33281e88b pango-1.38.1-emacs.tar.gz +# 1c8f3b0cbad474da0ab09018c4ecf2119ac4a52d pixman-0.38.4-emacs.tar.gz +# b687c8439d51634d921674dd009645e24873ca36 rsvg-2.40.21-emacs.tar.gz +# eda251614598aacb06f5984a0a280833de456b29 tiff-4.5.1-emacs.tar.gz +# c00d0ea9c6e848f5cce350cb3ed742024f2bdb8b tree-sitter-0.20.7-emacs.tar.gz + +download_tarball "giflib-5.2.1-emacs.tar.gz" "giflib-5.2.1" \ + "a407c568961d729bb2d0175a34e0d4ed4a269978" +download_tarball "libjpeg-turbo-3.0.2-emacs.tar.gz" "libjpeg-turbo-3.0.2" \ + "5091fe6f8b368ea2dcc92e2fd003add7bbc63a0a" +download_tarball "libpng-1.6.41-emacs.tar.gz" "libpng-1.6.41" \ + "85e10d1d289d7fd4621cb9648533a0cc69f352a8" +download_tarball "libxml2-2.12.4-emacs.tar.gz" "libxml2-2.12.4" \ + "73c3174f7b22d3cfedad9eb58db916199575eea4" +download_tarball "gmp-6.3.0-emacs.tar.gz" "gmp-6.3.0" \ + "66518ea7905cdb42a22b6f003551ca3f73d249f0" +download_tarball "nettle-3.8-emacs.tar.gz" "nettle-3.8" \ + "94882f5494e5435f885d64b57e3e7b3ee5345a3b" + +if test "$bits_64" = "yes"; then + download_tarball "gnutls-3.8.5-emacs.tar.gz" "gnutls-3.8.5" \ + "0491c778a81e42490789db9b30a9b7c69b650618" +else + download_tarball "gnutls-3.8.5-emacs-armv7a.tar.gz" "gnutls-3.8.5-armv7a" \ + "4e92fb479c96f1c0e9eb3577262f1ebe609a752e" +fi + +download_tarball "p11-kit-0.24.1-emacs.tar.gz" "p11-kit-0.24.1" \ + "b4680fcfec66220a09618489584c8f3270cc16fd" +download_tarball "libtasn1-4.19.0-emacs.tar.gz" "libtasn1-4.19.0" \ + "fdc827211075d9b70a8ba6ceffa02eb48d6741e9" +download_tarball "libselinux-3.6-emacs.tar.gz" "libselinux-3.6" \ + "8361966e19fe25ae987b08799f1442393ae6366b" +download_tarball "tree-sitter-0.20.7-emacs.tar.gz" "tree-sitter-0.20.7" \ + "c00d0ea9c6e848f5cce350cb3ed742024f2bdb8b" +download_tarball "harfbuzz-7.1.0-emacs.tar.gz" "harfbuzz-7.1.0" \ + "22dc71d503ab2eb263dc8411de9da1db144520f5" +download_tarball "tiff-4.5.1-emacs.tar.gz" "tiff-4.5.1" \ + "eda251614598aacb06f5984a0a280833de456b29" +download_tarball "gdk-pixbuf-2.22.1-emacs.tar.gz" "gdk-pixbuf-2.22.1" \ + "98de96764c64f31a6df23adec65425e1813f571b" +download_tarball "glib-2.33.14-emacs.tar.gz" "glib-2.33.14" \ + "e63bc0a628cec770a3a5124c00873d4a44c8c1ac" +download_tarball "libcroco-0.6.13-emacs.tar.gz" "libcroco-0.6.13" \ + "590f6c6c06dfe19a8190f526b5b76de34b999a07" +download_tarball "rsvg-2.40.21-emacs.tar.gz" "librsvg-2.40.21" \ + "b687c8439d51634d921674dd009645e24873ca36" +download_tarball "cairo-1.16.0-emacs.tar.gz" "cairo-1.16.0" \ + "31e74492a49cde9e420e2c71f6d6de0f2b9d6fd3" +download_tarball "libiconv-1.17-emacs.tar.gz" "libiconv-1.17" \ + "b9398f30e882b140ec790a761663e829ba9bce31" +download_tarball "pango-1.38.1-emacs.tar.gz" "pango-1.38.1" \ + "89bb17b09d4381835b32291a65107dc33281e88b" +download_tarball "pixman-0.38.4-emacs.tar.gz" "pixman-0.38.4" \ + "1c8f3b0cbad474da0ab09018c4ecf2119ac4a52d" +download_tarball "libffi-3.4.5-emacs.tar.gz" "libffi-3.4.5" \ + "23508b52a8d9fc3f3750c0187e4141b0d06f79c9" + +rm -rf sqlite +git clone https://android.googlesource.com/platform/external/sqlite -b android-7.1.2_r39 +ndk_path="$ndk_path $PWD/sqlite/dist" +rm -rf pcre +git clone https://android.googlesource.com/platform/external/pcre -b android-7.1.2_r39 +ndk_path="$ndk_path $PWD/pcre" +rm -rf libwebp +git clone https://chromium.googlesource.com/webm/libwebp -b v1.5.0 +ndk_path="$ndk_path $PWD/libwebp" + +sed -e 's/NEON := c.neon/NEON := c/g' \ + -e '/WEBP_CFLAGS *+=/s/-DHAVE_CPU_FEATURES_H//g' \ + -e 's/USE_CPUFEATURES *.*=.*$/USE_CPUFEATURES := no/g' \ + -i libwebp/Android.mk + +echo $ndk_path > search-path.txt commit fb90e21af1b05d8cdeac9ae62b03b76ae9c74ae0 Author: Thuna Date: Mon Dec 19 09:33:29 2022 +0100 Fix 'rcirc-buffer-process' not working on channel buffers * lisp/net/rcirc.el (rcirc-buffer-process): Look at BUFFER's 'rcirc-server-buffer's 'rcirc-process' instead. Signal an error if it has none. (Bug#60191) diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el index 98b99ebabd9..3f81672182b 100644 --- a/lisp/net/rcirc.el +++ b/lisp/net/rcirc.el @@ -1187,11 +1187,11 @@ element in PARTS is a list, append it to PARTS." (defun rcirc-buffer-process (&optional buffer) "Return the process associated with channel BUFFER. With no argument or nil as argument, use the current buffer." - (let ((buffer (or buffer (and (buffer-live-p rcirc-server-buffer) - rcirc-server-buffer)))) - (if buffer - (buffer-local-value 'rcirc-process buffer) - rcirc-process))) + (let ((buffer (or buffer (current-buffer)))) + (buffer-local-value + 'rcirc-process + (or (buffer-local-value 'rcirc-server-buffer buffer) + (error "Not an rcirc buffer: %S" buffer))))) (defun rcirc-server-name (process) "Return PROCESS server name, given by the 001 response." commit 77d0078a6c50c95b63ac7c3739ee325264deff34 Author: Trevor Arjeski Date: Wed Nov 27 10:12:07 2024 +0300 Fix Gnus logo color customization Fix a bug where customizing `gnus-logo-color-style' from use-package's :custom keyword did not set `gnus-logo-colors' before Gnus is launched. This patch does the following: - Implements a :set keyword on `gnus-logo-color-style' which will correctly set `gnus-logo-colors' - Exposes `gnus-logo-colors' using `defcustom' for more fine-grained customization - Uses :set-after on `gnus-logo-colors' so that it is set after `gnus-logo-color-style' * lisp/gnus/gnus.el (gnus-logo-colors): Convert to defcustom. (gnus-logo-color-style): Add :set property. (Bug#74554) diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 3099f95ebd3..bd967563aac 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -757,16 +757,22 @@ be used directly.") (september "#bf9900" "#ffcc00")) "Color alist used for the Gnus logo.") +(defcustom gnus-logo-colors nil + "Colors used for the Gnus logo." + :set-after '(gnus-logo-color-style) + :type '(list color color) + :group 'gnus-xmas) + (defcustom gnus-logo-color-style 'ma "Color styles used for the Gnus logo." :type `(choice ,@(mapcar (lambda (elem) (list 'const (car elem))) gnus-logo-color-alist)) + :set (lambda (sym val) + (set-default-toplevel-value sym val) + (set-default-toplevel-value 'gnus-logo-colors + (cdr (assq val gnus-logo-color-alist)))) :group 'gnus-xmas) -(defvar gnus-logo-colors - (cdr (assq gnus-logo-color-style gnus-logo-color-alist)) - "Colors used for the Gnus logo.") - (defvar image-load-path) (declare-function image-size "image.c" (spec &optional pixels frame)) commit 481336967cc5d262cec2b4822b83752348bbd494 Author: Stefan Kangas Date: Wed Feb 12 03:34:12 2025 +0100 ; Update :version tag of x-gtk-stock-map * lisp/term/pgtk-win.el (x-gtk-stock-map): * lisp/term/x-win.el (x-gtk-stock-map): Update :version tags. diff --git a/lisp/term/pgtk-win.el b/lisp/term/pgtk-win.el index 5940f961e40..fe9807f8c52 100644 --- a/lisp/term/pgtk-win.el +++ b/lisp/term/pgtk-win.el @@ -263,7 +263,7 @@ EVENT is a `preedit-text' event." "How icons for tool bars are mapped to Gtk+ stock items. Emacs must be compiled with the Gtk+ toolkit for this to have any effect. A value that begins with n: denotes a named icon instead of a stock icon." - :version "22.2" + :version "31.1" :type '(choice (repeat (choice symbol (cons (string :tag "Emacs icon") diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el index fd691958105..debcb669b76 100644 --- a/lisp/term/x-win.el +++ b/lisp/term/x-win.el @@ -1452,7 +1452,7 @@ This returns an error if any Emacs frames are X frames." "How icons for tool bars are mapped to Gtk+ stock items. Emacs must be compiled with the Gtk+ toolkit for this to have any effect. A value that begins with n: denotes a named icon instead of a stock icon." - :version "22.2" + :version "31.1" :type '(choice (repeat (choice symbol (cons (string :tag "Emacs icon") commit 0184acdd3174e95b79756433b9c8c08143737c81 Author: john muhl Date: Wed Jun 19 11:47:42 2024 -0500 Add icons used by 'mpc.el' to 'x-gtk-stock-map' * lisp/term/x-win.el (x-gtk-stock-map): * lisp/term/pgtk-win.el (x-gtk-stock-map): Include tool-bar icons used by 'mpc.el'. diff --git a/lisp/term/pgtk-win.el b/lisp/term/pgtk-win.el index 14808dc7c8b..5940f961e40 100644 --- a/lisp/term/pgtk-win.el +++ b/lisp/term/pgtk-win.el @@ -251,6 +251,14 @@ EVENT is a `preedit-text' event." ;; No themed versions available: ;; mail/preview (combining stock_mail and stock_zoom) ;; mail/save (combining stock_mail, stock_save and stock_convert) + ("images/mpc/prev" . "media-skip-backward") + ("images/mpc/rewind" . "media-seek-backward") + ("images/mpc/pause" . "media-playback-pause") + ("images/mpc/play" . "media-playback-start") + ("images/mpc/ffwd" . "media-seek-forward") + ("images/mpc/next" . "media-skip-forward") + ("images/mpc/stop" . "media-playback-stop") + ("images/mpc/add" . "list-add") ) "How icons for tool bars are mapped to Gtk+ stock items. Emacs must be compiled with the Gtk+ toolkit for this to have any effect. diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el index b614e9aa31d..fd691958105 100644 --- a/lisp/term/x-win.el +++ b/lisp/term/x-win.el @@ -1440,6 +1440,14 @@ This returns an error if any Emacs frames are X frames." ;; No themed versions available: ;; mail/preview (combining stock_mail and stock_zoom) ;; mail/save (combining stock_mail, stock_save and stock_convert) + ("images/mpc/prev" . "media-skip-backward") + ("images/mpc/rewind" . "media-seek-backward") + ("images/mpc/pause" . "media-playback-pause") + ("images/mpc/play" . "media-playback-start") + ("images/mpc/ffwd" . "media-seek-forward") + ("images/mpc/next" . "media-skip-forward") + ("images/mpc/stop" . "media-playback-stop") + ("images/mpc/add" . "list-add") ) "How icons for tool bars are mapped to Gtk+ stock items. Emacs must be compiled with the Gtk+ toolkit for this to have any effect. commit 3fd0b802de20dc83b5d5236b6d458df73c9d4e77 Author: João Távora Date: Tue Feb 11 16:50:23 2025 +0000 Eglot: use Eldoc in eglot-hierarchy-mode Use it to show details of the thing at point, like the full signature and the locus of the definition. * lisp/progmodes/eglot.el: Add optional arg MODE. (eglot--hierarchy-source-major-mode): New defvar. (eglot--hierarchy-1): Adjust. (eglot-hierarchy-mode): Set eldoc stuff. (eglot-hierarchy-center-on-node): Cosmetic fix. (eglot-hierarchy-detail-eldoc-function) (eglot-hierarchy-locus-eldoc-function): New eldoc functions. diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 2deeef9bce1..dbdb45d08cd 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -1956,32 +1956,34 @@ Doubles as an indicator of snippet support." (unless (bound-and-true-p yas-minor-mode) (yas-minor-mode 1)) (apply #'yas-expand-snippet args))))) - (defun eglot--format-markup (markup) + (defun eglot--format-markup (markup &optional mode) "Format MARKUP according to LSP's spec. MARKUP is either an LSP MarkedString or MarkupContent object." - (let (string mode language) + (let (string render-mode language) (cond ((stringp markup) (setq string markup - mode 'gfm-view-mode)) + render-mode (or mode 'gfm-view-mode))) ((setq language (plist-get markup :language)) ;; Deprecated MarkedString (setq string (concat "```" language "\n" (plist-get markup :value) "\n```") - mode 'gfm-view-mode)) + render-mode (or mode 'gfm-view-mode))) (t ;; MarkupContent (setq string (plist-get markup :value) - mode (pcase (plist-get markup :kind) - ("markdown" 'gfm-view-mode) - ("plaintext" 'text-mode) - (_ major-mode))))) + render-mode + (or mode + (pcase (plist-get markup :kind) + ("markdown" 'gfm-view-mode) + ("plaintext" 'text-mode) + (_ major-mode)))))) (with-temp-buffer (setq-local markdown-fontify-code-blocks-natively t) (insert string) (let ((inhibit-message t) (message-log-max nil) match) - (ignore-errors (delay-mode-hooks (funcall mode))) + (ignore-errors (delay-mode-hooks (funcall render-mode))) (font-lock-ensure) (goto-char (point-min)) (let ((inhibit-read-only t)) @@ -3488,8 +3490,7 @@ for which LSP on-type-formatting should be requested." (ensure-resolved (get-text-property 0 'eglot--lsp-item proxy)) :detail))) (when (and (stringp detail) (not (string= detail ""))) - ;; Forces major-mode based fontification - (eglot--format-markup (list :value detail))))) + (eglot--format-markup detail major-mode)))) :company-doc-buffer (lambda (proxy) (let* ((resolved @@ -4457,6 +4458,7 @@ If NOERROR, return predicate, else erroring function." (defvar-local eglot--hierarchy-roots nil) (defvar-local eglot--hierarchy-specs nil) +(defvar-local eglot--hierarchy-source-major-mode nil) (defun eglot--hierarchy-children (node) (cl-flet ((get-them (method node) @@ -4528,6 +4530,7 @@ If NOERROR, return predicate, else erroring function." (defun eglot--hierarchy-1 (name provider preparer specs) (eglot-server-capable-or-lose provider) (let* ((server (eglot-current-server)) + (mode major-mode) (roots (jsonrpc-request server preparer @@ -4540,6 +4543,7 @@ If NOERROR, return predicate, else erroring function." eglot--hierarchy-roots roots eglot--hierarchy-specs specs eglot--cached-server server + eglot--hierarchy-source-major-mode mode buffer-read-only t revert-buffer-function (lambda (&rest _ignore) @@ -4577,16 +4581,40 @@ If NOERROR, return predicate, else erroring function." (define-derived-mode eglot-hierarchy-mode special-mode "Eglot special" "Eglot mode for viewing hierarchies. \\{eglot-hierarchy-mode-map}" - :interactive nil) + :interactive nil + (setq eldoc-documentation-strategy + #'eldoc-documentation-compose) + (add-hook 'eldoc-documentation-functions + #'eglot-hierarchy-detail-eldoc-function + nil t) + (add-hook 'eldoc-documentation-functions + #'eglot-hierarchy-locus-eldoc-function + t t)) (defun eglot-hierarchy-center-on-node () "Refresh hierarchy, centering on node at point." (interactive) (setq-local eglot--hierarchy-roots (list (get-text-property (point) - 'eglot--hierarchy-node))) + 'eglot--hierarchy-node))) (eglot--hierarchy-2)) +(defun eglot-hierarchy-detail-eldoc-function (_cb &rest _ignored) + (when-let* ((detail + (plist-get (get-text-property (point) 'eglot--hierarchy-node) + :detail))) + (eglot--format-markup detail eglot--hierarchy-source-major-mode))) + +(defun eglot-hierarchy-locus-eldoc-function (_cb &rest _ignored) + (let* ((node (get-text-property (point) 'eglot--hierarchy-node)) + (uri (plist-get node :uri)) + (loc (plist-get (plist-get node :range) :start))) + (and uri loc + ;; maybe use `file-relative-name'? + (format "%s:%s:%s" (eglot-uri-to-path uri) + (1+ (plist-get loc :line)) + (plist-get loc :character))))) + ;;; Hacks ;;; commit e2991272f286af94f13d9d78ac609f08ad77183e Author: Manuel Giraud Date: Mon Jul 15 17:33:21 2024 +0200 Remove `smtpmail-address-buffer' temporary buffer * lisp/mail/smtpmail.el (smtpmail-address-buffer): Remove variable. (smtpmail-send-it): (smtpmail-deduce-address-list): Replace `smtpmail-address-buffer' with a temporary buffer. Set `smtpmail-recipient-address-list' only in caller. (Bug#72128) diff --git a/lisp/mail/smtpmail.el b/lisp/mail/smtpmail.el index 6cb576fe72b..43291a3028b 100644 --- a/lisp/mail/smtpmail.el +++ b/lisp/mail/smtpmail.el @@ -182,7 +182,6 @@ These will then be used when sending the queue." ;;; Variables -(defvar smtpmail-address-buffer) (defvar smtpmail-recipient-address-list nil) (defvar smtpmail--stored-queue-variables '(smtpmail-smtp-server @@ -357,11 +356,9 @@ for `smtpmail-try-auth-method'.") (erase-buffer)))) ;; Encode the header according to RFC2047. (mail-encode-header (point-min) delimline) - ;; - (setq smtpmail-address-buffer (generate-new-buffer "*smtp-mail*")) + ;; Get recipients' adresses (setq smtpmail-recipient-address-list (smtpmail-deduce-address-list tembuf (point-min) delimline)) - (kill-buffer smtpmail-address-buffer) (smtpmail-do-bcc delimline) ;; Send or queue @@ -1064,8 +1061,7 @@ Returns an error if the server cannot be contacted." (defun smtpmail-deduce-address-list (smtpmail-text-buffer header-start header-end) "Get address list suitable for smtp RCPT TO:
." - (with-current-buffer smtpmail-address-buffer - (erase-buffer) + (with-temp-buffer (let ((case-fold-search t) (simple-address-list "") this-line @@ -1108,7 +1104,7 @@ Returns an error if the server cannot be contacted." (backward-char 1) (setq recipient-address-list (cons (buffer-substring (match-beginning 1) (match-end 1)) recipient-address-list))) - (setq smtpmail-recipient-address-list recipient-address-list))))) + recipient-address-list)))) (defun smtpmail-do-bcc (header-end) "Delete [Resent-]Bcc: and their continuation lines from the header area. commit 0e76716c5faa5e91ac3913b02ba4dc690cf5df83 Author: Stefan Kangas Date: Tue Feb 11 19:04:00 2025 +0100 Delete redundant lambdas around unary functions This is not just stylistic, but also slightly faster. These are all regular defuns, of course, as this won't work with macros and defsubsts. * lisp/calc/calc-nlfit.el (math-nlfit-fit-curve) (calc-fit-hubbert-linear-curve): * lisp/calendar/cal-tex.el (cal-tex-latexify-list): * lisp/calendar/todo-mode.el (todo-sort): * lisp/cedet/semantic/ctxt.el (semantic-ctxt-end-of-symbol-default) (semantic-ctxt-current-symbol-default): * lisp/cedet/semantic/symref.el (semantic-symref-result-get-files): * lisp/cedet/semantic/texi.el (semantic-texi-command-completion-list): * lisp/descr-text.el (describe-char): * lisp/emacs-lisp/eieio-datadebug.el (data-debug-add-specialized-thing): * lisp/emacs-lisp/rmc.el (read-multiple-choice--short-answers): * lisp/eshell/em-pred.el (eshell-modifier-alist): * lisp/gnus/gnus-cache.el (gnus-cache-articles-in-group): * lisp/gnus/gnus-dired.el (gnus-dired-attach): * lisp/help-mode.el (help-package-def): * lisp/ibuf-ext.el (ibuffer-mark-modified-buffers): * lisp/image/image-dired.el: * lisp/international/quail.el (quail-keyseq-translate) (quail-get-translations): * lisp/isearch.el (isearch-pre-command-hook) (search-within-boundaries): * lisp/mail/supercite.el (sc-ask): * lisp/mh-e/mh-e.el (mh-variant-set): * lisp/net/rcirc.el (rcirc-nick-channels, rcirc-channel-nicks): (rcirc-browse-url): * lisp/obsolete/thumbs.el (thumbs-cleanup-thumbsdir): * lisp/org/org-agenda.el (org-agenda-filter-completion-function): * lisp/org/org-table.el (org-table-eval-formula): * lisp/org/org.el (org-set-regexps-and-options): * lisp/org/ox.el (org-export--get-inbuffer-options): * lisp/ses.el (ses-range): * lisp/textmodes/emacs-news-mode.el (emacs-news--buttonize): * lisp/textmodes/ispell.el (ispell-begin-tex-skip-regexp): * lisp/vc/vc-cvs.el (vc-cvs-stay-local-p): * lisp/window.el (window--state-get-1): * test/lisp/emacs-lisp/shortdoc-tests.el (shortdoc-all-groups-work): Delete redundant lambdas around unary functions. (Bug#66816) diff --git a/lisp/calc/calc-nlfit.el b/lisp/calc/calc-nlfit.el index 2761f35061e..82874284b65 100644 --- a/lisp/calc/calc-nlfit.el +++ b/lisp/calc/calc-nlfit.el @@ -678,7 +678,7 @@ (sdata (if (math-contains-sdev-p ydata) (mapcar (lambda (x) (math-get-sdev x t)) ydata) nil)) - (ydata (mapcar (lambda (x) (math-get-value x)) ydata)) + (ydata (mapcar #'math-get-value ydata)) (calc-curve-varnames nil) (calc-curve-coefnames nil) (calc-curve-nvars 1) @@ -757,7 +757,7 @@ (sdata (if (math-contains-sdev-p pdata) (mapcar (lambda (x) (math-get-sdev x t)) pdata) nil)) - (pdata (mapcar (lambda (x) (math-get-value x)) pdata)) + (pdata (mapcar #'math-get-value pdata)) (poverqdata (math-map-binop 'math-div pdata qdata)) (parmvals (math-nlfit-least-squares qdata poverqdata sdata sdevv)) (finalparms (list (nth 0 parmvals) diff --git a/lisp/calendar/cal-tex.el b/lisp/calendar/cal-tex.el index 8df47431889..c0bb9760810 100644 --- a/lisp/calendar/cal-tex.el +++ b/lisp/calendar/cal-tex.el @@ -1600,7 +1600,7 @@ FINAL-SEPARATOR is non-nil." (or separator (setq separator "\\\\")) (let (result) (setq result - (mapconcat (lambda (x) (cal-tex-LaTeXify-string x)) + (mapconcat #'cal-tex-LaTeXify-string (dolist (d date-list (reverse result)) (and (car d) (calendar-date-equal date (car d)) diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el index 27678328b4a..dc6f7345b21 100644 --- a/lisp/calendar/todo-mode.el +++ b/lisp/calendar/todo-mode.el @@ -3772,7 +3772,7 @@ option `todo-categories-align'." "Return a copy of LIST, possibly sorted according to KEY." (let* ((l (copy-sequence list)) (fn (if (eq key 'alpha) - (lambda (x) (upcase x)) ; Alphabetize case insensitively. + #'upcase ; Alphabetize case insensitively. (lambda (x) (todo-get-count key x)))) ;; Keep track of whether the last sort by key was descending or ;; ascending. diff --git a/lisp/cedet/semantic/ctxt.el b/lisp/cedet/semantic/ctxt.el index 9fc935f4893..3570ccd855d 100644 --- a/lisp/cedet/semantic/ctxt.el +++ b/lisp/cedet/semantic/ctxt.el @@ -362,7 +362,7 @@ This will move past type/field names when applicable. Depends on `semantic-type-relation-separator-character', and will work on C like languages." (if point (goto-char point)) - (let* ((fieldsep1 (mapconcat (lambda (a) (regexp-quote a)) + (let* ((fieldsep1 (mapconcat #'regexp-quote semantic-type-relation-separator-character "\\|")) ;; NOTE: The [ \n] expression below should used \\s-, but that @@ -446,7 +446,7 @@ This will include a list of type/field names when applicable. Depends on `semantic-type-relation-separator-character'." (save-excursion (if point (goto-char point)) - (let* ((fieldsep1 (mapconcat (lambda (a) (regexp-quote a)) + (let* ((fieldsep1 (mapconcat #'regexp-quote semantic-type-relation-separator-character "\\|")) ;; NOTE: The [ \n] expression below should used \\s-, but that diff --git a/lisp/cedet/semantic/sort.el b/lisp/cedet/semantic/sort.el index 9c4aad3db55..3eb4c159b75 100644 --- a/lisp/cedet/semantic/sort.el +++ b/lisp/cedet/semantic/sort.el @@ -243,7 +243,7 @@ unmodified as components of their parent tags." ;; table, and reorganize them into buckets based on class. ;; (defvar semantic-bucketize-tag-class - ;; Must use lambda because `semantic-tag-class' is a macro. + ;; Must use lambda because `semantic-tag-class' is a defsubst. (lambda (tok) (semantic-tag-class tok)) "Function used to get a symbol describing the class of a tag. This function must take one argument of a semantic tag. @@ -401,6 +401,7 @@ buckets with the bucket function." ;; get embedded types to scan and make copies ;; of them. (mapcar + ;; Must use lambda because `semantic-tag-clone' is a defsubst. (lambda (tok) (semantic-tag-clone tok)) (semantic-find-tags-by-class 'type (semantic-tag-type-members (car decent-list))))) diff --git a/lisp/cedet/semantic/symref.el b/lisp/cedet/semantic/symref.el index 99a3287343f..b1a99634ef0 100644 --- a/lisp/cedet/semantic/symref.el +++ b/lisp/cedet/semantic/symref.el @@ -398,7 +398,7 @@ this list.") (if (slot-boundp result 'hit-files) (oref result hit-files) (let* ((lines (oref result hit-lines)) - (files (mapcar (lambda (a) (cdr a)) lines)) + (files (mapcar #'cdr lines)) (ans nil)) (setq ans (list (car files)) files (cdr files)) diff --git a/lisp/cedet/semantic/texi.el b/lisp/cedet/semantic/texi.el index 27720930328..5965e62d151 100644 --- a/lisp/cedet/semantic/texi.el +++ b/lisp/cedet/semantic/texi.el @@ -385,7 +385,7 @@ Optional argument POINT is where to look for the environment." )) (defvar semantic-texi-command-completion-list - (append (mapcar (lambda (a) (car a)) texinfo-section-list) + (append (mapcar #'car texinfo-section-list) texinfo-environments ;; Is there a better list somewhere? Here are few ;; of the top of my head. diff --git a/lisp/descr-text.el b/lisp/descr-text.el index ff4c259463e..3fb21309f7b 100644 --- a/lisp/descr-text.el +++ b/lisp/descr-text.el @@ -407,8 +407,7 @@ The character information includes: (composition-string nil) (disp-vector (and display-table (aref display-table char))) (multibyte-p enable-multibyte-characters) - (overlays (mapcar (lambda (o) (overlay-properties o)) - (overlays-at pos))) + (overlays (mapcar #'overlay-properties (overlays-at pos))) (char-description (if (< char 128) (single-key-description char) (string (if (not multibyte-p) diff --git a/lisp/emacs-lisp/eieio-datadebug.el b/lisp/emacs-lisp/eieio-datadebug.el index 2acd1b8d2e4..5ae665a57fb 100644 --- a/lisp/emacs-lisp/eieio-datadebug.el +++ b/lisp/emacs-lisp/eieio-datadebug.el @@ -111,7 +111,7 @@ PREBUTTONTEXT is some text between PREFIX and the object button." ))))))) ;;; Augment the Data debug thing display list. -(data-debug-add-specialized-thing (lambda (thing) (eieio-object-p thing)) +(data-debug-add-specialized-thing #'eieio-object-p #'data-debug-insert-object-button) ;;; DEBUG METHODS diff --git a/lisp/emacs-lisp/rmc.el b/lisp/emacs-lisp/rmc.el index c4df8cf2f98..158c1e857cc 100644 --- a/lisp/emacs-lisp/rmc.el +++ b/lisp/emacs-lisp/rmc.el @@ -191,7 +191,7 @@ Usage example: (format "%s (%s): " prompt - (mapconcat (lambda (e) (cdr e)) altered-names ", "))) + (mapconcat #'cdr altered-names ", "))) tchar buf wrong-char answer command) (save-window-excursion (save-excursion diff --git a/lisp/eshell/em-pred.el b/lisp/eshell/em-pred.el index 754c17a1926..845fc5a3b3d 100644 --- a/lisp/eshell/em-pred.el +++ b/lisp/eshell/em-pred.el @@ -122,7 +122,7 @@ The format of each entry is (?e . (lambda (lst) (mapcar #'file-name-extension lst))) (?t . (lambda (lst) (mapcar #'file-name-nondirectory lst))) (?q . #'identity) ; Obsolete as of Emacs 31.1. - (?u . (lambda (lst) (seq-uniq lst))) + (?u . #'seq-uniq) (?o . (lambda (lst) (sort lst #'string-lessp))) (?O . (lambda (lst) (sort lst #'string-greaterp))) (?j . (eshell-join-members)) diff --git a/lisp/gnus/gnus-cache.el b/lisp/gnus/gnus-cache.el index b9af1ec93bb..59c5d7bb891 100644 --- a/lisp/gnus/gnus-cache.el +++ b/lisp/gnus/gnus-cache.el @@ -502,7 +502,7 @@ Returns the list of articles removed." (file-name-coding-system nnmail-pathname-coding-system)) (when (file-exists-p dir) (setq articles - (sort (mapcar (lambda (name) (string-to-number name)) + (sort (mapcar #'string-to-number (directory-files dir nil "\\`[0-9]+\\'" t)) #'<)) ;; Update the cache active file, just to synch more. diff --git a/lisp/gnus/gnus-dired.el b/lisp/gnus/gnus-dired.el index ce27fc404ac..1b296cbcffc 100644 --- a/lisp/gnus/gnus-dired.el +++ b/lisp/gnus/gnus-dired.el @@ -136,10 +136,8 @@ filenames." ;; warn if user tries to attach without any files marked (if (null files-to-attach) (error "No files to attach") - (setq files-str - (mapconcat - (lambda (f) (file-name-nondirectory f)) - files-to-attach ", ")) + (setq files-str (mapconcat #'file-name-nondirectory + files-to-attach ", ")) (setq bufs (gnus-dired-mail-buffers)) ;; set up destination mail composition buffer diff --git a/lisp/help-mode.el b/lisp/help-mode.el index 4ea4250556f..7f272de790e 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -368,7 +368,7 @@ The format is (FUNCTION ARGS...).") (define-button-type 'help-package-def :supertype 'help-xref - 'help-function (lambda (file) (dired file)) + 'help-function #'dired 'help-echo "mouse-2, RET: visit package directory") (define-button-type 'help-theme-def diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el index a8d60ff7917..94742cded01 100644 --- a/lisp/ibuf-ext.el +++ b/lisp/ibuf-ext.el @@ -1872,8 +1872,7 @@ Otherwise buffers whose name matches an element of (defun ibuffer-mark-modified-buffers () "Mark all modified buffers." (interactive) - (ibuffer-mark-on-buffer - (lambda (buf) (buffer-modified-p buf)))) + (ibuffer-mark-on-buffer #'buffer-modified-p)) ;;;###autoload (defun ibuffer-mark-unsaved-buffers () diff --git a/lisp/image/image-dired.el b/lisp/image/image-dired.el index 452be29c5d5..3b550fbc35a 100644 --- a/lisp/image/image-dired.el +++ b/lisp/image/image-dired.el @@ -2084,7 +2084,7 @@ when using per-directory thumbnail file storage")) ;; ;; Sort function. Compare time between two files. ;; (lambda (l1 l2) ;; (time-less-p (car l1) (car l2))))) -;; (dirsize (apply '+ (mapcar (lambda (x) (cadr x)) files)))) +;; (dirsize (apply #'+ (mapcar #'cadr files)))) ;; (while (> dirsize image-dired-dir-max-size) ;; (y-or-n-p ;; (format "Size of thumbnail directory: %d, delete old file %s? " diff --git a/lisp/international/quail.el b/lisp/international/quail.el index 94d4a758705..daa55b14b87 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -772,8 +772,7 @@ you type is correctly handled." (defun quail-keyseq-translate (keyseq) (apply 'string - (mapcar (lambda (x) (quail-keyboard-translate x)) - keyseq))) + (mapcar #'quail-keyboard-translate keyseq))) (defun quail-insert-kbd-layout (kbd-layout) "Insert the visual keyboard layout table according to KBD-LAYOUT. @@ -2144,9 +2143,7 @@ minibuffer and the selected frame has no other windows)." (setq str (format "%s[%s]" str - (concat (sort (mapcar (lambda (x) (car x)) - (cdr map)) - '<))))) + (concat (sort (mapcar #'car (cdr map)) #'<))))) ;; Show list of translations. (if (and quail-current-translations (not (quail-deterministic))) diff --git a/lisp/isearch.el b/lisp/isearch.el index 3d06e78f4f0..1e65a645a1d 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -3230,7 +3230,7 @@ See more for options in `search-exit-option'." (setq isearch-pre-move-point (point))) ;; Append control characters to the search string ((eq search-exit-option 'append) - (unless (memq nil (mapcar (lambda (k) (characterp k)) key)) + (unless (memq nil (mapcar #'characterp key)) (isearch-process-search-string key key)) (setq this-command 'ignore)) ;; Other characters terminate the search and are then executed normally. @@ -4654,8 +4654,7 @@ defaults to the value of `isearch-search-fun-default' when nil." (match-data))))) (when found (goto-char found)) (when match-data (set-match-data - (mapcar (lambda (m) (copy-marker m)) - match-data)))) + (mapcar #'copy-marker match-data)))) (setq found (funcall (or search-fun (isearch-search-fun-default)) string (if bound (if isearch-forward diff --git a/lisp/mail/supercite.el b/lisp/mail/supercite.el index dc580298c7f..1637f40b70c 100644 --- a/lisp/mail/supercite.el +++ b/lisp/mail/supercite.el @@ -596,7 +596,7 @@ selected letter is returned, or nil if the question was not answered. Note that WORD is a string and LETTER is a character. All LETTERs in the list should be unique." (let* ((prompt (concat - (mapconcat (lambda (elt) (car elt)) alist ", ") + (mapconcat #'car alist ", ") "? (" (mapconcat (lambda (elt) (char-to-string (cdr elt))) alist "/") diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el index 107b91f8355..ac13d3b2adb 100644 --- a/lisp/mh-e/mh-e.el +++ b/lisp/mh-e/mh-e.el @@ -878,7 +878,7 @@ finally GNU mailutils MH." (sit-for 5) (setq variant (concat "gnu-mh" (substring variant (match-end 0))))) - (let ((valid-list (mapcar (lambda (x) (car x)) (mh-variants)))) + (let ((valid-list (mapcar #'car (mh-variants)))) (cond ((eq variant 'none)) ((eq variant 'autodetect) diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el index 5a1f7eebeb0..98b99ebabd9 100644 --- a/lisp/net/rcirc.el +++ b/lisp/net/rcirc.el @@ -2272,8 +2272,7 @@ PROCESS is the process object for the current connection." "Return list of channels for NICK. PROCESS is the process object for the current connection." (with-rcirc-process-buffer process - (mapcar (lambda (x) (car x)) - (gethash nick rcirc-nick-table)))) + (mapcar #'car (gethash nick rcirc-nick-table)))) (defun rcirc-put-nick-channel (process nick channel &optional line) "Add CHANNEL to list associated with NICK. @@ -2327,7 +2326,7 @@ PROCESS is the process object for the current connection." (if record (setq nicks (cons (cons k (cdr record)) nicks))))) rcirc-nick-table) - (mapcar (lambda (x) (car x)) + (mapcar #'car (sort (nconc pseudo-nicks nicks) (lambda (x y) (let ((lx (or (cdr x) 0)) @@ -3004,8 +3003,8 @@ If ARG is given, opens the URL in a new browser window." (filtered (seq-filter (lambda (x) (>= point (cdr x))) rcirc-urls)) - (completions (mapcar (lambda (x) (car x)) filtered)) - (defaults (mapcar (lambda (x) (car x)) filtered))) + (completions (mapcar #'car filtered)) + (defaults (mapcar #'car filtered))) (browse-url (completing-read "Rcirc browse-url: " completions nil nil (car defaults) nil defaults) arg))) diff --git a/lisp/obsolete/thumbs.el b/lisp/obsolete/thumbs.el index fb24fa26a83..582bb7f0caf 100644 --- a/lisp/obsolete/thumbs.el +++ b/lisp/obsolete/thumbs.el @@ -204,7 +204,7 @@ reached." ,f))) (directory-files (thumbs-thumbsdir) t (image-file-name-regexp))) (lambda (l1 l2) (time-less-p (car l1) (car l2))))) - (dirsize (apply #'+ (mapcar (lambda (x) (cadr x)) files-list)))) + (dirsize (apply #'+ (mapcar #'cadr files-list)))) (while (> dirsize thumbs-thumbsdir-max-size) (progn (message "Deleting file %s" (cadr (cdar files-list)))) diff --git a/lisp/org/org-agenda.el b/lisp/org/org-agenda.el index 87eda4700b7..8fdd998fc52 100644 --- a/lisp/org/org-agenda.el +++ b/lisp/org/org-agenda.el @@ -8186,7 +8186,7 @@ FLAG specifies the type of completion operation to perform. This function is passed as a collection function to `completing-read', which see." (let ((completion-ignore-case t) ;tags are case-sensitive - (confirm (lambda (x) (stringp x))) + (confirm #'stringp) (prefix "") (operator "") table diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el index 22eecd55363..59e1b49f92c 100644 --- a/lisp/org/org-table.el +++ b/lisp/org/org-table.el @@ -2539,8 +2539,7 @@ location of point." ;; replace fields with duration values if relevant (if duration (setq fields - (mapcar (lambda (x) (org-table-time-string-to-seconds x)) - fields))) + (mapcar #'org-table-time-string-to-seconds fields))) (if (eq numbers t) (setq fields (mapcar (lambda (x) diff --git a/lisp/org/org.el b/lisp/org/org.el index a11eee94297..ab5316a0b13 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -4283,7 +4283,7 @@ related expressions." '("ARCHIVE" "CATEGORY" "COLUMNS" "PRIORITIES")))) ;; Startup options. Get this early since it does change ;; behavior for other options (e.g., tags). - (let ((startup (cl-mapcan (lambda (value) (split-string value)) + (let ((startup (cl-mapcan #'split-string (cdr (assoc "STARTUP" alist))))) (dolist (option startup) (pcase (assoc-string option org-startup-options t) diff --git a/lisp/org/ox.el b/lisp/org/ox.el index cc50d031765..7f3f66a6f26 100644 --- a/lisp/org/ox.el +++ b/lisp/org/ox.el @@ -1552,7 +1552,7 @@ Assume buffer is in Org mode. Narrowing, if any, is ignored." (newline (mapconcat #'identity values "\n")) (split - (cl-mapcan (lambda (v) (split-string v)) values)) + (cl-mapcan #'split-string values)) ((t) (org-last values)) (otherwise diff --git a/lisp/ses.el b/lisp/ses.el index eeef8f040f9..88e83ae160b 100644 --- a/lisp/ses.el +++ b/lisp/ses.el @@ -4011,7 +4011,7 @@ Use `math-format-value' as a printer for Calc objects." (unless reorient-x (setq result (mapcar #'nreverse result))) (when transpose - (let ((ret (mapcar (lambda (x) (list x)) (pop result))) iter) + (let ((ret (mapcar #'list (pop result))) iter) (while result (setq iter ret) (dolist (elt (pop result)) diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el index d49dd5eeac7..32a8a224df7 100644 --- a/lisp/textmodes/emacs-news-mode.el +++ b/lisp/textmodes/emacs-news-mode.el @@ -260,7 +260,7 @@ untagged NEWS entry." (while (re-search-forward "\"\\(([a-z0-9-]+)[ \n][^\"]\\{1,80\\}\\)\"" nil t) (buttonize-region (match-beginning 1) (match-end 1) - (lambda (node) (info node)) + #'info (match-string 1))))))) (defun emacs-news--sections (regexp) diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 24d09c3e9bc..9cec637f996 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -3310,9 +3310,7 @@ otherwise, the current line is skipped." Generated from `ispell-tex-skip-alists'." (concat ;; raw tex keys - (mapconcat (lambda (lst) (car lst)) - (car ispell-tex-skip-alists) - "\\|") + (mapconcat #'car (car ispell-tex-skip-alists) "\\|") "\\|" ;; keys wrapped in begin{} (mapconcat (lambda (lst) diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el index 91db030fa1c..06597ed7853 100644 --- a/lisp/vc/vc-cvs.el +++ b/lisp/vc/vc-cvs.el @@ -790,7 +790,7 @@ and that it passes `vc-cvs-global-switches' to it before FLAGS." If FILE is a list of files, return non-nil if any of them individually should stay local." (if (listp file) - (delq nil (mapcar (lambda (arg) (vc-cvs-stay-local-p arg)) file)) + (delq nil (mapcar #'vc-cvs-stay-local-p file)) (let ((stay-local vc-cvs-stay-local)) (if (symbolp stay-local) stay-local (let ((dirname (if (file-directory-p file) diff --git a/lisp/window.el b/lisp/window.el index ab15979baed..290b5cae64d 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -6309,8 +6309,7 @@ specific buffers." ,@(when next-buffers `((next-buffers . ,(if writable - (mapcar (lambda (buffer) (buffer-name buffer)) - next-buffers) + (mapcar #'buffer-name next-buffers) next-buffers)))) ,@(when prev-buffers `((prev-buffers diff --git a/test/lisp/emacs-lisp/shortdoc-tests.el b/test/lisp/emacs-lisp/shortdoc-tests.el index 14d757711be..560221f5533 100644 --- a/test/lisp/emacs-lisp/shortdoc-tests.el +++ b/test/lisp/emacs-lisp/shortdoc-tests.el @@ -56,7 +56,7 @@ (ert-deftest shortdoc-all-groups-work () "Test that all defined shortdoc groups display correctly." - (dolist (group (mapcar (lambda (x) (car x)) shortdoc--groups)) + (dolist (group (mapcar #'car shortdoc--groups)) (let ((buf-name (format "*Shortdoc %s*" group)) buf) (unwind-protect (progn commit 14e0f214e6d144030d696afc3ed2f2abdd3c9f06 Author: Juri Linkov Date: Tue Feb 11 19:47:21 2025 +0200 ; * lisp/treesit.el: Remove implemented TODO for integration with hideshow. diff --git a/lisp/treesit.el b/lisp/treesit.el index 58f1b38dc40..90426534842 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -2792,9 +2792,6 @@ friends." ;; ;; TODO: Integration with thing-at-point: once our thing interface is ;; stable. -;; -;; TODO: Integration with hideshow: I tried and failed, we need -;; SomeOne that understands hideshow to look at it. (defvar-local treesit-defun-type-regexp nil "A regexp that matches the node type of defun nodes. commit 58c09c3d36075c3a1a9f178fd8ee019309e6f403 Author: Juri Linkov Date: Tue Feb 11 19:42:33 2025 +0200 Improve outline-predicate of ts-modes (bug#74448) * lisp/progmodes/c-ts-mode.el (c-ts-mode--outline-predicate): Simplify since 'treesit-outline-search' was fixed in 302274b1862. Use 'treesit-parent-until' to handle the case with "pointer_declarator". * lisp/textmodes/yaml-ts-mode.el (yaml-ts-mode--outline-predicate): Add "block_sequence_item". diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index c5bf135e286..0396ddc2c8c 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -1041,14 +1041,11 @@ Return nil if NODE is not a defun node or doesn't have a name." (defun c-ts-mode--outline-predicate (node) "Match outlines on lines with function names." - (or (when-let* ((decl (treesit-node-child-by-field-name - (treesit-node-parent node) "declarator")) - (node-pos (treesit-node-start node)) - (decl-pos (treesit-node-start decl)) - (eol (save-excursion (goto-char node-pos) (line-end-position)))) - (and (equal (treesit-node-type decl) "function_declarator") - (<= node-pos decl-pos) - (< decl-pos eol))) + (or (and (equal (treesit-node-type node) "function_declarator") + ;; Handle the case when "function_definition" is + ;; not an immediate parent of "function_declarator" + ;; but there is e.g. "pointer_declarator" between them. + (treesit-parent-until node "function_definition")) ;; DEFUNs in Emacs sources. (and c-ts-mode-emacs-sources-support (c-ts-mode--emacs-defun-p node)))) diff --git a/lisp/textmodes/yaml-ts-mode.el b/lisp/textmodes/yaml-ts-mode.el index 7a5132634ca..72285d570f1 100644 --- a/lisp/textmodes/yaml-ts-mode.el +++ b/lisp/textmodes/yaml-ts-mode.el @@ -151,8 +151,9 @@ Return nil if there is no name or if NODE is not a defun node." (defun yaml-ts-mode--outline-predicate (node) "Limit outlines to top-level mappings." - (when (equal (treesit-node-type node) "block_mapping_pair") - (not (treesit-parent-until node treesit-outline-predicate)))) + (let ((regexp (rx (or "block_mapping_pair" "block_sequence_item")))) + (when (string-match-p regexp (treesit-node-type node)) + (not (treesit-parent-until node regexp))))) ;;;###autoload (define-derived-mode yaml-ts-mode text-mode "YAML" commit 3e699b3047af70bc8d30e21b295b98dbd6797e9c Author: João Távora Date: Tue Feb 11 16:14:43 2025 +0000 Eglot: fix thinko in previous commit * lisp/progmodes/eglot.el (eglot--hierarchy-1): 'roots' is a vector. diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index eb9ce613afb..2deeef9bce1 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -4532,7 +4532,8 @@ If NOERROR, return predicate, else erroring function." server preparer (eglot--TextDocumentPositionParams)))) - (unless roots (eglot--error "No hierarchy information here")) + (unless (cl-plusp (length roots)) + (eglot--error "No hierarchy information here")) (with-current-buffer (get-buffer-create name) (eglot-hierarchy-mode) (setq-local commit 13608ad64d13145df88b86a8efa893be42244792 Author: João Távora Date: Tue Feb 11 13:00:33 2025 +0000 Eglot: mention ocaml-ts-mode in eglot-server-programs * lisp/progmodes/eglot.el (eglot-server-programs): Mention ocaml-ts-mode. (cherry picked from commit 96dc5deddc2b60210feb10e3a68b74ecd2480b34) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 45e0e7d16cd..7c9a3dbf5c9 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -271,6 +271,7 @@ automatically)." . ,(eglot-alternatives '("clangd" "ccls"))) (((caml-mode :language-id "ocaml") + (ocaml-ts-mode :language-id "ocaml") (tuareg-mode :language-id "ocaml") reason-mode) . ("ocamllsp")) ((ruby-mode ruby-ts-mode) commit 19791839cfbb9202aff8a8d476ec76741592c97d Author: Stefan Kangas Date: Tue Feb 11 09:12:07 2025 +0100 ; Don't document a complicated default * doc/misc/message.texi (Superseding): Don't document the default value of 'message-ignored-supersedes-headers' here; the list was out-of-date, and is likely to become out-of-date again in the future if updated. It's also easy enough to look up for users outside of Info. diff --git a/doc/misc/message.texi b/doc/misc/message.texi index bd20aec5bc6..588108e27ff 100644 --- a/doc/misc/message.texi +++ b/doc/misc/message.texi @@ -289,12 +289,7 @@ supersede the message in the current buffer. @vindex message-ignored-supersedes-headers Headers matching the @code{message-ignored-supersedes-headers} are -removed before popping up the new message buffer. The default is@* -@samp{^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|@* -^Received:\\|^X-From-Line:\\|^X-Trace:\\|^X-Complaints-To:\\|@* -Return-Path:\\|^Supersedes:\\|^NNTP-Posting-Date:\\|^X-Trace:\\|@* -^X-Complaints-To:\\|^Cancel-Lock:\\|^Cancel-Key:\\|^X-Hashcash:\\|@* -^X-Payment:\\|^Approved:}. +removed before popping up the new message buffer. commit 88bc748f52fe3ed161d5c7b3aca1de0fb0fa1209 Author: Dmitry Gutov Date: Tue Feb 11 17:47:21 2025 +0200 Fix minibuffer-next-completion in completing-read-multiple * lisp/emacs-lisp/crm.el (completing-read-multiple): Adapt to the previous removal of completion-base-affixes (bug#48356, bug#48356). diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el index 454c3e85074..a371a8e14de 100644 --- a/lisp/emacs-lisp/crm.el +++ b/lisp/emacs-lisp/crm.el @@ -251,22 +251,16 @@ with empty strings removed." (setq-local minibuffer-completion-table #'crm--collection-fn) (setq-local minibuffer-completion-predicate predicate) (setq-local completion-list-insert-choice-function - (lambda (start end choice) - (if (and (stringp start) (stringp end)) - (let* ((beg (save-excursion - (goto-char (minibuffer-prompt-end)) - (or (search-forward start nil t) - (search-forward-regexp crm-separator nil t) - (minibuffer-prompt-end)))) - (end (save-excursion - (goto-char (point-max)) - (or (search-backward end nil t) - (progn - (goto-char beg) - (search-forward-regexp crm-separator nil t)) - (point-max))))) - (completion--replace beg end choice)) - (completion--replace start end choice)))) + (lambda (_start _end choice) + (let* ((beg (save-excursion + (if (search-backward-regexp crm-separator nil t) + (1+ (point)) + (minibuffer-prompt-end)))) + (end (save-excursion + (if (search-forward-regexp crm-separator nil t) + (1- (point)) + (point-max))))) + (completion--replace beg end choice)))) ;; see completing_read in src/minibuf.c (setq-local minibuffer-completion-confirm (unless (eq require-match t) require-match)) commit 9d2d8a4d39441ad9de3862164aa57dbdf5874baf Author: João Távora Date: Tue Feb 11 15:28:59 2025 +0000 Eglot: error if no hierarchies available at point * lisp/progmodes/eglot.el (eglot--hierarchy-1): Error if no hierarchy at point. diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 89161c6573d..eb9ce613afb 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -4532,6 +4532,7 @@ If NOERROR, return predicate, else erroring function." server preparer (eglot--TextDocumentPositionParams)))) + (unless roots (eglot--error "No hierarchy information here")) (with-current-buffer (get-buffer-create name) (eglot-hierarchy-mode) (setq-local commit 4847168c5b4b015eec0e9feca0ccc3cfdf17e837 Author: João Távora Date: Tue Feb 11 13:59:46 2025 +0000 Eglot: make better use of :company-docsig * lisp/progmodes/eglot.el (eglot-completion-at-point): Make better use of :company-docsig diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index ce0e388c560..89161c6573d 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -3483,12 +3483,13 @@ for which LSP on-type-formatting should be requested." 1) (eq t (plist-get lsp-item :deprecated))))) :company-docsig - ;; FIXME: autoImportText is specific to the pyright language server (lambda (proxy) - (when-let* ((lsp-comp (get-text-property 0 'eglot--lsp-item proxy)) - (data (plist-get (ensure-resolved lsp-comp) :data)) - (import-text (plist-get data :autoImportText))) - import-text)) + (let ((detail (plist-get + (ensure-resolved (get-text-property 0 'eglot--lsp-item proxy)) + :detail))) + (when (and (stringp detail) (not (string= detail ""))) + ;; Forces major-mode based fontification + (eglot--format-markup (list :value detail))))) :company-doc-buffer (lambda (proxy) (let* ((resolved commit 5f9982ededa3aa2e8890e86836eb56f57cfe4cf1 Author: João Távora Date: Tue Feb 11 13:32:07 2025 +0000 Eglot: cosmetic refactor of eglot-completion-at-point * lisp/progmodes/eglot.el (eglot-completion-at-point): rework. diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index b7f43c18b68..ce0e388c560 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -3343,81 +3343,79 @@ for which LSP on-type-formatting should be requested." (add-to-list 'completion-category-defaults '(eglot-capf (styles eglot--dumb-flex))) (add-to-list 'completion-styles-alist '(eglot--dumb-flex eglot--dumb-tryc eglot--dumb-allc)) -(defun eglot-completion-at-point () +(cl-defun eglot-completion-at-point (&aux completion-capability) "Eglot's `completion-at-point' function." ;; Commit logs for this function help understand what's going on. - (when-let* ((completion-capability (eglot-server-capable :completionProvider))) - (let* ((server (eglot--current-server-or-lose)) - (bounds (or (bounds-of-thing-at-point 'symbol) - (cons (point) (point)))) - (bounds-string (buffer-substring (car bounds) (cdr bounds))) - (sort-completions - (lambda (completions) - (cl-sort completions - #'string-lessp - :key (lambda (c) - (plist-get - (get-text-property 0 'eglot--lsp-item c) - :sortText))))) - (metadata `(metadata (category . eglot-capf) - (display-sort-function . ,sort-completions))) - (local-cache :none) - (orig-pos (point)) - (resolved (make-hash-table)) - (proxies - (lambda () - (if (listp local-cache) local-cache - (let* ((resp (eglot--request server - :textDocument/completion - (eglot--CompletionParams) - :cancel-on-input t)) - (items (append - (if (vectorp resp) resp (plist-get resp :items)) - nil)) - (cachep (and (listp resp) items - eglot-cache-session-completions - (eq (plist-get resp :isIncomplete) :json-false))) - (retval - (mapcar - (jsonrpc-lambda - (&rest item &key label insertText insertTextFormat - textEdit &allow-other-keys) - (let ((proxy - ;; Snippet or textEdit, it's safe to - ;; display/insert the label since - ;; it'll be adjusted. If no usable - ;; insertText at all, label is best, - ;; too. - (cond ((or (eql insertTextFormat 2) - textEdit - (null insertText) - (string-empty-p insertText)) - (string-trim-left label)) - (t insertText)))) - (unless (zerop (length proxy)) - (put-text-property 0 1 'eglot--lsp-item item proxy)) - proxy)) - items))) - ;; (trace-values "Requested" (length proxies) cachep bounds) - (setq eglot--capf-session - (if cachep (list bounds retval resolved orig-pos - bounds-string) :none)) - (setq local-cache retval))))) - (resolve-maybe - ;; Maybe completion/resolve JSON object `lsp-comp' into - ;; another JSON object, if at all possible. Otherwise, - ;; just return lsp-comp. - (lambda (lsp-comp &optional dont-cancel-on-input) - (or (gethash lsp-comp resolved) - (setf (gethash lsp-comp resolved) - (if (and (eglot-server-capable :completionProvider - :resolveProvider) - (plist-get lsp-comp :data)) - (eglot--request server :completionItem/resolve - lsp-comp :cancel-on-input - (not dont-cancel-on-input) - :immediate t) - lsp-comp)))))) + (setq completion-capability (eglot-server-capable :completionProvider)) + (unless completion-capability (cl-return-from eglot-completion-at-point)) + (let* ((server (eglot--current-server-or-lose)) + (bounds (or (bounds-of-thing-at-point 'symbol) + (cons (point) (point)))) + (bounds-string (buffer-substring (car bounds) (cdr bounds))) + (local-cache :none) + (orig-pos (point)) + (resolved (make-hash-table))) + (cl-labels + ((sort-completions (completions) + (cl-sort completions + #'string-lessp + :key (lambda (c) + (plist-get + (get-text-property 0 'eglot--lsp-item c) + :sortText)))) + (proxies () + (if (listp local-cache) local-cache + (let* ((resp (eglot--request server + :textDocument/completion + (eglot--CompletionParams) + :cancel-on-input t)) + (items (append + (if (vectorp resp) resp (plist-get resp :items)) + nil)) + (cachep (and (listp resp) items + eglot-cache-session-completions + (eq (plist-get resp :isIncomplete) :json-false))) + (retval + (mapcar + (jsonrpc-lambda + (&rest item &key label insertText insertTextFormat + textEdit &allow-other-keys) + (let ((proxy + ;; Snippet or textEdit, it's safe to + ;; display/insert the label since + ;; it'll be adjusted. If no usable + ;; insertText at all, label is best, + ;; too. + (cond ((or (eql insertTextFormat 2) + textEdit + (null insertText) + (string-empty-p insertText)) + (string-trim-left label)) + (t insertText)))) + (unless (zerop (length proxy)) + (put-text-property 0 1 'eglot--lsp-item item proxy)) + proxy)) + items))) + ;; (trace-values "Requested" (length proxies) cachep bounds) + (setq eglot--capf-session + (if cachep (list bounds retval resolved orig-pos + bounds-string) + :none)) + (setq local-cache retval)))) + (ensure-resolved (lsp-comp &optional dont-cancel-on-input) + ;; Maybe completion/resolve JSON object `lsp-comp' into + ;; another JSON object, if at all possible. Otherwise, + ;; just return lsp-comp. + (or (gethash lsp-comp resolved) + (setf (gethash lsp-comp resolved) + (if (and (eglot-server-capable :completionProvider + :resolveProvider) + (plist-get lsp-comp :data)) + (eglot--request server :completionItem/resolve + lsp-comp :cancel-on-input + (not dont-cancel-on-input) + :immediate t) + lsp-comp))))) (when (and (consp eglot--capf-session) (= (car bounds) (car (nth 0 eglot--capf-session))) (>= (cdr bounds) (cdr (nth 0 eglot--capf-session)))) @@ -3432,14 +3430,16 @@ for which LSP on-type-formatting should be requested." (cdr bounds) (lambda (pattern pred action) (cond - ((eq action 'metadata) metadata) ; metadata + ((eq action 'metadata) ; metadata + `(metadata (category . eglot-capf) + (display-sort-function . ,#'sort-completions))) ((eq action 'lambda) ; test-completion - (test-completion pattern (funcall proxies))) + (test-completion pattern (proxies))) ((eq (car-safe action) 'boundaries) nil) ; boundaries ((null action) ; try-completion - (try-completion pattern (funcall proxies))) + (try-completion pattern (proxies))) ((eq action t) ; all-completions - (let ((comps (funcall proxies))) + (let ((comps (proxies))) (dolist (c comps) (eglot--dumb-flex pattern c completion-ignore-case)) (all-completions "" @@ -3486,14 +3486,15 @@ for which LSP on-type-formatting should be requested." ;; FIXME: autoImportText is specific to the pyright language server (lambda (proxy) (when-let* ((lsp-comp (get-text-property 0 'eglot--lsp-item proxy)) - (data (plist-get (funcall resolve-maybe lsp-comp) :data)) + (data (plist-get (ensure-resolved lsp-comp) :data)) (import-text (plist-get data :autoImportText))) import-text)) :company-doc-buffer (lambda (proxy) - (let* ((documentation - (let ((lsp-comp (get-text-property 0 'eglot--lsp-item proxy))) - (plist-get (funcall resolve-maybe lsp-comp) :documentation))) + (let* ((resolved + (ensure-resolved (get-text-property 0 'eglot--lsp-item proxy))) + (documentation + (plist-get resolved :documentation)) (formatted (and documentation (eglot--format-markup documentation)))) (when formatted @@ -3524,15 +3525,14 @@ for which LSP on-type-formatting should be requested." (current-buffer)) (eglot--dbind ((CompletionItem) insertTextFormat insertText textEdit additionalTextEdits label) - (funcall - resolve-maybe + (ensure-resolved (or (get-text-property 0 'eglot--lsp-item proxy) ;; When selecting from the *Completions* ;; buffer, `proxy' won't have any properties. ;; A lookup should fix that (github#148) (get-text-property 0 'eglot--lsp-item - (cl-find proxy (funcall proxies) :test #'string=))) + (cl-find proxy (proxies) :test #'string=))) ;; Be sure to pass non-nil here since we don't want ;; any quick typing after the soon-to-be-undone ;; insertion to potentially cancel an essential commit 96dc5deddc2b60210feb10e3a68b74ecd2480b34 Author: João Távora Date: Tue Feb 11 13:00:33 2025 +0000 Eglot: mention ocaml-ts-mode in eglot-server-programs * lisp/progmodes/eglot.el (eglot-server-programs): Mention ocaml-ts-mode. diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 00142c9c829..b7f43c18b68 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -269,6 +269,7 @@ automatically)." . ,(eglot-alternatives '("clangd" "ccls"))) (((caml-mode :language-id "ocaml") + (ocaml-ts-mode :language-id "ocaml") (tuareg-mode :language-id "ocaml") reason-mode) . ("ocamllsp")) ((ruby-mode ruby-ts-mode) commit 737f249aa2c86fb555b134b9e430a5be9cf2b655 Author: Eli Zaretskii Date: Tue Feb 11 16:42:19 2025 +0200 ; Document 'completing-read-multiple' in the ELisp manual * doc/lispref/minibuf.texi (Minibuffer Completion): Mention 'completing-read-multiple' (bug#76194). diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index 43e87f89aee..9bff31aaf3c 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -1249,6 +1249,16 @@ different function to completely override the normal behavior of @code{completing-read}. @end defvar +@findex completing-read-multiple +@vindex crm-separator +If you need to prompt the user for several strings, like several +elements of a list or several parameters (e.g., user, host, and port) of +a connection, you can use @code{completing-read-multiple}. It allows +typing several strings separated by a separator string (by default, tabs +and commas; customize @code{crm-separator} to change that), and provides +completion for each individual string the user types. It returns the +strings that were read, as a list. + @node Completion Commands @subsection Minibuffer Commands that Do Completion commit 326593c88dfb98639f76a1b99c0b22958aae0e25 Author: Eli Zaretskii Date: Tue Feb 11 15:42:26 2025 +0200 * src/bidi.c: Add comments to uses of INT_PROMOTE (bug#75964). diff --git a/src/bidi.c b/src/bidi.c index 773513143d6..bad67fbb8a3 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -289,6 +289,8 @@ bidi_get_type (int ch, bidi_dir_t override) if (default_type == UNKNOWN_BT) emacs_abort (); + /* Promote default_type to int to allow not enumerating all the values + without compiler warnings. */ switch (INT_PROMOTE (default_type)) { case WEAK_BN: @@ -2010,7 +2012,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) embedding level of the _following_ characters, so we must first look at the type of the previous character to support that. */ - switch (INT_PROMOTE (prev_type)) + switch (INT_PROMOTE (prev_type)) /* promote to int to avoid warnings */ { case RLI: /* X5a */ if (current_level < BIDI_MAXDEPTH @@ -2074,7 +2076,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) bidi_it->type_after_wn = UNKNOWN_BT; - switch (INT_PROMOTE (type)) + switch (INT_PROMOTE (type)) /* promote to int to avoid warnings */ { case RLE: /* X2 */ case RLO: /* X4 */ @@ -2707,7 +2709,7 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it) /* Whenever we see a strong type, update the flags of all the slots on the stack. */ - switch (INT_PROMOTE (bidi_it->type)) + switch (INT_PROMOTE (bidi_it->type)) /* avoid warnings */ { case STRONG_L: flag = ((embedding_level & 1) == 0 @@ -2979,7 +2981,7 @@ bidi_resolve_brackets (struct bidi_it *bidi_it) if (prev_type_for_neutral == UNKNOWN_BT) prev_type_for_neutral = embedding_type; - switch (INT_PROMOTE (prev_type_for_neutral)) + switch (INT_PROMOTE (prev_type_for_neutral)) /* avoid warnings */ { case STRONG_R: case WEAK_EN: @@ -3175,7 +3177,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) } else { - switch (INT_PROMOTE (type)) + switch (INT_PROMOTE (type)) /* promotion to int avoids warnings */ { case STRONG_L: case STRONG_R: commit b2d2ad58ea45bbbcde772152b240f1c2c5a7c2fa Author: shipmints Date: Sun Feb 2 11:39:55 2025 -0500 Correct project-remember/forget-projects-under message grammar * lisp/progmodes/project.el: (project-remember-projects-under): Correct grammar for the singular case. Rather than "1 projects were found", say "1 project was found". (project-forget-projects-under): Ditto. (Bug#76016) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index f2a27ff91dd..5dd10071a1c 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -2054,8 +2054,9 @@ projects." (if (zerop count) (message "No projects were found") (project--write-project-list) - (message "%d project%s were found" - count (if (= count 1) "" "s"))) + (message (ngettext "%d project was found" + "%d projects were found" + count) count)) count)) (defun project-forget-zombie-projects () @@ -2085,8 +2086,9 @@ forgotten projects." (if (zerop count) (message "No projects were forgotten") (project--write-project-list) - (message "%d project%s were forgotten" - count (if (= count 1) "" "s"))) + (message (ngettext "%d project was forgotten" + "%d projects were forgotten" + count) count)) count)) commit 788380cf6a2529ee7477aaadaa430e889c76dacd Author: shipmints Date: Fri Feb 7 19:39:36 2025 -0500 Eliminate bookmark-maybe-historicize-string duplicates * lisp/bookmark.el (bookmark-maybe-historicize-string): Use 'add-to-history' to respect history-delete-duplicates and the 'history-length property. (Bug#76137) diff --git a/etc/NEWS b/etc/NEWS index f5ec2309090..9fe46d818bd 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -472,6 +472,13 @@ default), the 'whitespace-cleanup' function will now add the newline. ** Bookmark +--- +*** Bookmark history now saves each bookmark only once. +Previously, the variable 'bookmark-history' accumulated duplicate +bookmark names when bookmark features were used interactively. This +made their history larger than necessary for frequent bookmark users. +Bookmark names are now saved uniquely. + --- *** New user option 'bookmark-bmenu-type-column-width'. This user option controls the width of the type column on the bookmark diff --git a/lisp/bookmark.el b/lisp/bookmark.el index e8ad0cee31d..8495f33cb5f 100644 --- a/lisp/bookmark.el +++ b/lisp/bookmark.el @@ -603,7 +603,7 @@ from other commands that pass in the bookmark name, so `completing-read' never gets a chance to set `bookmark-history'." `(or (called-interactively-p 'interactive) - (setq bookmark-history (cons ,string bookmark-history)))) + (add-to-history 'bookmark-history ,string))) (defvar bookmark-make-record-function 'bookmark-make-record-default "A function that should be called to create a bookmark record. diff --git a/test/lisp/bookmark-tests.el b/test/lisp/bookmark-tests.el index 9099f6cb169..d551d429363 100644 --- a/test/lisp/bookmark-tests.el +++ b/test/lisp/bookmark-tests.el @@ -193,9 +193,12 @@ the lexically-bound variable `buffer'." (should (equal (bookmark-prop-get bmk 'filename) "prop"))))) (ert-deftest bookmark-tests-maybe-historicize-string () - (let ((bookmark-history)) + (let ((bookmark-history) + (history-delete-duplicates t)) (bookmark-maybe-historicize-string "foo") - (should (equal (car bookmark-history) "foo")))) + (bookmark-maybe-historicize-string "foo") + (should (equal (car bookmark-history) "foo")) + (should (= 1 (length bookmark-history))))) (defun bookmark-remove-last-modified (bmk) (assoc-delete-all 'last-modified bmk)) commit 34d353cd7207fc47e7c2945faad4ca6e4b864a0f Author: Stefan Kangas Date: Tue Feb 11 07:13:31 2025 +0100 Update webjump.el example links * lisp/net/webjump.el (webjump-sample-sites): Don't recommend some defunct or otherwise non-privacy respecting websites. Prefer HTTPS to HTTP. (webjump-to-iwin, webjump-state-to-postal-alist): Make obsolete, as this functionality seems to no longer work due to broken links. diff --git a/lisp/net/webjump.el b/lisp/net/webjump.el index 2d0f3ba5fd8..e401042e2ef 100644 --- a/lisp/net/webjump.el +++ b/lisp/net/webjump.el @@ -94,53 +94,34 @@ external browser like IceCat." ;; GNU FTP Mirror List from https://www.gnu.org/order/ftp.html [mirrors "https://ftp.gnu.org/pub/gnu/" "https://ftpmirror.gnu.org"]) - ("GNU Project Website" . "www.gnu.org") + ("GNU Project Website" . "https://www.gnu.org") ;; Emacs. ("Emacs Website" . - "www.gnu.org/software/emacs/emacs.html") + "https://www.gnu.org/software/emacs/emacs.html") ("Savannah Emacs page" . - "savannah.gnu.org/projects/emacs") - ("Emacs Lisp List" . - "www.damtp.cam.ac.uk/user/eglen/emacs/ell.html") + "https://savannah.gnu.org/projects/emacs") ("Emacs Wiki" . - [simple-query "www.emacswiki.org" - "www.emacswiki.org/cgi-bin/wiki/" ""]) + [simple-query "https://www.emacswiki.org" + "https://www.emacswiki.org/cgi-bin/wiki/" ""]) ;; Internet search engines. ("DuckDuckGo" . - [simple-query "duckduckgo.com" - "duckduckgo.com/?q=" ""]) - ("Google Groups" . - [simple-query "groups.google.com" - "groups.google.com/groups?q=" ""]) - ("Yahoo" . - [simple-query "www.yahoo.com" "search.yahoo.com/search?p=" ""]) - ("Yahoo: Reference" . "www.yahoo.com/Reference/") + [simple-query "https://duckduckgo.com" + "https://duckduckgo.com/?q=" ""]) ("Wikipedia" . - [simple-query "wikipedia.org" "wikipedia.org/wiki/" ""]) - - ;; Misc. general interest. - ("National Weather Service" . webjump-to-iwin) - ("Usenet FAQs" . - "http://www.faqs.org/faqs/") - ("RTFM Usenet FAQs by Group" . - "ftp://rtfm.mit.edu/pub/usenet-by-group/") - ("RTFM Usenet FAQs by Hierarchy" . - "ftp://rtfm.mit.edu/pub/usenet-by-hierarchy/") - ("X Consortium Archive" . "ftp.x.org") + [simple-query "https://wikipedia.org" "https://wikipedia.org/wiki/" ""]) ;; Computer social issues, privacy, professionalism. - ("Association for Computing Machinery" . "www.acm.org") + ("Association for Computing Machinery" . "https://www.acm.org") ("Computer Professionals for Social Responsibility" . "http://www.cpsr.org") - ("Electronic Frontier Foundation" . "www.eff.org") - ("IEEE Computer Society" . "www.computer.org") + ("Electronic Frontier Foundation" . "https://www.eff.org") + ("IEEE Computer Society" . "https://www.computer.org") ("Risks Digest" . webjump-to-risks) ;; More. ("Supplemental Web site list for webjump" . - "www.neilvandyke.org/webjump/") - + "https://www.neilvandyke.org/webjump/") ) "Sample hotlist for WebJump. See the documentation for `webjump' and `webjump-sites'.") @@ -162,6 +143,7 @@ See the documentation for `webjump' and `webjump-sites'.") ("Utah" . "ut") ("Vermont" . "vt") ("Virginia" . "va") ("Washington" . "wa") ("West Virginia" . "wv") ("Wisconsin" . "wi") ("Wyoming" . "wy"))) +(make-obsolete-variable 'webjump-state-to-postal-alist nil "31.1") ;;------------------------------------------------------------ Option Variables @@ -210,6 +192,7 @@ submitting the URL." ;;------------------------------------------------------- Sample Site Functions (defun webjump-to-iwin (name) + (declare (obsolete nil "31.1")) (let* ((prefix "http://www.nws.noaa.gov/view/") (state (webjump-read-choice name "state" (append '(("Puerto Rico" . "pr") commit 644476dc85974c1cd5bff3a3094cc4941c1ca9ff Author: Stefan Kangas Date: Tue Feb 11 06:28:03 2025 +0100 ; Delete redundant defvar * lisp/emacs-lisp/lisp-mnt.el (report-emacs-bug-address): Delete redudant defvar. diff --git a/lisp/emacs-lisp/lisp-mnt.el b/lisp/emacs-lisp/lisp-mnt.el index daa20cb29cf..111d512ef59 100644 --- a/lisp/emacs-lisp/lisp-mnt.el +++ b/lisp/emacs-lisp/lisp-mnt.el @@ -668,8 +668,6 @@ which do not include a recognizable synopsis." (lm-summary)) (when must-kill (kill-buffer (current-buffer)))))))) -(defvar report-emacs-bug-address) - (defun lm-report-bug (topic) "Report a bug in the package currently being visited to its maintainer. Prompts for bug subject TOPIC. Leaves you in a mail buffer." commit e6a2256c8b7357f9654a566e31647316f44780c3 Author: Stefan Kangas Date: Tue Feb 11 06:10:39 2025 +0100 Add new function lm-package-version * lisp/emacs-lisp/lisp-mnt.el (lm-package-version): New function. * lisp/emacs-lisp/package.el (package-buffer-info) (package-get-version): Use above new function. (lm-package-version): Declare. diff --git a/lisp/emacs-lisp/lisp-mnt.el b/lisp/emacs-lisp/lisp-mnt.el index 6b50bee6fbb..daa20cb29cf 100644 --- a/lisp/emacs-lisp/lisp-mnt.el +++ b/lisp/emacs-lisp/lisp-mnt.el @@ -468,6 +468,13 @@ package version (a string)." (lm--prepare-package-dependencies (package-read-from-string (mapconcat #'identity require-lines " ")))))) +(defun lm-package-version (&optional file) + "Return \"Package-Version\" or \"Version\" header. +Prefer Package-Version; if defined, the package author +probably wants us to use it. Otherwise try Version." + (lm-with-file file + (or (lm-header "package-version") (lm-header "version")))) + (defun lm-package-needs-footer-line (&optional file) "Return non-nil if package in current buffer needs a footer line. diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 0cf5dd2dc75..5239c8c34a1 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -1168,6 +1168,7 @@ Signal an error if the entire string was not used." (declare-function lm-header "lisp-mnt" (header)) (declare-function lm-package-requires "lisp-mnt" (&optional file)) +(declare-function lm-package-version "lisp-mnt" (&optional file)) (declare-function lm-website "lisp-mnt" (&optional file)) (declare-function lm-keywords-list "lisp-mnt" (&optional file)) (declare-function lm-maintainers "lisp-mnt" (&optional file)) @@ -1185,11 +1186,7 @@ boundaries." (let ((file-name (match-string-no-properties 1)) (desc (match-string-no-properties 2))) (require 'lisp-mnt) - ;; Use some headers we've invented to drive the process. - (let* (;; Prefer Package-Version; if defined, the package author - ;; probably wants us to use it. Otherwise try Version. - (version-info - (or (lm-header "package-version") (lm-header "version"))) + (let* ((version-info (lm-package-version)) (pkg-version (package-strip-rcs-id version-info)) (keywords (lm-keywords-list)) (website (lm-website))) @@ -4549,10 +4546,7 @@ the `Version:' header." (unless (file-readable-p mainfile) (setq mainfile file)) (when (file-readable-p mainfile) (require 'lisp-mnt) - (with-temp-buffer - (insert-file-contents mainfile) - (or (lm-header "package-version") - (lm-header "version"))))))))) + (lm-package-version mainfile))))))) ;;;; Quickstart: precompute activation actions for faster start up. commit 5b34dbf4003a96c1b48e4981eedf2ed7abe43849 Author: Stefan Kangas Date: Tue Feb 11 04:46:52 2025 +0100 Don't warn for packages without a footer line * lisp/emacs-lisp/package.el (package-buffer-info): Don't warn when the terminating comment (i.e., the footer line) is missing. (Bug#26490) diff --git a/etc/NEWS b/etc/NEWS index 77b1043a08d..f5ec2309090 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1095,6 +1095,12 @@ the directory into which the repository was cloned. ** Package ++++ +*** No longer warn if a package has no footer line. +package.el no longer warns for packages without a "footer line", which +is the line that usually appears at the very end of an Emacs Lisp file: +;;; FILENAME ends here + --- *** New optional argument to 'package-autoremove'. An optional argument NOCONFIRM has been added to 'package-autoremove'. diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 3611f7f1f5d..0cf5dd2dc75 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -1172,7 +1172,6 @@ Signal an error if the entire string was not used." (declare-function lm-keywords-list "lisp-mnt" (&optional file)) (declare-function lm-maintainers "lisp-mnt" (&optional file)) (declare-function lm-authors "lisp-mnt" (&optional file)) -(declare-function lm-package-needs-footer-line "lisp-mnt" (&optional file)) (defun package-buffer-info () "Return a `package-desc' describing the package in the current buffer. @@ -1184,20 +1183,8 @@ boundaries." (unless (re-search-forward "^;;; \\([^ ]*\\)\\.el ---[ \t]*\\(.*?\\)[ \t]*\\(-\\*-.*-\\*-[ \t]*\\)?$" nil t) (error "Package lacks a file header")) (let ((file-name (match-string-no-properties 1)) - (desc (match-string-no-properties 2)) - (start (line-beginning-position))) + (desc (match-string-no-properties 2))) (require 'lisp-mnt) - ;; This warning was added in Emacs 27.1, and should be removed at - ;; the earliest in version 31.1. The idea is to phase out the - ;; requirement for a "footer line" without unduly impacting users - ;; on earlier Emacs versions. See Bug#26490 for more details. - (unless (search-forward (concat ";;; " file-name ".el ends here") nil 'move) - (when (lm-package-needs-footer-line) - (lwarn '(package package-format) :warning - "Package lacks a terminating comment"))) - ;; Try to include a trailing newline. - (forward-line) - (narrow-to-region start (point)) ;; Use some headers we've invented to drive the process. (let* (;; Prefer Package-Version; if defined, the package author ;; probably wants us to use it. Otherwise try Version. @@ -1207,9 +1194,9 @@ boundaries." (keywords (lm-keywords-list)) (website (lm-website))) (unless pkg-version - (if version-info - (error "Unrecognized package version: %s" version-info) - (error "Package lacks a \"Version\" or \"Package-Version\" header"))) + (if version-info + (error "Unrecognized package version: %s" version-info) + (error "Package lacks a \"Version\" or \"Package-Version\" header"))) (package-desc-from-define file-name pkg-version desc (lm-package-requires) commit 37f255146028954e5c3c374fa2f1eb596b69f9a4 Author: Stefan Kangas Date: Tue Feb 11 07:50:05 2025 +0100 ; * lisp/gnus/nnweb.el (nnweb-type): Doc fix. diff --git a/lisp/gnus/nnweb.el b/lisp/gnus/nnweb.el index 57964f93437..9ada2dbc1d7 100644 --- a/lisp/gnus/nnweb.el +++ b/lisp/gnus/nnweb.el @@ -42,7 +42,7 @@ (defvoo nnweb-type 'google "What search engine type is being used. -Valid types include `google' and `dejanews'.") +The only valid type is currently `google'.") (defvar nnweb-type-definition '((google commit 79e5eae8a648a16bed4688f979692eba1e0ce037 Author: F. Jason Park Date: Mon Feb 10 21:59:52 2025 -0800 ; Mark erc-nicks test as :unstable * test/lisp/erc/erc-nicks-tests.el (erc-nicks-track-faces/prioritize): Mark as :unstable outside of EMBA and ERC's own CI. (Bug#76188) diff --git a/test/lisp/erc/erc-nicks-tests.el b/test/lisp/erc/erc-nicks-tests.el index 1e57fb83672..805c41e7023 100644 --- a/test/lisp/erc/erc-nicks-tests.el +++ b/test/lisp/erc/erc-nicks-tests.el @@ -615,6 +615,8 @@ (erc-tests-common-kill-buffers)) (ert-deftest erc-nicks-track-faces/prioritize () + :tags (and (null (getenv "CI")) '(:unstable)) + (should (eq erc-nicks-track-faces 'prioritize)) (erc-nicks-tests--track-faces (lambda (set-faces assert-result add-face bob-face alice-face) commit 2a405cb8979e08fd190e840f2a7b31efeb15a7cb Author: Stefan Kangas Date: Tue Feb 11 00:46:30 2025 +0100 Minor simplification in Fdescribe_buffer_bindings * src/keymap.c (Fdescribe_buffer_bindings): Minor simplification. diff --git a/src/keymap.c b/src/keymap.c index 5691b34c40d..bc731c54ef0 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -2866,7 +2866,7 @@ You type Translation\n\ if (alternate_heading) { insert_string (alternate_heading); - alternate_heading = 0; + alternate_heading = NULL; } bufend = push_key_description (translate[c], buf); @@ -2893,9 +2893,7 @@ You type Translation\n\ } /* Print the (major mode) local map. */ - Lisp_Object start1 = Qnil; - if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map))) - start1 = KVAR (current_kboard, Voverriding_terminal_local_map); + Lisp_Object start1 = KVAR (current_kboard, Voverriding_terminal_local_map); if (!NILP (start1)) { commit bc1090145c702bbc94fad0e3d8ccea445e2056c4 Author: Stefan Kangas Date: Mon Feb 10 23:50:59 2025 +0100 Prefer keyword arguments in message-mode menu definition * lisp/gnus/message.el (message-mode-menu): Prefer keyword arguments in menu definition. Reformat for readability and consistency. diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 7a84d6366db..1d035220bba 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -2972,33 +2972,38 @@ Consider adding this function to `message-header-setup-hook'" "M-n" #'message-display-abbrev) -(easy-menu-define - message-mode-menu message-mode-map "Message Menu." +(easy-menu-define message-mode-menu message-mode-map + "Message Menu." '("Message" - ["Yank Original" message-yank-original message-reply-buffer] - ["Fill Yanked Message" message-fill-yanked-message t] - ["Insert Signature" message-insert-signature t] - ["Caesar (rot13) Message" message-caesar-buffer-body t] - ["Caesar (rot13) Region" message-caesar-region mark-active] + ["Yank Original" message-yank-original + :active message-reply-buffer] + ["Fill Yanked Message" message-fill-yanked-message] + ["Insert Signature" message-insert-signature] + ["Caesar (rot13) Message" message-caesar-buffer-body] + ["Caesar (rot13) Region" message-caesar-region + :active mark-active] ["Elide Region" message-elide-region :active mark-active :help "Replace text in region with an ellipsis"] ["Delete Outside Region" message-delete-not-region :active mark-active :help "Delete all quoted text outside region"] - ["Kill To Signature" message-kill-to-signature t] - ["Newline and Reformat" message-newline-and-reformat t] - ["Rename buffer" message-rename-buffer t] - ["Spellcheck" ispell-message :help "Spellcheck this message"] + ["Kill To Signature" message-kill-to-signature] + ["Newline and Reformat" message-newline-and-reformat] + ["Rename buffer" message-rename-buffer] + ["Spellcheck" ispell-message + :help "Spellcheck this message"] "----" ["Insert Region Marked" message-mark-inserted-region - :active mark-active :help "Mark region with enclosing tags"] + :active mark-active + :help "Mark region with enclosing tags"] ["Insert File Marked..." message-mark-insert-file :help "Insert file at point marked with enclosing tags"] - ["Attach File..." mml-attach-file t] - ["Insert Screenshot" message-insert-screenshot t] + ["Attach File..." mml-attach-file] + ["Insert Screenshot" message-insert-screenshot] "----" - ["Send Message" message-send-and-exit :help "Send this message"] + ["Send Message" message-send-and-exit + :help "Send this message"] ["Postpone Message" message-dont-send :help "File this draft message and exit"] ["Send at Specific Time..." gnus-delay-article @@ -3006,38 +3011,37 @@ Consider adding this function to `message-header-setup-hook'" ["Kill Message" message-kill-buffer :help "Delete this message without sending"] "----" - ["Message manual" message-info :help "Display the Message manual"])) + ["Message manual" message-info + :help "Display the Message manual"])) -(easy-menu-define - message-mode-field-menu message-mode-map "" +(easy-menu-define message-mode-field-menu message-mode-map + "Field Menu." '("Field" - ["To" message-goto-to t] - ["From" message-goto-from t] - ["Subject" message-goto-subject t] - ["Change subject..." message-change-subject t] - ["Cc" message-goto-cc t] - ["Bcc" message-goto-bcc t] - ["Fcc" message-goto-fcc t] - ["Reply-To" message-goto-reply-to t] + ["To" message-goto-to] + ["From" message-goto-from] + ["Subject" message-goto-subject] + ["Change subject..." message-change-subject] + ["Cc" message-goto-cc] + ["Bcc" message-goto-bcc] + ["Fcc" message-goto-fcc] + ["Reply-To" message-goto-reply-to] ["Flag As Important" message-insert-importance-high :help "Mark this message as important"] ["Flag As Unimportant" message-insert-importance-low :help "Mark this message as unimportant"] - ["Request Receipt" - message-insert-disposition-notification-to + ["Request Receipt" message-insert-disposition-notification-to :help "Request a receipt notification"] "----" ;; (typical) news stuff - ["Summary" message-goto-summary t] - ["Keywords" message-goto-keywords t] - ["Newsgroups" message-goto-newsgroups t] - ["Fetch Newsgroups" message-insert-newsgroups t] - ["Followup-To" message-goto-followup-to t] - ;; ["Followup-To (with note in body)" message-cross-post-followup-to t] - ["Crosspost / Followup-To..." message-cross-post-followup-to t] - ["Distribution" message-goto-distribution t] - ["Expires" message-insert-expires t ] - ["X-No-Archive" message-add-archive-header t ] + ["Summary" message-goto-summary] + ["Keywords" message-goto-keywords] + ["Newsgroups" message-goto-newsgroups] + ["Fetch Newsgroups" message-insert-newsgroups] + ["Followup-To" message-goto-followup-to] + ["Crosspost / Followup-To..." message-cross-post-followup-to] + ["Distribution" message-goto-distribution] + ["Expires" message-insert-expires] + ["X-No-Archive" message-add-archive-header] "----" ;; (typical) mailing-lists stuff ["Fetch To" message-insert-to @@ -3045,18 +3049,18 @@ Consider adding this function to `message-header-setup-hook'" ["Fetch To and Cc" message-insert-wide-reply :help "Insert To and Cc headers as if you were doing a wide reply."] "----" - ["Send to list only" message-to-list-only t] - ["Mail-Followup-To" message-goto-mail-followup-to t] + ["Send to list only" message-to-list-only] + ["Mail-Followup-To" message-goto-mail-followup-to] ["Unsubscribed list post" message-generate-unsubscribed-mail-followup-to :help "Insert a reasonable `Mail-Followup-To:' header."] - ["Reduce To: to Cc:" message-reduce-to-to-cc t] + ["Reduce To: to Cc:" message-reduce-to-to-cc] "----" - ["Sort Headers" message-sort-headers t] - ["Encode non-ASCII domain names" message-idna-to-ascii-rhs t] + ["Sort Headers" message-sort-headers] + ["Encode non-ASCII domain names" message-idna-to-ascii-rhs] ;; We hide `message-hidden-headers' by narrowing the buffer. - ["Show Hidden Headers" message-widen-and-recenter t] - ["Goto Body" message-goto-body t] - ["Goto Signature" message-goto-signature t])) + ["Show Hidden Headers" message-widen-and-recenter] + ["Goto Body" message-goto-body] + ["Goto Signature" message-goto-signature])) (defvar message-tool-bar-map nil) commit 71c369bf666d529712be54fc1bc7fd3dffd8ace6 Author: Stefan Kangas Date: Mon Feb 10 23:46:18 2025 +0100 ; Quote function symbols in help-fns-tests.el * test/lisp/help-fns-tests.el: Properly quote function symbols as such. diff --git a/test/lisp/help-fns-tests.el b/test/lisp/help-fns-tests.el index b697bb894ed..4f65db028e4 100644 --- a/test/lisp/help-fns-tests.el +++ b/test/lisp/help-fns-tests.el @@ -44,50 +44,50 @@ Return first line of the output of (describe-function-1 FUNC)." (ert-deftest help-fns-test-bug17410 () "Test for https://debbugs.gnu.org/17410 ." (let ((regexp "autoloaded Lisp macro") - (result (help-fns-tests--describe-function 'help-fns-test--macro))) + (result (help-fns-tests--describe-function #'help-fns-test--macro))) (should (string-match regexp result)))) (ert-deftest help-fns-test-built-in () (let ((regexp "a primitive-function in .C source code") - (result (help-fns-tests--describe-function 'mapcar))) + (result (help-fns-tests--describe-function #'mapcar))) (should (string-match regexp result)))) (ert-deftest help-fns-test-interactive-built-in () (let ((regexp "an interactive primitive-function in .C source code") - (result (help-fns-tests--describe-function 're-search-forward))) + (result (help-fns-tests--describe-function #'re-search-forward))) (should (string-match regexp result)))) (ert-deftest help-fns-test-lisp-macro () (let ((regexp "a Lisp macro in .+subr\\.el") - (result (help-fns-tests--describe-function 'when))) + (result (help-fns-tests--describe-function #'when))) (should (string-match regexp result)))) (ert-deftest help-fns-test-lisp-defun () (let ((regexp "a \\([^ ]+\\) in .+subr\\.el") - (result (help-fns-tests--describe-function 'last))) + (result (help-fns-tests--describe-function #'last))) (should (string-match regexp result)) (should (member (match-string 1 result) '("native-comp-function" "byte-code-function"))))) (ert-deftest help-fns-test-lisp-defsubst () (let ((regexp "a byte-code-function in .+subr\\.el") - (result (help-fns-tests--describe-function 'posn-window))) + (result (help-fns-tests--describe-function #'posn-window))) (should (string-match regexp result)))) (ert-deftest help-fns-test-alias-to-defun () (let ((regexp "an alias for .set-file-modes. in .+subr\\.el") - (result (help-fns-tests--describe-function 'chmod))) + (result (help-fns-tests--describe-function #'chmod))) (should (string-match regexp result)))) (ert-deftest help-fns-test-bug23887 () "Test for https://debbugs.gnu.org/23887 ." (let ((regexp "an alias for .re-search-forward. in .+subr\\.el") - (result (help-fns-tests--describe-function 'search-forward-regexp))) + (result (help-fns-tests--describe-function #'search-forward-regexp))) (should (string-match regexp result)))) (ert-deftest help-fns-test-bug76172 () "No error when describing `menu-bar-open-mouse'." - (should (stringp (help-fns-tests--describe-function 'menu-bar-open-mouse)))) + (should (stringp (help-fns-tests--describe-function #'menu-bar-open-mouse)))) (ert-deftest help-fns-test-bug76179 () "No error when describing `bindat--type'." commit 2d257fa24ffb6e622b2a3b6beb861bddfdb764b3 Author: Stefan Kangas Date: Mon Feb 10 22:37:40 2025 +0100 Add test for Bug#76179 * test/lisp/help-fns-tests.el (help-fns-test-bug76179): New test. (Bug#76179) diff --git a/test/lisp/help-fns-tests.el b/test/lisp/help-fns-tests.el index 8f04669f447..b697bb894ed 100644 --- a/test/lisp/help-fns-tests.el +++ b/test/lisp/help-fns-tests.el @@ -89,6 +89,11 @@ Return first line of the output of (describe-function-1 FUNC)." "No error when describing `menu-bar-open-mouse'." (should (stringp (help-fns-tests--describe-function 'menu-bar-open-mouse)))) +(ert-deftest help-fns-test-bug76179 () + "No error when describing `bindat--type'." + (require 'bindat) + (should (stringp (help-fns-tests--describe-function 'bindat--type)))) + ;;; Test describe-function over functions with funny names (defun abc\\\[universal-argument\]b\`c\'d\\e\"f (x) commit 7fbdad01e510984e9166191191a9046a065dffd9 Author: Stefan Kangas Date: Mon Feb 10 22:31:26 2025 +0100 ; Move describe-symbol test to its proper section * test/lisp/help-fns-tests.el (help-fns-test-dangling-alias): Move test to its proper section. diff --git a/test/lisp/help-fns-tests.el b/test/lisp/help-fns-tests.el index 2429cd73513..8f04669f447 100644 --- a/test/lisp/help-fns-tests.el +++ b/test/lisp/help-fns-tests.el @@ -89,11 +89,6 @@ Return first line of the output of (describe-function-1 FUNC)." "No error when describing `menu-bar-open-mouse'." (should (stringp (help-fns-tests--describe-function 'menu-bar-open-mouse)))) -(ert-deftest help-fns-test-dangling-alias () - "Make sure we don't burp on bogus aliases." - (let ((f (make-symbol "bogus-alias"))) - (define-obsolete-function-alias f 'help-fns-test--undefined-function "past") - (describe-symbol f))) ;;; Test describe-function over functions with funny names (defun abc\\\[universal-argument\]b\`c\'d\\e\"f (x) @@ -131,12 +126,18 @@ Return first line of the output of (describe-function-1 FUNC)." (goto-char (point-min)) (should (looking-at "^font-lock-comment-face is ")))) -(defvar foo-test-map) -(defvar help-fns-test--describe-keymap-foo) +(ert-deftest help-fns-test-dangling-alias () + "Make sure we don't burp on bogus aliases." + (let ((f (make-symbol "bogus-alias"))) + (define-obsolete-function-alias f 'help-fns-test--undefined-function "past") + (describe-symbol f))) ;;; Tests for describe-keymap +(defvar foo-test-map) +(defvar help-fns-test--describe-keymap-foo) + (defvar-keymap help-fns-test-map "a" 'test-cmd-a "b" 'test-cmd-b commit 467a88394f8d7fe545bd236586a9a3ed991ab9dc Author: Paul Eggert Date: Sat Feb 8 15:56:04 2025 -0800 Pacify gcc -Wswitch-enum in bidi.c * src/bidi.c (bidi_get_type, bidi_resolve_explicit) (bidi_find_bracket_pairs, bidi_resolve_brackets) (bidi_resolve_neutral): Use ‘switch (INT_PROMOTE (E))’ to indicate that it’s intended that we not enumerate all the enum values. diff --git a/src/bidi.c b/src/bidi.c index d8754e2db73..773513143d6 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -289,7 +289,7 @@ bidi_get_type (int ch, bidi_dir_t override) if (default_type == UNKNOWN_BT) emacs_abort (); - switch (default_type) + switch (INT_PROMOTE (default_type)) { case WEAK_BN: case NEUTRAL_B: @@ -2010,7 +2010,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) embedding level of the _following_ characters, so we must first look at the type of the previous character to support that. */ - switch (prev_type) + switch (INT_PROMOTE (prev_type)) { case RLI: /* X5a */ if (current_level < BIDI_MAXDEPTH @@ -2074,7 +2074,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) bidi_it->type_after_wn = UNKNOWN_BT; - switch (type) + switch (INT_PROMOTE (type)) { case RLE: /* X2 */ case RLO: /* X4 */ @@ -2707,7 +2707,7 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it) /* Whenever we see a strong type, update the flags of all the slots on the stack. */ - switch (bidi_it->type) + switch (INT_PROMOTE (bidi_it->type)) { case STRONG_L: flag = ((embedding_level & 1) == 0 @@ -2979,7 +2979,7 @@ bidi_resolve_brackets (struct bidi_it *bidi_it) if (prev_type_for_neutral == UNKNOWN_BT) prev_type_for_neutral = embedding_type; - switch (prev_type_for_neutral) + switch (INT_PROMOTE (prev_type_for_neutral)) { case STRONG_R: case WEAK_EN: @@ -3175,7 +3175,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) } else { - switch (type) + switch (INT_PROMOTE (type)) { case STRONG_L: case STRONG_R: commit 4936a8d5acbfee2dee6d903400eba48cb2e3a6a7 Merge: 8a669b6be52 411db554327 Author: Stefan Monnier Date: Mon Feb 10 16:03:02 2025 -0500 Merge remote-tracking branch 'origin/emacs-30' commit 8a669b6be523e043423b81571a8c94cb49ccc8e5 Author: Stefan Kangas Date: Sun Feb 9 22:50:34 2025 +0100 Set process-adaptive-read-buffering to nil by default * src/process.c (syms_of_process) : Set the default to nil. (Bug#75574) diff --git a/etc/NEWS b/etc/NEWS index 1519ee8e257..77b1043a08d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -305,6 +305,11 @@ on the header lines are now these two: the selected window uses ** In 'customize-face', the "Font family" attribute now supports completion. +** 'process-adaptive-read-buffering' is now nil by default. +Setting this variable to a non-nil value reduces performance and leads +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. + * Editing Changes in Emacs 31.1 diff --git a/src/process.c b/src/process.c index 807f06f990b..e61ec425f7e 100644 --- a/src/process.c +++ b/src/process.c @@ -8878,7 +8878,7 @@ allow them to produce more output before Emacs tries to read it. If the value is t, the delay is reset after each write to the process; any other non-nil value means that the delay is not reset on write. The variable takes effect when `start-process' is called. */); - Vprocess_adaptive_read_buffering = Qt; + Vprocess_adaptive_read_buffering = Qnil; DEFVAR_BOOL ("process-prioritize-lower-fds", process_prioritize_lower_fds, doc: /* Whether to start checking for subprocess output from first file descriptor. commit af528d9ea40d027fa0100578b8b753b1ec3c0432 Author: Stefan Kangas Date: Mon Feb 10 15:28:56 2025 +0100 ; Add test for my last commit * test/lisp/help-fns-tests.el (help-fns-test-bug76172): New test. diff --git a/test/lisp/help-fns-tests.el b/test/lisp/help-fns-tests.el index 67fc9d96c9c..2429cd73513 100644 --- a/test/lisp/help-fns-tests.el +++ b/test/lisp/help-fns-tests.el @@ -85,6 +85,10 @@ Return first line of the output of (describe-function-1 FUNC)." (result (help-fns-tests--describe-function 'search-forward-regexp))) (should (string-match regexp result)))) +(ert-deftest help-fns-test-bug76172 () + "No error when describing `menu-bar-open-mouse'." + (should (stringp (help-fns-tests--describe-function 'menu-bar-open-mouse)))) + (ert-deftest help-fns-test-dangling-alias () "Make sure we don't burp on bogus aliases." (let ((f (make-symbol "bogus-alias"))) commit 411db5543274275896ff4bf93096e9fd5574d06e Author: Stefan Monnier Date: Mon Feb 10 15:35:20 2025 -0500 lisp/help.el (help-function-arglist): Fix out-of-bounds access (bug#76179) diff --git a/lisp/help.el b/lisp/help.el index 5d4c3e61599..1d87c2209c8 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -2381,7 +2381,7 @@ the same names as used in the original source code, when possible." (dolist (arg arglist) (unless (and (symbolp arg) (let ((name (symbol-name arg))) - (if (eq (aref name 0) ?&) + (if (and (> (length name) 0) (eq (aref name 0) ?&)) (memq arg '(&rest &optional)) (not (string-search "." name))))) (setq valid nil))) commit 0c7214dc97aef577487d71851580e8a68784075d Author: Michael Albinus Date: Mon Feb 10 16:37:25 2025 +0100 * lisp/ansi-osc.el (ansi-osc-directory-tracker): Don't check host name. diff --git a/lisp/ansi-osc.el b/lisp/ansi-osc.el index 2a93b582479..97d6f6c8754 100644 --- a/lisp/ansi-osc.el +++ b/lisp/ansi-osc.el @@ -116,19 +116,16 @@ such as with the following command: printf \"\\e]7;file://%s%s\\e\\\\\" \"$HOSTNAME\" \"$PWD\" -`default-directory' remote file name forms are maintained. +A remote `default-directory' is maintained. This functionality serves as an alternative to `dirtrack-mode' and `shell-dirtrack-mode'." - (let ((url (url-generic-parse-url text))) - (when (and (string= (url-type url) "file") - (or (null (url-host url)) - ;; Use `downcase' to match `url-generic-parse-url' behavior - (string= (url-host url) (downcase (system-name))))) - (ignore-errors - (cd-absolute - (concat (file-remote-p default-directory - (url-unhex-string (url-filename url))))))))) + (when-let* ((url (url-generic-parse-url text)) + ((string= (url-type url) "file"))) + (ignore-errors + (cd-absolute + (concat (file-remote-p default-directory) + (url-unhex-string (url-filename url))))))) ;; Hyperlink handling (OSC 8) commit 55ffbeaab1da66abee8a84f79c2cebd2c61f336f Author: Stefan Kangas Date: Mon Feb 10 14:57:03 2025 +0100 Don't error on 'C-h f menu-bar-open-mouse RET' * lisp/help-fns.el (help-fns--insert-menu-bindings): Fix error when passed 'menu-bar-open-mouse'. (Bug#76172) diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 9324cf85454..6112df99850 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -649,7 +649,8 @@ the C sources, too." (lambda (entry level) (when (symbolp map) (setq map (symbol-function map))) - (when-let* ((elem (assq entry (cdr map)))) + (when-let* ((elem (assq entry (cdr map))) + (_ (proper-list-p elem))) (when (> level 0) (push sep string)) (if (eq (nth 1 elem) 'menu-item) commit e33eb91061d53b31ee4c5557600f13749aa4ffd5 Author: Stefan Kangas Date: Mon Feb 10 13:00:12 2025 +0100 ; Silence byte-compiler * lisp/transient.el (transient-set-default-level) (transient-scope): Silence byte-compiler. diff --git a/lisp/transient.el b/lisp/transient.el index 610e5871ccc..aa0fc442638 100644 --- a/lisp/transient.el +++ b/lisp/transient.el @@ -1564,7 +1564,7 @@ level of such a binding. The default level can only be set for commands that were defined using `transient-define-suffix', `transient-define-infix' or `transient-define-argument'." - (if-let ((proto (transient--suffix-prototype command))) + (if-let* ((proto (transient--suffix-prototype command))) (oset proto level level) (user-error "Cannot set level for `%s'; no prototype object exists" command))) @@ -3891,13 +3891,13 @@ If no prefix matches, return nil." (if (or prefixes classes) (let ((prefixes (ensure-list prefixes)) (type (if (symbolp classes) classes (cons 'or classes)))) - (if-let ((obj (cl-flet ((match (obj) - (and obj - (or (memq (oref obj command) prefixes) - (cl-typep obj type)) - obj))) - (or (match transient-current-prefix) - (match transient--prefix))))) + (if-let* ((obj (cl-flet ((match (obj) + (and obj + (or (memq (oref obj command) prefixes) + (cl-typep obj type)) + obj))) + (or (match transient-current-prefix) + (match transient--prefix))))) (oref obj scope) (and (get (car prefixes) 'transient--prefix) (oref (transient--init-prefix (car prefixes)) scope)))) commit 8b3a276e4b3d096afed2b130d4d7f47dca7f7fc6 Author: Gerd Möllmann Date: Mon Feb 10 14:33:55 2025 +0100 ; * lisp/emacs-lisp/eieio.el (defclass): Add autoload cookie. diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index 475433bb221..1fa177b08da 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -58,6 +58,7 @@ ;;; Defining a new class ;; +;;;###autoload (defmacro defclass (name superclasses slots &rest options-and-doc) "Define NAME as a new class derived from SUPERCLASS with SLOTS. OPTIONS-AND-DOC is used as the class' options and base documentation. commit 68770e28deadc60e39a545c84b7f7462ac0eaa88 Author: Michael Albinus Date: Mon Feb 10 13:18:51 2025 +0100 ; * etc/NEWS: Fix last change. diff --git a/etc/NEWS b/etc/NEWS index cd3ba2f3fef..1519ee8e257 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -534,10 +534,10 @@ It removes all the buttons in the specified region. but completes on comint inputs. --- -*** ansi-osc-directory-tracker now respects remote files. -Remote file forms are now retained when changes to 'default-directory' -are detected by this filter. For example, /ssh:hostname:/home/username -would have been stripped to just /home/username. +*** 'ansi-osc-directory-tracker' now respects remote directories. +Remote directories are now retained when changes to 'default-directory' +are detected by this filter. For example, "/ssh:hostname:/home/username" +would have been stripped to just "/home/username" before. ** Eshell commit 424fc4a56cb33af05a1d59c75c9159df7086b3c6 Author: shipmints Date: Mon Feb 10 12:55:54 2025 +0100 ansi-osc-directory-tracker respects remote files * etc/NEWS: ansi-osc-directory-tracker supports remote directories. * lisp/ansi-osc.el (ansi-osc-directory-tracker): If 'default-directory' is a remote-file form, retain that form when 'default-directory' changes are detected. diff --git a/etc/NEWS b/etc/NEWS index acaa88d5574..cd3ba2f3fef 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -533,6 +533,12 @@ It removes all the buttons in the specified region. 'comint-complete-input-ring' ('C-x ') is like 'minibuffer-complete-history' but completes on comint inputs. +--- +*** ansi-osc-directory-tracker now respects remote files. +Remote file forms are now retained when changes to 'default-directory' +are detected by this filter. For example, /ssh:hostname:/home/username +would have been stripped to just /home/username. + ** Eshell --- diff --git a/lisp/ansi-osc.el b/lisp/ansi-osc.el index bbd75033ba0..2a93b582479 100644 --- a/lisp/ansi-osc.el +++ b/lisp/ansi-osc.el @@ -116,6 +116,8 @@ such as with the following command: printf \"\\e]7;file://%s%s\\e\\\\\" \"$HOSTNAME\" \"$PWD\" +`default-directory' remote file name forms are maintained. + This functionality serves as an alternative to `dirtrack-mode' and `shell-dirtrack-mode'." (let ((url (url-generic-parse-url text))) @@ -124,7 +126,9 @@ and `shell-dirtrack-mode'." ;; Use `downcase' to match `url-generic-parse-url' behavior (string= (url-host url) (downcase (system-name))))) (ignore-errors - (cd-absolute (url-unhex-string (url-filename url))))))) + (cd-absolute + (concat (file-remote-p default-directory + (url-unhex-string (url-filename url))))))))) ;; Hyperlink handling (OSC 8) commit b92cfadc6af3abf773f666bedc571bb85402b001 Author: Michael Albinus Date: Mon Feb 10 11:30:32 2025 +0100 * doc/misc/ert.texi (Helper Functions): Improve index. Fix markups. diff --git a/doc/misc/ert.texi b/doc/misc/ert.texi index 35128fcfeb0..566fa03bf3f 100644 --- a/doc/misc/ert.texi +++ b/doc/misc/ert.texi @@ -1107,8 +1107,8 @@ result of @var{NAME-FORM}. Example: @dots{})) @end lisp -This uses the test buffer @t{"*Test buffer (backtrace-tests--variables): -variables*"}. +This uses the test buffer @file{*Test buffer +(backtrace-tests--variables): variables*}. @end defmac @defmac ert-with-buffer-selected (buffer &body body) @@ -1130,7 +1130,7 @@ value is the last form in @var{body}. Example: @dots{})) @end lisp -This displays a temporary buffer @t{" *temp*-739785"*}. +This displays a temporary buffer like @file{ *temp*-739785*}. @end defmac @defmac ert-with-test-buffer-selected ((&key name) &body body) @@ -1146,8 +1146,8 @@ It combines @code{ert-with-test-buffer} and @dots{})) @end lisp -This displays the test buffer @t{"*Test buffer -(whitespace-tests--global): global*"}. +This displays the test buffer @file{*Test buffer +(whitespace-tests--global): global*}. @end defmac @defun ert-kill-all-test-buffers () @@ -1162,7 +1162,7 @@ temporary name, creates a new buffer named @var{buffer-name}, executes to @var{buffer-name}. This is useful if @var{body} has undesirable side-effects on an Emacs -buffer with a fixed name such as @t{"*Messages*"}. Example: +buffer with a fixed name such as @file{*Messages*}. Example: @lisp (ert-with-buffer-renamed ("*Messages*") @dots{}) @@ -1178,7 +1178,7 @@ and @code{princ} to the echo area. Messages issued from C code using the above mentioned functions will not be captured. This is useful for separating the issuance of messages by the code under -test from the behavior of the @t{"*Messages*"} buffer. Example: +test from the behavior of the @file{*Messages*} buffer. Example: @lisp (ert-with-message-capture captured-messages @dots{}) @@ -1193,14 +1193,17 @@ The path to the resource directory is the @file{resources} directory in the same directory as the test file this is called from. If that directory doesn't exist, find a directory based on the test file -name. If the file is named @file{foo-tests.el}, it returns the absolute -file name for @file{foo-resources}. Example: +name. If the test file is named @file{foo-tests.el}, it returns the +absolute file name for @file{foo-resources}. Example: @lisp (let ((dir (ert-resource-directory))) @dots{}) @end lisp +@vindex ert-resource-directory-format +@vindex ert-resource-directory-trim-left-regexp +@vindex ert-resource-directory-trim-right-regexp In order to use a different resource directory naming scheme, the variable @code{ert-resource-directory-format} can be changed. Before formatting, the file name will be trimmed using @code{string-trim} with @@ -1229,23 +1232,25 @@ defined as any file placed in the resource directory as returned by @end lisp It returns the absolute file name for @file{foo-resources/bar/baz} when -called in file @file{foo-tests.el}. +called in test file @file{foo-tests.el}. @end defmac @defmac ert-with-temp-file (name &rest body) -This macro binds @var{name} to the name of a new temporary file and evaluates @var{body}. -It deletes the temporary file after @var{body} exits normally or -non-locally. @var{name} will be bound to the file name of the temporary -file. +This macro binds @var{name} to the name of a new temporary file and +evaluates @var{body}. It deletes the temporary file after @var{body} +exits normally or non-locally. @var{name} will be bound to the file +name of the temporary file. The following keyword arguments are supported: @table @code +@vindex ert-temp-file-prefix @item :prefix @var{string} If non-nil, pass @var{string} to @code{make-temp-file} as the @var{prefix} argument. Otherwise, use the value of @code{ert-temp-file-prefix}. +@vindex ert-temp-file-suffix @item :suffix @var{string} If non-nil, pass @var{string} to @code{make-temp-file} as the @var{suffix} argument. Otherwise, use the value of @@ -1254,7 +1259,8 @@ generate a suffix based on the name of the file that @code{ert-with-temp-file} is called from. @item :text @var{string} -If non-nil, pass @var{string} to @code{make-temp-file} as the @var{text} argument. +If non-nil, pass @var{string} to @code{make-temp-file} as the @var{text} +argument. @item :buffer @var{symbol} Open the temporary file using @code{find-file-noselect} and bind @@ -1307,7 +1313,7 @@ be possible when running on MS Windows). The default value is If a real remote connection shall be used for testing, this can be overwritten by the environment variable -@env{REMOTE_TEMPORARY_FILE_DIRECTORY}. Example +@env{REMOTE_TEMPORARY_FILE_DIRECTORY}. Example: @example # env REMOTE_TEMPORARY_FILE_DIRECTORY=/ssh:host:/tmp make @dots{} @@ -1330,8 +1336,8 @@ symbol and the rest are arguments to the command. Example: @end lisp @strong{Note}: Since the command is not called by -@code{call-interactively}, a test for @code{(called-interactively-p 'interactive)} -in the command will fail. +@code{call-interactively}, a test for @code{(called-interactively-p +'interactive)} in the command will fail. @end defun @defmac ert-simulate-keys (keys &rest body) @@ -1365,11 +1371,12 @@ Example: @end defun @defun ert-propertized-string (&rest args) -This function returns a string with properties as specified by @var{args}. +This function returns a string with properties as specified by +@var{args}. @var{args} is a list of strings and plists. The strings in @var{args} are concatenated to produce an output string. In the output string, -each string from @var{args} will be have the preceding plist as its +each string from @var{args} will have the preceding plist as its property list, or no properties if there is no plist before it. Example: commit efa9b97b454d2bf56d50fb4ef37e8378bb2e4b2a Author: Martin Rudalics Date: Mon Feb 10 10:58:05 2025 +0100 Implement tab line dragging with mouse (Bug#76084) * lisp/mouse.el (mouse-drag-line): Allow tab line dragging if there's a window above. Consider tab line height when calculating 'position'. Add 'tab-line' binding to transient map. (mouse-drag-tab-line): Have it drag the tab line only (and not the entire frame) when the tab line is between two windows. diff --git a/lisp/mouse.el b/lisp/mouse.el index 3a8388870be..1f0ca6a51b6 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -844,7 +844,7 @@ must be one of the symbols `header', `mode', or `vertical'." ;; Decide on whether we are allowed to track at all and whose ;; window's edge we drag. (cond - ((eq line 'header) + ((memq line '(header tab)) ;; Drag bottom edge of window above the header line. (setq window (window-in-direction 'above window t))) ((eq line 'mode)) @@ -903,10 +903,13 @@ must be one of the symbols `header', `mode', or `vertical'." (when (window-live-p posn-window) ;; Add top edge of `posn-window' to `position'. (setq position (+ (window-pixel-top posn-window) position)) - ;; If necessary, add height of header line to `position' + ;; If necessary, add height of header and tab line to + ;; `position'. (when (memq (posn-area start) '(nil left-fringe right-fringe left-margin right-margin)) - (setq position (+ (window-header-line-height posn-window) position)))) + (setq position (+ (window-header-line-height posn-window) + (window-tab-line-height posn-window) + position)))) ;; When the cursor overshoots after shrinking a window to its ;; minimum size and the dragging direction changes, have the ;; cursor first catch up with the window edge. @@ -947,6 +950,7 @@ must be one of the symbols `header', `mode', or `vertical'." ;; with a mode-line, header-line or vertical-line prefix ... (define-key map [mode-line] map) (define-key map [header-line] map) + (define-key map [tab-line] map) (define-key map [vertical-line] map) ;; ... and some maybe even with a right- or bottom-divider ;; or left- or right-margin prefix ... @@ -1035,8 +1039,9 @@ START-EVENT is the starting mouse event of the drag action." (interactive "e") (let* ((start (event-start start-event)) (window (posn-window start))) - (when (and (window-live-p window) - (window-at-side-p window 'top)) + (if (and (window-live-p window) + (not (window-at-side-p window 'top))) + (mouse-drag-line start-event 'tab) (let ((frame (window-frame window))) (when (frame-parameter frame 'drag-with-tab-line) (mouse-drag-frame-move start-event)))))) commit 4d1ceac9f9332f74ac2ab300eb2a629ea742b1dc Author: Martin Rudalics Date: Mon Feb 10 10:36:38 2025 +0100 Fix handling of visibility on tty frames (Bug#76031) * src/frame.h (FRAME_REDISPLAY_P): Remove. Use the new function frame_redisplay_p instead. Extern frame_redisplay_p. * src/frame.c (frame_redisplay_p): New function to replace FRAME_REDISPLAY_P macro. (make_terminal_frame): Don't tinker with frame visibility and don't make the new frame the terminal's top frame. (do_switch_frame): Make sure frame switched to and any of its ancestors are visible. Don't reset the visibility of other frames. (other_frames): Do not assume tty frames are by default visible. (Fmake_frame_invisible): When making the selected tty frame invisible, explicitly select the next visible frame. * src/dispnew.c (Fredraw_display): Use frame_redisplay_p instead of FRAME_REDISPLAY_P. * src/xdisp.c (clear_garbaged_frames, echo_area_display) (prepare_menu_bars, redisplay_internal, display_and_set_cursor) (gui_clear_cursor): Use frame_redisplay_p instead of FRAME_REDISPLAY_P. * src/keyboard.c (tty_read_avail_input): When storing an event and the selected frame is a child frame whose root is its terminal's top frame, set the frame_or_window slot to the child frame since otherwise the next switch frame event will select the top frame instead. diff --git a/src/dispnew.c b/src/dispnew.c index 5f5575d484b..a952f7623c0 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -3240,7 +3240,7 @@ DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "", Lisp_Object tail, frame; FOR_EACH_FRAME (tail, frame) - if (FRAME_REDISPLAY_P (XFRAME (frame))) + if (frame_redisplay_p (XFRAME (frame))) redraw_frame (XFRAME (frame)); return Qnil; diff --git a/src/frame.c b/src/frame.c index 6e125b9561c..2ccdec6fc41 100644 --- a/src/frame.c +++ b/src/frame.c @@ -338,6 +338,51 @@ predicates which report frame's specific UI-related capabilities. */) return type; } +/** Return true if F can be redisplayed, that is if F is visible and, if + F is a tty frame, all its ancestors are visible too. */ +bool +frame_redisplay_p (struct frame *f) +{ + if (is_tty_frame (f)) + { + struct frame *p = FRAME_PARENT_FRAME (f); + struct frame *q = NULL; + + while (p) + { + if (!p->visible) + /* A tty child frame cannot be redisplayed if one of its + ancestors is invisible. */ + return false; + else + { + q = p; + p = FRAME_PARENT_FRAME (p); + } + } + + struct tty_display_info *tty = FRAME_TTY (f); + struct frame *r = XFRAME (tty->top_frame); + + /* A tty child frame can be redisplayed iff its root is the top + frame of its terminal. Any other tty frame can be redisplayed + iff it is the top frame of its terminal itself which must be + always visible. */ + return (q ? q == r : f == r); + } + else +#ifndef HAVE_X_WINDOWS + return FRAME_VISIBLE_P (f); +#else + /* Under X, frames can continue to be displayed to the user by the + compositing manager even if they are invisible, so this also + checks whether or not the frame is reported visible by the X + server. */ + return (FRAME_VISIBLE_P (f) + || (FRAME_X_P (f) && FRAME_X_VISIBLE (f))); +#endif +} + /* Placeholder used by temacs -nw before window.el is loaded. */ DEFUN ("frame-windows-min-size", Fframe_windows_min_size, Sframe_windows_min_size, 4, 4, 0, @@ -1407,18 +1452,6 @@ make_terminal_frame (struct terminal *terminal, Lisp_Object parent, FRAME_TEXT_HEIGHT (f) = FRAME_TEXT_HEIGHT (f) - FRAME_MENU_BAR_HEIGHT (f) - FRAME_TAB_BAR_HEIGHT (f); - /* Mark current topmost frame obscured if we make a new root frame. - Child frames don't completely obscure other frames. */ - if (NILP (parent) && FRAMEP (FRAME_TTY (f)->top_frame)) - { - struct frame *top = XFRAME (FRAME_TTY (f)->top_frame); - struct frame *root = root_frame (top); - if (FRAME_LIVE_P (root)) - SET_FRAME_VISIBLE (root, false); - } - - /* Set the top frame to the newly created frame. */ - FRAME_TTY (f)->top_frame = frame; return f; } @@ -1772,28 +1805,27 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor struct tty_display_info *tty = FRAME_TTY (f); Lisp_Object top_frame = tty->top_frame; - /* Switching to a frame on a different root frame is special. The - old root frame has to be marked invisible, and the new root - frame has to be made visible. */ - if (!EQ (frame, top_frame) - && (!FRAMEP (top_frame) - || root_frame (f) != root_frame (XFRAME (top_frame)))) + /* When FRAME's root frame is not its terminal's top frame, make + that root frame the new top frame of FRAME's terminal. */ + if (root_frame (f) != XFRAME (top_frame)) { - struct frame *new_root = root_frame (f); - SET_FRAME_VISIBLE (new_root, true); - SET_FRAME_VISIBLE (f, true); + struct frame *p = FRAME_PARENT_FRAME (f); + + XSETFRAME (top_frame, root_frame (f)); + tty->top_frame = top_frame; - /* Mark previously displayed root frame as no longer - visible. */ - if (FRAMEP (top_frame)) + while (p) { - struct frame *top = XFRAME (top_frame); - struct frame *old_root = root_frame (top); - if (old_root != new_root) - SET_FRAME_VISIBLE (old_root, false); + /* If FRAME is a child frame, make its ancsetors visible + and garbage them ... */ + SET_FRAME_VISIBLE (p, true); + SET_FRAME_GARBAGED (p); + p = FRAME_PARENT_FRAME (p); } - tty->top_frame = frame; + /* ... and FRAME itself too. */ + SET_FRAME_VISIBLE (f, true); + SET_FRAME_GARBAGED (f); /* FIXME: Why is it correct to set FrameCols/Rows here? */ if (!FRAME_PARENT_FRAME (f)) @@ -1808,10 +1840,8 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor } } else - { - SET_FRAME_VISIBLE (f, true); - tty->top_frame = frame; - } + /* Should be covered by the condition above. */ + SET_FRAME_VISIBLE (f, true); } sf->select_mini_window_flag = MINI_WINDOW_P (XWINDOW (sf->selected_window)); @@ -2229,8 +2259,8 @@ DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame, * other_frames: * * Return true if there exists at least one visible or iconified frame - * but F. Tooltip frames do not qualify as candidates. Return false - * if no such frame exists. + * but F. Tooltip and child frames do not qualify as candidates. + * Return false if no such frame exists. * * INVISIBLE true means we are called from make_frame_invisible where * such a frame must be visible or iconified. INVISIBLE nil means we @@ -2322,7 +2352,6 @@ other_frames (struct frame *f, bool invisible, bool force) /* For invisibility and normal deletions, at least one visible or iconified frame must remain (Bug#26682). */ && (FRAME_VISIBLE_P (f1) - || is_tty_frame (f1) || FRAME_ICONIFIED_P (f1) || (!invisible && (force @@ -3234,11 +3263,18 @@ displayed in the terminal. */) if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook) FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, false); - /* The ELisp manual says that this "usually" makes child frames - invisible, too, but without saying when not. Since users can't - rely on this, it's not implemented. */ - if (is_tty_frame (f)) - SET_FRAME_VISIBLE (f, false); + if (is_tty_frame (f) && EQ (frame, selected_frame)) + /* On a tty if FRAME is the selected frame, we have to select another + frame instead. If FRAME is a child frame, use the first visible + ancestor as returned by 'mru_rooted_frame'. If FRAME is a root + frame, use the frame returned by 'next-frame' which must exist since + otherwise other_frames above would have lied. */ + Fselect_frame (FRAME_PARENT_FRAME (f) + ? mru_rooted_frame (f) + : next_frame (frame, make_fixnum (0)), + Qnil); + + SET_FRAME_VISIBLE (f, false); /* Make menu bar update for the Buffers and Frames menus. */ windows_or_buffers_changed = 16; diff --git a/src/frame.h b/src/frame.h index fea8baa7332..c9cc65e597d 100644 --- a/src/frame.h +++ b/src/frame.h @@ -1152,20 +1152,6 @@ default_pixels_per_inch_y (void) /* True if frame F is currently visible. */ #define FRAME_VISIBLE_P(f) (f)->visible -/* True if frame F should be redisplayed. This is normally the same - as FRAME_VISIBLE_P (f). Under X, frames can continue to be - displayed to the user by the compositing manager even if they are - invisible, so this also checks whether or not the frame is reported - visible by the X server. */ - -#ifndef HAVE_X_WINDOWS -#define FRAME_REDISPLAY_P(f) FRAME_VISIBLE_P (f) -#else -#define FRAME_REDISPLAY_P(f) (FRAME_VISIBLE_P (f) \ - || (FRAME_X_P (f) \ - && FRAME_X_VISIBLE (f))) -#endif - /* True if frame F is currently iconified. */ #define FRAME_ICONIFIED_P(f) (f)->iconified @@ -1473,6 +1459,7 @@ extern struct frame *decode_live_frame (Lisp_Object); extern struct frame *decode_any_frame (Lisp_Object); extern struct frame *make_initial_frame (void); extern struct frame *make_frame (bool); +extern bool frame_redisplay_p (struct frame *); extern int tty_child_pos_param (struct frame *, Lisp_Object, Lisp_Object, int); extern int tty_child_size_param (struct frame *, Lisp_Object, diff --git a/src/keyboard.c b/src/keyboard.c index ac143af83f4..b22814d702d 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -8133,8 +8133,15 @@ tty_read_avail_input (struct terminal *terminal, buf.code = cbuf[i]; /* Set the frame corresponding to the active tty. Note that the value of selected_frame is not reliable here, redisplay tends - to temporarily change it. */ - buf.frame_or_window = tty->top_frame; + to temporarily change it. However, if the selected frame is a + child frame, don't do that since it will cause switch frame + events to switch to the root frame instead. */ + if (FRAME_PARENT_FRAME (XFRAME (selected_frame)) + && (root_frame (XFRAME (selected_frame)) + == XFRAME (tty->top_frame))) + buf.frame_or_window = selected_frame; + else + buf.frame_or_window = tty->top_frame; buf.arg = Qnil; kbd_buffer_store_event (&buf); diff --git a/src/xdisp.c b/src/xdisp.c index 804a19e048f..c9bcafe57fd 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -13453,7 +13453,7 @@ clear_garbaged_frames (void) { struct frame *f = XFRAME (frame); - if (FRAME_REDISPLAY_P (f) && FRAME_GARBAGED_P (f)) + if (frame_redisplay_p (f) && FRAME_GARBAGED_P (f)) { if (f->resized_p /* It makes no sense to redraw a non-selected TTY @@ -13507,7 +13507,7 @@ echo_area_display (bool update_frame_p) /* Don't display if frame is invisible or not yet initialized or if redisplay is inhibited. */ - if (!FRAME_REDISPLAY_P (f) || !f->glyphs_initialized_p + if (!frame_redisplay_p (f) || !f->glyphs_initialized_p || !NILP (Vinhibit_redisplay)) return; @@ -14048,7 +14048,7 @@ prepare_menu_bars (void) TTY frames to be completely redrawn, when there are more than one of them, even though nothing should be changed on display. */ - || (FRAME_REDISPLAY_P (f) && FRAME_WINDOW_P (f)))) + || (frame_redisplay_p (f) && FRAME_WINDOW_P (f)))) gui_consider_frame_title (frame); } } @@ -17062,8 +17062,8 @@ redisplay_internal (void) { struct frame *f = XFRAME (frame); - /* FRAME_REDISPLAY_P true basically means the frame is visible. */ - if (FRAME_REDISPLAY_P (f)) + /* frame_redisplay_p true basically means the frame is visible. */ + if (frame_redisplay_p (f)) { ++number_of_visible_frames; /* Adjust matrices for visible frames only. */ @@ -17206,7 +17206,7 @@ redisplay_internal (void) && !w->update_mode_line && !current_buffer->clip_changed && !current_buffer->prevent_redisplay_optimizations_p - && FRAME_REDISPLAY_P (XFRAME (w->frame)) + && frame_redisplay_p (XFRAME (w->frame)) && !XFRAME (w->frame)->cursor_type_changed && !XFRAME (w->frame)->face_change /* Make sure recorded data applies to current buffer, etc. */ @@ -17467,7 +17467,7 @@ redisplay_internal (void) if (is_tty_frame (f)) { /* Ignore all invisble tty frames, children or root. */ - if (!FRAME_VISIBLE_P (root_frame (f))) + if (!frame_redisplay_p (f)) continue; /* Remember tty root frames which we've seen. */ @@ -17498,7 +17498,7 @@ redisplay_internal (void) if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook) FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f); - if (FRAME_REDISPLAY_P (f)) + if (frame_redisplay_p (f)) { /* Don't allow freeing images and faces for this frame as long as the frame's update wasn't @@ -17524,7 +17524,7 @@ redisplay_internal (void) if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook) FRAME_TERMINAL (f)->judge_scroll_bars_hook (f); - if (FRAME_REDISPLAY_P (f)) + if (frame_redisplay_p (f)) { /* If fonts changed on visible frame, display again. */ if (f->fonts_changed) @@ -17630,7 +17630,7 @@ redisplay_internal (void) } } } - else if (FRAME_REDISPLAY_P (sf)) + else if (frame_redisplay_p (sf)) { sf->inhibit_clear_image_cache = true; displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents); @@ -17681,7 +17681,7 @@ redisplay_internal (void) unrequest_sigio (); STOP_POLLING; - if (FRAME_REDISPLAY_P (sf)) + if (frame_redisplay_p (sf)) { if (hscroll_retries <= MAX_HSCROLL_RETRIES && hscroll_windows (selected_window)) @@ -17763,7 +17763,7 @@ redisplay_internal (void) FOR_EACH_FRAME (tail, frame) { - if (FRAME_REDISPLAY_P (XFRAME (frame))) + if (frame_redisplay_p (XFRAME (frame))) new_count++; } @@ -34268,7 +34268,7 @@ display_and_set_cursor (struct window *w, bool on, windows and frames; in the latter case, the frame or window may be in the midst of changing its size, and x and y may be off the window. */ - if (! FRAME_REDISPLAY_P (f) + if (! frame_redisplay_p (f) || vpos >= w->current_matrix->nrows || hpos >= w->current_matrix->matrix_w) return; @@ -34436,7 +34436,7 @@ gui_update_cursor (struct frame *f, bool on_p) void gui_clear_cursor (struct window *w) { - if (FRAME_REDISPLAY_P (XFRAME (w->frame)) && w->phys_cursor_on_p) + if (frame_redisplay_p (XFRAME (w->frame)) && w->phys_cursor_on_p) update_window_cursor (w, false); } diff --git a/src/xterm.h b/src/xterm.h index 7c2fadbf094..57e37a1a8f5 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1494,7 +1494,7 @@ extern void x_mark_frame_dirty (struct frame *f); #define FRAME_X_VISUAL_INFO(f) (&FRAME_DISPLAY_INFO (f)->visual_info) /* Whether or not the frame is visible. Do not test this alone. - Instead, use FRAME_REDISPLAY_P. */ + Instead, use frame_redisplay_p. */ #define FRAME_X_VISIBLE(f) (FRAME_X_OUTPUT (f)->visibility_state \ != VisibilityFullyObscured) commit 317a5015f8a561317da829f3430829a3ef8a4d13 Author: Stefan Kangas Date: Mon Feb 10 01:31:30 2025 +0100 ; * .mailmap: Add a few more entries. diff --git a/.mailmap b/.mailmap index 83e94049272..f1caf77cbc0 100644 --- a/.mailmap +++ b/.mailmap @@ -22,6 +22,9 @@ Andrea Corallo Andrea Corallo Andrea Corallo Andrea Corallo +Andrea Corallo +Andrea Corallo +Andrea Corallo Andrew G Cohen Andrew G Cohen Arash Esbati @@ -79,14 +82,17 @@ Gnus developers Gregory Heytings Grégoire Jadi Ian Dunn +Ignacio Casso Jan Djärv Jan Djärv +Jan Synáček Jason Rumney Jeff Walsh Jeff Walsh Jeff Walsh Jens Lechtenbörger Jim Blandy +Jim Meyering U. Ser Jimmy Aguilar Mena Joakim Verona Joakim Verona @@ -151,6 +157,7 @@ Philip Kaludercic Philip Kaludercic Philip Kaludercic Philipp Stephani +Philipp Stephani Phillip Lord Pierre Lorenzon Pieter van Oostrum @@ -158,8 +165,9 @@ Pip Cet Po Lu Po Lu Po Lu via Przemysław Wojnowski -Rasmus +Rasmus Pank Roulund Richard M. Stallman +Robert Brown Robert J. Chassell Robert Weiner Roland Winkler commit f599860b50ecd288144987ff9de40ca3b40a417b Author: Stefan Kangas Date: Sun Feb 9 16:26:48 2025 +0100 ; * .mailmap: Add Felicián Németh. diff --git a/.mailmap b/.mailmap index bbfe4bceba1..83e94049272 100644 --- a/.mailmap +++ b/.mailmap @@ -67,6 +67,7 @@ Eric S. Raymond Etienne Prud’homme Fabián Ezequiel Gallina Fabián Ezequiel Gallina +Felicián Németh Francis Litterio Gabor Vida Gerd Möllmann commit 798ce492d51d16204a28820eb0c8d61fdc8a49e7 Author: Eli Zaretskii Date: Sun Feb 9 09:17:31 2025 +0200 ; * etc/PROBLEMS: Fix last change (bug#74220). diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 366c9e4140c..1f44c38ee3a 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -2815,7 +2815,7 @@ set the 'visible-cursor' variable to nil in your ~/.emacs: Still other way is to change the "cvvis" capability to send the "\E[?25h\E[?0c" command. -*** GNU/Linux: GPM mouse does not display but still otherwise works. +*** GNU/Linux: GPM mouse does not display pointer, but otherwise works. This happens on Linux kernel versions from 6.7 to 6.13. On these versions, the Linux kernel does not allow programs to draw the mouse @@ -2825,7 +2825,7 @@ programs such as your shell and many ncurses based programs, but not for Emacs. To solve this, you need to change your kernel to a version with this bug -fixed, such as 6.14. See associated Linux kernel fix: +fixed, such as 6.14 or later. See associated Linux kernel fix: https://lore.kernel.org/regressions/20250110142122.1013222-1-gnoack@google.com/ ** FreeBSD commit d78a4c0f4cb534dd5b1dc8cfe91f34b6d2c996d3 Author: Jared Finder Date: Sat Feb 8 19:08:05 2025 -0800 ; * etc/PROBLEMS: Document problem with GPM mouse display (bug#74220). diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 49e9248c688..366c9e4140c 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -2815,6 +2815,19 @@ set the 'visible-cursor' variable to nil in your ~/.emacs: Still other way is to change the "cvvis" capability to send the "\E[?25h\E[?0c" command. +*** GNU/Linux: GPM mouse does not display but still otherwise works. + +This happens on Linux kernel versions from 6.7 to 6.13. On these +versions, the Linux kernel does not allow programs to draw the mouse +pointer unless they have superuser permissions. The GPM daemon +normally has such permissions and it draws the mouse pointer for other +programs such as your shell and many ncurses based programs, but not +for Emacs. + +To solve this, you need to change your kernel to a version with this bug +fixed, such as 6.14. See associated Linux kernel fix: +https://lore.kernel.org/regressions/20250110142122.1013222-1-gnoack@google.com/ + ** FreeBSD *** FreeBSD: Getting a Meta key on the console.