commit 92ed2fe6886a367f00cf04a11d39b4fbf7a44edc (HEAD, refs/remotes/origin/master) Merge: aab2477516 7078f32b5b Author: Stefan Kangas Date: Wed Dec 15 06:30:41 2021 +0100 Merge from origin/emacs-28 7078f32b5b Fix crash when dumping charset_table with portable dumper ... a4fcbf46a7 ; etc/NEWS: Move the note about Xref EIEIO change to the p... f88c1d222f Remove maintainer comment from Emacs 28 module snippet. # Conflicts: # etc/NEWS commit 7078f32b5befd90c1f1956a319f4c847b6961f48 (refs/remotes/origin/emacs-28) Author: YAMAMOTO Mitsuharu Date: Wed Dec 15 13:12:02 2021 +0900 Fix crash when dumping charset_table with portable dumper (Bug#52461) * src/charset.h: * src/charset.c (charset_table_used): Now extern. * src/pdumper.c (dump_charset): Don't dump code_space_mask for unused slots of charset_table. diff --git a/src/charset.c b/src/charset.c index 7cd0fa78f0..670fd48a2d 100644 --- a/src/charset.c +++ b/src/charset.c @@ -63,7 +63,7 @@ Lisp_Object Vcharset_hash_table; /* Table of struct charset. */ struct charset *charset_table; int charset_table_size; -static int charset_table_used; +int charset_table_used; /* Special charsets corresponding to symbols. */ int charset_ascii; diff --git a/src/charset.h b/src/charset.h index 97122d82a6..8c538234d8 100644 --- a/src/charset.h +++ b/src/charset.h @@ -249,6 +249,7 @@ extern Lisp_Object Vcharset_hash_table; /* Table of struct charset. */ extern struct charset *charset_table; extern int charset_table_size; +extern int charset_table_used; #define CHARSET_FROM_ID(id) (charset_table + (id)) diff --git a/src/pdumper.c b/src/pdumper.c index 98c760162e..2782648e7a 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -3174,7 +3174,7 @@ dump_charset (struct dump_context *ctx, int cs_i) DUMP_FIELD_COPY (&out, cs, hash_index); DUMP_FIELD_COPY (&out, cs, dimension); memcpy (out.code_space, &cs->code_space, sizeof (cs->code_space)); - if (cs->code_space_mask) + if (cs_i < charset_table_used && cs->code_space_mask) dump_field_fixup_later (ctx, &out, cs, &cs->code_space_mask); DUMP_FIELD_COPY (&out, cs, code_linear_p); DUMP_FIELD_COPY (&out, cs, iso_chars_96); @@ -3195,7 +3195,7 @@ dump_charset (struct dump_context *ctx, int cs_i) memcpy (out.fast_map, &cs->fast_map, sizeof (cs->fast_map)); DUMP_FIELD_COPY (&out, cs, code_offset); dump_off offset = dump_object_finish (ctx, &out, sizeof (out)); - if (cs->code_space_mask) + if (cs_i < charset_table_used && cs->code_space_mask) dump_remember_cold_op (ctx, COLD_OP_CHARSET, Fcons (dump_off_to_lisp (cs_i), dump_off_to_lisp (offset))); commit aab247751663641cc5ba5912cde7fe78e7be4d42 Author: Po Lu Date: Wed Dec 15 10:34:51 2021 +0800 Prevent GDK from handling emulated button events * src/xterm.c (handle_one_xevent): Drop emulated button events. diff --git a/src/xterm.c b/src/xterm.c index 1f377f838b..646985bdc2 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -10234,7 +10234,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, && xev->detail >= 4 && xev->detail <= 8 && xev->flags & XIPointerEmulated) - goto XI_OTHER; + { + *finish = X_EVENT_DROP; + goto XI_OTHER; + } #endif device = xi_device_from_id (dpyinfo, xev->deviceid); commit 861eee42418f510679a6e3ae1ee433353194cb68 Author: Po Lu Date: Wed Dec 15 10:27:27 2021 +0800 Work around pixel scrolling issues when line numbers are displayed * lisp/pixel-scroll.el (pixel-point-and-height-at-unseen-line): Compare start position against line number display width instead. diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el index 142ebf9c65..fa0185b16e 100644 --- a/lisp/pixel-scroll.el +++ b/lisp/pixel-scroll.el @@ -417,7 +417,8 @@ window, and the pixel height of that line." (set-window-start nil pos0 t) (set-window-vscroll nil vscroll0 t) (when (and line-height - (> (car (posn-x-y (posn-at-point pos0))) 0)) + (> (car (posn-x-y (posn-at-point pos0))) + (line-number-display-width t))) (setq line-height (- line-height (save-excursion (goto-char pos0) commit a4fcbf46a7bb71c39b22e4f6a865939ee8721d83 Author: Dmitry Gutov Date: Wed Dec 15 04:05:11 2021 +0300 ; etc/NEWS: Move the note about Xref EIEIO change to the proper section diff --git a/etc/NEWS b/etc/NEWS index d2565e50e1..e7d7215902 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1011,20 +1011,6 @@ file: (add-hook 'foo-mode-hook (lambda () (auto-fill-mode -1)) -** Xref migrated from EIEIO to cl-defstruct for its core objects. -This means that 'oref' and 'with-slots' no longer works on them, and -'make-instance' can no longer be used to create those instances (which -wasn't recommended anyway). Packages should restrict themselves to -using functions like 'xref-make', 'xref-make-match', -'xref-make-*-location', as well as accessor functions -'xref-item-summary' and 'xref-item-location'. - -Among the benefits are better performance (noticeable when there are a -lot of matches) and improved flexibility: 'xref-match-item' instances -do not require that 'location' inherits from 'xref-location' anymore -(that class was removed), so packages can create new location types to -use with "match items" without adding EIEIO as a dependency. - * Editing Changes in Emacs 28.1 @@ -3724,6 +3710,20 @@ user option has been renamed to 'find-library-source-path', and --- ** The macro 'vc-call' no longer evaluates its second argument twice. +** Xref migrated from EIEIO to cl-defstruct for its core objects. +This means that 'oref' and 'with-slots' no longer works on them, and +'make-instance' can no longer be used to create those instances (which +wasn't recommended anyway). Packages should restrict themselves to +using functions like 'xref-make', 'xref-make-match', +'xref-make-*-location', as well as accessor functions +'xref-item-summary' and 'xref-item-location'. + +Among the benefits are better performance (noticeable when there are a +lot of matches) and improved flexibility: 'xref-match-item' instances +do not require that 'location' inherits from 'xref-location' anymore +(that class was removed), so packages can create new location types to +use with "match items" without adding EIEIO as a dependency. + * Lisp Changes in Emacs 28.1 commit ad768d767bd7725bf8e5489cec546c83f19d79ea Author: Dmitry Gutov Date: Wed Dec 15 02:58:45 2021 +0300 project-kill-buffers-display-buffer-list: Fix :package-version value * lisp/progmodes/project.el (project-kill-buffers-display-buffer-list): Fix :package-version value. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 28c1e47e6e..8fecdbb61c 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1218,7 +1218,7 @@ Used by `project-kill-buffers'." :type 'boolean :version "29.1" :group 'project - :package-version '(project . "0.8.1") + :package-version '(project . "0.8.2") :safe #'booleanp) (defun project--buffer-list (pr) commit 38977b6134e7c57788ca92a31362d536d4c7687a Author: Dmitry Gutov Date: Wed Dec 15 02:57:20 2021 +0300 Add 'comint-mode' and 'change-log-mode' to project-kill-buffer-conditions * lisp/progmodes/project.el (project-kill-buffer-conditions): Add 'comint-mode' and 'change-log-mode' to the list (bug#52465). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index c2e125a017..28c1e47e6e 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1173,7 +1173,9 @@ displayed." (not (major-mode . help-mode))) (derived-mode . compilation-mode) (derived-mode . dired-mode) - (derived-mode . diff-mode)) + (derived-mode . diff-mode) + (derived-mode . comint-mode) + (derived-mode . change-log-mode)) "List of conditions to kill buffers related to a project. This list is used by `project-kill-buffers'. Each condition is either: @@ -1206,9 +1208,9 @@ current project, it will be killed." (const and) sexp) (cons :tag "Disjunction" (const or) sexp))) - :version "28.1" + :version "29.1" :group 'project - :package-version '(project . "0.6.0")) + :package-version '(project . "0.8.2")) (defcustom project-kill-buffers-display-buffer-list nil "Non-nil to display list of buffers to kill before killing project buffers. commit 0cc2c2dcdbe34869f47a0f591321024d35507965 Author: Stefan Monnier Date: Tue Dec 14 17:01:34 2021 -0500 eieio-compat.el: Move to lisp/obsolete The file only contains obsolete definitions, so it really belongs in `lisp/obsolete`. Moving it there will also signal a warning for those people who run old `.elc` files using EIEIO and generated with Emacs<25 and who otherwise might not know about the obsolescence of some of the functions they use. * lisp/emacs-lisp/eieio-compat.el: Move to ... * lisp/obsolete/eieio-compat.el: ... here. diff --git a/lisp/emacs-lisp/eieio-compat.el b/lisp/emacs-lisp/eieio-compat.el index 60b0638c63..a5f3750009 100644 --- a/lisp/emacs-lisp/eieio-compat.el +++ b/lisp/emacs-lisp/eieio-compat.el @@ -5,6 +5,7 @@ ;; Author: Eric M. Ludlam ;; Keywords: OO, lisp ;; Package: eieio +;; Obsolete-Since: 25.1 ;; This file is part of GNU Emacs. diff --git a/lisp/obsolete/eieio-compat.el b/lisp/obsolete/eieio-compat.el new file mode 100644 index 0000000000..60b0638c63 --- /dev/null +++ b/lisp/obsolete/eieio-compat.el @@ -0,0 +1,277 @@ +;;; eieio-compat.el --- Compatibility with Older EIEIO versions -*- lexical-binding:t -*- + +;; Copyright (C) 1995-1996, 1998-2021 Free Software Foundation, Inc. + +;; Author: Eric M. Ludlam +;; Keywords: OO, lisp +;; Package: eieio + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Backward compatibility definition of old EIEIO functions in +;; terms of newer equivalent. + +;; The main elements are the old EIEIO `defmethod' and `defgeneric' which are +;; now implemented on top of cl-generic. The differences we have to +;; accommodate are: +;; - EIEIO's :static methods (turned into a new `eieio--static' specializer). +;; - EIEIO's support for `call-next-method' and `next-method-p' instead of +;; `cl-next-method-p' and `cl-call-next-method' (simple matter of renaming). +;; - Different errors are signaled. +;; - EIEIO's defgeneric does not reset the function. +;; - EIEIO's no-next-method and no-applicable-method can't be aliases of +;; cl-generic's namesakes since they have different calling conventions, +;; which means that packages that (defmethod no-next-method ..) don't work. +;; - EIEIO's `call-next-method' and `next-method-p' had dynamic scope whereas +;; cl-generic's `cl-next-method-p' and `cl-call-next-method' are lexically +;; scoped. + +;;; Code: + +(require 'eieio-core) +(require 'cl-generic) + +(put 'eieio--defalias 'byte-hunk-handler + #'byte-compile-file-form-defalias) ;;(get 'defalias 'byte-hunk-handler) +;;;###autoload +(defun eieio--defalias (name body) + "Like `defalias', but with less side-effects. +More specifically, it has no side-effects at all when the new function +definition is the same (`eq') as the old one." + (cl-assert (not (symbolp body))) + (while (and (fboundp name) (symbolp (symbol-function name))) + ;; Follow aliases, so methods applied to obsolete aliases still work. + (setq name (symbol-function name))) + (unless (and (fboundp name) + (eq (symbol-function name) body)) + (defalias name body))) + +;;;###autoload +(defmacro defgeneric (method args &optional doc-string) + "Create a generic function METHOD. +DOC-STRING is the base documentation for this class. A generic +function has no body, as its purpose is to decide which method body +is appropriate to use. Uses `defmethod' to create methods, and calls +`defgeneric' for you. With this implementation the ARGS are +currently ignored. You can use `defgeneric' to apply specialized +top level documentation to a method." + (declare (doc-string 3) (obsolete cl-defgeneric "25.1") + (indent defun)) + `(eieio--defalias ',method + (eieio--defgeneric-init-form + ',method + ,(if doc-string (help-add-fundoc-usage doc-string args))))) + +;;;###autoload +(defmacro defmethod (method &rest args) + "Create a new METHOD through `defgeneric' with ARGS. + +The optional second argument KEY is a specifier that +modifies how the method is called, including: + :before - Method will be called before the :primary + :primary - The default if not specified + :after - Method will be called after the :primary + :static - First arg could be an object or class +The next argument is the ARGLIST. The ARGLIST specifies the arguments +to the method as with `defun'. The first argument can have a type +specifier, such as: + ((VARNAME CLASS) ARG2 ...) +where VARNAME is the name of the local variable for the method being +created. The CLASS is a class symbol for a class made with `defclass'. +A DOCSTRING comes after the ARGLIST, and is optional. +All the rest of the args are the BODY of the method. A method will +return the value of the last form in the BODY. + +Summary: + + (defmethod mymethod [:before | :primary | :after | :static] + ((typearg class-name) arg2 &optional opt &rest rest) + \"doc-string\" + body)" + (declare (doc-string 3) (obsolete cl-defmethod "25.1") + (indent defun) + (debug + (&define ; this means we are defining something + [&name sexp] ;Allow (setf ...) additionally to symbols. + ;; ^^ This is the methods symbol + [ &optional symbolp ] ; this is key :before etc + cl-generic-method-args ; arguments + [ &optional stringp ] ; documentation string + def-body ; part to be debugged + ))) + (let* ((key (if (keywordp (car args)) (pop args))) + (params (car args)) + (arg1 (car params)) + (fargs (if (consp arg1) + (cons (car arg1) (cdr params)) + params)) + (class (if (consp arg1) (nth 1 arg1))) + (code `(lambda ,fargs ,@(cdr args)))) + `(progn + ;; Make sure there is a generic and the byte-compiler sees it. + (defgeneric ,method ,args) + (eieio--defmethod ',method ',key ',class #',code)))) + +(defun eieio--generic-static-symbol-specializers (tag &rest _) + (cl-assert (or (null tag) (eieio--class-p tag))) + (when (eieio--class-p tag) + (let ((superclasses (eieio--generic-subclass-specializers tag)) + (specializers ())) + (dolist (superclass superclasses) + (push superclass specializers) + (push `(eieio--static ,(cadr superclass)) specializers)) + (nreverse specializers)))) + +(cl-generic-define-generalizer eieio--generic-static-symbol-generalizer + ;; Give it a slightly higher priority than `subclass' so that the + ;; interleaved list comes before subclass's non-interleaved list. + 61 (lambda (name &rest _) `(and (symbolp ,name) (cl--find-class ,name))) + #'eieio--generic-static-symbol-specializers) +(cl-generic-define-generalizer eieio--generic-static-object-generalizer + ;; Give it a slightly higher priority than `class' so that the + ;; interleaved list comes before the class's non-interleaved list. + 51 #'cl--generic-struct-tag + (lambda (tag &rest _) + (and (symbolp tag) (setq tag (cl--find-class tag)) + (eieio--class-p tag) + (let ((superclasses (eieio--class-precedence-list tag)) + (specializers ())) + (dolist (superclass superclasses) + (setq superclass (eieio--class-name superclass)) + (push superclass specializers) + (push `(eieio--static ,superclass) specializers)) + (nreverse specializers))))) + +(cl-defmethod cl-generic-generalizers ((_specializer (head eieio--static))) + (list eieio--generic-static-symbol-generalizer + eieio--generic-static-object-generalizer)) + +;;;###autoload +(defun eieio--defgeneric-init-form (method doc-string) + (if doc-string (put method 'function-documentation doc-string)) + (if (memq method '(no-next-method no-applicable-method)) + (symbol-function method) + (let ((generic (cl-generic-ensure-function method))) + (or (symbol-function (cl--generic-name generic)) + (cl--generic-make-function generic))))) + +;;;###autoload +(defun eieio--defmethod (method kind argclass code) + (setq kind (intern (downcase (symbol-name kind)))) + (let* ((specializer (if (not (eq kind :static)) + (or argclass t) + (setq kind nil) + `(eieio--static ,argclass))) + (uses-cnm (not (memq kind '(:before :after)))) + (specializers `((arg ,specializer))) + (code + ;; Backward compatibility for `no-next-method' and + ;; `no-applicable-method', which have slightly different calling + ;; convention than their cl-generic counterpart. + (pcase method + ('no-next-method + (setq method 'cl-no-next-method) + (setq specializers `(generic method ,@specializers)) + (lambda (_generic _method &rest args) (apply code args))) + ('no-applicable-method + (setq method 'cl-no-applicable-method) + (setq specializers `(generic ,@specializers)) + (lambda (generic arg &rest args) + (apply code arg (cl--generic-name generic) (cons arg args)))) + (_ code)))) + (cl-generic-define-method + method (unless (memq kind '(nil :primary)) (list kind)) + specializers uses-cnm + (if uses-cnm + (let* ((docstring (documentation code 'raw)) + (args (help-function-arglist code 'preserve-names)) + (doc-only (if docstring + (let ((split (help-split-fundoc docstring nil))) + (if split (cdr split) docstring))))) + (lambda (cnm &rest args) + (:documentation + (help-add-fundoc-usage doc-only (cons 'cl-cnm args))) + (cl-letf (((symbol-function 'call-next-method) cnm) + ((symbol-function 'next-method-p) + (lambda () (cl--generic-isnot-nnm-p cnm)))) + (apply code args)))) + code)) + ;; The old EIEIO code did not signal an error when there are methods + ;; applicable but only of the before/after kind. So if we add a :before + ;; or :after, make sure there's a matching dummy primary. + (when (and (memq kind '(:before :after)) + ;; FIXME: Use `cl-find-method'? + (not (cl-find-method method () + (mapcar (lambda (arg) + (if (consp arg) (nth 1 arg) t)) + specializers)))) + (cl-generic-define-method method () specializers t + (lambda (cnm &rest args) + (if (cl--generic-isnot-nnm-p cnm) + (apply cnm args))))) + method)) + +;; Compatibility with code which tries to catch `no-method-definition' errors. +(push 'no-method-definition (get 'cl-no-applicable-method 'error-conditions)) + +(defun generic-p (fname) (not (null (cl--generic fname)))) + +(defun no-next-method (&rest args) + (declare (obsolete cl-no-next-method "25.1")) + (apply #'cl-no-next-method 'unknown nil args)) + +(defun no-applicable-method (object method &rest args) + (declare (obsolete cl-no-applicable-method "25.1")) + (apply #'cl-no-applicable-method method object args)) + +(define-obsolete-function-alias 'call-next-method 'cl-call-next-method "25.1") +(defun next-method-p () + (declare (obsolete cl-next-method-p "25.1")) + ;; EIEIO's `next-method-p' just returned nil when called in an + ;; invalid context. + (message "next-method-p called outside of a primary or around method") + nil) + +;;;###autoload +(defun eieio-defmethod (method args) + "Obsolete work part of an old version of the `defmethod' macro." + (declare (obsolete cl-defmethod "24.1")) + (eval `(defmethod ,method ,@args)) + method) + +;;;###autoload +(defun eieio-defgeneric (method doc-string) + "Obsolete work part of an old version of the `defgeneric' macro." + (declare (obsolete cl-defgeneric "24.1")) + (eval `(defgeneric ,method (x) ,@(if doc-string `(,doc-string)))) + ;; Return the method + 'method) + +;;;###autoload +(defun eieio-defclass (cname superclasses slots options) + (declare (obsolete eieio-defclass-internal "25.1")) + (eval `(defclass ,cname ,superclasses ,slots ,@options))) + + +;; Local Variables: +;; generated-autoload-file: "eieio-loaddefs.el" +;; End: + +(provide 'eieio-compat) + +;;; eieio-compat.el ends here commit 75eac285af405ccd8f2cba89b1047992984a7b7d Author: Stefan Kangas Date: Tue Dec 14 20:19:32 2021 +0100 Prefer command remapping in allout.el * lisp/allout.el (allout-compose-and-institute-keymap): Use command remapping instead of substitute-key-definition. diff --git a/lisp/allout.el b/lisp/allout.el index 174184fc7a..f684751a2a 100644 --- a/lisp/allout.el +++ b/lisp/allout.el @@ -133,15 +133,10 @@ respective `allout-mode' keybinding variables, `allout-command-prefix', (when (boundp 'allout-unprefixed-keybindings) (dolist (entry allout-unprefixed-keybindings) (define-key map (car (read-from-string (car entry))) (cadr entry)))) - (substitute-key-definition #'beginning-of-line #'allout-beginning-of-line - map global-map) - (substitute-key-definition #'move-beginning-of-line - #'allout-beginning-of-line - map global-map) - (substitute-key-definition #'end-of-line #'allout-end-of-line - map global-map) - (substitute-key-definition #'move-end-of-line #'allout-end-of-line - map global-map) + (define-key map [remap beginning-of-line] #'allout-beginning-of-line) + (define-key map [remap move-beginning-of-line] #'allout-beginning-of-line) + (define-key map [remap end-of-line] #'allout-end-of-line) + (define-key map [remap move-end-of-line] #'allout-end-of-line) (allout-institute-keymap map))) ;;;_ > allout-institute-keymap (map) (defun allout-institute-keymap (map) commit 71ff4b97abebf8cf5e33bab32f1480a7d4263b30 Author: Lars Ingebrigtsen Date: Tue Dec 14 16:28:02 2021 +0100 Fix ert.texi error from previous change * doc/misc/ert.texi (Running Tests in Batch Mode): Fix @r command. diff --git a/doc/misc/ert.texi b/doc/misc/ert.texi index f47cb72efc..71c423ad9c 100644 --- a/doc/misc/ert.texi +++ b/doc/misc/ert.texi @@ -447,7 +447,7 @@ mode---only the names of the failed tests are listed. If the @env{EMACS_TEST_VERBOSE} environment variable is set, the failure summaries will also include the data from the failing test. -@vindex EMACS_TEST_JUNIT_REPORT{, environment variable} +@vindex EMACS_TEST_JUNIT_REPORT@r{, environment variable} ERT can produce JUnit test reports in batch mode. If the environment variable @env{EMACS_TEST_JUNIT_REPORT} is set, ERT will produce for every test package @file{my-tests.el} a corresponding JUnit test commit e07d69e2dc4375111f56029ffe396839d13ce5f0 Author: Stefan Kangas Date: Tue Dec 14 16:10:43 2021 +0100 * lisp/net/eudc.el (custom-menu-create): Remove unnecessary autoload. diff --git a/lisp/net/eudc.el b/lisp/net/eudc.el index 14e5c28b2d..62c2913b50 100644 --- a/lisp/net/eudc.el +++ b/lisp/net/eudc.el @@ -46,16 +46,9 @@ ;;; Code: (require 'wid-edit) - (require 'cl-lib) - -(unless (fboundp 'custom-menu-create) - (autoload 'custom-menu-create "cus-edit")) - (require 'eudc-vars) - - ;;{{{ Internal cooking ;;{{{ Internal variables and compatibility tricks commit 8704165197d987bc91bce336a73d23fc45669fa3 Author: Stefan Kangas Date: Tue Dec 14 12:35:57 2021 +0100 Remove Emacs 21 compat code for command-remapping * lisp/arc-mode.el (archive-mode-map): * lisp/obsolete/iswitchb.el (iswitchb-global-map): Remove Emacs 21 compat code. diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el index 5576ae3505..1fd1d66c36 100644 --- a/lisp/arc-mode.el +++ b/lisp/arc-mode.el @@ -431,12 +431,8 @@ be added." ;; Let mouse-1 follow the link. (define-key map [follow-link] 'mouse-face) - (if (fboundp 'command-remapping) - (progn - (define-key map [remap advertised-undo] 'archive-undo) - (define-key map [remap undo] 'archive-undo)) - (substitute-key-definition 'advertised-undo 'archive-undo map global-map) - (substitute-key-definition 'undo 'archive-undo map global-map)) + (define-key map [remap advertised-undo] #'archive-undo) + (define-key map [remap undo] #'archive-undo) (define-key map [mouse-2] 'archive-extract) diff --git a/lisp/obsolete/iswitchb.el b/lisp/obsolete/iswitchb.el index 807f5485d5..f1e4414e93 100644 --- a/lisp/obsolete/iswitchb.el +++ b/lisp/obsolete/iswitchb.el @@ -467,9 +467,7 @@ interfere with other minibuffer usage.") (switch-to-buffer-other-window . iswitchb-buffer-other-window) (switch-to-buffer-other-frame . iswitchb-buffer-other-frame) (display-buffer . iswitchb-display-buffer))) - (if (fboundp 'command-remapping) - (define-key map (vector 'remap (car b)) (cdr b)) - (substitute-key-definition (car b) (cdr b) map global-map))) + (define-key map (vector 'remap (car b)) (cdr b))) map) "Global keymap for `iswitchb-mode'.") commit 78a9d151b5c53ddcd1408e0ab38b1a53d58fad85 Author: Michael Albinus Date: Tue Dec 14 14:40:18 2021 +0100 Minor Tramp cleanup * lisp/net/tramp.el (tramp-get-buffer-string): Simplify. (tramp-lock-pid): Fix docstring. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 6b05dadc0e..940e25e04f 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1874,8 +1874,9 @@ version, the function does nothing." (defsubst tramp-get-buffer-string (&optional buffer) "Return contents of BUFFER. -If BUFFER is not a buffer, return the contents of `current-buffer'." - (with-current-buffer (if (bufferp buffer) buffer (current-buffer)) +If BUFFER is not a buffer or a buffer name, return the contents +of `current-buffer'." + (with-current-buffer (or buffer (current-buffer)) (substring-no-properties (buffer-string)))) (put #'tramp-get-buffer-string 'tramp-suppress-trace t) @@ -3964,7 +3965,7 @@ Return nil when there is no lockfile." (defvar tramp-lock-pid nil "A random nunber local for every connection. -Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'") +Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.") (defun tramp-get-lock-pid (file) "Determine pid for lockfile of FILE." @@ -3985,9 +3986,11 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'") "Like `file-locked-p' for Tramp files." (when-let ((info (tramp-get-lock-file file)) (match (string-match tramp-lock-file-info-regexp info))) - (or (and (string-equal (match-string 1 info) (user-login-name)) + (or ; Locked by me. + (and (string-equal (match-string 1 info) (user-login-name)) (string-equal (match-string 2 info) (system-name)) (string-equal (match-string 3 info) (tramp-get-lock-pid file))) + ; User name. (match-string 1 info)))) (defun tramp-handle-lock-file (file) commit 6a48ef0cbe01bec250734a383f46ab45721f50f5 Author: Michael Albinus Date: Tue Dec 14 14:39:53 2021 +0100 Explain JUnit test reports in ert doc * doc/misc/ert.texi (Running Tests in Batch Mode): Explain generation of JUnit test reports. diff --git a/doc/misc/ert.texi b/doc/misc/ert.texi index af215482f4..f47cb72efc 100644 --- a/doc/misc/ert.texi +++ b/doc/misc/ert.texi @@ -109,6 +109,7 @@ Appendix @end menu @end ifnottex + @node Introduction @chapter Introduction @cindex introduction to ERT @@ -123,7 +124,7 @@ commands to run them to verify whether the definitions that are currently loaded in Emacs pass the tests. Some Lisp files have comments like the following (adapted from the -package @code{pp.el}): +package @file{pp.el}): @lisp ;; (pp-to-string '(quote quote)) ; expected: "'quote" @@ -358,6 +359,7 @@ Prompt for a test and then show its documentation. @end table + @node Running Tests in Batch Mode @section Running Tests in Batch Mode @cindex running tests in batch mode @@ -375,7 +377,7 @@ emacs -batch -l ert -l my-tests.el -f ert-run-tests-batch-and-exit @end example This command will start up Emacs in batch mode, load ERT, load -@code{my-tests.el}, and run all tests defined in it. It will exit +@file{my-tests.el}, and run all tests defined in it. It will exit with a zero exit status if all tests passed, or nonzero if any tests failed or if anything else went wrong. It will also print progress messages and error diagnostics to standard output. @@ -439,10 +441,21 @@ emacs -batch -l ert -l my-tests.el \ -eval '(ert-run-tests-batch-and-exit "to-match")' @end example +@vindex EMACS_TEST_VERBOSE@r{, environment variable} By default, ERT test failure summaries are quite brief in batch mode---only the names of the failed tests are listed. If the -EMACS_TEST_VERBOSE environment variable is set, the failure summaries -will also include the data from the failing test. +@env{EMACS_TEST_VERBOSE} environment variable is set, the failure +summaries will also include the data from the failing test. + +@vindex EMACS_TEST_JUNIT_REPORT{, environment variable} +ERT can produce JUnit test reports in batch mode. If the environment +variable @env{EMACS_TEST_JUNIT_REPORT} is set, ERT will produce for +every test package @file{my-tests.el} a corresponding JUnit test +report @file{my-tests.xml}. The function +@code{ert-summarize-tests-batch-and-exit} collects all these package +test reports into a new JUnit test report, with the respective name of +that environment variable. + @node Test Selectors @section Test Selectors @@ -514,6 +527,7 @@ to find where a test was defined if the test was loaded from a file. * erts files:: Files containing many buffer tests. @end menu + @node The @code{should} Macro @section The @code{should} Macro @@ -793,6 +807,7 @@ code is to restructure the code slightly to provide better interfaces for testing. Usually, this makes the interfaces easier to use as well. + @node erts files @section erts files @@ -907,6 +922,7 @@ non-@code{nil} value, the test will be skipped. If you need to use the literal line single line @samp{=-=} in a test section, you can quote it with a @samp{\} character. + @node How to Debug Tests @chapter How to Debug Tests @@ -1108,6 +1124,7 @@ For information on mocks, stubs, fixtures, or test suites, see below. * Fixtures and Test Suites:: How ERT differs from tools for other languages. @end menu + @node Mocks and Stubs @section Other Tools for Emacs Lisp @cindex mocks and stubs @@ -1182,11 +1199,13 @@ e.g., to run quick tests during interactive development and slow tests less often. This can be achieved with the @code{:tag} argument to @code{ert-deftest} and @code{tag} test selectors. + @node Index @unnumbered Index @printindex cp + @node GNU Free Documentation License @appendix GNU Free Documentation License @include doclicense.texi commit 1d67bbf6c9e957c12f09c17345aa95e4ebd08417 Author: Stefan Kangas Date: Tue Dec 14 12:27:57 2021 +0100 Use defvar-keymap in elisp-mode.el * lisp/progmodes/elisp-mode.el (emacs-lisp-mode-map) (elisp--dynlex-modeline-map, lisp-interaction-mode-map): Use defvar-keymap. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 7da93a351a..efb5df8ebf 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -45,15 +45,13 @@ It has `lisp-mode-abbrev-table' as its parent." table) "Syntax table used in `emacs-lisp-mode'.") -(defvar emacs-lisp-mode-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map lisp-mode-shared-map) - (define-key map "\e\t" 'completion-at-point) - (define-key map "\e\C-x" 'eval-defun) - (define-key map "\e\C-q" 'indent-pp-sexp) - map) - "Keymap for Emacs Lisp mode. -All commands in `lisp-mode-shared-map' are inherited by this map.") +(defvar-keymap emacs-lisp-mode-map + :doc "Keymap for Emacs Lisp mode. +All commands in `lisp-mode-shared-map' are inherited by this map." + :parent lisp-mode-shared-map + "M-TAB" #'completion-at-point + "C-M-x" #'eval-defun + "C-M-q" #'indent-pp-sexp) (easy-menu-define emacs-lisp-mode-menu emacs-lisp-mode-map "Menu for Emacs Lisp mode." @@ -270,10 +268,8 @@ Comments in the form will be lost." (setq-local lexical-binding t) (add-file-local-variable-prop-line 'lexical-binding t interactive)))) -(defvar elisp--dynlex-modeline-map - (let ((map (make-sparse-keymap))) - (define-key map [mode-line mouse-1] 'elisp-enable-lexical-binding) - map)) +(defvar-keymap elisp--dynlex-modeline-map + " " #'elisp-enable-lexical-binding) ;;;###autoload (define-derived-mode emacs-lisp-mode lisp-data-mode @@ -1200,16 +1196,14 @@ namespace but with lower confidence." ;;; Elisp Interaction mode -(defvar lisp-interaction-mode-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map lisp-mode-shared-map) - (define-key map "\e\C-x" 'eval-defun) - (define-key map "\e\C-q" 'indent-pp-sexp) - (define-key map "\e\t" 'completion-at-point) - (define-key map "\n" 'eval-print-last-sexp) - map) - "Keymap for Lisp Interaction mode. -All commands in `lisp-mode-shared-map' are inherited by this map.") +(defvar-keymap lisp-interaction-mode-map + :doc "Keymap for Lisp Interaction mode. +All commands in `lisp-mode-shared-map' are inherited by this map." + :parent lisp-mode-shared-map + "C-M-x" #'eval-defun + "C-M-q" #'indent-pp-sexp + "M-TAB" #'completion-at-point + "C-j" #'eval-print-last-sexp) (easy-menu-define lisp-interaction-mode-menu lisp-interaction-mode-map "Menu for Lisp Interaction mode." commit b86ab359725fcab09215512709d2b3b06bea9bd8 Author: Stefan Kangas Date: Tue Dec 14 04:41:45 2021 +0100 Prefer command remapping in cperl-mode.el * lisp/progmodes/cperl-mode.el (cperl-mode-map): Use command remapping instead of substitute-key-definition. diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index a23505a9d3..fe9612a09a 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -1019,15 +1019,9 @@ Unless KEEP, removes the old indentation." (define-key map [(control ?c) (control ?h) ?v] ;;(concat (char-to-string help-char) "v") ; does not work 'cperl-get-help)) - (substitute-key-definition - 'indent-sexp 'cperl-indent-exp - map global-map) - (substitute-key-definition - 'indent-region 'cperl-indent-region - map global-map) - (substitute-key-definition - 'indent-for-comment 'cperl-indent-for-comment - map global-map) + (define-key map [remap indent-sexp] #'cperl-indent-exp) + (define-key map [remap indent-region] #'cperl-indent-region) + (define-key map [remap indent-for-comment] #'cperl-indent-for-comment) map) "Keymap used in CPerl mode.") commit f88c1d222f17d3483bf6f387dc41be4366a047ab Author: Philipp Stephani Date: Tue Dec 14 11:17:37 2021 +0100 Remove maintainer comment from Emacs 28 module snippet. This is the same as 44c13eefe8d30841000a96d82f467fb8d222e365 on master. We should also remove this comment on the release branch, otherwise it ends up in the emacs-module.h shipped to users. * src/module-env-28.h: Remove maintainer comment. diff --git a/src/module-env-28.h b/src/module-env-28.h index f8820b0606..bea80a5553 100644 --- a/src/module-env-28.h +++ b/src/module-env-28.h @@ -1,7 +1,3 @@ - /* Add module environment functions newly added in Emacs 28 here. - Before Emacs 28 is released, remove this comment and start - module-env-29.h on the master branch. */ - void (*(*EMACS_ATTRIBUTE_NONNULL (1) get_function_finalizer) (emacs_env *env, emacs_value arg)) (void *) EMACS_NOEXCEPT; commit 8c0f9be0d1ace6437d4c604b9af79b7b0006dec4 Author: Lars Ingebrigtsen Date: Tue Dec 14 09:29:06 2021 +0100 Only allow SQLite extensions from an allowlist * src/sqlite.c (Fsqlite_load_extension): Only allow extensions from an allowlist. diff --git a/src/sqlite.c b/src/sqlite.c index 248ad478d5..428b84b21e 100644 --- a/src/sqlite.c +++ b/src/sqlite.c @@ -591,16 +591,42 @@ DEFUN ("sqlite-load-extension", Fsqlite_load_extension, doc: /* Load an SQlite MODULE into DB. MODULE should be the name of an SQlite module's file, a shared library in the system-dependent format and having a -system-dependent file-name extension. */) +system-dependent file-name extension. + +Only modules on Emacs' list of allowed modules can be loaded. */) (Lisp_Object db, Lisp_Object module) { check_sqlite (db, false); CHECK_STRING (module); - Lisp_Object module_encoded = ENCODE_FILE (Fexpand_file_name (module, Qnil)); - sqlite3 *sdb = XSQLITE (db)->db; - int result = sqlite3_load_extension (sdb, SSDATA (module_encoded), - NULL, NULL); + /* Add names of useful and free modules here. */ + const char *allowlist[3] = { "pcre", "csvtable", NULL }; + char *name = SSDATA (Ffile_name_nondirectory (module)); + /* Possibly skip past a common prefix. */ + const char *prefix = "libsqlite3_mod_"; + if (!strncmp (name, prefix, strlen (prefix))) + name += strlen (prefix); + + bool do_allow = false; + for (const char **allow = allowlist; *allow; allow++) + { + if (strlen (*allow) < strlen (name) + && !strncmp (*allow, name, strlen (*allow)) + && (!strcmp (name + strlen (*allow), ".so") + || !strcmp (name + strlen (*allow), ".DLL"))) + { + do_allow = true; + break; + } + } + + if (!do_allow) + xsignal (Qerror, build_string ("Module name not on allowlist")); + + int result = sqlite3_load_extension + (XSQLITE (db)->db, + SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil))), + NULL, NULL); if (result == SQLITE_OK) return Qt; return Qnil; diff --git a/test/src/sqlite-tests.el b/test/src/sqlite-tests.el index 6a88f0fd6c..d1076e481c 100644 --- a/test/src/sqlite-tests.el +++ b/test/src/sqlite-tests.el @@ -182,4 +182,36 @@ (sqlite-close db) (should-error (sqlite-select db "select * from test6")))) +(ert-deftest sqlite-load-extension () + (skip-unless (sqlite-available-p)) + (let (db) + (setq db (sqlite-open)) + (should-error + (sqlite-load-extension db "/usr/lib/sqlite3/notpcre.so")) + (should-error + (sqlite-load-extension db "/usr/lib/sqlite3/n")) + (should-error + (sqlite-load-extension db "/usr/lib/sqlite3/")) + (should-error + (sqlite-load-extension db "/usr/lib/sqlite3")) + (should + (memq + (sqlite-load-extension db "/usr/lib/sqlite3/pcre.so") + '(nil t))) + + (should-error + (sqlite-load-extension + db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_notcsvtable.so")) + (should-error + (sqlite-load-extension + db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtablen.so")) + (should-error + (sqlite-load-extension + db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable")) + (should + (memq + (sqlite-load-extension + db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so") + '(nil t))))) + ;;; sqlite-tests.el ends here