diff options
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r-- | lisp/emacs-lisp/advice.el | 19 | ||||
-rw-r--r-- | lisp/emacs-lisp/byte-opt.el | 57 | ||||
-rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 24 | ||||
-rw-r--r-- | lisp/emacs-lisp/checkdoc.el | 21 | ||||
-rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 2 | ||||
-rw-r--r-- | lisp/emacs-lisp/ert.el | 3 | ||||
-rw-r--r-- | lisp/emacs-lisp/helper.el | 1 | ||||
-rw-r--r-- | lisp/emacs-lisp/loaddefs-gen.el | 35 | ||||
-rw-r--r-- | lisp/emacs-lisp/macroexp.el | 2 | ||||
-rw-r--r-- | lisp/emacs-lisp/nadvice.el | 24 | ||||
-rw-r--r-- | lisp/emacs-lisp/package.el | 2 | ||||
-rw-r--r-- | lisp/emacs-lisp/pcase.el | 13 | ||||
-rw-r--r-- | lisp/emacs-lisp/ring.el | 4 | ||||
-rw-r--r-- | lisp/emacs-lisp/seq.el | 20 | ||||
-rw-r--r-- | lisp/emacs-lisp/subr-x.el | 22 |
15 files changed, 138 insertions, 111 deletions
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el index 2a2bcca7007..d383650f4e5 100644 --- a/lisp/emacs-lisp/advice.el +++ b/lisp/emacs-lisp/advice.el @@ -1054,9 +1054,9 @@ ;; (print "Let's clean up now!")) ;; foo ;; -;; Now `foo's advice is byte-compiled: +;; Now `foo's advice is compiled: ;; -;; (byte-code-function-p 'ad-Advice-foo) +;; (compiled-function-p 'ad-Advice-foo) ;; t ;; ;; (foo 3) @@ -1298,7 +1298,7 @@ ;; constructed during preactivation was used, even though we did not specify ;; the `compile' flag: ;; -;; (byte-code-function-p 'ad-Advice-fum) +;; (compiled-function-p 'ad-Advice-fum) ;; t ;; ;; (fum 2) @@ -1329,7 +1329,7 @@ ;; ;; A new uncompiled advised definition got constructed: ;; -;; (byte-code-function-p 'ad-Advice-fum) +;; (compiled-function-p 'ad-Advice-fum) ;; nil ;; ;; (fum 2) @@ -1580,8 +1580,6 @@ :link '(custom-manual "(elisp)Advising Functions") :group 'lisp) -(defconst ad-version "2.14") - ;;;###autoload (defcustom ad-redefinition-action 'warn "Defines what to do with redefinitions during Advice de/activation. @@ -2118,9 +2116,9 @@ the cache-id will clear the cache." (defsubst ad-compiled-p (definition) "Return non-nil if DEFINITION is a compiled byte-code object." - (or (byte-code-function-p definition) - (and (macrop definition) - (byte-code-function-p (ad-lambdafy definition))))) + (or (compiled-function-p definition) + (and (macrop definition) + (compiled-function-p (ad-lambdafy definition))))) (defsubst ad-compiled-code (compiled-definition) "Return the byte-code object of a COMPILED-DEFINITION." @@ -3250,6 +3248,9 @@ Use only in REAL emergencies." (message "Oops! Left over advised function %S" function) (ad-pop-advised-function function))) +(defconst ad-version "2.14") +(make-obsolete-variable 'ad-version 'emacs-version "29.1") + (provide 'advice) ;;; advice.el ends here diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 7a4bbf2e8af..52e00952846 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1207,25 +1207,26 @@ See Info node `(elisp) Integer Basics'." form))) (defun byte-optimize-apply (form) - ;; If the last arg is a literal constant, turn this into a funcall. - ;; The funcall optimizer can then transform (funcall 'foo ...) -> (foo ...). - (if (= (length form) 2) - ;; single-argument `apply' is not worth optimizing (bug#40968) - form - (let ((fn (nth 1 form)) - (last (nth (1- (length form)) form))) ; I think this really is fastest - (or (if (or (null last) - (eq (car-safe last) 'quote)) - (if (listp (nth 1 last)) - (let ((butlast (nreverse (cdr (reverse (cdr (cdr form))))))) - (nconc (list 'funcall fn) butlast - (mapcar (lambda (x) (list 'quote x)) (nth 1 last)))) + (let ((len (length form))) + (if (>= len 2) + (let ((fn (nth 1 form)) + (last (nth (1- len) form))) + (cond + ;; (apply F ... '(X Y ...)) -> (funcall F ... 'X 'Y ...) + ((or (null last) + (eq (car-safe last) 'quote)) + (let ((last-value (nth 1 last))) + (if (listp last-value) + `(funcall ,fn ,@(butlast (cddr form)) + ,@(mapcar (lambda (x) (list 'quote x)) last-value)) (byte-compile-warn-x - last - "last arg to apply can't be a literal atom: `%s'" - last) - nil)) - form)))) + last "last arg to apply can't be a literal atom: `%s'" last) + nil))) + ;; (apply F ... (list X Y ...)) -> (funcall F ... X Y ...) + ((eq (car-safe last) 'list) + `(funcall ,fn ,@(butlast (cddr form)) ,@(cdr last))) + (t form))) + form))) (put 'funcall 'byte-optimizer #'byte-optimize-funcall) (put 'apply 'byte-optimizer #'byte-optimize-apply) @@ -1747,10 +1748,10 @@ See Info node `(elisp) Integer Basics'." byte-goto-if-not-nil-else-pop)) (defconst byte-after-unbind-ops - '(byte-constant byte-dup + '(byte-constant byte-dup byte-stack-ref byte-stack-set byte-discard byte-symbolp byte-consp byte-stringp byte-listp byte-numberp byte-integerp byte-eq byte-not - byte-cons byte-list1 byte-list2 ; byte-list3 byte-list4 + byte-cons byte-list1 byte-list2 byte-list3 byte-list4 byte-listN byte-interactive-p) ;; How about other side-effect-free-ops? Is it safe to move an ;; error invocation (such as from nth) out of an unwind-protect? @@ -1762,7 +1763,8 @@ See Info node `(elisp) Integer Basics'." (defconst byte-compile-side-effect-and-error-free-ops '(byte-constant byte-dup byte-symbolp byte-consp byte-stringp byte-listp byte-integerp byte-numberp byte-eq byte-equal byte-not byte-car-safe - byte-cdr-safe byte-cons byte-list1 byte-list2 byte-point byte-point-max + byte-cdr-safe byte-cons byte-list1 byte-list2 byte-list3 byte-list4 + byte-listN byte-point byte-point-max byte-point-min byte-following-char byte-preceding-char byte-current-column byte-eolp byte-eobp byte-bolp byte-bobp byte-current-buffer byte-stack-ref)) @@ -2113,13 +2115,15 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." (setcar (cdr rest) lap0) (setq keep-going t)) ;; - ;; varbind-X unbind-N --> discard unbind-(N-1) - ;; save-excursion unbind-N --> unbind-(N-1) - ;; save-restriction unbind-N --> unbind-(N-1) + ;; varbind-X unbind-N --> discard unbind-(N-1) + ;; save-excursion unbind-N --> unbind-(N-1) + ;; save-restriction unbind-N --> unbind-(N-1) + ;; save-current-buffer unbind-N --> unbind-(N-1) ;; ((and (eq 'byte-unbind (car lap1)) (memq (car lap0) '(byte-varbind byte-save-excursion - byte-save-restriction)) + byte-save-restriction + byte-save-current-buffer)) (< 0 (cdr lap1))) (if (zerop (setcdr lap1 (1- (cdr lap1)))) (delq lap1 rest)) @@ -2475,8 +2479,7 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." ;; itself, compile some of its most used recursive functions (at load time). ;; (eval-when-compile - (or (byte-code-function-p (symbol-function 'byte-optimize-form)) - (subr-native-elisp-p (symbol-function 'byte-optimize-form)) + (or (compiled-function-p (symbol-function 'byte-optimize-form)) (assq 'byte-code (symbol-function 'byte-optimize-form)) (let ((byte-optimize nil) (byte-compile-warnings nil)) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 9d5f6682b5a..907015eb48e 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1395,7 +1395,7 @@ when printing the error message." (or (symbolp (symbol-function fn)) (consp (symbol-function fn)) (and (not macro-p) - (byte-code-function-p (symbol-function fn))))) + (compiled-function-p (symbol-function fn))))) (setq fn (symbol-function fn))) (let ((advertised (gethash (if (and (symbolp fn) (fboundp fn)) ;; Could be a subr. @@ -1407,7 +1407,7 @@ when printing the error message." (if macro-p `(macro lambda ,advertised) `(lambda ,advertised))) - ((and (not macro-p) (byte-code-function-p fn)) fn) + ((and (not macro-p) (compiled-function-p fn)) fn) ((not (consp fn)) nil) ((eq 'macro (car fn)) (cdr fn)) (macro-p nil) @@ -2946,11 +2946,11 @@ If FORM is a lambda or a macro, byte-compile it as a function." (setq fun (cdr fun))) (prog1 (cond - ;; Up until Emacs-24.1, byte-compile silently did nothing when asked to - ;; compile something invalid. So let's tune down the complaint from an - ;; error to a simple message for the known case where signaling an error - ;; causes problems. - ((byte-code-function-p fun) + ;; Up until Emacs-24.1, byte-compile silently did nothing + ;; when asked to compile something invalid. So let's tone + ;; down the complaint from an error to a simple message for + ;; the known case where signaling an error causes problems. + ((compiled-function-p fun) (message "Function %s is already compiled" (if (symbolp form) form "provided")) fun) @@ -3527,7 +3527,7 @@ lambda-expression." (byte-compile-out-tag endtag))) (defun byte-compile-unfold-bcf (form) - "Inline call to byte-code-functions." + "Inline call to byte-code function." (let* ((byte-compile-bound-variables byte-compile-bound-variables) (fun (car form)) (fargs (aref fun 0)) @@ -5254,11 +5254,13 @@ invoked interactively." ((not (consp f)) "<malformed function>") ((eq 'macro (car f)) - (if (or (byte-code-function-p (cdr f)) + (if (or (compiled-function-p (cdr f)) + ;; FIXME: Can this still happen? (assq 'byte-code (cdr (cdr (cdr f))))) " <compiled macro>" " <macro>")) ((assq 'byte-code (cdr (cdr f))) + ;; FIXME: Can this still happen? "<compiled lambda>") ((eq 'lambda (car f)) "<function>") @@ -5507,9 +5509,7 @@ and corresponding effects." ;; itself, compile some of its most used recursive functions (at load time). ;; (eval-when-compile - (or (byte-code-function-p (symbol-function 'byte-compile-form)) - (subr-native-elisp-p (symbol-function 'byte-compile-form)) - (assq 'byte-code (symbol-function 'byte-compile-form)) + (or (compiled-function-p (symbol-function 'byte-compile-form)) (let ((byte-optimize nil) ; do it fast (byte-compile-warnings nil)) (mapc (lambda (x) diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index ac589b82f83..04ead562f2f 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -1,6 +1,6 @@ ;;; checkdoc.el --- check documentation strings for style requirements -*- lexical-binding:t -*- -;; Copyright (C) 1997-1998, 2001-2022 Free Software Foundation, Inc. +;; Copyright (C) 1997-2022 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam <zappo@gnu.org> ;; Old-Version: 0.6.2 @@ -1357,23 +1357,6 @@ checking of documentation strings. checkdoc-common-verbs-wrong-voice "\\|") "\\)\\>")))) -;; Profiler says this is not yet faster than just calling assoc -;;(defun checkdoc-word-in-alist-vector (word vector) -;; "Check to see if WORD is in the car of an element of VECTOR. -;;VECTOR must be sorted. The CDR should be a replacement. Since the -;;word list is getting bigger, it is time for a quick bisecting search." -;; (let ((max (length vector)) (min 0) i -;; (found nil) (fw nil)) -;; (setq i (/ max 2)) -;; (while (and (not found) (/= min max)) -;; (setq fw (car (aref vector i))) -;; (cond ((string= word fw) (setq found (cdr (aref vector i)))) -;; ((string< word fw) (setq max i)) -;; (t (setq min i))) -;; (setq i (/ (+ max min) 2)) -;; ) -;; found)) - ;;; Checking engines ;; (defun checkdoc-this-string-valid (&optional take-notes) @@ -2860,8 +2843,6 @@ function called to create the messages." (custom-add-option 'emacs-lisp-mode-hook 'checkdoc-minor-mode) -;; Obsolete - (define-obsolete-function-alias 'checkdoc-run-hooks #'run-hook-with-args-until-success "28.1") (defvar checkdoc-version "0.6.2" diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index eefaa36b911..80ca43c902a 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -3411,7 +3411,7 @@ Of course, we really can't know that for sure, so it's just a heuristic." (character . natnump) (char-table . char-table-p) (command . commandp) - (compiled-function . byte-code-function-p) + (compiled-function . compiled-function-p) (hash-table . hash-table-p) (cons . consp) (fixnum . fixnump) diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index c8ff6b68144..047b0069bb9 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -1813,8 +1813,7 @@ Ran \\([0-9]+\\) tests, \\([0-9]+\\) results as expected\ (unless (or (null tests) (zerop high)) (message "\nLONG-RUNNING TESTS") (message "------------------") - (setq tests (sort tests (lambda (x y) (> (car x) (car y))))) - (when (< high (length tests)) (setcdr (nthcdr (1- high) tests) nil)) + (setq tests (ntake high (sort tests (lambda (x y) (> (car x) (car y)))))) (message "%s" (mapconcat #'cdr tests "\n"))) ;; More details on hydra and emba, where the logs are harder to get to. (when (and (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI")) diff --git a/lisp/emacs-lisp/helper.el b/lisp/emacs-lisp/helper.el index 654dbbc5fef..10bb2973253 100644 --- a/lisp/emacs-lisp/helper.el +++ b/lisp/emacs-lisp/helper.el @@ -131,7 +131,6 @@ (defun Helper-describe-bindings () "Describe local key bindings of current mode." (interactive) - (message "Making binding list...") (save-window-excursion (describe-bindings)) (Helper-help-scroller)) diff --git a/lisp/emacs-lisp/loaddefs-gen.el b/lisp/emacs-lisp/loaddefs-gen.el index 3b329357ad9..31e1514193f 100644 --- a/lisp/emacs-lisp/loaddefs-gen.el +++ b/lisp/emacs-lisp/loaddefs-gen.el @@ -519,15 +519,21 @@ binds `generated-autoload-file' as a file-local variable, write its autoloads into the specified file instead. The function does NOT recursively descend into subdirectories of the -directory or directories specified. +directory or directories specified by DIRS. -If EXTRA-DATA, include this string at the start of the generated -file. This will also force generation of OUTPUT-FILE even if -there are no autoloads to put into the file. +Optional argument EXCLUDED-FILES, if non-nil, should be a list of +files, such as preloaded files, whose autoloads should not be written +to OUTPUT-FILE. -If INCLUDE-PACKAGE-VERSION, include package version data. +If EXTRA-DATA is non-nil, it should be a string; include that string +at the beginning of the generated file. This will also force the +generation of OUTPUT-FILE even if there are no autoloads to put into +that file. -If GENERATE-FULL, don't update, but regenerate all the loaddefs files." +If INCLUDE-PACKAGE-VERSION is non-nil, include package version data. + +If GENERATE-FULL is non-nil, regenerate all the loaddefs files anew, +instead of just updating them with the new/changed autoloads." (let* ((files-re (let ((tmp nil)) (dolist (suf (get-load-suffixes)) ;; We don't use module-file-suffix below because @@ -545,6 +551,11 @@ If GENERATE-FULL, don't update, but regenerate all the loaddefs files." (updating (and (file-exists-p output-file) (not generate-full))) (defs nil)) + ;; Allow the excluded files to be relative. + (setq excluded-files + (mapcar (lambda (file) (expand-file-name file dir)) + excluded-files)) + ;; Collect all the autoload data. (let ((progress (make-progress-reporter (byte-compile-info @@ -583,7 +594,8 @@ If GENERATE-FULL, don't update, but regenerate all the loaddefs files." ;; We have some data, so generate the loaddef files. First ;; group per output file. (dolist (fdefs (seq-group-by #'car defs)) - (let ((loaddefs-file (car fdefs))) + (let ((loaddefs-file (car fdefs)) + hash) (with-temp-buffer (if (and updating (file-exists-p loaddefs-file)) (insert-file-contents loaddefs-file) @@ -593,6 +605,7 @@ If GENERATE-FULL, don't update, but regenerate all the loaddefs files." (when extra-data (insert extra-data) (ensure-empty-lines 1))) + (setq hash (buffer-hash)) ;; Then group by source file (and sort alphabetically). (dolist (section (sort (seq-group-by #'cadr (cdr fdefs)) (lambda (e1 e2) @@ -629,9 +642,11 @@ If GENERATE-FULL, don't update, but regenerate all the loaddefs files." (loaddefs-generate--print-form def)) (unless (bolp) (insert "\n"))))) - (write-region (point-min) (point-max) loaddefs-file nil 'silent) - (byte-compile-info (file-relative-name loaddefs-file lisp-directory) - t "GEN"))))))) + ;; Only write the file if we actually made a change. + (unless (equal (buffer-hash) hash) + (write-region (point-min) (point-max) loaddefs-file nil 'silent) + (byte-compile-info + (file-relative-name loaddefs-file lisp-directory) t "GEN")))))))) (defun loaddefs-generate--print-form (def) "Print DEF in a format that makes sense for version control." diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index 6a193a56d2d..5ae9d8368f0 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -823,7 +823,7 @@ test of free variables in the following ways: (eval-when-compile (add-hook 'emacs-startup-hook (lambda () - (and (not (byte-code-function-p + (and (not (compiled-function-p (symbol-function 'macroexpand-all))) (locate-library "macroexp.elc") (load "macroexp.elc"))))) diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el index 2d5a1b5e77b..a9a20ab5abf 100644 --- a/lisp/emacs-lisp/nadvice.el +++ b/lisp/emacs-lisp/nadvice.el @@ -167,31 +167,31 @@ DOC is a string where \"FUNCTION\" and \"OLDFUN\" are expected.") (defun advice--interactive-form (function) "Like `interactive-form' but tries to avoid autoloading functions." - (when (commandp function) - (if (not (and (symbolp function) (autoloadp (indirect-function function)))) - (interactive-form function) + (if (not (and (symbolp function) (autoloadp (indirect-function function)))) + (interactive-form function) + (when (commandp function) `(interactive (advice-eval-interactive-spec (cadr (interactive-form ',function))))))) -(defun advice--make-interactive-form (function main) +(defun advice--make-interactive-form (iff ifm) ;; TODO: make it so that interactive spec can be a constant which ;; dynamically checks the advice--car/cdr to do its job. ;; For that, advice-eval-interactive-spec needs to be more faithful. - (let* ((iff (advice--interactive-form function)) - (ifm (advice--interactive-form main)) - (fspec (cadr iff))) + (let* ((fspec (cadr iff))) (when (eq 'function (car-safe fspec)) ;; Macroexpanded lambda? - (setq fspec (nth 1 fspec))) + (setq fspec (eval fspec t))) (if (functionp fspec) `(funcall ',fspec ',(cadr ifm)) (cadr (or iff ifm))))) (cl-defmethod oclosure-interactive-form ((ad advice) &optional _) - (let ((car (advice--car ad)) - (cdr (advice--cdr ad))) - (when (or (commandp car) (commandp cdr)) - `(interactive ,(advice--make-interactive-form car cdr))))) + (let* ((car (advice--car ad)) + (cdr (advice--cdr ad)) + (ifa (advice--interactive-form car)) + (ifd (advice--interactive-form cdr))) + (when (or ifa ifd) + `(interactive ,(advice--make-interactive-form ifa ifd))))) (cl-defmethod cl-print-object ((object advice) stream) (cl-assert (advice--p object)) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index d2959f7728c..ed23ee5f221 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -3530,7 +3530,7 @@ If optional arg BUTTON is non-nil, describe its associated package." (let ((place (cdr desc)) (out (copy-sequence (car desc)))) (add-text-properties place (1+ place) - '(face (bold font-lock-warning-face)) + '(face help-key-binding) out) out)) (package--prettify-quick-help-key (cons desc 0)))) diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 07443dabfef..10bd4bc6886 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -607,31 +607,38 @@ recording whether the var has been referenced by earlier parts of the match." (symbolp . vectorp) (symbolp . stringp) (symbolp . byte-code-function-p) + (symbolp . compiled-function-p) (symbolp . recordp) (integerp . consp) (integerp . arrayp) (integerp . vectorp) (integerp . stringp) (integerp . byte-code-function-p) + (integerp . compiled-function-p) (integerp . recordp) (numberp . consp) (numberp . arrayp) (numberp . vectorp) (numberp . stringp) (numberp . byte-code-function-p) + (numberp . compiled-function-p) (numberp . recordp) (consp . arrayp) (consp . atom) (consp . vectorp) (consp . stringp) (consp . byte-code-function-p) + (consp . compiled-function-p) (consp . recordp) (arrayp . byte-code-function-p) + (arrayp . compiled-function-p) (vectorp . byte-code-function-p) + (vectorp . compiled-function-p) (vectorp . recordp) (stringp . vectorp) (stringp . recordp) - (stringp . byte-code-function-p))) + (stringp . byte-code-function-p) + (stringp . compiled-function-p))) (defun pcase--mutually-exclusive-p (pred1 pred2) (or (member (cons pred1 pred2) @@ -771,8 +778,8 @@ A and B can be one of: ((consp (cadr pat)) #'consp) ((stringp (cadr pat)) #'stringp) ((vectorp (cadr pat)) #'vectorp) - ((byte-code-function-p (cadr pat)) - #'byte-code-function-p)))) + ((compiled-function-p (cadr pat)) + #'compiled-function-p)))) (pcase--mutually-exclusive-p (cadr upat) otherpred)) '(:pcase--fail . nil)) ;; Since we turn (or 'a 'b 'c) into (pred (pcase--flip (memq '(a b c)))) diff --git a/lisp/emacs-lisp/ring.el b/lisp/emacs-lisp/ring.el index 2b2039f9d15..e8b92a532fa 100644 --- a/lisp/emacs-lisp/ring.el +++ b/lisp/emacs-lisp/ring.el @@ -42,6 +42,8 @@ ;;; Code: +(eval-when-compile (require 'cl-lib)) + ;;; User Functions: ;;;###autoload @@ -51,6 +53,8 @@ (consp (cdr x)) (integerp (cadr x)) (vectorp (cddr x)))) +(cl-deftype ring () '(satisfies ring-p)) + ;;;###autoload (defun make-ring (size) "Make a ring that can contain SIZE elements." diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 6ddd8de6e8d..b6f0f66e5b1 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -458,11 +458,21 @@ TESTFN is used to compare elements, or `equal' if TESTFN is nil." (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)) + ;; Fast path. If the list is long, use a hash table to speed + ;; things up even more. + (let ((l (length sequence))) + (if (> l 100) + (let ((hash (make-hash-table :test #'equal :size l))) + (while sequence + (unless (gethash (car sequence) hash) + (setf (gethash (car sequence) hash) t) + (push (car sequence) result)) + (setq sequence (cdr sequence)))) + ;; Short list. + (while sequence + (unless (member (car sequence) result) + (push (car sequence) result)) + (pop sequence)))) ;; Slower path. (while sequence (unless (seq-find (lambda (elem) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index b7083bfe7cc..bd7c3c82f97 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -254,13 +254,9 @@ the string." (unless (natnump length) (signal 'wrong-type-argument (list 'natnump length))) (let ((pad-length (- length (length string)))) - (if (< pad-length 0) - string - (concat (and start - (make-string pad-length (or padding ?\s))) - string - (and (not start) - (make-string pad-length (or padding ?\s))))))) + (cond ((<= pad-length 0) string) + (start (concat (make-string pad-length (or padding ?\s)) string)) + (t (concat string (make-string pad-length (or padding ?\s))))))) (defun string-chop-newline (string) "Remove the final newline (if any) from STRING." @@ -471,6 +467,18 @@ be marked unmodified, effectively ignoring those changes." (equal ,hash (buffer-hash))) (restore-buffer-modified-p nil)))))))) +(defun emacs-etc--hide-local-variables () + "Hide local variables. +Used by `emacs-authors-mode' and `emacs-news-mode'." + (narrow-to-region (point-min) + (save-excursion + (goto-char (point-max)) + ;; Obfuscate to avoid this being interpreted + ;; as a local variable section itself. + (if (re-search-backward "^Local\sVariables:$" nil t) + (progn (forward-line -1) (point)) + (point-max))))) + (provide 'subr-x) ;;; subr-x.el ends here |