emacs-diffs
[Top][All Lists]
Advanced

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

master 2504d19dad 3/3: Merge branch 'master' of git.savannah.gnu.org:/sr


From: Eli Zaretskii
Subject: master 2504d19dad 3/3: Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs
Date: Tue, 9 Aug 2022 13:44:45 -0400 (EDT)

branch: master
commit 2504d19dade7bcfcce7cd93011edf06f3c955a50
Merge: 8813399cfa b2bf91003d
Author: Eli Zaretskii <eliz@gnu.org>
Commit: Eli Zaretskii <eliz@gnu.org>

    Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs
---
 lisp/emacs-lisp/lisp-mode.el        |  2 +-
 lisp/emacs-lisp/seq.el              | 17 +++++++
 lisp/gnus/gnus-util.el              | 11 +----
 lisp/gnus/nnimap.el                 |  2 +-
 lisp/gnus/nnmaildir.el              |  6 +--
 lisp/ibuf-ext.el                    | 46 +++++++-----------
 lisp/ibuf-macs.el                   |  2 +-
 lisp/ibuffer.el                     | 16 +++----
 lisp/international/ja-dic-utl.el    |  8 ++--
 lisp/international/mule-diag.el     | 62 +++++++++++++-----------
 lisp/international/quail.el         |  8 ++--
 lisp/net/tramp-adb.el               | 20 +++-----
 lisp/progmodes/python.el            | 22 ++++++---
 test/lisp/emacs-lisp/seq-tests.el   | 13 +++++
 test/lisp/net/tramp-tests.el        | 32 ++++---------
 test/lisp/progmodes/python-tests.el | 95 +++++++++++++++++++++++++++++++++----
 16 files changed, 222 insertions(+), 140 deletions(-)

diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index 1bc2c0ece6..c31fbec640 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -774,7 +774,7 @@ decided heuristically.)"
           ;; name).  If the symbol starts with \"def\", then it's
           ;; likely that the next symbol is the name.
           (when (and (not name)
-                     (string-match-p "\\`def" (symbol-name symbol)))
+                     (string-match-p "\\(\\`\\|-\\)def" (symbol-name symbol)))
             (when-let ((candidate (ignore-errors (read (current-buffer)))))
               (cond
                ((symbolp candidate)
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 1b8d86563a..6ddd8de6e8 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -455,6 +455,23 @@ TESTFN is used to compare elements, or `equal' if TESTFN 
is nil."
         (setq result (cons elt result))))
     (nreverse result)))
 
+(cl-defmethod seq-uniq ((sequence list) &optional testfn)
+  (let ((result nil))
+    (if (not testfn)
+        ;; Fast path.
+        (while sequence
+          (unless (member (car sequence) result)
+            (push (car sequence) result))
+          (pop sequence))
+      ;; Slower path.
+      (while sequence
+        (unless (seq-find (lambda (elem)
+                            (funcall testfn elem (car sequence)))
+                          result)
+          (push (car sequence) result))
+        (pop sequence)))
+    (nreverse result)))
+
 (cl-defgeneric seq-mapcat (function sequence &optional type)
   "Concatenate the result of applying FUNCTION to each element of SEQUENCE.
 The result is a sequence of type TYPE, or a list if TYPE is nil."
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index 880192e3bb..d1ad5bd7b2 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -750,15 +750,6 @@ nil.  See also `gnus-bind-print-variables'."
   (when (file-exists-p file)
     (delete-file file)))
 
-(defun gnus-delete-duplicates (list)
-  "Remove duplicate entries from LIST."
-  (let ((result nil))
-    (while list
-      (unless (member (car list) result)
-       (push (car list) result))
-      (pop list))
-    (nreverse result)))
-
 (defun gnus-delete-directory (directory)
   "Delete files in DIRECTORY.  Subdirectories remain.
 If there's no subdirectory, delete DIRECTORY as well."
@@ -1550,6 +1541,8 @@ lists of strings."
 ;; gnus-util.
 (autoload 'gnus-output-to-rmail "gnus-rmail")
 
+(define-obsolete-function-alias 'gnus-delete-duplicates #'seq-uniq "29.1")
+
 (provide 'gnus-util)
 
 ;;; gnus-util.el ends here
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 17bbfda08f..73cd183a02 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -555,7 +555,7 @@ during splitting, which may be slow."
                                ;; Look for the credentials based on
                                ;; the virtual server name and the address
                                (nnimap-credentials
-                               (gnus-delete-duplicates
+                                (seq-uniq
                                 (list server nnimap-address))
                                 ports
                                 nnimap-user))))
diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el
index 951978fc5b..3dc74c95fb 100644
--- a/lisp/gnus/nnmaildir.el
+++ b/lisp/gnus/nnmaildir.el
@@ -99,7 +99,7 @@ SUFFIX should start with \":2,\"."
   (let* ((flags (substring suffix 3))
         (flags-as-list (append flags nil))
         (new-flags
-         (concat (gnus-delete-duplicates
+          (concat (seq-uniq
                   ;; maildir flags must be sorted
                   (sort (cons flag flags-as-list) #'<)))))
     (concat ":2," new-flags)))
@@ -1015,7 +1015,7 @@ This variable is set by `nnmaildir-request-article'.")
            dir (nnmaildir--nndir dir)
            dir (nnmaildir--marks-dir dir)
             ls (nnmaildir--group-ls nnmaildir--cur-server pgname)
-           all-marks (gnus-delete-duplicates
+            all-marks (seq-uniq
                       ;; get mark names from mark dirs and from flag
                       ;; mappings
                       (append
@@ -1697,7 +1697,7 @@ This variable is set by `nnmaildir-request-article'.")
             pgname (nnmaildir--pgname nnmaildir--cur-server gname)
             ls (nnmaildir--group-ls nnmaildir--cur-server pgname)
            all-marks (funcall ls marksdir nil "\\`[^.]" 'nosort)
-           all-marks (gnus-delete-duplicates
+            all-marks (seq-uniq
                       ;; get mark names from mark dirs and from flag
                       ;; mappings
                       (append
diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el
index 621e648a2d..44c1ae867d 100644
--- a/lisp/ibuf-ext.el
+++ b/lisp/ibuf-ext.el
@@ -52,17 +52,6 @@
            (setq alist (remove it alist)) it))
   alist)
 
-;; borrowed from Gnus
-(defun ibuffer-remove-duplicates (list)
-  "Return a copy of LIST with duplicate elements removed."
-  (let ((new nil)
-       (tail list))
-    (while tail
-      (or (member (car tail) new)
-         (setq new (cons (car tail) new)))
-      (setq tail (cdr tail)))
-    (nreverse new)))
-
 (defun ibuffer-split-list (fn elts)
   (declare (obsolete seq-group-by "29.1"))
   (let ((res (seq-group-by fn elts)))
@@ -799,7 +788,7 @@ specification, with the same structure as an element of the 
list
         (mapcar (lambda (mode)
                   (cons (format "%s" mode) `((mode . ,mode))))
                 (let ((modes
-                       (ibuffer-remove-duplicates
+                       (seq-uniq
                         (mapcar (lambda (buf)
                                  (buffer-local-value 'major-mode buf))
                                 (buffer-list)))))
@@ -876,7 +865,7 @@ specification, with the same structure as an element of the 
list
   "Move point to the filter group whose name is NAME."
   (interactive
    (list (ibuffer-read-filter-group-name "Jump to filter group: ")))
-  (ibuffer-aif (assoc name (ibuffer-current-filter-groups-with-position))
+  (if-let ((it (assoc name (ibuffer-current-filter-groups-with-position))))
       (goto-char (cdr it))
     (error "No filter group with name %s" name)))
 
@@ -887,7 +876,7 @@ The group will be added to 
`ibuffer-filter-group-kill-ring'."
   (interactive (list (ibuffer-read-filter-group-name "Kill filter group: " t)))
   (when (equal name "Default")
     (error "Can't kill default filter group"))
-  (ibuffer-aif (assoc name ibuffer-filter-groups)
+  (if-let ((it (assoc name ibuffer-filter-groups)))
       (progn
        (push (copy-tree it) ibuffer-filter-group-kill-ring)
        (setq ibuffer-filter-groups (ibuffer-remove-alist
@@ -902,13 +891,12 @@ The group will be added to 
`ibuffer-filter-group-kill-ring'."
   "Kill the filter group at point.
 See also `ibuffer-kill-filter-group'."
   (interactive "P\np")
-  (ibuffer-aif (save-excursion
-                (ibuffer-forward-line 0)
-                (get-text-property (point) 'ibuffer-filter-group-name))
-      (progn
-       (ibuffer-kill-filter-group it))
-      (funcall (if interactive-p #'call-interactively #'funcall)
-              #'kill-line arg)))
+  (if-let ((it (save-excursion
+                 (ibuffer-forward-line 0)
+                 (get-text-property (point) 'ibuffer-filter-group-name))))
+      (ibuffer-kill-filter-group it)
+    (funcall (if interactive-p #'call-interactively #'funcall)
+             #'kill-line arg)))
 
 (defun ibuffer-insert-filter-group-before (newgroup group)
   (let* ((found nil)
@@ -964,7 +952,7 @@ prompt for NAME, and use the current filters."
      (list
       (read-from-minibuffer "Save current filter groups as: ")
       ibuffer-filter-groups)))
-  (ibuffer-aif (assoc name ibuffer-saved-filter-groups)
+  (if-let ((it (assoc name ibuffer-saved-filter-groups)))
       (setcdr it groups)
     (push (cons name groups) ibuffer-saved-filter-groups))
   (ibuffer-maybe-save-stuff))
@@ -1136,7 +1124,7 @@ Interactively, prompt for NAME, and use the current 
filters."
      (list
       (read-from-minibuffer "Save current filters as: ")
       ibuffer-filtering-qualifiers)))
-  (ibuffer-aif (assoc name ibuffer-saved-filters)
+  (if-let ((it (assoc name ibuffer-saved-filters)))
       (setcdr it filters)
     (push (cons name filters) ibuffer-saved-filters))
   (ibuffer-maybe-save-stuff))
@@ -1348,11 +1336,11 @@ pattern.  For example, for a buffer associated with file
 For a buffer associated with file '/a/b/c.d', this matches
 against '/a/b'.  For a buffer not associated with a file, this
 matches against the value of `default-directory' in that buffer."
-  (:description "directory name"
-   :reader (read-from-minibuffer "Filter by directory name (regex): "))
-  (ibuffer-aif (with-current-buffer buf (ibuffer-buffer-file-name))
-      (let ((dirname (file-name-directory it)))
-        (when dirname (string-match qualifier dirname)))
+  ( :description "directory name"
+    :reader (read-from-minibuffer "Filter by directory name (regex): "))
+  (if-let ((it (with-current-buffer buf (ibuffer-buffer-file-name))))
+      (when-let ((dirname (file-name-directory it)))
+        (string-match qualifier dirname))
     (when default-directory (string-match qualifier default-directory))))
 
 ;;;###autoload (autoload 'ibuffer-filter-by-size-gt  "ibuf-ext")
@@ -1986,6 +1974,8 @@ defaults to one."
        (push buf ibuffer-do-occur-bufs)))
     (occur-1 regexp nlines ibuffer-do-occur-bufs)))
 
+(define-obsolete-function-alias 'ibuffer-remove-duplicates #'seq-uniq "29.1")
+
 (provide 'ibuf-ext)
 
 ;; Local Variables:
diff --git a/lisp/ibuf-macs.el b/lisp/ibuf-macs.el
index 718b779a92..acffb74ead 100644
--- a/lisp/ibuf-macs.el
+++ b/lisp/ibuf-macs.el
@@ -35,7 +35,7 @@
 If TEST returns non-nil, bind `it' to the value, and evaluate
 TRUE-BODY.  Otherwise, evaluate forms in FALSE-BODY as if in `progn'.
 Compare with `if'."
-  (declare (indent 2))
+  (declare (obsolete if-let "29.1") (indent 2))
   (let ((sym (make-symbol "ibuffer-aif-sym")))
     `(let ((,sym ,test))
        (if ,sym
diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el
index d6870aab5d..5cb4fe2a7a 100644
--- a/lisp/ibuffer.el
+++ b/lisp/ibuffer.el
@@ -832,7 +832,7 @@ width and the longest string in LIST."
       (let ((pt (save-excursion
                  (mouse-set-point event)
                  (point))))
-       (ibuffer-aif (get-text-property (point) 'ibuffer-filter-group-name)
+        (if-let ((it (get-text-property (point) 'ibuffer-filter-group-name)))
            (ibuffer-toggle-marks it)
          (goto-char pt)
          (let ((mark (ibuffer-current-mark)))
@@ -1263,8 +1263,8 @@ become unmarked.
 If point is on a group name, then this function operates on that
 group."
   (interactive)
-  (ibuffer-aif (get-text-property (point) 'ibuffer-filter-group-name)
-      (setq group it))
+  (when-let ((it (get-text-property (point) 'ibuffer-filter-group-name)))
+    (setq group it))
   (let ((count
         (ibuffer-map-lines
          (lambda (_buf mark)
@@ -1336,7 +1336,7 @@ If point is on a group name, this function operates on 
that group."
   (when (and movement (< movement 0))
     (setq arg (- arg)))
   (ibuffer-forward-line 0)
-  (ibuffer-aif (get-text-property (point) 'ibuffer-filter-group-name)
+  (if-let ((it (get-text-property (point) 'ibuffer-filter-group-name)))
       (progn
        (require 'ibuf-ext)
        (ibuffer-mark-on-buffer #'identity mark it))
@@ -1540,7 +1540,7 @@ If point is on a group name, this function operates on 
that group."
                    ;; `ibuffer-inline-columns' alist and insert it
                    ;; into our generated code.  Otherwise, we just
                    ;; generate a call to the column function.
-                   (ibuffer-aif (assq sym ibuffer-inline-columns)
+                    (if-let ((it (assq sym ibuffer-inline-columns)))
                        (nth 1 it)
                      `(or (,sym buffer mark) "")))
                   ;; You're not expected to understand this.  Hell, I
@@ -1737,7 +1737,7 @@ If point is on a group name, this function operates on 
that group."
        (cond ((zerop total) "No processes")
             ((= 1 total) "1 process")
             (t (format "%d processes" total))))))
-  (ibuffer-aif (get-buffer-process buffer)
+  (if-let ((it (get-buffer-process buffer)))
       (format "(%s %s)" it (process-status it))
     ""))
 
@@ -1872,8 +1872,8 @@ the buffer object itself and the current mark symbol."
            (let ((result
                   (if (buffer-live-p (ibuffer-current-buffer))
                       (when (or (null group)
-                                (ibuffer-aif (get-text-property (point) 
'ibuffer-filter-group)
-                                    (equal group it)))
+                                 (when-let ((it (get-text-property (point) 
'ibuffer-filter-group)))
+                                   (equal group it)))
                         (save-excursion
                           (funcall function
                                    (ibuffer-current-buffer)
diff --git a/lisp/international/ja-dic-utl.el b/lisp/international/ja-dic-utl.el
index cc636986f9..3f6500669a 100644
--- a/lisp/international/ja-dic-utl.el
+++ b/lisp/international/ja-dic-utl.el
@@ -112,11 +112,9 @@ without okurigana are placed at the head of the returned 
list."
                 (princ (substitute-command-keys "\
 The library `ja-dic' can't be loaded.
 
-The most common case is that you have not yet installed the library
-included in LEIM (Libraries of Emacs Input Method) which is
-distributed separately from Emacs.
-
-LEIM is available from the same ftp directory as Emacs.")))
+This might indicate a problem with your Emacs installation, as
+LEIM (Libraries of Emacs Input Method) should normally always be
+installed together with Emacs.")))
               (signal (car err) (cdr err)))))
 
   (let ((vec (make-vector len 0))
diff --git a/lisp/international/mule-diag.el b/lisp/international/mule-diag.el
index 6b630c73e8..cdf2e527e2 100644
--- a/lisp/international/mule-diag.el
+++ b/lisp/international/mule-diag.el
@@ -1065,35 +1065,39 @@ see the function `describe-fontset' for the format of 
the list."
            (help-xref-button 1 'help-input-method (match-string 1))))))))
 
 (defun list-input-methods-1 ()
-  (if (not input-method-alist)
-      (princ "
-No input method is available, perhaps because you have not
-installed LEIM (Libraries of Emacs Input Methods).")
-    (princ (substitute-command-keys
-            "LANGUAGE\n  NAME (`TITLE' in mode line)\n"))
-    (princ "    SHORT-DESCRIPTION\n------------------------------\n")
-    (setq input-method-alist
-         (sort input-method-alist
-               (lambda (x y) (string< (nth 1 x) (nth 1 y)))))
-
-    (let (language)
-      (dolist (elt input-method-alist)
-       (when (not (equal language (nth 1 elt)))
-         (setq language (nth 1 elt))
-         (princ language)
-         (terpri))
-       (princ (format-message
-                "  %s (`%s' in mode line)\n    %s\n"
-                (car elt)
-                (let ((title (nth 3 elt)))
-                  (if (and (consp title) (stringp (car title)))
-                      (car title)
-                    title))
-                ;; If the doc is multi-line, indent all
-                ;; non-blank lines. (Bug#8066)
-                (replace-regexp-in-string
-                 "\n\\(.\\)" "\n    \\1"
-                 (substitute-command-keys (or (nth 4 elt) "")))))))))
+  (with-current-buffer standard-output
+    (if (not input-method-alist)
+        (insert "
+No input method is available.
+
+This might indicate a problem with your Emacs installation, as
+LEIM (Libraries of Emacs Input Method) should normally always be
+installed together with Emacs.")
+      (insert (substitute-command-keys
+               "LANGUAGE\n  NAME (`TITLE' in mode line)\n"))
+      (insert "    SHORT-DESCRIPTION\n------------------------------\n")
+      (setq input-method-alist
+            (sort input-method-alist
+                  (lambda (x y) (string< (nth 1 x) (nth 1 y)))))
+
+      (let (language)
+        (dolist (elt input-method-alist)
+          (when (not (equal language (nth 1 elt)))
+            (setq language (nth 1 elt))
+            (insert "\n" (propertize language 'face 'help-for-help-header) 
"\n\n"))
+          (insert (format-message
+                   "  %s (`%s' in mode line)\n    %s\n"
+                   (car elt)
+                   (let ((title (nth 3 elt)))
+                     (if (and (consp title) (stringp (car title)))
+                         (car title)
+                       title))
+                   ;; If the doc is multi-line, indent all
+                   ;; non-blank lines. (Bug#8066)
+                   (replace-regexp-in-string
+                    "\n\\(.\\)" "\n    \\1"
+                    (substitute-command-keys (or (nth 4 elt) ""))))))))))
+
 
 ;;; DIAGNOSIS
 
diff --git a/lisp/international/quail.el b/lisp/international/quail.el
index 529cf97215..4bb6dbcc8e 100644
--- a/lisp/international/quail.el
+++ b/lisp/international/quail.el
@@ -249,11 +249,9 @@ This activates input method defined by PACKAGE-NAME by 
running
                  (princ (car libraries))
                  (princ (substitute-command-keys "\" is not in `load-path'.
 
-The most common case is that you have not yet installed appropriate
-libraries in LEIM (Libraries of Emacs Input Method) which is
-distributed separately from Emacs.
-
-LEIM is available from the same ftp directory as Emacs.")))
+This might indicate a problem with your Emacs installation, as
+LEIM (Libraries of Emacs Input Method) should normally always be
+installed together with Emacs.")))
                (error "Can't use the Quail package `%s'" package-name))
            (setq libraries (cdr libraries))))))
   (quail-select-package package-name)
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index ed51628c4a..d033667e87 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -257,7 +257,7 @@ arguments to pass to the OPERATION."
     (tramp-convert-file-attributes v localname id-format
       (and
        (tramp-adb-send-command-and-check
-       v (format "%s -d -l %s"
+       v (format "%s -d -l %s | cat"
                  (tramp-adb-get-ls-command v)
                  (tramp-shell-quote-argument localname)))
        (with-current-buffer (tramp-get-buffer v)
@@ -310,16 +310,15 @@ arguments to pass to the OPERATION."
       directory full match nosort id-format count
     (with-current-buffer (tramp-get-buffer v)
       (when (tramp-adb-send-command-and-check
-            v (format "%s -a -l %s"
+            v (format "%s -a -l %s | cat"
                       (tramp-adb-get-ls-command v)
                       (tramp-shell-quote-argument localname)))
        ;; We insert also filename/. and filename/.., because "ls"
-       ;; doesn't.  Looks like it does include them in toybox, since
-       ;; Android 6.
+       ;; doesn't on some file systems, like "sdcard".
        (unless (re-search-backward "\\.$" nil t)
          (narrow-to-region (point-max) (point-max))
          (tramp-adb-send-command
-          v (format "%s -d -a -l %s %s"
+          v (format "%s -d -a -l %s %s | cat"
                     (tramp-adb-get-ls-command v)
                     (tramp-shell-quote-argument
                      (tramp-compat-file-name-concat localname "."))
@@ -362,10 +361,6 @@ arguments to pass to the OPERATION."
 Android's \"ls\" command doesn't insert size column for directories:
 Emacs dired can't find files."
   (save-excursion
-    ;; Fix file names with spaces.
-    ;; FIXME: It would be better if we could call "ls" with proper
-    ;; argument or environment variable.
-    (replace-string-in-region "\\ " " " (point-min))
     ;; Insert missing size.
     (goto-char (point-min))
     (while
@@ -460,7 +455,7 @@ Emacs dired can't find files."
    (with-parsed-tramp-file-name (expand-file-name directory) nil
      (with-tramp-file-property v localname "file-name-all-completions"
        (tramp-adb-send-command
-       v (format "%s -a %s"
+       v (format "%s -a %s | cat"
                  (tramp-adb-get-ls-command v)
                  (tramp-shell-quote-argument localname)))
        (mapcar
@@ -471,9 +466,8 @@ Emacs dired can't find files."
        (with-current-buffer (tramp-get-buffer v)
          (delete-dups
           (append
-           ;; In older Android versions, "." and ".." are not
-           ;; included.  In newer versions (toybox, since Android 6)
-           ;; they are.  We fix this by `delete-dups'.
+           ;; On some file systems like "sdcard", "." and ".." are
+           ;; not included.  We fix this by `delete-dups'.
            '("." "..")
            (delq
             nil
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 5edd6e7df5..96f9d14832 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -432,7 +432,7 @@ This variant of `rx' supports common Python named REGEXPS."
              (seq (not "\\")
                   (group (or "\\\\" "\\'" "\\a" "\\b" "\\f"
                              "\\n" "\\r" "\\t" "\\v"
-                             (seq "\\" (= 3 (in "0-7")))
+                             (seq "\\" (** 1 3 (in "0-7")))
                              (seq "\\x" hex hex)))))
             (string-escape-sequence
              (or bytes-escape-sequence
@@ -556,7 +556,14 @@ the {...} holes that appear within f-strings."
   "A regular expression matching the start of a not-raw bytes literal.")
 
 (defconst python--not-raw-string-literal-start-regexp
-  (rx (or bos (not alnum)) (? (or "u" "U" "F" "f")) (or "\"" "\"\"\"" "'" 
"'''") eos)
+  (rx bos (or
+           ;; Multi-line string literals
+           (seq (? (? (not alnum)) (or "u" "U" "F" "f")) (or "\"\"\"" "'''"))
+           (seq (? anychar) (not alnum) (or "\"\"\"" "'''"))
+           ;; Single line string literals
+           (seq (? (** 0 2 anychar) (not alnum)) (or "u" "U" "F" "f") (or "'" 
"\""))
+           (seq (? (** 0 3 anychar) (not (any "'\"" alnum))) (or "'" "\"")))
+      eos)
   "A regular expression matching the start of a not-raw string literal.")
 
 (defun python--string-bytes-literal-matcher (regexp start-regexp)
@@ -565,11 +572,12 @@ the {...} holes that appear within f-strings."
     (cl-loop for result = (re-search-forward regexp limit t)
              for result-valid = (and
                                  result
-                                 (let* ((pos (nth 8 (syntax-ppss)))
-                                        (before-quote
-                                         (buffer-substring-no-properties
-                                          (max (- pos 5) (point-min))
-                                          (min (+ pos 1) (point-max)))))
+                                 (when-let* ((pos (nth 8 (syntax-ppss)))
+                                             (before-quote
+                                              (buffer-substring-no-properties
+                                               (max (- pos 4) (point-min))
+                                               (min (+ pos 1) (point-max)))))
+                                   (backward-char)
                                    (string-match-p start-regexp before-quote)))
              until (or (not result) result-valid)
              finally return (and result-valid result))))
diff --git a/test/lisp/emacs-lisp/seq-tests.el 
b/test/lisp/emacs-lisp/seq-tests.el
index 3b22e42df2..a655377e6c 100644
--- a/test/lisp/emacs-lisp/seq-tests.el
+++ b/test/lisp/emacs-lisp/seq-tests.el
@@ -559,5 +559,18 @@ Evaluate BODY for each created sequence.
     (should (equal (seq-split seq 3)
                    '("012" "345" "678" "9")))))
 
+(ert-deftest test-seq-uniq-list ()
+  (let ((list '(1 2 3)))
+    (should (equal (seq-uniq (append list list)) '(1 2 3))))
+  (let ((list '(1 2 3 2 1)))
+    (should (equal (seq-uniq list) '(1 2 3))))
+  (let ((list (list (substring "1")
+                    (substring "2")
+                    (substring "3")
+                    (substring "2")
+                    (substring "1"))))
+    (should (equal (seq-uniq list) '("1" "2" "3")))
+    (should (equal (seq-uniq list #'eq) '("1" "2" "3" "2" "1")))))
+
 (provide 'seq-tests)
 ;;; seq-tests.el ends here
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index a3e80e8956..ad81d0c09e 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -4160,7 +4160,8 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
                            (file-attributes tmp-name1))))
            ;; Skip the test, if the remote handler is not able to set
            ;; the correct time.
-           (skip-unless (set-file-times tmp-name1 (seconds-to-time 1)))
+           ;; Some remote machines cannot resolve seconds.  So we use a minute.
+           (skip-unless (set-file-times tmp-name1 (seconds-to-time 60)))
            ;; Dumb remote shells without perl(1) or stat(1) are not
            ;; able to return the date correctly.  They say "don't know".
            (unless (tramp-compat-time-equal-p
@@ -4168,16 +4169,9 @@ This tests also `make-symbolic-link', `file-truename' 
and `add-name-to-file'."
                      (file-attributes tmp-name1))
                     tramp-time-dont-know)
              (should
-              (or (tramp-compat-time-equal-p
-                    (file-attribute-modification-time
-                    (file-attributes tmp-name1))
-                   (seconds-to-time 1))
-                  ;; Some remote machines cannot resolve seconds.
-                  ;; The return the modification time `(0 0).
-                  (tramp-compat-time-equal-p
-                    (file-attribute-modification-time
-                    (file-attributes tmp-name1))
-                   (seconds-to-time 0))))
+              (tramp-compat-time-equal-p
+                (file-attribute-modification-time (file-attributes tmp-name1))
+               (seconds-to-time 60)))
              ;; Setting the time for not existing files shall fail.
              (should-error
               (set-file-times tmp-name2)
@@ -4192,18 +4186,12 @@ This tests also `make-symbolic-link', `file-truename' 
and `add-name-to-file'."
              ;; regular files, there shouldn't be a difference.
              (when (tramp--test-emacs28-p)
                (with-no-warnings
-                 (set-file-times tmp-name1 (seconds-to-time 1) 'nofollow)
+                 (set-file-times tmp-name1 (seconds-to-time 60) 'nofollow)
                  (should
-                  (or (tramp-compat-time-equal-p
-                       (file-attribute-modification-time
-                        (file-attributes tmp-name1))
-                       (seconds-to-time 1))
-                      ;; Some remote machines cannot resolve seconds.
-                      ;; The return the modification time `(0 0).
-                      (tramp-compat-time-equal-p
-                       (file-attribute-modification-time
-                        (file-attributes tmp-name1))
-                       (seconds-to-time 0))))))))
+                  (tramp-compat-time-equal-p
+                    (file-attribute-modification-time
+                    (file-attributes tmp-name1))
+                   (seconds-to-time 60)))))))
 
        ;; Cleanup.
        (ignore-errors
diff --git a/test/lisp/progmodes/python-tests.el 
b/test/lisp/progmodes/python-tests.el
index e3c8d5554a..d303050fad 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -407,6 +407,81 @@ u\"\\n\""
      (31 . font-lock-constant-face)
      (33 . font-lock-string-face))))
 
+(ert-deftest python-font-lock-escape-sequence-multiline-string ()
+  (python-tests-assert-faces
+   (let ((escape-sequences "\\x12 \123 \\n \\u1234 \\U00010348 \\N{Plus-Minus 
Sign}"))
+     (cl-loop for string-prefix in '("" "f" "rf" "fr" "r" "rb" "br" "b")
+              concat (cl-loop for quote-string in '("\"\"\"" "'''")
+                              concat (concat string-prefix
+                                             quote-string
+                                             escape-sequences
+                                             quote-string
+                                             "\n"))))
+   '((1 . font-lock-doc-face)
+     (4 . font-lock-constant-face)
+     (8 . font-lock-doc-face)
+     (11 . font-lock-constant-face)
+     (13 . font-lock-doc-face)
+     (14 . font-lock-constant-face)
+     (20 . font-lock-doc-face)
+     (21 . font-lock-constant-face)
+     (31 . font-lock-doc-face)
+     (32 . font-lock-constant-face)
+     (51 . font-lock-doc-face) (54)
+     (55 . font-lock-doc-face)
+     (58 . font-lock-constant-face)
+     (62 . font-lock-doc-face)
+     (65 . font-lock-constant-face)
+     (67 . font-lock-doc-face)
+     (68 . font-lock-constant-face)
+     (74 . font-lock-doc-face)
+     (75 . font-lock-constant-face)
+     (85 . font-lock-doc-face)
+     (86 . font-lock-constant-face)
+     (105 . font-lock-doc-face) (108)
+     (110 . font-lock-string-face)
+     (113 . font-lock-constant-face)
+     (117 . font-lock-string-face)
+     (120 . font-lock-constant-face)
+     (122 . font-lock-string-face)
+     (123 . font-lock-constant-face)
+     (129 . font-lock-string-face)
+     (130 . font-lock-constant-face)
+     (140 . font-lock-string-face)
+     (141 . font-lock-constant-face)
+     (160 . font-lock-string-face) (163)
+     (165 . font-lock-string-face)
+     (168 . font-lock-constant-face)
+     (172 . font-lock-string-face)
+     (175 . font-lock-constant-face)
+     (177 . font-lock-string-face)
+     (178 . font-lock-constant-face)
+     (184 . font-lock-string-face)
+     (185 . font-lock-constant-face)
+     (195 . font-lock-string-face)
+     (196 . font-lock-constant-face)
+     (215 . font-lock-string-face) (218)
+     (221 . font-lock-string-face) (274)
+     (277 . font-lock-string-face) (330)
+     (333 . font-lock-string-face) (386)
+     (389 . font-lock-string-face) (442)
+     (444 . font-lock-string-face) (497)
+     (499 . font-lock-string-face) (552)
+     (555 . font-lock-string-face) (608)
+     (611 . font-lock-string-face) (664)
+     (667 . font-lock-string-face) (720)
+     (723 . font-lock-string-face) (776)
+     (778 . font-lock-string-face)
+     (781 . font-lock-constant-face)
+     (785 . font-lock-string-face)
+     (788 . font-lock-constant-face)
+     (790 . font-lock-string-face) (831)
+     (833 . font-lock-string-face)
+     (836 . font-lock-constant-face)
+     (840 . font-lock-string-face)
+     (843 . font-lock-constant-face)
+     (845 . font-lock-string-face) (886))))
+
 (ert-deftest python-font-lock-escape-sequence-bytes-newline ()
   (python-tests-assert-faces
    "b'\\n'
@@ -421,19 +496,23 @@ b\"\\n\""
 
 (ert-deftest python-font-lock-escape-sequence-hex-octal ()
   (python-tests-assert-faces
-   "b'\\x12 \\777'
-'\\x12 \\777'"
+   "b'\\x12 \\777 \\1\\23'
+'\\x12 \\777 \\1\\23'"
    '((1)
      (2 . font-lock-doc-face)
      (3 . font-lock-constant-face)
      (7 . font-lock-doc-face)
      (8 . font-lock-constant-face)
-     (12 . font-lock-doc-face) (13)
-     (14 . font-lock-doc-face)
-     (15 . font-lock-constant-face)
-     (19 . font-lock-doc-face)
-     (20 . font-lock-constant-face)
-     (24 . font-lock-doc-face))))
+     (12 . font-lock-doc-face)
+     (13 . font-lock-constant-face)
+     (18 . font-lock-doc-face) (19)
+     (20 . font-lock-doc-face)
+     (21 . font-lock-constant-face)
+     (25 . font-lock-doc-face)
+     (26 . font-lock-constant-face)
+     (30 . font-lock-doc-face)
+     (31 . font-lock-constant-face)
+     (36 . font-lock-doc-face))))
 
 (ert-deftest python-font-lock-escape-sequence-unicode ()
   (python-tests-assert-faces



reply via email to

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