emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

scratch/icomplete-lazy-highlight-attempt-2 704855a 3/4: Merge branch 'ma


From: João Távora
Subject: scratch/icomplete-lazy-highlight-attempt-2 704855a 3/4: Merge branch 'master' into scratch/icomplete-lazy-highlight-attempt-2
Date: Mon, 16 Aug 2021 05:57:01 -0400 (EDT)

branch: scratch/icomplete-lazy-highlight-attempt-2
commit 704855af17a307077243572a41a9df9343b04ced
Merge: 4fa1935 ab23fa4
Author: João Távora <joaotavora@gmail.com>
Commit: João Távora <joaotavora@gmail.com>

    Merge branch 'master' into scratch/icomplete-lazy-highlight-attempt-2
---
 doc/lispref/modes.texi                      | 10 ++++-
 doc/lispref/sequences.texi                  | 17 ++++++++
 etc/NEWS                                    | 35 ++++++++++++----
 lisp/cus-theme.el                           |  2 +-
 lisp/emacs-lisp/easymenu.el                 | 14 +++----
 lisp/emacs-lisp/lisp-mnt.el                 | 18 +++-----
 lisp/emacs-lisp/map.el                      | 60 ++++++++++++++++----------
 lisp/emacs-lisp/memory-report.el            |  5 +--
 lisp/emacs-lisp/seq.el                      |  8 ++++
 lisp/emacs-lisp/shortdoc.el                 | 11 ++---
 lisp/emacs-lisp/subr-x.el                   |  1 +
 lisp/font-lock.el                           | 14 ++++++-
 lisp/mail/mail-extr.el                      |  5 ++-
 lisp/mail/mail-parse.el                     | 39 +++++++++++++++++
 lisp/minibuffer.el                          | 54 ++++++++++++++----------
 lisp/progmodes/cc-engine.el                 | 62 ++++++++++++++++++---------
 lisp/progmodes/python.el                    |  3 +-
 lisp/simple.el                              | 29 +++++++++----
 lisp/vc/diff-mode.el                        | 10 ++---
 lisp/vc/vc-git.el                           | 65 ++++++++++++++++-------------
 src/alloc.c                                 |  4 +-
 src/w32.c                                   |  9 +++-
 src/xdisp.c                                 | 17 +++++---
 test/lisp/autorevert-tests.el               |  2 +-
 test/lisp/emacs-lisp/map-tests.el           | 24 +++++++----
 test/lisp/emacs-lisp/memory-report-tests.el | 16 +++++++
 test/lisp/emacs-lisp/seq-tests.el           | 24 +++++++++++
 test/lisp/mail/mail-parse-tests.el          | 54 ++++++++++++++++++++++++
 test/lisp/net/netrc-resources/netrc-folding |  6 +++
 test/lisp/net/netrc-tests.el                |  7 ++++
 test/lisp/vc/diff-mode-tests.el             | 12 ++++++
 31 files changed, 470 insertions(+), 167 deletions(-)

diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index d48c9cc..4274810 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -3444,9 +3444,17 @@ for string constants.
 
 @item font-lock-doc-face
 @vindex font-lock-doc-face
-for documentation strings in the code.  This inherits, by default, from
+for documentation embedded in program code inside specially-formed
+comments or strings.  This face inherits, by default, from
 @code{font-lock-string-face}.
 
+@item font-lock-doc-markup-face
+@vindex font-lock-doc-markup-face
+for mark-up elements in text using @code{font-lock-doc-face}.
+It is typically used for the mark-up constructs in documentation embedded
+in program code, following conventions such as Haddock, Javadoc or Doxygen.
+This face inherits, by default, from @code{font-lock-constant-face}.
+
 @item font-lock-negation-char-face
 @vindex font-lock-negation-char-face
 for easily-overlooked negation characters.
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 545fd40..20816ce 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -1111,6 +1111,23 @@ The @code{pcase} patterns provide an alternative 
facility for
 destructuring binding, see @ref{Destructuring with pcase Patterns}.
 @end defmac
 
