From e74fb4688b78f549fbc79a2163c92ba64296ee3d Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Mon, 24 Feb 2020 09:55:09 -0500 Subject: * lisp/emacs-lisp/cursor-sensor.el (cursor-sensor--detect): Change last fix Make sure we always work in the selected-window's buffer. --- lisp/emacs-lisp/cursor-sensor.el | 112 ++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 55 deletions(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/emacs-lisp/cursor-sensor.el b/lisp/emacs-lisp/cursor-sensor.el index 7728e78c471..d50f7ad0be5 100644 --- a/lisp/emacs-lisp/cursor-sensor.el +++ b/lisp/emacs-lisp/cursor-sensor.el @@ -141,61 +141,63 @@ By convention, this is a list of symbols where each symbol stands for the ;;; Detect cursor movement. (defun cursor-sensor--detect (&optional window) - (unless cursor-sensor-inhibit - (let* ((point (window-point window)) - ;; It's often desirable to make the cursor-sensor-functions property - ;; non-sticky on both ends, but that means get-pos-property might - ;; never see it. - (new (and (eq (current-buffer) (window-buffer)) - (or (get-char-property point 'cursor-sensor-functions) - (unless (<= (point-min) point) - (get-char-property (1- point) 'cursor-sensor-functions))))) - (old (window-parameter window 'cursor-sensor--last-state)) - (oldposmark (car old)) - (oldpos (or (if oldposmark (marker-position oldposmark)) - (point-min))) - (start (min oldpos point)) - (end (max oldpos point))) - (unless (or (null old) (eq (marker-buffer oldposmark) (current-buffer))) - ;; `window' does not display the same buffer any more! - (setcdr old nil)) - (if (or (and (null new) (null (cdr old))) - (and (eq new (cdr old)) - (eq (next-single-char-property-change - start 'cursor-sensor-functions nil end) - end))) - ;; Clearly nothing to do. - nil - ;; Maybe something to do. Let's see exactly what needs to run. - (let* ((missing-p - (lambda (f) - "Non-nil if F is missing somewhere between START and END." - (let ((pos start) - (missing nil)) - (while (< pos end) - (setq pos (next-single-char-property-change - pos 'cursor-sensor-functions - nil end)) - (unless (memq f (get-char-property - pos 'cursor-sensor-functions)) - (setq missing t))) - missing))) - (window (selected-window))) - (dolist (f (cdr old)) - (unless (and (memq f new) (not (funcall missing-p f))) - (funcall f window oldpos 'left))) - (dolist (f new) - (unless (and (memq f (cdr old)) (not (funcall missing-p f))) - (funcall f window oldpos 'entered))))) - - ;; Remember current state for next time. - ;; Re-read cursor-sensor-functions since the functions may have moved - ;; window-point! - (if old - (progn (move-marker (car old) point) - (setcdr old new)) - (set-window-parameter window 'cursor-sensor--last-state - (cons (copy-marker point) new)))))) + (with-current-buffer (window-buffer window) + (unless cursor-sensor-inhibit + (let* ((point (window-point window)) + ;; It's often desirable to make the + ;; cursor-sensor-functions property non-sticky on both + ;; ends, but that means get-pos-property might never + ;; see it. + (new (or (get-char-property point 'cursor-sensor-functions) + (unless (<= (point-min) point) + (get-char-property (1- point) + 'cursor-sensor-functions)))) + (old (window-parameter window 'cursor-sensor--last-state)) + (oldposmark (car old)) + (oldpos (or (if oldposmark (marker-position oldposmark)) + (point-min))) + (start (min oldpos point)) + (end (max oldpos point))) + (unless (or (null old) (eq (marker-buffer oldposmark) (current-buffer))) + ;; `window' does not display the same buffer any more! + (setcdr old nil)) + (if (or (and (null new) (null (cdr old))) + (and (eq new (cdr old)) + (eq (next-single-char-property-change + start 'cursor-sensor-functions nil end) + end))) + ;; Clearly nothing to do. + nil + ;; Maybe something to do. Let's see exactly what needs to run. + (let* ((missing-p + (lambda (f) + "Non-nil if F is missing somewhere between START and END." + (let ((pos start) + (missing nil)) + (while (< pos end) + (setq pos (next-single-char-property-change + pos 'cursor-sensor-functions + nil end)) + (unless (memq f (get-char-property + pos 'cursor-sensor-functions)) + (setq missing t))) + missing))) + (window (selected-window))) + (dolist (f (cdr old)) + (unless (and (memq f new) (not (funcall missing-p f))) + (funcall f window oldpos 'left))) + (dolist (f new) + (unless (and (memq f (cdr old)) (not (funcall missing-p f))) + (funcall f window oldpos 'entered))))) + + ;; Remember current state for next time. + ;; Re-read cursor-sensor-functions since the functions may have moved + ;; window-point! + (if old + (progn (move-marker (car old) point) + (setcdr old new)) + (set-window-parameter window 'cursor-sensor--last-state + (cons (copy-marker point) new))))))) ;;;###autoload (define-minor-mode cursor-sensor-mode -- cgit v1.2.3 From 696ee02c3a40cf0e19f963cfaf8004ca42f7e897 Mon Sep 17 00:00:00 2001 From: Štěpán Němec Date: Thu, 29 Aug 2019 19:42:21 +0200 Subject: checkdoc: Don't mistake "cf." for sentence end * lisp/emacs-lisp/checkdoc.el (checkdoc-sentencespace-region-engine): Recognize "cf." as an abbreviation, not a sentence end. --- lisp/emacs-lisp/checkdoc.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index ccdddb47c35..e15836ee7d8 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -2073,7 +2073,7 @@ If the offending word is in a piece of quoted text, then it is skipped." ;; piece of an abbreviation ;; FIXME etc (looking-at - "\\([a-zA-Z]\\|[iI]\\.?e\\|[eE]\\.?g\\)\\.")) + "\\([a-zA-Z]\\|[iI]\\.?e\\|[eE]\\.?g\\|[cC]f\\)\\.")) (error t)))) (if (checkdoc-autofix-ask-replace b e -- cgit v1.2.3 From d42419590563964fd61b35dea7738e77c0f90cba Mon Sep 17 00:00:00 2001 From: Mattias Engdegård Date: Sat, 29 Feb 2020 10:12:10 +0100 Subject: Fix rx charset generation * lisp/emacs-lisp/rx.el (rx--charset-p): Don't overquote. (rx--generate-alt): Generate '.' for negated newline. * test/lisp/emacs-lisp/rx-tests.el (rx-any, rx-charset-or): Test. --- lisp/emacs-lisp/rx.el | 6 +++++- test/lisp/emacs-lisp/rx-tests.el | 11 +++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index b4cab5715da..1ee5e8294a6 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -305,7 +305,7 @@ Return (REGEXP . PRECEDENCE)." "Whether FORM looks like a charset, only consisting of character intervals and set operations." (or (and (consp form) - (or (and (memq (car form) '(any 'in 'char)) + (or (and (memq (car form) '(any in char)) (rx--every (lambda (x) (not (symbolp x))) (cdr form))) (and (memq (car form) '(not or | intersection)) (rx--every #'rx--charset-p (cdr form))))) @@ -450,6 +450,10 @@ classes." (not negated)) (cons (list (regexp-quote (char-to-string (caar items)))) t)) + ;; Negated newline. + ((and (equal items '((?\n . ?\n))) + negated) + (rx--translate-symbol 'nonl)) ;; At least one character or class, possibly negated. (t (cons diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index a6c172adfe7..2e34d65a9aa 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -130,7 +130,10 @@ (should (equal (rx (any "") (not (any ""))) "\\`a\\`[^z-a]")) (should (equal (rx (any space ?a digit space)) - "[a[:space:][:digit:]]"))) + "[a[:space:][:digit:]]")) + (should (equal (rx (not "\n") (not ?\n) (not (any "\n")) (not-char ?\n) + (| (not (in "a\n")) (not (char ?\n (?b . ?b))))) + "....."))) (ert-deftest rx-pcase () (should (equal (pcase "a 1 2 3 1 1 b" @@ -298,7 +301,11 @@ (not (any "a-k")))) "[^abh-k]")) (should (equal (rx (or ?f (any "b-e") "a") (not (or ?x "y" (any "s-w")))) - "[a-f][^s-y]"))) + "[a-f][^s-y]")) + (should (equal (rx (not (or (in "abc") (char "bcd")))) + "[^a-d]")) + (should (equal (rx (or (not (in "abc")) (not (char "bcd")))) + "[^bc]"))) (ert-deftest rx-def-in-charset-or () (rx-let ((a (any "badc")) -- cgit v1.2.3 From 49d3cd90bd80a225d5ec26027318ffb4606ff513 Mon Sep 17 00:00:00 2001 From: Mattias Engdegård Date: Tue, 11 Feb 2020 20:04:42 +0100 Subject: rx: Improve 'or' compositionality (bug#37659) Perform 'regexp-opt' on nested 'or' forms, and after expansion of user-defined and 'eval' forms. Characters are now turned into strings for wider 'regexp-opt' scope. This preserves the longest-match semantics for string in 'or' forms over composition. * doc/lispref/searching.texi (Rx Constructs): Document. * lisp/emacs-lisp/rx.el (rx--normalise-or-arg) (rx--all-string-or-args): New. (rx--translate-or): Normalise arguments first, and check for strings in subforms. (rx--expand-eval): Extracted from rx--translate-eval. (rx--translate-eval): Call rx--expand-eval. * test/lisp/emacs-lisp/rx-tests.el (rx-or, rx-def-in-or): Add tests. * etc/NEWS: Announce. --- doc/lispref/searching.texi | 5 +-- etc/NEWS | 6 ++++ lisp/emacs-lisp/rx.el | 76 +++++++++++++++++++++++++--------------- test/lisp/emacs-lisp/rx-tests.el | 13 ++++++- 4 files changed, 69 insertions(+), 31 deletions(-) (limited to 'lisp/emacs-lisp') diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi index a4d5a27203f..1a090ebe101 100644 --- a/doc/lispref/searching.texi +++ b/doc/lispref/searching.texi @@ -1086,8 +1086,9 @@ Corresponding string regexp: @samp{@var{A}@var{B}@dots{}} @itemx @code{(| @var{rx}@dots{})} @cindex @code{|} in rx Match exactly one of the @var{rx}s. -If all arguments are string literals, the longest possible match -will always be used. Otherwise, either the longest match or the +If all arguments are strings, characters, or @code{or} forms +so constrained, the longest possible match will always be used. +Otherwise, either the longest match or the first (in left-to-right order) will be used. Without arguments, the expression will not match anything at all.@* Corresponding string regexp: @samp{@var{A}\|@var{B}\|@dots{}}. diff --git a/etc/NEWS b/etc/NEWS index e9dfd266b46..6e2b1fe00e2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2325,6 +2325,12 @@ expressions from simpler parts. +++ *** 'not' argument can now be a character or single-char string. ++++ +*** Nested 'or' forms of strings guarantee a longest match. +For example, (or (or "IN" "OUT") (or "INPUT" "OUTPUT")) now matches +the whole string "INPUT" if present, not just "IN". Previously, this +was only guaranteed inside a single 'or' form of string literals. + ** Frames +++ diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index 1ee5e8294a6..a0b2444346a 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -254,22 +254,39 @@ Left-fold the list L, starting with X, by the binary function F." (setq l (cdr l))) x) +(defun rx--normalise-or-arg (form) + "Normalise the `or' argument FORM. +Characters become strings, user-definitions and `eval' forms are expanded, +and `or' forms are normalised recursively." + (cond ((characterp form) + (char-to-string form)) + ((and (consp form) (memq (car form) '(or |))) + (cons (car form) (mapcar #'rx--normalise-or-arg (cdr form)))) + ((and (consp form) (eq (car form) 'eval)) + (rx--normalise-or-arg (rx--expand-eval (cdr form)))) + (t + (let ((expanded (rx--expand-def form))) + (if expanded + (rx--normalise-or-arg expanded) + form))))) + +(defun rx--all-string-or-args (body) + "If BODY only consists of strings or such `or' forms, return all the strings. +Otherwise throw `rx--nonstring'." + (mapcan (lambda (form) + (cond ((stringp form) (list form)) + ((and (consp form) (memq (car form) '(or |))) + (rx--all-string-or-args (cdr form))) + (t (throw 'rx--nonstring nil)))) + body)) + (defun rx--translate-or (body) "Translate an or-pattern of zero or more rx items. Return (REGEXP . PRECEDENCE)." ;; FIXME: Possible improvements: ;; - ;; - Turn single characters to strings: (or ?a ?b) -> (or "a" "b"), - ;; so that they can be candidates for regexp-opt. - ;; - ;; - Translate compile-time strings (`eval' forms), again for regexp-opt. - ;; ;; - Flatten sub-patterns first: (or (or A B) (or C D)) -> (or A B C D) - ;; in order to improve effectiveness of regexp-opt. - ;; This would also help composability. - ;; - ;; - Use associativity to run regexp-opt on contiguous subsets of arguments - ;; if not all of them are strings. Example: + ;; Then call regexp-opt on runs of string arguments. Example: ;; (or (+ digit) "CHARLIE" "CHAN" (+ blank)) ;; -> (or (+ digit) (or "CHARLIE" "CHAN") (+ blank)) ;; @@ -279,27 +296,26 @@ Return (REGEXP . PRECEDENCE)." ;; so that (or "@" "%" digit (any "A-Z" space) (syntax word)) ;; -> (any "@" "%" digit "A-Z" space word) ;; -> "[A-Z@%[:digit:][:space:][:word:]]" - ;; - ;; Problem: If a subpattern is carefully written to be - ;; optimizable by regexp-opt, how do we prevent the transforms - ;; above from destroying that property? - ;; Example: (or "a" (or "abc" "abd" "abe")) (cond ((null body) ; No items: a never-matching regexp. (rx--empty)) ((null (cdr body)) ; Single item. (rx--translate (car body))) - ((rx--every #'stringp body) ; All strings. - (cons (list (regexp-opt body nil)) - t)) - ((rx--every #'rx--charset-p body) ; All charsets. - (rx--translate-union nil body)) (t - (cons (append (car (rx--translate (car body))) - (mapcan (lambda (item) - (cons "\\|" (car (rx--translate item)))) - (cdr body))) - nil)))) + (let* ((args (mapcar #'rx--normalise-or-arg body)) + (all-strings (catch 'rx--nonstring (rx--all-string-or-args args)))) + (cond + (all-strings ; Only strings. + (cons (list (regexp-opt all-strings nil)) + t)) + ((rx--every #'rx--charset-p args) ; All charsets. + (rx--translate-union nil args)) + (t + (cons (append (car (rx--translate (car args))) + (mapcan (lambda (item) + (cons "\\|" (car (rx--translate item)))) + (cdr args))) + nil))))))) (defun rx--charset-p (form) "Whether FORM looks like a charset, only consisting of character intervals @@ -840,11 +856,15 @@ Return (REGEXP . PRECEDENCE)." (cons (list (list 'regexp-quote arg)) 'seq)) (t (error "rx `literal' form with non-string argument"))))) -(defun rx--translate-eval (body) - "Translate the `eval' form. Return (REGEXP . PRECEDENCE)." +(defun rx--expand-eval (body) + "Expand `eval' arguments. Return a new rx form." (unless (and body (null (cdr body))) (error "rx `eval' form takes exactly one argument")) - (rx--translate (eval (car body)))) + (eval (car body))) + +(defun rx--translate-eval (body) + "Translate the `eval' form. Return (REGEXP . PRECEDENCE)." + (rx--translate (rx--expand-eval body))) (defvar rx--regexp-atomic-regexp nil) diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index 2e34d65a9aa..4888e1d9d1e 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -42,13 +42,24 @@ (ert-deftest rx-or () (should (equal (rx (or "ab" (| "c" nonl) "de")) "ab\\|c\\|.\\|de")) - (should (equal (rx (or "ab" "abc" "a")) + (should (equal (rx (or "ab" "abc" ?a)) "\\(?:a\\(?:bc?\\)?\\)")) + (should (equal (rx (or "ab" (| (or "abcd" "abcde")) (or "a" "abc"))) + "\\(?:a\\(?:b\\(?:c\\(?:de?\\)?\\)?\\)?\\)")) + (should (equal (rx (or "a" (eval (string ?a ?b)))) + "\\(?:ab?\\)")) (should (equal (rx (| nonl "a") (| "b" blank)) "\\(?:.\\|a\\)\\(?:b\\|[[:blank:]]\\)")) (should (equal (rx (|)) "\\`a\\`"))) +(ert-deftest rx-def-in-or () + (rx-let ((a b) + (b (or "abc" c)) + (c ?a)) + (should (equal (rx (or a (| "ab" "abcde") "abcd")) + "\\(?:a\\(?:b\\(?:c\\(?:de?\\)?\\)?\\)?\\)")))) + (ert-deftest rx-char-any () "Test character alternatives with `]' and `-' (Bug#25123)." (should (equal -- cgit v1.2.3 From 40b217c2bfde6da6529499c9526a460fcdbeec8f Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Wed, 4 Mar 2020 04:41:45 +0100 Subject: Bump checkdoc-version to match library header * lisp/emacs-lisp/checkdoc.el (checkdoc-version): Bump version. --- lisp/emacs-lisp/checkdoc.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index e15836ee7d8..fa5d1cff417 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -168,7 +168,7 @@ ;; not specifically docstring related. Would this even be useful? ;;; Code: -(defvar checkdoc-version "0.6.1" +(defvar checkdoc-version "0.6.2" "Release version of checkdoc you are currently running.") (require 'cl-lib) -- cgit v1.2.3 From 40fb20061e6b9b2b22aeee5b7e9f038dc9ba843b Mon Sep 17 00:00:00 2001 From: Mattias Engdegård Date: Thu, 5 Mar 2020 12:10:51 +0100 Subject: * lisp/emacs-lisp/rx.el (rx--string-to-intervals): Fix error string. --- lisp/emacs-lisp/rx.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index a0b2444346a..d4a91710273 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -360,7 +360,7 @@ character X becomes (?X . ?X). Return the intervals in a list." (push (cons start end) intervals)) (t (error "Invalid rx `any' range: %s" - (substring str i 3)))) + (substring str i (+ i 3))))) (setq i (+ i 3)))) (t ;; Single character. -- cgit v1.2.3 From 1814c7e158685045278f991de5eba4e40e8c8199 Mon Sep 17 00:00:00 2001 From: Mattias Engdegård Date: Thu, 5 Mar 2020 12:49:26 +0100 Subject: Fix rx error with ? and ?? The ? and ?? rx operators are special in that they can be written as characters (space and '?' respectively). This confused the definition look-up mechanism in rare cases. * lisp/emacs-lisp/rx.el (rx--expand-def): Don't look up non-symbols. * test/lisp/emacs-lisp/rx-tests.el (rx-charset-or): Test. --- lisp/emacs-lisp/rx.el | 2 +- test/lisp/emacs-lisp/rx-tests.el | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index d4a91710273..aa4b2addd47 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -134,7 +134,7 @@ Each entry is: (if (cdr def) (error "Not an `rx' symbol definition: %s" form) (car def))))) - ((consp form) + ((and (consp form) (symbolp (car form))) (let* ((op (car form)) (def (rx--lookup-def op))) (and def diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index 4888e1d9d1e..0fece4004bd 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -316,7 +316,9 @@ (should (equal (rx (not (or (in "abc") (char "bcd")))) "[^a-d]")) (should (equal (rx (or (not (in "abc")) (not (char "bcd")))) - "[^bc]"))) + "[^bc]")) + (should (equal (rx (or "x" (? "yz"))) + "x\\|\\(?:yz\\)?"))) (ert-deftest rx-def-in-charset-or () (rx-let ((a (any "badc")) -- cgit v1.2.3 From 363d927086dbdc4e5073393889b76eb0470785f4 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 7 Mar 2020 09:47:03 -0800 Subject: Fix bug with JIT stealth timers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * lisp/emacs-lisp/timer.el (run-at-time): Don’t assume that Lisp time values must be conses (Bug#39944). --- lisp/emacs-lisp/timer.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el index 74a94957e73..9eb8feed0f1 100644 --- a/lisp/emacs-lisp/timer.el +++ b/lisp/emacs-lisp/timer.el @@ -378,7 +378,7 @@ This function returns a timer object which you can use in (decoded-time-year now) (decoded-time-zone now))))))) - (or (consp time) + (or (time-equal-p time time) (error "Invalid time format")) (let ((timer (timer-create))) -- cgit v1.2.3 From 3cbf4cb79600ade39a186f31448e56e0e6fdd364 Mon Sep 17 00:00:00 2001 From: Andrew Eggenberger Date: Thu, 27 Feb 2020 21:43:47 -0600 Subject: Eliminate use of cl-concatenate in 'seq' package Fixes (Bug#39761) by making cl-extra dependent on seq rather than vice versa. * lisp/emacs-lisp/seq.el (seq-concatenate): Move cl-concatenate's code here instead of calling it. * lisp/emacs-lisp/cl-extra.el (cl-concatenate): Use cl-concatenate. Copyright-paperwork-exempt: yes --- lisp/emacs-lisp/cl-extra.el | 6 +----- lisp/emacs-lisp/seq.el | 6 +++++- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el index e3dabdfcef2..e9bfe8df5f2 100644 --- a/lisp/emacs-lisp/cl-extra.el +++ b/lisp/emacs-lisp/cl-extra.el @@ -556,11 +556,7 @@ too large if positive or too small if negative)." (defun cl-concatenate (type &rest sequences) "Concatenate, into a sequence of type TYPE, the argument SEQUENCEs. \n(fn TYPE SEQUENCE...)" - (pcase type - ('vector (apply #'vconcat sequences)) - ('string (apply #'concat sequences)) - ('list (apply #'append (append sequences '(nil)))) - (_ (error "Not a sequence type name: %S" type)))) + (seq-concatenate type sequences)) ;;; List functions. diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 0b946dd7365..629a7a5fb30 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -285,7 +285,11 @@ sorted. FUNCTION must be a function of one argument." TYPE must be one of following symbols: vector, string or list. \n(fn TYPE SEQUENCE...)" - (apply #'cl-concatenate type (seq-map #'seq-into-sequence sequences))) + (pcase type + ('vector (apply #'vconcat sequences)) + ('string (apply #'concat sequences)) + ('list (apply #'append (append sequences '(nil)))) + (_ (error "Not a sequence type name: %S" type)))) (cl-defgeneric seq-into-sequence (sequence) "Convert SEQUENCE into a sequence. -- cgit v1.2.3 From b16ba4041db928826df5f58e9bfac9fb38208145 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 7 Mar 2020 18:45:23 -0500 Subject: ; lisp/emacs-lisp/seq.el: Explain why we don't use cl-lib here --- lisp/emacs-lisp/seq.el | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lisp/emacs-lisp') diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 629a7a5fb30..e3037a71901 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -58,6 +58,10 @@ (eval-when-compile (require 'cl-generic)) +;; We used to use some sequence functions from cl-lib, but this +;; dependency was swapped around so that it will be easier to make +;; seq.el preloaded in the future. See also Bug#39761#26. + (defmacro seq-doseq (spec &rest body) "Loop over a sequence. Evaluate BODY with VAR bound to each element of SEQUENCE, in turn. -- cgit v1.2.3 From e4fb95fa18072cedb021a82f7aa0e79fa6ca387a Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sat, 7 Mar 2020 23:28:12 -0500 Subject: * lisp/emacs-lisp/bytecomp.el: Drop warning for loading into Emacs<23 Stash the major version of the compiling Emacs such that the loading Emacs can later detect when loading a file compiled by a too-new Emacs. (byte-compile-fix-header): Remove. (byte-compile-from-buffer): Don't call it any more. (byte-compile-insert-header): Stash the emacs-major-version in it. Don't leave space for `byte-compile-fix-header`. --- lisp/emacs-lisp/bytecomp.el | 68 ++++++++++----------------------------------- 1 file changed, 15 insertions(+), 53 deletions(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 63348456a15..4f01918bdb9 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2140,50 +2140,9 @@ With argument ARG, insert value in current buffer after the form." ;; Make warnings about unresolved functions ;; give the end of the file as their position. (setq byte-compile-last-position (point-max)) - (byte-compile-warn-about-unresolved-functions)) - ;; Fix up the header at the front of the output - ;; if the buffer contains multibyte characters. - (and byte-compile-current-file - (with-current-buffer byte-compile--outbuffer - (byte-compile-fix-header byte-compile-current-file)))) + (byte-compile-warn-about-unresolved-functions))) byte-compile--outbuffer))) -(defun byte-compile-fix-header (_filename) - "If the current buffer has any multibyte characters, insert a version test." - (when (< (point-max) (position-bytes (point-max))) - (goto-char (point-min)) - ;; Find the comment that describes the version condition. - (when (search-forward "\n;;; This file does not contain utf-8" nil t) - (narrow-to-region (line-beginning-position) (point-max)) - ;; Find the first line of ballast semicolons. - (search-forward ";;;;;;;;;;") - (beginning-of-line) - (narrow-to-region (point-min) (point)) - (let ((old-header-end (point)) - (minimum-version "23") - delta) - (delete-region (point-min) (point-max)) - (insert - ";;; This file contains utf-8 non-ASCII characters,\n" - ";;; and so cannot be loaded into Emacs 22 or earlier.\n" - ;; Have to check if emacs-version is bound so that this works - ;; in files loaded early in loadup.el. - "(and (boundp 'emacs-version)\n" - ;; If there is a name at the end of emacs-version, - ;; don't try to check the version number. - " (< (aref emacs-version (1- (length emacs-version))) ?A)\n" - (format " (string-lessp emacs-version \"%s\")\n" minimum-version) - ;; Because the header must fit in a fixed width, we cannot - ;; insert arbitrary-length file names (Bug#11585). - " (error \"`%s' was compiled for " - (format "Emacs %s or later\" #$))\n\n" minimum-version)) - ;; Now compensate for any change in size, to make sure all - ;; positions in the file remain valid. - (setq delta (- (point-max) old-header-end)) - (goto-char (point-max)) - (widen) - (delete-char delta))))) - (defun byte-compile-insert-header (_filename outbuffer) "Insert a header at the start of OUTBUFFER. Call from the source buffer." @@ -2201,7 +2160,19 @@ Call from the source buffer." ;; 0 string ;ELC GNU Emacs Lisp compiled file, ;; >4 byte x version %d (insert - ";ELC" 23 "\000\000\000\n" + ";ELC" + (let ((version + (if (zerop emacs-minor-version) + ;; Let's allow silently loading into Emacs-27 + ;; files compiled with Emacs-28.0.NN since the two can + ;; be almost identical (e.g. right after cutting the + ;; release branch) and people running the development + ;; branch can be presumed to know that it's risky anyway. + (1- emacs-major-version) emacs-major-version))) + ;; Make sure the version is a plain byte that doesn't end the comment! + (cl-assert (and (> version 13) (< version 128))) + version) + "\000\000\000\n" ";;; Compiled\n" ";;; in Emacs version " emacs-version "\n" ";;; with" @@ -2213,16 +2184,7 @@ Call from the source buffer." ".\n" (if dynamic ";;; Function definitions are lazy-loaded.\n" "") - "\n" - ;; Note that byte-compile-fix-header may change this. - ";;; This file does not contain utf-8 non-ASCII characters,\n" - ";;; and so can be loaded in Emacs versions earlier than 23.\n\n" - ;; Insert semicolons as ballast, so that byte-compile-fix-header - ;; can delete them so as to keep the buffer positions - ;; constant for the actual compiled code. - ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n" - ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n" - ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n")))) + "\n\n")))) (defun byte-compile-output-file-form (form) ;; Write the given form to the output buffer, being careful of docstrings -- cgit v1.2.3 From 0a3f8da6e1a56ada409cf1677ac40fcc75a8a33c Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 8 Mar 2020 00:25:15 -0800 Subject: Simplify run-at-time * lisp/emacs-lisp/timer.el (run-at-time): Remove unnecessary test (Bug#39944). --- lisp/emacs-lisp/timer.el | 3 --- 1 file changed, 3 deletions(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el index 9eb8feed0f1..61fd05cbb80 100644 --- a/lisp/emacs-lisp/timer.el +++ b/lisp/emacs-lisp/timer.el @@ -378,9 +378,6 @@ This function returns a timer object which you can use in (decoded-time-year now) (decoded-time-zone now))))))) - (or (time-equal-p time time) - (error "Invalid time format")) - (let ((timer (timer-create))) (timer-set-time timer time repeat) (timer-set-function timer function args) -- cgit v1.2.3