+@defmac seq-setq var-sequence val-sequence
+@cindex sequence destructuring
+  This macro works similarly to @code{seq-let}, except that values are
+assigned to variables as if by @code{setq} instead of as in a
+@code{let} binding.
+
+@example
+@group
+(let ((a nil)
+      (b nil))
+  (seq-setq (_ a _ b) '(1 2 3 4))
+  (list a b))
+@result{} (2 4)
+@end group
+@end example
+@end defmac
+
 @defun seq-random-elt sequence
   This function returns an element of @var{sequence} taken at random.
 
diff --git a/etc/NEWS b/etc/NEWS
index b40c2bd..09ace73 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -149,6 +149,15 @@ invoked with the '--declarations' command-line option.
 ** New command 'font-lock-update', bound to 'C-x x f'.
 This command updates the syntax highlighting in this buffer.
 
++++
+** A new standard face 'font-lock-doc-markup-face'.
+Intended for documentation mark-up syntax and tags inside text that
+uses 'font-lock-doc-face', with which it should harmonise.  It would
+typically be used in structured documentation comments in program
+source code by language-specific modes, for mark-up conventions like
+Haddock, Javadoc or Doxygen.  By default this face inherits from
+'font-lock-constant-face'.
+
 ** The new NonGNU ELPA archive is enabled by default alongside GNU ELPA.
 
 +++
@@ -952,12 +961,6 @@ keys, add the following to your init file:
 
 ** Change Logs and VC
 
-*** vc-git now sets the 'GIT_LITERAL_PATHSPECS' environment variable.
-This ensures that Git operations on files containing wildcard
-characters work as they're supposed to.  However, this also affects
-scripts running from Git hooks, and these have to "unset
-GIT_LITERAL_PATHSPECS" to work as before.
-
 *** More VC commands can be used from non-file buffers.
 The relevant commands are those that don't change the VC state.
 The non-file buffers which can use VC commands are those that have
@@ -1627,6 +1630,14 @@ This is a slightly deeper copy than the previous 
'copy-sequence'.
 ---
 *** The function 'map-contains-key' now supports plists.
 
+---
+*** More consistent duplicate key handling in 'map-merge-with'.
+Until now, 'map-merge-with' promised to call its function argument
+whenever multiple maps contained 'eql' keys.  However, this did not
+always coincide with the keys that were actually merged, which could
+be 'equal' instead.  The function argument is now called whenever keys
+are merged, for greater consistency with 'map-merge' and 'map-elt'.
+
 ** Package
 
 ---
@@ -2341,7 +2352,8 @@ a list.
 
 ---
 *** New face 'diff-changed-unspecified'.
-This is used when 'diff-use-changed-face' is non-nil.
+This is used to highlight "changed" lines (those marked with '!') in
+context diffs, when 'diff-use-changed-face' is non-nil.
 
 ---
 *** New 'diff-mode' font locking face 'diff-error'.
@@ -2426,6 +2438,15 @@ images are marked.
 ** Miscellaneous
 
 ---
+*** New function 'mail-header-parse-addresses-lax'.
+This takes a comma-separated string and returns a list of mail/name
+pairs.
+
+---
+*** New function 'mail-header-parse-address-lax'.
+Parse a string as a mail address-like string.
+
+---
 *** 'shell-script-mode' now supports 'outline-minor-mode'.
 The outline headings have lines that start with "###".
 
diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el
index f4885d0..7457d9e 100644
--- a/lisp/cus-theme.el
+++ b/lisp/cus-theme.el
@@ -66,7 +66,7 @@ Do not call this mode function yourself.  It is meant for 
internal use."
   shadow secondary-selection trailing-whitespace
   font-lock-builtin-face font-lock-comment-delimiter-face
   font-lock-comment-face font-lock-constant-face
-  font-lock-doc-face font-lock-function-name-face
+  font-lock-doc-face font-lock-doc-markup-face font-lock-function-name-face
   font-lock-keyword-face font-lock-negation-char-face
   font-lock-preprocessor-face font-lock-regexp-grouping-backslash
   font-lock-regexp-grouping-construct font-lock-string-face
diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el
index f666154..360e685 100644
--- a/lisp/emacs-lisp/easymenu.el
+++ b/lisp/emacs-lisp/easymenu.el
@@ -175,16 +175,14 @@ This is expected to be bound to a mouse event."
       (set symbol keymap)
       (defalias symbol
        (lambda (event) (:documentation doc) (interactive "@e")
-          ;; FIXME: XEmacs uses popup-menu which calls the binding
-          ;; while x-popup-menu only returns the selection.
           (x-popup-menu event
-                        (or (and (symbolp symbol)
+                        (or (and (symbolp keymap)
                                  (funcall
-                                  (or (plist-get (get symbol 'menu-prop)
+                                  (or (plist-get (get keymap 'menu-prop)
                                                  :filter)
                                        #'identity)
-                                  (symbol-function symbol)))
-                            symbol))))
+                                  (symbol-function keymap)))
+                            keymap))))
       ;; These symbols are commands, but not interesting for users
       ;; to `M-x TAB'.
       (function-put symbol 'completion-predicate #'ignore))
@@ -257,7 +255,7 @@ possibly preceded by keyword pairs as described in 
`easy-menu-define'."
                      ;; anyway, so we'd better not convert it at all (it will
                      ;; be converted on the fly by easy-menu-filter-return).
                      menu-items
-                   (append menu (mapcar 'easy-menu-convert-item menu-items))))
+                   (append menu (mapcar #'easy-menu-convert-item menu-items))))
       (when prop
        (setq menu (easy-menu-make-symbol menu 'noexp))
        (put menu 'menu-prop prop))
@@ -667,7 +665,7 @@ In some cases we use that to select between the local and 
global maps."
            (let* ((name (if path (format "%s" (car (reverse path)))))
                   (newmap (make-sparse-keymap name)))
              (define-key (or map (current-local-map))
-               (apply 'vector (mapcar 'easy-menu-intern path))
+               (apply #'vector (mapcar #'easy-menu-intern path))
                (if name (cons name newmap) newmap))
              newmap))))
   (or (keymapp map) (error "Malformed menu in easy-menu: (%s)" map))
diff --git a/lisp/emacs-lisp/lisp-mnt.el b/lisp/emacs-lisp/lisp-mnt.el
index 4d1b42e..df14a5c 100644
--- a/lisp/emacs-lisp/lisp-mnt.el
+++ b/lisp/emacs-lisp/lisp-mnt.el
@@ -111,6 +111,8 @@
 
 ;;; Code:
 
+(require 'mail-parse)
+
 ;;; Variables:
 
 (defgroup lisp-mnt nil
@@ -359,19 +361,9 @@ Return argument is of the form (\"HOLDER\" \"YEAR1\" ... 
\"YEARN\")"
 (defun lm-crack-address (x)
   "Split up email address(es) X into full name and real email address.
 The value is a list of elements of the form (FULLNAME . ADDRESS)."
-  (cond ((string-match
-         (concat "[,\s\t]*\\(?:"
-                 "\\(.+?\\) +[(<]\\(\\S-+@\\S-+\\)[>)]"
-                 "\\|"
-                 "\\(?2:\\S-+@\\S-+\\) +[(<]\\(?1:[^,]*\\)[>)]"
-                 "\\|"
-                 "\\(?2:\\S-+@\\S-+\\)"
-                 "\\)")
-         x)
-        `((,(string-trim-right (match-string 1 x)) . ,(match-string 2 x))
-          . ,(lm-crack-address (substring x (match-end 0)))))
-       ((string-match "\\`[,\s\t]*\\'" x) nil)
-       (t `((,x)))))
+  (mapcar (lambda (elem)
+            (cons (cdr elem) (car elem)))
+          (mail-header-parse-addresses-lax x)))
 
 (defun lm-authors (&optional file)
   "Return the author list of file FILE, or current buffer if FILE is nil.
diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index c593428..988a62a 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -5,7 +5,7 @@
 ;; Author: Nicolas Petton <nicolas@petton.fr>
 ;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: extensions, lisp
-;; Version: 3.0
+;; Version: 3.1
 ;; Package-Requires: ((emacs "26"))
 
 ;; This file is part of GNU Emacs.
@@ -371,37 +371,51 @@ The default implementation delegates to `map-do'."
             map)
     t))
 
+(defun map--merge (merge type &rest maps)
+  "Merge into a map of TYPE all the key/value pairs in MAPS.
+MERGE is a function that takes the target MAP, a KEY, and a
+VALUE, merges KEY and VALUE into MAP, and returns the result.
+MAP may be of a type other than TYPE."
+  ;; Use a hash table internally if `type' is a list.  This avoids
+  ;; both quadratic lookup behavior and the type ambiguity of nil.
+  (let* ((tolist (memq type '(list alist plist)))
+         (result (map-into (pop maps)
+                            ;; Use same testfn as `map-elt' gv setter.
+                           (cond ((eq type 'plist) '(hash-table :test eq))
+                                 (tolist '(hash-table :test equal))
+                                 (type)))))
+    (dolist (map maps)
+      (map-do (lambda (key value)
+                (setq result (funcall merge result key value)))
+              map))
+    ;; Convert internal representation to desired type.
+    (if tolist (map-into result type) result)))
+
 (defun map-merge (type &rest maps)
   "Merge into a map of TYPE all the key/value pairs in MAPS.
 See `map-into' for all supported values of TYPE."
-  (let ((result (map-into (pop maps) type)))
-    (while maps
-      ;; FIXME: When `type' is `list', we get an O(N^2) behavior.
-      ;; For small tables, this is fine, but for large tables, we
-      ;; should probably use a hash-table internally which we convert
-      ;; to an alist in the end.
-      (map-do (lambda (key value)
-                (setf (map-elt result key) value))
-              (pop maps)))
-    result))
+  (apply #'map--merge
+         (lambda (result key value)
+           (setf (map-elt result key) value)
+           result)
+         type maps))
 
 (defun map-merge-with (type function &rest maps)
   "Merge into a map of TYPE all the key/value pairs in MAPS.
-When two maps contain the same (`eql') key, call FUNCTION on the two
+When two maps contain the same key, call FUNCTION on the two
 values and use the value returned by it.
 Each of MAPS can be an alist, plist, hash-table, or array.
 See `map-into' for all supported values of TYPE."
-  (let ((result (map-into (pop maps) type))
-        (not-found (list nil)))
-    (while maps
-      (map-do (lambda (key value)
-                (cl-callf (lambda (old)
-                            (if (eql old not-found)
-                                value
-                              (funcall function old value)))
-                    (map-elt result key not-found)))
-              (pop maps)))
-    result))
+  (let ((not-found (list nil)))
+    (apply #'map--merge
+           (lambda (result key value)
+             (cl-callf (lambda (old)
+                         (if (eql old not-found)
+                             value
+                           (funcall function old value)))
+                 (map-elt result key not-found))
+             result)
+           type maps)))
 
 (cl-defgeneric map-into (map type)
   "Convert MAP into a map of TYPE.")
diff --git a/lisp/emacs-lisp/memory-report.el b/lisp/emacs-lisp/memory-report.el
index 1125dde..aee2a00 100644
--- a/lisp/emacs-lisp/memory-report.el
+++ b/lisp/emacs-lisp/memory-report.el
@@ -230,8 +230,7 @@ by counted more than once."
   (let ((total (+ (memory-report--size 'vector)
                   (* (memory-report--size 'object) (length value)))))
     (cl-loop for elem across value
-             do (setf (gethash elem counted) t)
-             (cl-incf total (memory-report--object-size counted elem)))
+             do (cl-incf total (memory-report--object-size counted elem)))
     total))
 
 (cl-defmethod memory-report--object-size-1 (counted (value hash-table))
@@ -239,8 +238,6 @@ by counted more than once."
                   (* (memory-report--size 'object) (hash-table-size value)))))
     (maphash
      (lambda (key elem)
-       (setf (gethash key counted) t)
-       (setf (gethash elem counted) t)
        (cl-incf total (memory-report--object-size counted key))
        (cl-incf total (memory-report--object-size counted elem)))
      value)
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index e8fc4a2..f0dc283 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -93,6 +93,14 @@ name to be bound to the rest of SEQUENCE."
   (declare (indent 2) (debug (sexp form body)))
   `(pcase-let ((,(seq--make-pcase-patterns args) ,sequence))
      ,@body))
+
+(defmacro seq-setq (args sequence)
+  "Assign to the variables in ARGS the elements of SEQUENCE.
+
+ARGS can also include the `&rest' marker followed by a variable
+name to be bound to the rest of SEQUENCE."
+  (declare (debug (sexp form)))
+  `(pcase-setq ,(seq--make-pcase-patterns args) ,sequence))
 
 
 ;;; Basic seq functions that have to be implemented by new sequence types
diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el
index a74a5a4..1b0fbfd 100644
--- a/lisp/emacs-lisp/shortdoc.el
+++ b/lisp/emacs-lisp/shortdoc.el
@@ -1317,7 +1317,8 @@ Example:
   "Keymap for `shortdoc-mode'.")
 
 (define-derived-mode shortdoc-mode special-mode "shortdoc"
-  "Mode for shortdoc.")
+  "Mode for shortdoc."
+  :interactive nil)
 
 (defun shortdoc--goto-section (arg sym &optional reverse)
   (unless (natnump arg)
@@ -1332,26 +1333,26 @@ Example:
 (defun shortdoc-next (&optional arg)
   "Move cursor to the next function.
 With ARG, do it that many times."
-  (interactive "p")
+  (interactive "p" shortdoc-mode)
   (shortdoc--goto-section arg 'shortdoc-function))
 
 (defun shortdoc-previous (&optional arg)
   "Move cursor to the previous function.
 With ARG, do it that many times."
-  (interactive "p")
+  (interactive "p" shortdoc-mode)
   (shortdoc--goto-section arg 'shortdoc-function t)
   (backward-char 1))
 
 (defun shortdoc-next-section (&optional arg)
   "Move cursor to the next section.
 With ARG, do it that many times."
-  (interactive "p")
+  (interactive "p" shortdoc-mode)
   (shortdoc--goto-section arg 'shortdoc-section))
 
 (defun shortdoc-previous-section (&optional arg)
   "Move cursor to the previous section.
 With ARG, do it that many times."
-  (interactive "p")
+  (interactive "p" shortdoc-mode)
   (shortdoc--goto-section arg 'shortdoc-section t)
   (forward-line -2))
 
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index 468d124..4204d20 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -240,6 +240,7 @@ carriage return."
       (substring string 0 (- (length string) (length suffix)))
     string))
 
+;;;###autoload
 (defun string-clean-whitespace (string)
   "Clean up whitespace in STRING.
 All sequences of whitespaces in STRING are collapsed into a
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index 4dc42d9..c00a62a 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -312,6 +312,9 @@ If a number, only buffers greater than this size have 
fontification messages."
 (defvar font-lock-doc-face             'font-lock-doc-face
   "Face name to use for documentation.")
 
+(defvar font-lock-doc-markup-face       'font-lock-doc-markup-face
+  "Face name to use for documentation mark-up.")
+
 (defvar font-lock-keyword-face         'font-lock-keyword-face
   "Face name to use for keywords.")
 
@@ -2003,7 +2006,16 @@ Sets various variables using `font-lock-defaults' and
 
 (defface font-lock-doc-face
   '((t :inherit font-lock-string-face))
-  "Font Lock mode face used to highlight documentation."
+  "Font Lock mode face used to highlight documentation embedded in program 
code.
+It is typically used for special documentation comments or strings."
+  :group 'font-lock-faces)
+
+(defface font-lock-doc-markup-face
+  '((t :inherit font-lock-constant-face))
+  "Font Lock mode face used to highlight embedded documentation mark-up.
+It is meant for mark-up elements in text that uses `font-lock-doc-face', such
+as the constructs of Haddock, Javadoc and similar systems."
+  :version "28.1"
   :group 'font-lock-faces)
 
 (defface font-lock-keyword-face
diff --git a/lisp/mail/mail-extr.el b/lisp/mail/mail-extr.el
index 88fb086..24d8311 100644
--- a/lisp/mail/mail-extr.el
+++ b/lisp/mail/mail-extr.el
@@ -707,7 +707,10 @@ This function is primarily meant for when you're 
displaying the
 result to the user: Many prettifications are applied to the
 result returned.  If you want to decode an address for further
 non-display use, you should probably use
-`mail-header-parse-address' instead."
+`mail-header-parse-address' instead.  Also see
+`mail-header-parse-address-lax' for a function that's less strict
+than `mail-header-parse-address', but does less post-processing
+to the results."
   (let ((canonicalization-buffer (get-buffer-create " *canonical address*"))
        (extraction-buffer (get-buffer-create " *extract address components*"))
        value-list)
diff --git a/lisp/mail/mail-parse.el b/lisp/mail/mail-parse.el
index e72ed82..212fadf 100644
--- a/lisp/mail/mail-parse.el
+++ b/lisp/mail/mail-parse.el
@@ -71,6 +71,45 @@
 (defalias 'mail-decode-encoded-address-region 'rfc2047-decode-address-region)
 (defalias 'mail-decode-encoded-address-string 'rfc2047-decode-address-string)
 
+(defun mail-header-parse-addresses-lax (string)
+  "Parse STRING as a comma-separated list of mail addresses.
+The return value is a list with mail/name pairs."
+  (delq nil
+        (mapcar (lambda (elem)
+                  (or (mail-header-parse-address elem)
+                      (mail-header-parse-address-lax elem)))
+                (mail-header-parse-addresses string t))))
+
+(defun mail-header-parse-address-lax (string)
+  "Parse STRING as a mail address.
+Returns a mail/name pair.
+
+This function will first try to parse STRING as a
+standards-compliant address string, and if that fails, try to use
+heuristics to determine the email address and the name in the
+string."
+  (with-temp-buffer
+    (insert (string-clean-whitespace string))
+    ;; Find the bit with the @ and guess that that's the mail.
+    (goto-char (point-max))
+    (when (search-backward "@" nil t)
+      (if (re-search-backward " " nil t)
+          (forward-char 1)
+        (goto-char (point-min)))
+      (let* ((start (point))
+             (mail (buffer-substring
+                    start (or (re-search-forward " " nil t)
+                              (goto-char (point-max))))))
+        (delete-region start (point))
+        ;; We've now removed the email bit, so the rest of the stuff
+        ;; has to be the name.
+        (cons (string-trim mail "[<]+" "[>]+")
+              (let ((name (string-trim (buffer-string)
+                                       "[ \t\n\r(]+" "[ \t\n\r)]+")))
+                (if (length= name 0)
+                    nil
+                  name)))))))
+
 (provide 'mail-parse)
 
 ;;; mail-parse.el ends here
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 0843f94..5ca5e8d 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -4000,27 +4000,39 @@ that is non-nil."
       ((compose-flex-sort-fn
         (existing-sort-fn) ; wish `cl-flet' had proper indentation...
         (lambda (completions)
-          (let ((pre-sorted
-                 (if existing-sort-fn
-                     (funcall existing-sort-fn completions)
-                   completions)))
-            (cond
-             ((or (not (window-minibuffer-p))
-                  ;; JT@2019-12-23: FIXME: this is still wrong.  What
-                  ;; we need to test here is "some input that actually
-                  ;; leads to flex filtering", not "something after
-                  ;; the minibuffer prompt".  Among other
-                  ;; inconsistencies, the latter is always true for
-                  ;; file searches, meaning the next clauses will be
-                  ;; ignored.
-                  (> (point-max) (minibuffer-prompt-end)))
-              (sort
-               pre-sorted
-               (lambda (c1 c2)
-                 (let ((s1 (get-text-property 0 'completion-score c1))
-                       (s2 (get-text-property 0 'completion-score c2)))
-                   (> (or s1 0) (or s2 0))))))
-             (t pre-sorted))))))
+          (cond
+           (;; Sort by flex score whenever outside the minibuffer or
+            ;; in the minibuffer with some input.  JT@2019-12-23:
+            ;; FIXME: this is still wrong.  What we need to test here
+            ;; is "some input that actually leads to flex filtering",
+            ;; not "something after the minibuffer prompt".  Among
+            ;; other inconsistencies, the latter is always true for
+            ;; file searches, meaning the next clauses in this cond
+            ;; will be ignored.
+            (or (not (window-minibuffer-p))
+                (> (point-max) (minibuffer-prompt-end)))
+            (sort
+             (if existing-sort-fn
+                 (funcall existing-sort-fn completions)
+               completions)
+             (lambda (c1 c2)
+               (let ((s1 (get-text-property 0 'completion-score c1))
+                     (s2 (get-text-property 0 'completion-score c2)))
+                 (> (or s1 0) (or s2 0))))))
+           (;; If no existing sort fn and nothing flexy happening, use
+            ;; the customary sorting strategy.
+            ;;
+            ;; JT@2021-08-15: FIXME: ideally this wouldn't repeat
+            ;; logic in `completion-all-sorted-completions', but that
+            ;; logic has other context that is either expensive to
+            ;; compute or not easy to access here.
+            (not existing-sort-fn)
+            (let ((lalpha (minibuffer--sort-by-length-alpha completions))
+                  (hist (and (minibufferp)
+                             (and (not (eq minibuffer-history-variable t))
+                                  (symbol-value 
minibuffer-history-variable)))))
+              (if hist (minibuffer--sort-by-position hist lalpha) lalpha)))
+           (t (funcall existing-sort-fn completions))))))
     `(metadata
       (display-sort-function
        . ,(compose-flex-sort-fn
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 4222dbe..7f7175f 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -7393,29 +7393,51 @@ multi-line strings (but not C++, for example)."
   (save-excursion
     (goto-char beg)
     (when open-delim
+      ;; If BEG is in an opener, move back to a position we know to be "safe".
       (if (<= beg (cadr open-delim))
          (goto-char (cadr open-delim))
        (c-ml-string-back-to-neutral (car open-delim))))
-    (or (and c-ml-string-back-closer-re
-            (looking-at c-ml-string-any-closer-re)
-            (eq (c-in-literal) 'string)
-            (goto-char (match-end 0)))
-       (progn
-         (while
-             (and
-              (search-forward-regexp
-               c-ml-string-any-closer-re
-               (min (+ end c-ml-string-max-closer-len-no-leader) (point-max))
-               t)
-              (save-excursion
-                (goto-char (match-end 1))
-                (not (c-in-literal)))
-              (<= (point) beg)
-              (not (save-excursion
-                     (goto-char (match-beginning 2))
-                     (c-literal-start)))))))
-
-    (unless (or (and (not (eobp))
+
+    (let (saved-match-data)
+      (or
+       ;; If we might be in the middle of "context" bytes at the start of a
+       ;; closer, move to after the closer.
+       (and c-ml-string-back-closer-re
+           (looking-at c-ml-string-any-closer-re)
+           (eq (c-in-literal) 'string)
+           (setq saved-match-data (match-data))
+           (goto-char (match-end 0)))
+
+       ;; Otherwise, move forward over closers while we haven't yet reached 
END,
+       ;; until we're after BEG.
+       (progn
+        (while
+            (let (found)
+              (while                   ; Go over a single real closer.
+                  (and
+                   (search-forward-regexp
+                    c-ml-string-any-closer-re
+                    (min (+ end c-ml-string-max-closer-len-no-leader)
+                         (point-max))
+                    t)
+                   (save-excursion
+                     (goto-char (match-end 1))
+                     (if (c-in-literal) ; a psuedo closer.
+                         t
+                       (setq saved-match-data (match-data))
+                       (setq found t)
+                       nil))))
+              (and found
+                   (<= (point) beg))
+              ;; (not (save-excursion
+              ;;        (goto-char (match-beginning 2))
+              ;;        (c-literal-start)))
+              ))))
+      (set-match-data saved-match-data))
+
+    ;; Test whether we've found the sought closing delimiter.
+    (unless (or (null (match-data))
+               (and (not (eobp))
                     (<= (point) beg))
                (> (match-beginning 0) beg)
                (progn (goto-char (match-beginning 2))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 2557704..20299c2 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -3085,7 +3085,8 @@ t when called interactively."
    (list (read-string "Python command: ") nil t))
   (let ((process (or process (python-shell-get-process-or-error msg))))
     (if (string-match ".\n+." string)   ;Multiline.
-        (let* ((temp-file-name (python-shell--save-temp-file string))
+        (let* ((temp-file-name (with-current-buffer (process-buffer process)
+                                 (python-shell--save-temp-file string)))
                (file-name (or (buffer-file-name) temp-file-name)))
           (python-shell-send-file file-name process temp-file-name t))
       (comint-send-string process string)
diff --git a/lisp/simple.el b/lisp/simple.el
index 985beb0..1661346 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2194,6 +2194,8 @@ Also see `suggest-key-bindings'."
           (setq binding candidate))))
     binding))
 
+(defvar execute-extended-command--binding-timer nil)
+
 (defun execute-extended-command (prefixarg &optional command-name typed)
   ;; Based on Fexecute_extended_command in keyboard.c of Emacs.
   ;; Aaron S. Hawley <aaron.s.hawley(at)gmail.com> 2009-08-24
@@ -2258,15 +2260,24 @@ invoking, give a prefix argument to 
`execute-extended-command'."
             (setq binding (execute-extended-command--shorter
                            (symbol-name function) typed))))
         (when binding
-          (with-temp-message
-              (format-message "You can run the command `%s' with %s"
-                              function
-                              (if (stringp binding)
-                                  (concat "M-x " binding " RET")
-                                (key-description binding)))
-            (sit-for (if (numberp suggest-key-bindings)
-                         suggest-key-bindings
-                       2))))))))
+          ;; This is normally not necessary -- the timer should run
+          ;; immediately, but be defensive and ensure that we never
+          ;; have two of these timers in flight.
+          (when execute-extended-command--binding-timer
+            (cancel-timer execute-extended-command--binding-timer))
+          (setq execute-extended-command--binding-timer
+                (run-at-time
+                 0 nil
+                 (lambda ()
+                   (with-temp-message
+                       (format-message "You can run the command `%s' with %s"
+                                       function
+                                       (if (stringp binding)
+                                           (concat "M-x " binding " RET")
+                                         (key-description binding)))
+                     (sit-for (if (numberp suggest-key-bindings)
+                                  suggest-key-bindings
+                                2)))))))))))
 
 (defun execute-extended-command-for-buffer (prefixarg &optional
                                                       command-name typed)
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index bb1c46c..eeb32f8 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -969,11 +969,11 @@ If the OLD prefix arg is passed, tell the file NAME of 
the old file."
               (list (match-string 1)))
             header-files
              ;; this assumes that there are no spaces in filenames
-            (when (re-search-backward
-                   "^diff \\(-\\S-+ +\\)*\\(\\S-+\\)\\( +\\(\\S-+\\)\\)?"
-                   nil t)
-              (list (if old (match-string 2) (match-string 4))
-                    (if old (match-string 4) (match-string 2)))))))))
+             (and (re-search-backward "^diff " nil t)
+                  (looking-at
+                  "^diff \\(-[^ \t\nL]+ +\\)*\\(-L +\\S-+ +\\)*\\(\\S-+\\)\\( 
+\\(\\S-+\\)\\)?")
+                 (list (if old (match-string 3) (match-string 5))
+                       (if old (match-string 4) (match-string 3)))))))))
 
 (defun diff-find-file-name (&optional old noprompt prefix)
   "Return the file corresponding to the current patch.
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index 1430871..ffe1e68 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -242,6 +242,15 @@ included in the completions."
 ;;;###autoload         (load "vc-git" nil t)
 ;;;###autoload         (vc-git-registered file))))
 
+(defun vc-git--literal-pathspec (pathspec)
+  "Prepend :(literal) path magic to PATHSPEC."
+  ;; Good example of PATHSPEC that needs this: "test[56].xx".
+  (and pathspec (concat ":(literal)" pathspec)))
+
+(defun vc-git--literal-pathspecs (pathspecs)
+  "Prepend :(literal) path magic to PATHSPECS."
+  (mapcar #'vc-git--literal-pathspec pathspecs))
+
 (defun vc-git-registered (file)
   "Check whether FILE is registered with git."
   (let ((dir (vc-git-root file)))
@@ -255,12 +264,12 @@ included in the completions."
                (name (file-relative-name file dir))
                (str (with-demoted-errors "Error: %S"
                       (cd dir)
-                      (vc-git--out-ok "ls-files" "-c" "-z" "--" name)
+                      (vc-git--out-ok "ls-files" "-c" "-z" "--" 
(vc-git--literal-pathspec name))
                       ;; If result is empty, use ls-tree to check for deleted
                       ;; file.
                       (when (eq (point-min) (point-max))
                         (vc-git--out-ok "ls-tree" "--name-only" "-z" "HEAD"
-                                        "--" name))
+                                        "--" (vc-git--literal-pathspec name)))
                       (buffer-string))))
           (and str
                (> (length str) (length name))
@@ -342,7 +351,7 @@ in the order given by `git status'."
             ,@(when (version<= "1.7.6.3" (vc-git--program-version))
                 '("--ignored"))
             "--"))
-        (status (apply #'vc-git--run-command-string file args)))
+        (status (apply #'vc-git--run-command-string (vc-git--literal-pathspec 
file) args)))
     (if (null status)
         ;; If status is nil, there was an error calling git, likely because
         ;; the file is not in a git repo.
@@ -620,28 +629,28 @@ or an empty string if none."
     (pcase (vc-git-dir-status-state->stage git-state)
       ('update-index
        (if files
-           (vc-git-command (current-buffer) 'async files "add" "--refresh" 
"--")
+           (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs 
files) "add" "--refresh" "--")
          (vc-git-command (current-buffer) 'async nil
                          "update-index" "--refresh")))
       ('ls-files-added
-       (vc-git-command (current-buffer) 'async files
+       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs 
files)
                        "ls-files" "-z" "-c" "-s" "--"))
       ('ls-files-up-to-date
-       (vc-git-command (current-buffer) 'async files
+       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs 
files)
                        "ls-files" "-z" "-c" "-s" "--"))
       ('ls-files-conflict
-       (vc-git-command (current-buffer) 'async files
+       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs 
files)
                        "ls-files" "-z" "-u" "--"))
       ('ls-files-unknown
-       (vc-git-command (current-buffer) 'async files
+       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs 
files)
                        "ls-files" "-z" "-o" "--exclude-standard" "--"))
       ('ls-files-ignored
-       (vc-git-command (current-buffer) 'async files
+       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs 
files)
                        "ls-files" "-z" "-o" "-i" "--directory"
                        "--no-empty-directory" "--exclude-standard" "--"))
       ;; --relative added in Git 1.5.5.
       ('diff-index
-       (vc-git-command (current-buffer) 'async files
+       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs 
files)
                        "diff-index" "--relative" "-z" "-M" "HEAD" "--")))
     (vc-run-delayed
       (vc-git-after-dir-status-stage git-state))))
@@ -867,14 +876,14 @@ The car of the list is the current branch."
          (push crt dlist)
        (push crt flist)))
     (when flist
-      (vc-git-command nil 0 flist "update-index" "--add" "--"))
+      (vc-git-command nil 0 (vc-git--literal-pathspecs flist) "update-index" 
"--add" "--"))
     (when dlist
-      (vc-git-command nil 0 dlist "add"))))
+      (vc-git-command nil 0 (vc-git--literal-pathspecs dlist) "add"))))
 
 (defalias 'vc-git-responsible-p #'vc-git-root)
 
 (defun vc-git-unregister (file)
-  (vc-git-command nil 0 file "rm" "-f" "--cached" "--"))
+  (vc-git-command nil 0 (vc-git--literal-pathspec file) "rm" "-f" "--cached" 
"--"))
 
 (declare-function log-edit-mode "log-edit" ())
 (declare-function log-edit-toggle-header "log-edit" (header value))
@@ -941,7 +950,7 @@ It is based on `log-edit-mode', and has Git-specific 
extensions.")
                (lambda (value) (when (equal value "yes") (list argument)))))
       ;; When operating on the whole tree, better pass "-a" than ".", since "."
       ;; fails when we're committing a merge.
-      (apply #'vc-git-command nil 0 (if only files)
+      (apply #'vc-git-command nil 0 (if only (vc-git--literal-pathspecs files))
              (nconc (if msg-file (list "commit" "-F"
                                        (file-local-name msg-file))
                       (list "commit" "-m"))
@@ -968,7 +977,7 @@ It is based on `log-edit-mode', and has Git-specific 
extensions.")
         (coding-system-for-write 'binary)
         (fullname
          (let ((fn (vc-git--run-command-string
-                    file "ls-files" "-z" "--full-name" "--")))
+                    (vc-git--literal-pathspec file) "ls-files" "-z" 
"--full-name" "--")))
            ;; ls-files does not return anything when looking for a
            ;; revision of a file that has been renamed or removed.
            (if (string= fn "")
@@ -985,14 +994,14 @@ It is based on `log-edit-mode', and has Git-specific 
extensions.")
                    (vc-git-root file)))
 
 (defun vc-git-checkout (file &optional rev)
-  (vc-git-command nil 0 file "checkout" (or rev "HEAD")))
+  (vc-git-command nil 0 (vc-git--literal-pathspec file) "checkout" (or rev 
"HEAD")))
 
 (defun vc-git-revert (file &optional contents-done)
   "Revert FILE to the version stored in the git repository."
   (if contents-done
       (vc-git-command nil 0 file "update-index" "--")
-    (vc-git-command nil 0 file "reset" "-q" "--")
-    (vc-git-command nil nil file "checkout" "-q" "--")))
+    (vc-git-command nil 0 (vc-git--literal-pathspec file) "reset" "-q" "--")
+    (vc-git-command nil nil (vc-git--literal-pathspec file) "checkout" "-q" 
"--")))
 
 (defvar vc-git-error-regexp-alist
   '(("^ \\(.+\\)\\> *|" 1 nil nil 0))
@@ -1076,7 +1085,7 @@ This prompts for a branch to merge from."
 (defun vc-git-conflicted-files (directory)
   "Return the list of files with conflicts in DIRECTORY."
   (let* ((status
-          (vc-git--run-command-string directory "status" "--porcelain" "--"))
+          (vc-git--run-command-string (vc-git--literal-pathspec directory) 
"status" "--porcelain" "--"))
          (lines (when status (split-string status "\n" 'omit-nulls)))
          files)
     (dolist (line lines files)
@@ -1157,7 +1166,7 @@ If LIMIT is a revision string, use it as an end-revision."
     (let ((inhibit-read-only t))
       (with-current-buffer buffer
        (apply #'vc-git-command buffer
-              'async files
+              'async (vc-git--literal-pathspecs files)
               (append
                '("log" "--no-color")
                 (when (and vc-git-print-log-follow
@@ -1408,7 +1417,7 @@ This requires git 1.8.4 or later, for the \"-L\" option 
of \"git log\"."
     (if vc-git-diff-switches
         (apply #'vc-git-command (or buffer "*vc-diff*")
               1 ; bug#21969
-              files
+              (vc-git--literal-pathspecs files)
                command
                "--exit-code"
                (append (vc-switches 'git 'diff)
@@ -1493,7 +1502,7 @@ This requires git 1.8.4 or later, for the \"-L\" option 
of \"git log\"."
       (let* ((fname (file-relative-name file))
              (prev-rev (with-temp-buffer
                          (and
-                          (vc-git--out-ok "rev-list" "-2" rev "--" fname)
+                          (vc-git--out-ok "rev-list" "-2" rev "--" 
(vc-git--literal-pathspec fname))
                           (goto-char (point-max))
                           (bolp)
                           (zerop (forward-line -1))
@@ -1521,7 +1530,7 @@ This requires git 1.8.4 or later, for the \"-L\" option 
of \"git log\"."
          (current-rev
           (with-temp-buffer
             (and
-             (vc-git--out-ok "rev-list" "-1" rev "--" file)
+             (vc-git--out-ok "rev-list" "-1" rev "--" 
(vc-git--literal-pathspec file))
              (goto-char (point-max))
              (bolp)
              (zerop (forward-line -1))
@@ -1533,7 +1542,7 @@ This requires git 1.8.4 or later, for the \"-L\" option 
of \"git log\"."
           (and current-rev
                (with-temp-buffer
                  (and
-                  (vc-git--out-ok "rev-list" "HEAD" "--" file)
+                  (vc-git--out-ok "rev-list" "HEAD" "--" 
(vc-git--literal-pathspec file))
                   (goto-char (point-min))
                   (search-forward current-rev nil t)
                   (zerop (forward-line -1))
@@ -1543,13 +1552,13 @@ This requires git 1.8.4 or later, for the \"-L\" option 
of \"git log\"."
     (or (vc-git-symbolic-commit next-rev) next-rev)))
 
 (defun vc-git-delete-file (file)
-  (vc-git-command nil 0 file "rm" "-f" "--"))
+  (vc-git-command nil 0 (vc-git--literal-pathspecs file) "rm" "-f" "--"))
 
 (defun vc-git-rename-file (old new)
-  (vc-git-command nil 0 (list old new) "mv" "-f" "--"))
+  (vc-git-command nil 0 (vc-git--literal-pathspecs (list old new)) "mv" "-f" 
"--"))
 
 (defun vc-git-mark-resolved (files)
-  (vc-git-command nil 0 files "add"))
+  (vc-git-command nil 0 (vc-git--literal-pathspecs files) "add"))
 
 (defvar vc-git-extra-menu-map
   (let ((map (make-sparse-keymap)))
@@ -1772,7 +1781,6 @@ The difference to vc-do-command is that this function 
always invokes
         (process-environment
          (append
           `("GIT_DIR"
-            "GIT_LITERAL_PATHSPECS=1"
             ;; Avoid repository locking during background operations
             ;; (bug#21559).
             ,@(when revert-buffer-in-progress-p
@@ -1807,7 +1815,6 @@ The difference to vc-do-command is that this function 
always invokes
        (process-environment
         (append
          `("GIT_DIR"
-            "GIT_LITERAL_PATHSPECS=1"
            ;; Avoid repository locking during background operations
            ;; (bug#21559).
            ,@(when revert-buffer-in-progress-p
diff --git a/src/alloc.c b/src/alloc.c
index 8edcd06..4ea337d 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -7318,7 +7318,7 @@ Frames, windows, buffers, and subprocesses count as 
vectors
                make_int (strings_consed));
 }
 
-#ifdef GNU_LINUX
+#if defined GNU_LINUX && defined __GLIBC__
 DEFUN ("malloc-info", Fmalloc_info, Smalloc_info, 0, 0, "",
        doc: /* Report malloc information to stderr.
 This function outputs to stderr an XML-formatted
@@ -7678,7 +7678,7 @@ N should be nonnegative.  */);
   defsubr (&Sgarbage_collect_maybe);
   defsubr (&Smemory_info);
   defsubr (&Smemory_use_counts);
-#ifdef GNU_LINUX
+#if defined GNU_LINUX && defined __GLIBC__
   defsubr (&Smalloc_info);
 #endif
   defsubr (&Ssuspicious_object);
diff --git a/src/w32.c b/src/w32.c
index 968b4bb..0eb69d4 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -2389,8 +2389,13 @@ rand_as183 (void)
 int
 random (void)
 {
-  /* rand_as183 () gives us 15 random bits...hack together 30 bits.  */
+  /* rand_as183 () gives us 15 random bits...hack together 30 bits for
+     Emacs with 32-bit EMACS_INT, and at least 31 bit for wider EMACS_INT.  */
+#if EMACS_INT_MAX > INT_MAX
+  return ((rand_as183 () << 30) | (rand_as183 () << 15) | rand_as183 ());
+#else
   return ((rand_as183 () << 15) | rand_as183 ());
+#endif
 }
 
 void
@@ -8753,7 +8758,7 @@ int
 _sys_read_ahead (int fd)
 {
   child_process * cp;
-  int rc;
+  int rc = 0;
 
   if (fd < 0 || fd >= MAXDESC)
     return STATUS_READ_ERROR;
diff --git a/src/xdisp.c b/src/xdisp.c
index e62f7e3..972b901 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -17275,8 +17275,11 @@ run_window_scroll_functions (Lisp_Object window, 
struct text_pos startp)
 
   if (!NILP (Vwindow_scroll_functions))
     {
+      ptrdiff_t count = SPECPDL_INDEX ();
+      specbind (Qinhibit_quit, Qt);
       run_hook_with_args_2 (Qwindow_scroll_functions, window,
                            make_fixnum (CHARPOS (startp)));
+      unbind_to (count, Qnil);
       SET_TEXT_POS_FROM_MARKER (startp, w->start);
       /* In case the hook functions switch buffers.  */
       set_buffer_internal (XBUFFER (w->contents));
@@ -19269,7 +19272,7 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
   w->start_at_line_beg = (CHARPOS (startp) == BEGV
                          || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
 
-  /* Display the mode line, if we must.  */
+  /* Display the mode line, header line, and tab-line, if we must.  */
   if ((update_mode_line
        /* If window not full width, must redo its mode line
          if (a) the window to its side is being redone and
@@ -19288,8 +19291,11 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
          || window_wants_header_line (w)
          || window_wants_tab_line (w)))
     {
+      ptrdiff_t count1 = SPECPDL_INDEX ();
 
+      specbind (Qinhibit_quit, Qt);
       display_mode_lines (w);
+      unbind_to (count1, Qnil);
 
       /* If mode line height has changed, arrange for a thorough
         immediate redisplay using the correct mode line height.  */
@@ -19337,7 +19343,7 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
  finish_menu_bars:
 
   /* When we reach a frame's selected window, redo the frame's menu
-     bar and the frame's title.  */
+     bar, tool bar, tab-bar, and the frame's title.  */
   if (update_mode_line
       && EQ (FRAME_SELECTED_WINDOW (f), window))
     {
@@ -25428,8 +25434,9 @@ redisplay_mode_lines (Lisp_Object window, bool force)
 }
 
 
-/* Display the mode and/or header line of window W.  Value is the
-   sum number of mode lines and header lines displayed.  */
+/* Display the mode line, the header line, and the tab-line of window
+   W.  Value is the sum number of mode lines, header lines, and tab
+   lines actually displayed.  */
 
 static int
 display_mode_lines (struct window *w)
@@ -27009,7 +27016,7 @@ decode_mode_spec (struct window *w, register int c, int 
field_width,
        Lisp_Object val = Qnil;
 
        if (STRINGP (curdir))
-         val = call1 (intern ("file-remote-p"), curdir);
+         val = safe_call1 (intern ("file-remote-p"), curdir);
 
        val = unbind_to (count, val);
 
diff --git a/test/lisp/autorevert-tests.el b/test/lisp/autorevert-tests.el
index 449dabf..96169c7 100644
--- a/test/lisp/autorevert-tests.el
+++ b/test/lisp/autorevert-tests.el
@@ -286,7 +286,7 @@ This expects `auto-revert--messages' to be bound by
   ;; Repeated unpredictable failures, bug#32645.
   ;; Unlikely to be hydra-specific?
 ;  (skip-unless (not (getenv "EMACS_HYDRA_CI")))
-
+  :tags '(:unstable)
   (with-auto-revert-test
    (let ((tmpfile (make-temp-file "auto-revert-test"))
          ;; Try to catch bug#32645.
diff --git a/test/lisp/emacs-lisp/map-tests.el 
b/test/lisp/emacs-lisp/map-tests.el
index a04c6be..658ed2e 100644
--- a/test/lisp/emacs-lisp/map-tests.el
+++ b/test/lisp/emacs-lisp/map-tests.el
@@ -446,16 +446,24 @@ Evaluate BODY for each created map."
 
 (ert-deftest test-map-merge ()
   "Test `map-merge'."
-  (should (equal (map-merge 'list '(a 1) '((b . 2) (c . 3))
-                            #s(hash-table data (c 4)))
-                 '((c . 4) (b . 2) (a . 1)))))
+  (should (equal (sort (map-merge 'list '(a 1) '((b . 2) (c . 3))
+                                  #s(hash-table data (c 4)))
+                       (lambda (x y) (string< (car x) (car y))))
+                 '((a . 1) (b . 2) (c . 4))))
+  (should (equal (map-merge 'list () '(:a 1)) '((:a . 1))))
+  (should (equal (map-merge 'alist () '(:a 1)) '((:a . 1))))
+  (should (equal (map-merge 'plist () '(:a 1)) '(:a 1))))
 
 (ert-deftest test-map-merge-with ()
-  (should (equal (map-merge-with 'list #'+
-                                 '((1 . 2))
-                                 '((1 . 3) (2 . 4))
-                                 '((1 . 1) (2 . 5) (3 . 0)))
-                 '((3 . 0) (2 . 9) (1 . 6)))))
+  (should (equal (sort (map-merge-with 'list #'+
+                                       '((1 . 2))
+                                       '((1 . 3) (2 . 4))
+                                       '((1 . 1) (2 . 5) (3 . 0)))
+                       #'car-less-than-car)
+                 '((1 . 6) (2 . 9) (3 . 0))))
+  (should (equal (map-merge-with 'list #'+ () '(:a 1)) '((:a . 1))))
+  (should (equal (map-merge-with 'alist #'+ () '(:a 1)) '((:a . 1))))
+  (should (equal (map-merge-with 'plist #'+ () '(:a 1)) '(:a 1))))
 
 (ert-deftest test-map-merge-empty ()
   "Test merging of empty maps."
diff --git a/test/lisp/emacs-lisp/memory-report-tests.el 
b/test/lisp/emacs-lisp/memory-report-tests.el
index da5f4f5..0c0297b 100644
--- a/test/lisp/emacs-lisp/memory-report-tests.el
+++ b/test/lisp/emacs-lisp/memory-report-tests.el
@@ -45,6 +45,7 @@
 
   (should (equal (memory-report-object-size (list 'foo)) 16))
 
+  (should (equal (memory-report-object-size (vector 1 2 3)) 64))
   (should (equal (memory-report-object-size (vector 1 2 3 4)) 80))
 
   (should (equal (memory-report-object-size "") 32))
@@ -52,6 +53,21 @@
   (should (equal (memory-report-object-size (propertize "a" 'face 'foo))
                  81)))
 
+(ert-deftest memory-report-sizes-vectors ()
+  (should (= (memory-report--object-size
+              (make-hash-table :test #'eq)
+              ["long string that should be at least 40 bytes"])
+             108))
+  (let ((string "long string that should be at least 40 bytes"))
+    (should (= (memory-report--object-size
+                (make-hash-table :test #'eq)
+                (vector string))
+               108))
+    (should (= (memory-report--object-size
+                (make-hash-table :test #'eq)
+                (vector string string))
+               124))))
+
 (provide 'memory-report-tests)
 
 ;;; memory-report-tests.el ends here
diff --git a/test/lisp/emacs-lisp/seq-tests.el 
b/test/lisp/emacs-lisp/seq-tests.el
index 05c7fbe..44e855e 100644
--- a/test/lisp/emacs-lisp/seq-tests.el
+++ b/test/lisp/emacs-lisp/seq-tests.el
@@ -383,6 +383,30 @@ Evaluate BODY for each created sequence.
       (should (null b))
       (should (null c)))))
 
+(ert-deftest test-seq-setq ()
+  (with-test-sequences (seq '(1 2 3 4))
+    (let (a b c d e)
+      (seq-setq (a b c d e) seq)
+      (should (= a 1))
+      (should (= b 2))
+      (should (= c 3))
+      (should (= d 4))
+      (should (null e)))
+    (let (a b others)
+      (seq-setq (a b &rest others) seq)
+      (should (= a 1))
+      (should (= b 2))
+      (should (same-contents-p others (seq-drop seq 2)))))
+  (let ((a)
+        (seq '(1 (2 (3 (4))))))
+    (seq-setq (_ (_ (_ (a)))) seq)
+    (should (= a 4)))
+  (let (seq a b c)
+    (seq-setq (a b c) seq)
+    (should (null a))
+    (should (null b))
+    (should (null c))))
+
 (ert-deftest test-seq-min-max ()
   (with-test-sequences (seq '(4 5 3 2 0 4))
     (should (= (seq-min seq) 0))
diff --git a/test/lisp/mail/mail-parse-tests.el 
b/test/lisp/mail/mail-parse-tests.el
new file mode 100644
index 0000000..70de92d
--- /dev/null
+++ b/test/lisp/mail/mail-parse-tests.el
@@ -0,0 +1,54 @@
+;;; mail-parse-tests.el --- tests for mail-parse.el  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'mail-parse)
+(require 'subr-x)
+
+(ert-deftest test-mail-header-parse-address-lax ()
+  (should (equal (mail-header-parse-address-lax
+                  "Lars Ingebrigtsen <larsi@gnus.org>")
+                 '("larsi@gnus.org" . "Lars Ingebrigtsen")))
+  (should (equal (mail-header-parse-address-lax
+                  "Lars Ingebrigtsen larsi@gnus.org>")
+                 '("larsi@gnus.org" . "Lars Ingebrigtsen")))
+  (should (equal (mail-header-parse-address-lax
+                  "Lars Ingebrigtsen larsi@gnus.org")
+                 '("larsi@gnus.org" . "Lars Ingebrigtsen")))
+  (should (equal (mail-header-parse-address-lax
+                  "larsi@gnus.org (Lars Ingebrigtsen)")
+                 '("larsi@gnus.org " . "Lars Ingebrigtsen")))
+  (should (equal (mail-header-parse-address-lax "larsi@gnus.org")
+                 '("larsi@gnus.org")))
+  (should (equal (mail-header-parse-address-lax "foo")
+                 nil)))
+
+(ert-deftest test-mail-header-parse-addresses-lax ()
+  (should (equal (mail-header-parse-addresses-lax
+                  "Bob Weiner <rsw@gnu.org>, Mats Lidell <matsl@gnu.org>")
+                 '(("rsw@gnu.org" . "Bob Weiner")
+                   ("matsl@gnu.org" . "Mats Lidell")))))
+
+(provide 'mail-parse-tests)
+
+;;; mail-parse-tests.el ends here
diff --git a/test/lisp/net/netrc-resources/netrc-folding 
b/test/lisp/net/netrc-resources/netrc-folding
new file mode 100644
index 0000000..85e5e32
--- /dev/null
+++ b/test/lisp/net/netrc-resources/netrc-folding
@@ -0,0 +1,6 @@
+# Foo
+machine XM login XL password XP
+
+machine YM
+  login YL
+  password YP
diff --git a/test/lisp/net/netrc-tests.el b/test/lisp/net/netrc-tests.el
index 1328b19..f75328a 100644
--- a/test/lisp/net/netrc-tests.el
+++ b/test/lisp/net/netrc-tests.el
@@ -48,6 +48,13 @@
     (should (equal (netrc-credentials "ftp.example.org")
                    '("jrh" "*baz*")))))
 
+(ert-deftest test-netrc-credentials ()
+  (let ((netrc-file (ert-resource-file "netrc-folding")))
+    (should
+     (equal (netrc-parse netrc-file)
+            '((("machine" . "XM") ("login" . "XL") ("password" . "XP"))
+              (("machine" . "YM")) (("login" . "YL")) (("password" . 
"YP")))))))
+
 (provide 'netrc-tests)
 
 ;;; netrc-tests.el ends here
diff --git a/test/lisp/vc/diff-mode-tests.el b/test/lisp/vc/diff-mode-tests.el
index 5bc4ad6..5218659 100644
--- a/test/lisp/vc/diff-mode-tests.el
+++ b/test/lisp/vc/diff-mode-tests.el
@@ -468,4 +468,16 @@ baz"))))
                        (114 131 (diff-mode syntax face font-lock-string-face))
                        (134 140 (diff-mode syntax face 
font-lock-keyword-face))))))))
 
+(ert-deftest test-hunk-file-names ()
+  (with-temp-buffer
+    (insert "diff -c /tmp/ange-ftp13518wvE.el /tmp/ange-ftp1351895K.el\n")
+    (goto-char (point-min))
+    (should (equal (diff-hunk-file-names)
+                   '("/tmp/ange-ftp1351895K.el" "/tmp/ange-ftp13518wvE.el"))))
+  (with-temp-buffer
+    (insert "diff -c -L /ftp\:slbhao\:/home/albinus/src/tramp/lisp/tramp.el -L 
/ftp\:slbhao\:/home/albinus/src/emacs/lisp/net/tramp.el 
/tmp/ange-ftp13518wvE.el /tmp/ange-ftp1351895K.el\n")
+    (goto-char (point-min))
+    (should (equal (diff-hunk-file-names)
+                   '("/tmp/ange-ftp1351895K.el" "/tmp/ange-ftp13518wvE.el")))))
+
 (provide 'diff-mode-tests)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]