Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package emacs-compat for openSUSE:Factory checked in at 2024-08-05 17:21:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/emacs-compat (Old) and /work/SRC/openSUSE:Factory/.emacs-compat.new.7232 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "emacs-compat" Mon Aug 5 17:21:20 2024 rev:4 rq:1191460 version:30.0.0.0 Changes: -------- --- /work/SRC/openSUSE:Factory/emacs-compat/emacs-compat.changes 2024-03-26 19:29:54.570783006 +0100 +++ /work/SRC/openSUSE:Factory/.emacs-compat.new.7232/emacs-compat.changes 2024-08-05 17:21:48.144419976 +0200 @@ -1,0 +2,34 @@ +Sat Aug 3 17:21:16 UTC 2024 - Björn Bidar <[email protected]> + +- Add back the install_info macro's for Leap, info triggers + are not old enough for Leap +- Add patch to fix Texinfo references inside the manual: + 0002-compat.texi-Fix-references-to-Emacs-30.1-in-Support-.patch + +------------------------------------------------------------------- +Sat Aug 03 16:23:59 UTC 2024 - Björn Bidar <[email protected]> + +- Remove use deprecated install_info macro's +- Rebase 0001-Add-install-target.patch against new upstream version +- Update to version 30.0.0.0: + * compat-28: Mark =subr-native-elisp-p= as obsolete (renamed in Emacs 30). + * compat-30: New function =char-to-name=. + * compat-30: New function =obarray-clear=. + * compat-30: New function =interpreted-function-p=. + * compat-30: New function =primitive-function-p=. + * compat-30: New function =closurep=. + * compat-30: Add extended function =sort= with keyword arguments. + * compat-30: New function =value<=. + * compat-30: Add extended =copy-tree= with support for copying records with + non-nil optional second argument. + * compat-30: New macro =static-if=. + * compat-30: New alias =drop=. + * compat-30: New function =merge-ordered-lists=. + * compat-30: New variables =completion-lazy-hilit= and =completion-lazy-hilit-fn= + and new function =completion-lazy-hilit=. + * compat-30: New function =require-with-check=. + * compat-30: New functions =find-buffer= and =get-truename-buffer=. + * compat-30: Add extended =completion-metadata-get= with support for + =completion-category-overrides= and =completion-extra-properties=. + +------------------------------------------------------------------- Old: ---- compat-29.1.4.5.tar.gz New: ---- 0002-compat.texi-Fix-references-to-Emacs-30.1-in-Support-.patch compat-30.0.0.0.tar.gz BETA DEBUG BEGIN: New:- Add patch to fix Texinfo references inside the manual: 0002-compat.texi-Fix-references-to-Emacs-30.1-in-Support-.patch BETA DEBUG END: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ emacs-compat.spec ++++++ --- /var/tmp/diff_new_pack.wS2lQL/_old 2024-08-05 17:21:48.812447347 +0200 +++ /var/tmp/diff_new_pack.wS2lQL/_new 2024-08-05 17:21:48.816447511 +0200 @@ -20,7 +20,7 @@ %global _name compat Name: emacs-%{_name} -Version: 29.1.4.5 +Version: 30.0.0.0 Release: 0 Summary: COMPATibility Library for Emacs Lisp License: GPL-3.0-or-later @@ -35,10 +35,14 @@ BuildRequires: makeinfo Requires: emacs Supplements: emacs -Requires(post): %{install_info_prereq} -Requires(preun): %{install_info_prereq} +%if 0%{?suse_version} <= 1600 +Requires(post): %install_info_prereq +Requires(preun): %install_info_prereq +%endif # PATCH-FEATURE-UPSTREAM install targets PR 30 Patch1: 0001-Add-install-target.patch +# # PATCH-FEATURE-UPSTREAM Fix Texinfo references PR 49 +Patch2: 0002-compat.texi-Fix-references-to-Emacs-30.1-in-Support-.patch %description compat.el, the forwards-compatibility library for (GNU) Emacs Lisp, versions 24.4 and newer. The intended audience are package developers that are interested in using newer developments, without having to break compatibility. @@ -52,11 +56,15 @@ %install %make_install +%check + +%if 0%{?suse_version} >= 1600 %post %install_info --info-dir=%{_infodir} %{_infodir}/%{_name}.info.gz %preun %install_info_delete --info-dir=%{_infodir} %{_infodir}/%{_name}.info.gz +%endif %files %doc README.md ++++++ 0001-Add-install-target.patch ++++++ --- /var/tmp/diff_new_pack.wS2lQL/_old 2024-08-05 17:21:48.836448330 +0200 +++ /var/tmp/diff_new_pack.wS2lQL/_new 2024-08-05 17:21:48.840448495 +0200 @@ -8,14 +8,14 @@ Signed-off-by: Björn Bidar <[email protected]> --- - Makefile | 35 ++++++++++++++++++++++++++++++++--- - 1 file changed, 32 insertions(+), 3 deletions(-) + Makefile | 34 ++++++++++++++++++++++++++++++++-- + 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile -index 3c5949418789b1525c8df26cfad02876730b8c53..5c07efcef76313e645ecb97e153cc28023cb9846 100644 +index 3f298c9cd5f991fa394749215e4ec3665434ad9a..9d368d669d3f1d21486ed93bf3ac77c1625adde8 100644 --- a/Makefile +++ b/Makefile -@@ -29,19 +29,32 @@ +@@ -29,20 +29,34 @@ ### Code: .POSIX: @@ -39,7 +39,8 @@ compat-27.elc \ compat-28.elc \ compat-29.elc \ -- compat.elc \ + compat-30.elc \ + compat.elc \ + compat.elc +DEVELOPMENT = \ compat-macs.elc \ @@ -51,7 +52,7 @@ all: compile -@@ -73,6 +86,22 @@ check: +@@ -74,6 +88,22 @@ check: sort | uniq > /tmp/compat-links @ (diff /tmp/compat-defs /tmp/compat-defs) ++++++ 0002-compat.texi-Fix-references-to-Emacs-30.1-in-Support-.patch ++++++ >From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Bidar?= <[email protected]> Date: Sat, 3 Aug 2024 20:03:38 +0300 Subject: [PATCH] compat.texi: Fix references to Emacs 30.1 in Support section Fixes: makeinfo compat.texi compat.texi:2251: warning: node `Emacs 30.1' is next for `Emacs 29.1' in sectioning but not in menu compat.texi:3316: warning: node `Emacs 29.1' is prev for `Emacs 30.1' in sectioning but not in menu compat.texi:3316: warning: node `Support' is up for `Emacs 30.1' in sectioning but not in menu compat.texi:300: node `Support' lacks menu item for `Emacs 30.1' despite being its Up target make: *** [Makefile:116: compat.info] Error 1 --- compat.texi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compat.texi b/compat.texi index 41725d03bd2f8fd6065d0293b34ec0d390a54353..b7bb45c809b785927d4367a024fc746e4eda5242 100644 --- a/compat.texi +++ b/compat.texi @@ -74,6 +74,7 @@ Support * Emacs 27.1:: Compatibility support for Emacs 27.1 * Emacs 28.1:: Compatibility support for Emacs 28.1 * Emacs 29.1:: Compatibility support for Emacs 29.1 +* Emacs 30.1:: Compatibility support for Emacs 30.1 @end detailmenu @end menu @@ -309,6 +310,7 @@ manage to provide for each Emacs version. * Emacs 27.1:: Compatibility support for Emacs 27.1 * Emacs 28.1:: Compatibility support for Emacs 28.1 * Emacs 29.1:: Compatibility support for Emacs 29.1 +* Emacs 30.1:: Compatibility support for Emacs 30.1 @end menu @node Emacs 25.1 ++++++ compat-29.1.4.5.tar.gz -> compat-30.0.0.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compat-29.1.4.5/.dir-locals.el new/compat-30.0.0.0/.dir-locals.el --- old/compat-29.1.4.5/.dir-locals.el 1970-01-01 01:00:00.000000000 +0100 +++ new/compat-30.0.0.0/.dir-locals.el 2024-07-08 20:22:28.000000000 +0200 @@ -0,0 +1,8 @@ +;;; Directory Local Variables +;;; For more information see (info "(emacs) Directory Variables") + +((nil + (fill-column . 72) + (sentence-end-double-space . t) + (show-trailing-whitespace . t) + (indent-tabs-mode . nil))) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compat-29.1.4.5/.elpaignore new/compat-30.0.0.0/.elpaignore --- old/compat-29.1.4.5/.elpaignore 2024-03-16 11:54:18.000000000 +0100 +++ new/compat-30.0.0.0/.elpaignore 2024-07-08 20:22:28.000000000 +0200 @@ -1,8 +1,9 @@ -compat-tests.el -Makefile +.dir-locals.el +.elpaignore .github .gitignore -.elpaignore COPYING +Makefile README.md -compat.texi +compat-tests.el +compat.texi \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compat-29.1.4.5/.github/workflows/makefile.yml new/compat-30.0.0.0/.github/workflows/makefile.yml --- old/compat-29.1.4.5/.github/workflows/makefile.yml 2024-03-16 11:54:18.000000000 +0100 +++ new/compat-30.0.0.0/.github/workflows/makefile.yml 2024-07-08 20:22:28.000000000 +0200 @@ -33,6 +33,7 @@ - '28.2' - '29.1' - '29.2' + - '29.3' - 'release-snapshot' - 'snapshot' steps: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compat-29.1.4.5/Makefile new/compat-30.0.0.0/Makefile --- old/compat-29.1.4.5/Makefile 2024-03-16 11:54:18.000000000 +0100 +++ new/compat-30.0.0.0/Makefile 2024-07-08 20:22:28.000000000 +0200 @@ -39,6 +39,7 @@ compat-27.elc \ compat-28.elc \ compat-29.elc \ + compat-30.elc \ compat.elc \ compat-macs.elc \ compat-tests.elc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compat-29.1.4.5/NEWS.org new/compat-30.0.0.0/NEWS.org --- old/compat-29.1.4.5/NEWS.org 2024-03-16 11:54:18.000000000 +0100 +++ new/compat-30.0.0.0/NEWS.org 2024-07-08 20:22:28.000000000 +0200 @@ -2,6 +2,30 @@ #+link: compat-gh https://github.com/emacs-compat/compat/issues/ #+options: toc:nil num:nil author:nil +* Release of "Compat" Version 30.0.0.0 + +- compat-28: Mark =subr-native-elisp-p= as obsolete (renamed in Emacs 30). +- compat-30: New function =char-to-name=. +- compat-30: New function =obarray-clear=. +- compat-30: New function =interpreted-function-p=. +- compat-30: New function =primitive-function-p=. +- compat-30: New function =closurep=. +- compat-30: Add extended function =sort= with keyword arguments. +- compat-30: New function =value<=. +- compat-30: Add extended =copy-tree= with support for copying records with + non-nil optional second argument. +- compat-30: New macro =static-if=. +- compat-30: New alias =drop=. +- compat-30: New function =merge-ordered-lists=. +- compat-30: New variables =completion-lazy-hilit= and =completion-lazy-hilit-fn= + and new function =completion-lazy-hilit=. +- compat-30: New function =require-with-check=. +- compat-30: New functions =find-buffer= and =get-truename-buffer=. +- compat-30: Add extended =completion-metadata-get= with support for + =completion-category-overrides= and =completion-extra-properties=. + +(Release <2024-07-08 Mon>) + * Release of "Compat" Version 29.1.4.5 - Minor optimization of ~plist-get~ and ~plist-put~. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compat-29.1.4.5/compat-25.el new/compat-30.0.0.0/compat-25.el --- old/compat-29.1.4.5/compat-25.el 2024-03-16 11:54:18.000000000 +0100 +++ new/compat-30.0.0.0/compat-25.el 2024-07-08 20:22:28.000000000 +0200 @@ -40,23 +40,6 @@ i (1+ i))) vec)) -;;;; Defined in fns.c - -(compat-defun sort (seq predicate) ;; <compat-tests:sort> - "Handle vector SEQ." - :extended t - (cond - ((listp seq) - (sort seq predicate)) - ((vectorp seq) - (let* ((list (sort (append seq nil) predicate)) - (p list) (i 0)) - (while p - (aset seq i (car p)) - (setq i (1+ i) p (cdr p))) - (apply #'vector list))) - (t (signal 'wrong-type-argument (list 'list-or-vector-p seq))))) - ;;;; Defined in editfns.c (compat-defalias format-message format) ;; <compat-tests:format-message> @@ -267,5 +250,11 @@ form)))))))) (t form))) +;;;; Defined in minibuffer.el + +(compat-defun completion--category-override (category tag) ;; <compat-tests:completion-metadata-get> + "Return completion category override for CATEGORY and TAG." + (assq tag (cdr (assq category completion-category-overrides)))) + (provide 'compat-25) ;;; compat-25.el ends here diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compat-29.1.4.5/compat-28.el new/compat-30.0.0.0/compat-28.el --- old/compat-29.1.4.5/compat-28.el 2024-03-16 11:54:18.000000000 +0100 +++ new/compat-30.0.0.0/compat-28.el 2024-07-08 20:22:28.000000000 +0200 @@ -396,7 +396,8 @@ ;;;; Defined in data.c -(compat-defalias subr-native-elisp-p ignore) ;; <compat-tests:subr-native-elisp-p> +;; Renamed in Emacs 30 to `native-comp-function-p'. +(compat-defalias subr-native-elisp-p ignore :obsolete t) ;; <compat-tests:obsolete-subr-native-elisp-p> ;;;; Defined in subr-x.el @@ -835,7 +836,7 @@ ;;;; Defined in button.el ;; Obsolete Alias since 29 -(compat-defalias button-buttonize buttonize :obsolete t) ;; <compat-tests:button-buttonize> +(compat-defalias button-buttonize buttonize :obsolete t) ;; <compat-tests:obsolete-button-buttonize> ;;;; Defined in wid-edit.el diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compat-29.1.4.5/compat-30.el new/compat-30.0.0.0/compat-30.el --- old/compat-29.1.4.5/compat-30.el 1970-01-01 01:00:00.000000000 +0100 +++ new/compat-30.0.0.0/compat-30.el 2024-07-08 20:22:28.000000000 +0200 @@ -0,0 +1,355 @@ +;;; compat-30.el --- Functionality added in Emacs 30 -*- lexical-binding: t; -*- + +;; Copyright (C) 2023-2024 Free Software Foundation, Inc. + +;; This program 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. + +;; This program 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 this program. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Functionality added in Emacs 30, needed by older Emacs versions. + +;;; Code: + +(eval-when-compile (load "compat-macs.el" nil t t)) +(compat-require compat-29 "29.1") + +;; TODO Update to 30.1 as soon as the Emacs emacs-30 branch version bumped +(compat-version "30.0.50") + +;;;; Defined in lread.c + +(compat-defun obarray-clear (ob) ;; <compat-tests:obarray> + "Remove all symbols from obarray OB." + (fillarray ob 0)) + +;;;; Defined in buffer.c + +(compat-defun find-buffer (variable value) ;; <compat-tests:find-buffer> + "Return the buffer with buffer-local VARIABLE equal to VALUE. +If there is no such live buffer, return nil." + (cl-loop for buffer the buffers + if (equal (buffer-local-value variable buffer) value) + return buffer)) + +(compat-defun get-truename-buffer (filename) ;; <compat-tests:get-truename-buffer> + "Return the buffer with `file-truename' equal to FILENAME (a string). +If there is no such live buffer, return nil. +See also `find-buffer-visiting'." + (find-buffer 'buffer-file-truename filename)) + +;;;; Defined in files.el + +(compat-defun require-with-check (feature &optional filename noerror) ;; <compat-tests:require-with-check> + "If FEATURE is not already loaded, load it from FILENAME. +This is like `require' except if FEATURE is already a member of the list +`featuresâ, then we check if this was provided by a different file than the +one that we would load now (presumably because `load-path' has been +changed since the file was loaded). +If it's the case, we either signal an error (the default), or forcibly reload +the new file (if NOERROR is equal to `reload'), or otherwise emit a warning." + (let ((lh load-history) + (res (require feature filename (if (eq noerror 'reload) nil noerror)))) + ;; If the `feature' was not yet provided, `require' just loaded the right + ;; file, so we're done. + (when (eq lh load-history) + ;; If `require' did nothing, we need to make sure that was warranted. + (let ((fn (locate-file (or filename (symbol-name feature)) + load-path (get-load-suffixes)))) + (cond + ((assoc fn load-history) nil) ;We loaded the right file. + ((eq noerror 'reload) (load fn nil 'nomessage)) + (t (funcall (if noerror #'warn #'error) + "Feature provided by other file: %S" feature))))) + res)) + +;;;; Defined in minibuffer.el + +(compat-defun completion--metadata-get-1 (metadata prop) ;; <compat-tests:completion-metadata-get> + "Helper function. +See for `completion-metadata-get' for METADATA and PROP arguments." + (or (alist-get prop metadata) + (plist-get completion-extra-properties + (or (get prop 'completion-extra-properties--keyword) + (put prop 'completion-extra-properties--keyword + (intern (concat ":" (symbol-name prop)))))))) + +(compat-defun completion-metadata-get (metadata prop) ;; <compat-tests:completion-metadata-get> + "Get property PROP from completion METADATA. +If the metadata specifies a completion category, the variables +`completion-category-overrides' and +`completion-category-defaults' take precedence for +category-specific overrides. If the completion metadata does not +specify the property, the `completion-extra-properties' plist is +consulted. Note that the keys of the +`completion-extra-properties' plist are keyword symbols, not +plain symbols." + :extended t + (if-let ((cat (and (not (eq prop 'category)) + (completion--metadata-get-1 metadata 'category))) + (over (completion--category-override cat prop))) + (cdr over) + (completion--metadata-get-1 metadata prop))) + +(compat-defvar completion-lazy-hilit nil ;; <compat-tests:completion-lazy-hilit> + "If non-nil, request lazy highlighting of completion candidates. + +Lisp programs (a.k.a. \"front ends\") that present completion +candidates may opt to bind this variable to a non-nil value when +calling functions (such as `completion-all-completions') which +produce completion candidates. This tells the underlying +completion styles that they do not need to fontify (i.e., +propertize with the `face' property) completion candidates in a +way that highlights the matching parts. Then it is the front end +which presents the candidates that becomes responsible for this +fontification. The front end does that by calling the function +`completion-lazy-hilit' on each completion candidate that is to be +displayed to the user. + +Note that only some completion styles take advantage of this +variable for optimization purposes. Other styles will ignore the +hint and fontify eagerly as usual. It is still safe for a +front end to call `completion-lazy-hilit' in these situations. + +To author a completion style that takes advantage of this variable, +see `completion-lazy-hilit-fn' and `completion-pcm--hilit-commonality'.") + +(compat-defvar completion-lazy-hilit-fn nil ;; <compat-tests:completion-lazy-hilit> + "Fontification function set by lazy-highlighting completions styles. +When a given style wants to enable support for `completion-lazy-hilit' +\(which see), that style should set this variable to a function of one +argument. It will be called with each completion candidate, a string, to +be displayed to the user, and should destructively propertize these +strings with the `face' property.") + +(compat-defun completion-lazy-hilit (str) ;; <compat-tests:completion-lazy-hilit> + "Return a copy of completion candidate STR that is `face'-propertized. +See documentation of the variable `completion-lazy-hilit' for more +details." + (if (and completion-lazy-hilit completion-lazy-hilit-fn) + (funcall completion-lazy-hilit-fn (copy-sequence str)) + str)) + +;;;; Defined in subr.el + +(compat-defmacro static-if (condition then-form &rest else-forms) ;; <compat-tests:static-if> + "A conditional compilation macro. +Evaluate CONDITION at macro-expansion time. If it is non-nil, +expand the macro to THEN-FORM. Otherwise expand it to ELSE-FORMS +enclosed in a `progn' form. ELSE-FORMS may be empty." + (declare (indent 2) (debug (sexp sexp &rest sexp))) + (if (eval condition lexical-binding) + then-form + (cons 'progn else-forms))) + +(compat-defun closurep (object) ;; <compat-tests:closurep> + "Return t if OBJECT is a function of type closure." + (declare (side-effect-free error-free)) + (eq (car-safe object) 'closure)) + +(compat-defalias interpreted-function-p closurep) ;; <compat-tests:closurep> + +(compat-defun primitive-function-p (object) ;; <compat-tests:primitive-function-p> + "Return t if OBJECT is a built-in primitive function. +This excludes special forms, since they are not functions." + (declare (side-effect-free error-free)) + (and (subrp object) + (not (or (with-no-warnings (subr-native-elisp-p object)) + (special-form-p object))))) + +(compat-defalias drop nthcdr) ;; <compat-tests:drop> + +(compat-defun merge-ordered-lists (lists &optional error-function) ;; <compat-tests:merge-ordered-lists> + "Merge LISTS in a consistent order. +LISTS is a list of lists of elements. +Merge them into a single list containing the same elements (removing +duplicates), obeying their relative positions in each list. +The order of the (sub)lists determines the final order in those cases where +the order within the sublists does not impose a unique choice. +Equality of elements is tested with `eql'. + +If a consistent order does not exist, call ERROR-FUNCTION with +a remaining list of lists that we do not know how to merge. +It should return the candidate to use to continue the merge, which +has to be the head of one of the lists. +By default we choose the head of the first list." + (let ((result '())) + (setq lists (remq nil lists)) + (while (cdr (setq lists (delq nil lists))) + (let* ((next nil) + (tail lists)) + (while tail + (let ((candidate (caar tail)) + (other-lists lists)) + (while other-lists + (if (not (memql candidate (cdr (car other-lists)))) + (setq other-lists (cdr other-lists)) + (setq candidate nil) + (setq other-lists nil))) + (if (not candidate) + (setq tail (cdr tail)) + (setq next candidate) + (setq tail nil)))) + (unless next + (setq next (funcall (or error-function #'caar) lists)) + (unless (funcall + (eval-when-compile (if (fboundp 'compat--assoc) 'compat--assoc 'assoc)) + next lists #'eql) + (error "Invalid candidate returned by error-function: %S" next))) + (push next result) + (setq lists + (mapcar (lambda (l) (if (eql (car l) next) (cdr l) l)) + lists)))) + (if (null result) (car lists) + (append (nreverse result) (car lists))))) + +(compat-defun copy-tree (tree &optional vectors-and-records) ;; <compat-tests:copy-tree> + "Handle copying records when optional arg is non-nil." + :extended t + (declare (side-effect-free error-free)) + (if (fboundp 'recordp) + (if (consp tree) + (let (result) + (while (consp tree) + (let ((newcar (car tree))) + (if (or (consp (car tree)) + (and vectors-and-records + (or (vectorp (car tree)) (recordp (car tree))))) + (setq newcar (compat--copy-tree (car tree) vectors-and-records))) + (push newcar result)) + (setq tree (cdr tree))) + (nconc (nreverse result) + (if (and vectors-and-records (or (vectorp tree) (recordp tree))) + (compat--copy-tree tree vectors-and-records) + tree))) + (if (and vectors-and-records (or (vectorp tree) (recordp tree))) + (let ((i (length (setq tree (copy-sequence tree))))) + (while (>= (setq i (1- i)) 0) + (aset tree i (compat--copy-tree (aref tree i) vectors-and-records))) + tree) + tree)) + (copy-tree tree vectors-and-records))) + +;;;; Defined in fns.c + +(compat-defun value< (a b) ;; <compat-tests:value<> + "Return non-nil if A precedes B in standard value order. +A and B must have the same basic type. +Numbers are compared with <. +Strings and symbols are compared with string-lessp. +Lists, vectors, bool-vectors and records are compared lexicographically. +Markers are compared lexicographically by buffer and position. +Buffers and processes are compared by name. +Other types are considered unordered and the return value will be ânilâ." + (cond + ((or (and (numberp a) (numberp b)) + (and (markerp a) (markerp b))) + (< a b)) + ((or (and (stringp a) (stringp b)) + (and (symbolp a) (symbolp b))) + (string< a b)) + ((and (listp a) (listp b)) + (while (and (consp a) (consp b) (equal (car a) (car b))) + (setq a (cdr a) b (cdr b))) + (cond + ((not b) nil) + ((not a) t) + ((and (consp a) (consp b)) (value< (car a) (car b))) + (t (value< a b)))) + ((and (vectorp a) (vectorp b)) + (let* ((na (length a)) + (nb (length b)) + (n (min na nb)) + (i 0)) + (while (and (< i n) (equal (aref a i) (aref b i))) + (cl-incf i)) + (if (< i n) (value< (aref a i) (aref b i)) (< n nb)))) + ((and (bufferp a) (bufferp b)) + ;; `buffer-name' is nil for killed buffers. + (setq a (buffer-name a) + b (buffer-name b)) + (cond + ((and a b) (string< a b)) + (b t))) + ((and (processp a) (processp b)) + (string< (process-name a) (process-name b))) + ;; TODO Add support for more types here. + ;; Other values of equal type are considered unordered (return value nil). + ((eq (type-of a) (type-of b)) nil) + ;; Different types. + (t (error "value< type mismatch: %S %S" a b)))) + +(compat-defun sort (seq &optional lessp &rest rest) ;; <compat-tests:sort> + "Sort function with support for keyword arguments. +The following arguments are defined: + +:key FUNC -- FUNC is a function that takes a single element from SEQ and + returns the key value to be used in comparison. If absent or nil, + `identity' is used. + +:lessp FUNC -- FUNC is a function that takes two arguments and returns + non-nil if the first element should come before the second. + If absent or nil, `value<' is used. + +:reverse BOOL -- if BOOL is non-nil, the sorting order implied by FUNC is + reversed. This does not affect stability: equal elements still retain + their order in the input sequence. + +:in-place BOOL -- if BOOL is non-nil, SEQ is sorted in-place and returned. + Otherwise, a sorted copy of SEQ is returned and SEQ remains unmodified; + this is the default. + +For compatibility, the calling convention (sort SEQ LESSP) can also be used; +in this case, sorting is always done in-place." + :extended t + (let ((in-place t) (reverse nil) (orig-seq seq)) + (when (or (not lessp) rest) + (setq + rest (if lessp (cons lessp rest) rest) + in-place (plist-get rest :in-place) + reverse (plist-get rest :reverse) + lessp (let ((key (plist-get rest :key)) + (< (or (plist-get rest :lessp) #'value<))) + (if key + (lambda (a b) (funcall < (funcall key a) (funcall key b))) + <)) + seq (if (or (and (eval-when-compile (< emacs-major-version 25)) (vectorp orig-seq)) + in-place) + seq + (copy-sequence seq)))) + ;; Emacs 24 does not support vectors. Convert to list. + (when (and (eval-when-compile (< emacs-major-version 25)) (vectorp orig-seq)) + (setq seq (append seq nil))) + (setq seq (if reverse + (nreverse (sort (nreverse seq) lessp)) + (sort seq lessp))) + ;; Emacs 24: Convert back to vector. + (if (and (eval-when-compile (< emacs-major-version 25)) (vectorp orig-seq)) + (if in-place + (cl-loop for i from 0 for x in seq + do (aset orig-seq i x) + finally return orig-seq) + (apply #'vector seq)) + seq))) + +;;;; Defined in mule-cmds.el + +(compat-defun char-to-name (char) ;; <compat-tests:char-to-name> + "Return the Unicode name for CHAR, if it has one, else nil. +Return nil if CHAR is not a character." + (and (characterp char) + (or (get-char-code-property char 'name) + (get-char-code-property char 'old-name)))) + +(provide 'compat-30) +;;; compat-30.el ends here diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compat-29.1.4.5/compat-tests.el new/compat-30.0.0.0/compat-tests.el --- old/compat-29.1.4.5/compat-tests.el 2024-03-16 11:54:18.000000000 +0100 +++ new/compat-30.0.0.0/compat-tests.el 2024-07-08 20:22:28.000000000 +0200 @@ -75,13 +75,9 @@ (defmacro should-equal (a b) `(should (equal ,a ,b))) -(defmacro compat-tests--if (cond then &rest else) - (declare (indent 2)) - (if (eval cond t) then (macroexp-progn else))) - (ert-deftest compat-loaded-features () (let ((version 0)) - (while (< version 30) + (while (< version 31) (should-equal (> version emacs-major-version) (featurep (intern (format "compat-%s" version)))) (setq version (1+ version))))) @@ -96,7 +92,7 @@ (defconst compat-tests--version (package-get-version)) (ert-deftest compat-package-get-version () (should (stringp compat-tests--version)) - (should-equal 29 (car (version-to-list compat-tests--version)))) + (should-equal 30 (car (version-to-list compat-tests--version)))) (ert-deftest compat-buffer-match-p () (let ((b "*compat-test-buffer*") @@ -216,7 +212,7 @@ (should-equal 'h (get-text-property 0 'help-echo b)) (should-equal 'h (get-text-property 5 'help-echo b)))) -(ert-deftest compat-button-buttonize () +(ert-deftest compat-obsolete-button-buttonize () (let ((b (with-no-warnings (button-buttonize "button" 'c 'd)))) (should-equal b "button") (should-equal 'c (get-text-property 0 'action b)) @@ -892,7 +888,7 @@ (should-equal (function-alias-p 'compat-tests--alias-a) '(compat-tests--alias-b compat-tests--alias-c)) ;; Emacs 30 disallows cyclic function aliases - (compat-tests--if (>= emacs-major-version 30) + (static-if (>= emacs-major-version 30) (should-error (progn (defalias 'compat-tests--cyclic-alias-a 'compat-tests--cyclic-alias-b) @@ -961,6 +957,10 @@ (should-equal '(1 2) (take 5 '(1 2))) (should-equal '(1 2 3) (take 3 '(1 2 3 4)))) +(ert-deftest compat-drop () + (should-not (drop 5 nil)) + (should-equal '(3 4 5) (drop 2 '(1 2 3 4 5)))) + (ert-deftest compat-format-message () (should-equal (format-message "a=%s b=%s" 1 2) "a=1 b=2")) @@ -1005,6 +1005,19 @@ (should-equal compat-tests--local 2) (should-not (boundp 'compat-tests--unexist))))) +(ert-deftest compat-obarray-clear () + ;; obarray APIs are only available since 26 + (static-if (> emacs-major-version 25) + (progn + (let ((ob (obarray-make))) + (should-not (obarray-get ob "sym1")) + (should (intern "sym1" ob)) + (should (obarray-get ob "sym1")) + (obarray-clear ob) + (should-not (obarray-get ob "sym1")) + (should (intern "sym2" ob)) + (should (obarray-get ob "sym2")))))) + (ert-deftest compat-gensym () (let ((orig gensym-counter)) (should (integerp gensym-counter)) @@ -1300,8 +1313,26 @@ (ert-deftest compat-native-comp-available-p () (should (memq (native-comp-available-p) '(nil t)))) -(ert-deftest compat-subr-native-elisp-p () - (should-not (subr-native-elisp-p (symbol-function 'identity)))) +(ert-deftest compat-obsolete-subr-native-elisp-p () + (with-no-warnings + (static-if (< emacs-major-version 30) + (should-not (subr-native-elisp-p (symbol-function 'identity)))))) + +(ert-deftest compat-closurep () + (should (interpreted-function-p (eval '(lambda (x) x) t))) + (should (closurep (eval '(lambda (x) x) t))) + (should-not (closurep '(lambda (x) x))) + (should-not (closurep 'identity)) + (should-not (closurep (symbol-function 'identity))) + (should-not (closurep (symbol-function 'if))) + (should-not (closurep (symbol-function 'defun)))) + +(ert-deftest compat-primitive-function-p () + (should (primitive-function-p (symbol-function 'identity))) + (should-not (primitive-function-p (eval '(lambda (x) x) t))) + (should-not (primitive-function-p '(lambda (x) x))) + (should-not (primitive-function-p (symbol-function 'if))) + (should-not (primitive-function-p (symbol-function 'defun)))) (ert-deftest compat-subr-primitive-p () (should (subr-primitive-p (symbol-function 'identity))) ;function from fns.c @@ -1757,6 +1788,47 @@ (should-equal '(1 2 3 4) (flatten-tree '((1) nil 2 ((3 4))))) (should-equal '(1 2 3 4) (flatten-tree '(((1 nil)) 2 (((3 nil nil) 4)))))) +(defmacro compat--should-value< (x y) + "Helper for (value< X Y) test." + `(progn + (should (value< ,x ,y)) + (should-not (value< ,y ,x)))) + +(ert-deftest compat-value< () + ;; Type mismatch + (should-error (value< 'aa "aa")) + (should-error (value< 1 "aa")) + (should-error (value< 1 (cons 1 2))) + ;; Nil symbol + (compat--should-value< nil t) + (compat--should-value< nil 'nim) + (compat--should-value< nil 'nll) + (compat--should-value< 'mil nil) + ;; Atoms + (compat--should-value< 1 2) + (compat--should-value< "aa" "b") + (compat--should-value< 'aa 'b) + ;; Lists + (compat--should-value< nil '(1)) + (compat--should-value< '(1 2) '(2 3)) + (compat--should-value< '(1 2 3) '(2)) + (compat--should-value< '(0 1 2) '(0 2 3)) + (compat--should-value< '(0 1 2 3) '(0 2)) + ;; Pairs and improper lists + (compat--should-value< nil '(1 . 2)) + (compat--should-value< nil '(1 2 . 3)) + (compat--should-value< '(1 . 2) '(2 . 2)) + (compat--should-value< '(1 . 2) '(1 . 3)) + (compat--should-value< '(1 2 . 3) '(1 2 . 4)) + ;; Vectors + (compat--should-value< [] [1]) + (compat--should-value< [1 2] [2 3]) + (compat--should-value< [1 2 3] [2]) + (compat--should-value< [0 1 2] [0 2 3]) + (compat--should-value< [0 1 2 3] [0 2]) + ;; Buffers are compared by name + (compat--should-value< (get-buffer-create "a") (get-buffer-create "b"))) + (ert-deftest compat-sort () (should-equal (list 1 2 3) (sort (list 1 2 3) #'<)) (should-equal (list 1 2 3) (sort (list 1 3 2) #'<)) @@ -1764,14 +1836,34 @@ (should-equal (list 1 2 3) (compat-call sort (list 1 2 3) #'<)) (should-equal (list 1 2 3) (compat-call sort (list 1 3 2) #'<)) (should-equal (list 1 2 3) (compat-call sort (list 3 2 1) #'<)) + ;; Test Emacs 25 support for vectors. (should-equal [1 2 3] (compat-call sort (vector 1 2 3) #'<)) (should-equal [1 2 3] (compat-call sort (vector 1 3 2) #'<)) (should-equal [1 2 3] (compat-call sort (vector 3 2 1) #'<)) ;; Test side effect (let* ((vec (vector 4 5 8 3 1 2 3 2 3 4)) (sorted (compat-call sort vec #'>))) + (should (eq vec sorted)) (should-equal sorted [8 5 4 4 3 3 3 2 2 1]) - (should-equal vec [8 5 4 4 3 3 3 2 2 1]))) + (should-equal vec [8 5 4 4 3 3 3 2 2 1])) + ;; Test Emacs 30 keyword arguments. + (should-equal '(1 2 3) (compat-call sort '(2 3 1))) + (should-equal '(3 2 1) (compat-call sort '(2 3 1) :reverse t)) + (should-equal '((x 3) (y 2) (z 1)) (compat-call sort '((z 1) (x 3) (y 2)) :key #'car)) + (should-equal '((z 1) (y 2) (x 3)) (compat-call sort '((z 1) (x 3) (y 2)) :key #'car :reverse t)) + (should-equal '((z 1) (y 2) (x 3)) (compat-call sort '((z 1) (x 3) (y 2)) :key #'cadr)) + (should-equal '((x 3) (y 2) (z 1)) (compat-call sort '((z 1) (x 3) (y 2)) :key #'cadr :reverse t)) + (should-equal '(3 2 1) (compat-call sort '(2 3 1) :lessp #'>)) + (should-equal '(1 2 3) (compat-call sort '(2 3 1) :reverse t :lessp #'>)) + (should-equal '((30 1) (20 2) (10 3)) (compat-call sort '((30 1) (10 3) (20 2)) :key #'car :lessp #'>)) + (should-equal '((10 3) (20 2) (30 1)) (compat-call sort '((30 1) (10 3) (20 2)) :key #'car :reverse t :lessp #'>)) + (should-equal '((x 3) (y 2) (z 1)) (compat-call sort '((z 1) (x 3) (y 2)) :key #'cadr :lessp #'>)) + (should-equal '((z 1) (y 2) (x 3)) (compat-call sort '((z 1) (x 3) (y 2)) :key #'cadr :reverse t :lessp #'>)) + (let* ((vec (vector 4 5 8 3 1 2 3 2 3 4)) + (sorted (compat-call sort vec :in-place t))) + (should (eq vec sorted)) + (should-equal sorted [1 2 2 3 3 3 4 4 5 8]) + (should-equal vec [1 2 2 3 3 3 4 4 5 8]))) (ert-deftest compat-replace-string-in-region () (with-temp-buffer @@ -1840,6 +1932,9 @@ (should-equal (replace-regexp-in-region " bar" "" (point-min) 8) 1) (should-equal (buffer-string) "foo bar")))) +(ert-deftest compat-char-to-name () + (should-equal (char-to-name ?.) "FULL STOP")) + (ert-deftest compat-char-uppercase-p () (dolist (c (list ?R ?S ?Ω ?Ψ)) (should (char-uppercase-p c))) @@ -1900,7 +1995,7 @@ (should-equal '(" abc" " bcd " "cde ") (string-lines " abc\n bcd \ncde ")) ;; NOTE: Behavior for trailing newline was different on Emacs 28 - (compat-tests--if (= emacs-major-version 28) + (static-if (= emacs-major-version 28) (should-equal '("a" "b" "c" "") (string-lines "a\nb\nc\n")) (should-equal '("a" "b" "c") (string-lines "a\nb\nc\n")) (should-equal '("a\n" "\n" "b\n" "c\n") (string-lines "a\n\nb\nc\n" nil t)) @@ -2225,7 +2320,7 @@ (ert-deftest compat-when-let () ;; FIXME Broken on Emacs 25 - (compat-tests--if (= emacs-major-version 25) + (static-if (= emacs-major-version 25) (should-equal "second" (when-let ((x 3) @@ -2255,7 +2350,7 @@ (ert-deftest compat-if-let () ;; FIXME Broken on Emacs 25 - (compat-tests--if (= emacs-major-version 25) + (static-if (= emacs-major-version 25) (should-equal "then" (if-let ((x 3) @@ -3015,5 +3110,127 @@ (with-temp-buffer (should-equal (take 3 (widget-create 'key)) '(key :value "")))) +(ert-deftest compat-copy-tree () + ;; Adapted from Emacs /test/lisp/subr-tests.el + ;; Check that values other than conses, vectors and records are + ;; neither copied nor traversed. + (let ((s (propertize "abc" 'prop (list 11 12))) + (h (make-hash-table :test #'equal))) + (puthash (list 1 2) (list 3 4) h) + (dolist (x (list nil 'a "abc" s h)) + (should (eq (compat-call copy-tree x) x)) + (should (eq (compat-call copy-tree x t) x)))) + + (cl-defstruct compat-tests--rec foo) + (let* ((rec (make-compat-tests--rec :foo 1)) + (lst (list rec rec))) + ;; Plain record + (should-equal (compat-call copy-tree rec) rec) + (should-equal (compat-call copy-tree rec t) rec) + (should (eq (compat-call copy-tree rec) rec)) + (should-not (eq (compat-call copy-tree rec t) rec)) + ;; Record inside list + (should-equal (compat-call copy-tree lst) lst) + (should-not (eq (compat-call copy-tree lst) lst)) + (should (eq (car (compat-call copy-tree lst)) rec)) + (should-not (eq (car (compat-call copy-tree lst t)) rec)) + (should (eq (cadr (compat-call copy-tree lst)) rec)) + (should-not (eq (cadr (compat-call copy-tree lst t)) rec))) + + ;; Use the printer to detect common parts of Lisp values. + (let ((print-circle t)) + (cl-labels ((prn3 (x y z) (prin1-to-string (list x y z))) + (cat3 (x y z) (concat "(" x " " y " " z ")"))) + (let ((x '(a (b ((c) . d) e) (f)))) + (should-equal (prn3 x (compat-call copy-tree x) (compat-call copy-tree x t)) + (cat3 "(a (b ((c) . d) e) (f))" + "(a (b ((c) . d) e) (f))" + "(a (b ((c) . d) e) (f))")))))) + +(ert-deftest compat-static-if () + (should-equal "true" (static-if t "true")) + (should-not (static-if nil "true")) + (should-equal "else2" (static-if nil "true" "else1" "else2"))) + +(ert-deftest compat-completion-lazy-hilit () + (let ((completion-lazy-hilit t) + (completion-lazy-hilit-fn (lambda (x) (concat "<" x ">")))) + (should-equal (completion-lazy-hilit "test") "<test>")) + (should-equal (completion-lazy-hilit "test") "test")) + +(ert-deftest compat-merge-ordered-lists () + (should-equal (merge-ordered-lists + '((B A) (C A) (D B) (E D C)) + (lambda (_) (error "cycle"))) + '(E D B C A)) + (should-equal (merge-ordered-lists + '((E D C) (B A) (C A) (D B)) + (lambda (_) (error "cycle"))) + '(E D C B A)) + (should-error (merge-ordered-lists + '((E C D) (B A) (A C) (D B)) + (lambda (_) (error "cycle"))))) + +(ert-deftest compat-require-with-check () + (ert-with-temp-directory dir1 + (ert-with-temp-directory dir2 + (dolist (dir (list dir1 dir2)) + (with-temp-buffer + (insert "(provide 'compat-reload)") + (write-region (point-min) (point-max) + (file-name-concat dir "compat-reload.el")))) + (should-not (require-with-check 'compat-does-not-exist nil 'noerror)) + (should-not (require-with-check 'compat-does-not-exist "compat-does-not-exist.el" 'noerror)) + (let ((load-path (cons dir1 load-path))) + (should-equal 'compat-reload (require-with-check 'compat-reload)) + (should-equal 'compat-reload (require-with-check 'compat-reload))) + (let ((load-path (cons dir2 load-path))) + (should-error (require-with-check 'compat-reload)) + (should-equal 'compat-reload (require-with-check 'compat-reload nil 'noerror)) + (should-equal 'compat-reload (require-with-check 'compat-reload nil 'reload)))))) + +(defvar compat-tests-find-buffer nil) +(ert-deftest compat-find-buffer () + (let ((buf1 (get-buffer-create "*compat-tests-buf1*")) + (buf2 (get-buffer-create "*compat-tests-buf2*"))) + (with-current-buffer buf1 + (setq-local compat-tests-find-buffer 1)) + (with-current-buffer buf2 + (setq-local compat-tests-find-buffer 2)) + (should-equal buf1 (find-buffer 'compat-tests-find-buffer 1)) + (should-equal buf2 (find-buffer 'compat-tests-find-buffer 2)) + (should-not (find-buffer 'compat-tests-find-buffer 3)))) + +(ert-deftest compat-get-truename-buffer () + (let ((buf1 (get-buffer-create "*compat-tests-buf1*")) + (buf2 (get-buffer-create "*compat-tests-buf2*"))) + (with-current-buffer buf1 + (setq-local buffer-file-truename "compat-tests-file1")) + (with-current-buffer buf2 + (setq-local buffer-file-truename "compat-tests-file2")) + (should-equal buf1 (get-truename-buffer "compat-tests-file1")) + (should-equal buf2 (get-truename-buffer "compat-tests-file2")) + (should-not (get-truename-buffer "compat-tests-file3")))) + +(ert-deftest compat-completion-metadata-get () + (let ((md '((a . 1) (b . 2) (c . 3) (category . compat-test)))) + (should-equal 'compat-test (compat-call completion-metadata-get md 'category)) + (should-equal 1 (compat-call completion-metadata-get md 'a)) + (should-equal 2 (compat-call completion-metadata-get md 'b)) + (should-equal 3 (compat-call completion-metadata-get md 'c)) + (should-not (compat-call completion-metadata-get md 'd)) + (let ((completion-extra-properties '(:d 4))) + (should-equal 4 (compat-call completion-metadata-get md 'd))) + (let ((completion-category-overrides '((compat-test (a . 10))))) + (should-equal 10 (compat-call completion-metadata-get md 'a)))) + (let ((md '((a . 1) (b . 2)))) + (should-not (compat-call completion-metadata-get md 'category)) + (let ((completion-extra-properties '(:category compat-test))) + (should-equal 1 (compat-call completion-metadata-get md 'a)) + (should-equal 2 (compat-call completion-metadata-get md 'b)) + (should-equal 'compat-test (compat-call completion-metadata-get md 'category)) + (let ((completion-category-overrides '((compat-test (a . 10))))) + (should-equal 10 (compat-call completion-metadata-get md 'a)))))) + (provide 'compat-tests) ;;; compat-tests.el ends here diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compat-29.1.4.5/compat.el new/compat-30.0.0.0/compat.el --- old/compat-29.1.4.5/compat.el 2024-03-16 11:54:18.000000000 +0100 +++ new/compat-30.0.0.0/compat.el 2024-07-08 20:22:28.000000000 +0200 @@ -4,7 +4,7 @@ ;; Author: Philip Kaludercic <[email protected]>, Daniel Mendler <[email protected]> ;; Maintainer: Compat Development <~pkal/[email protected]> -;; Version: 29.1.4.5 +;; Version: 30.0.0.0 ;; URL: https://github.com/emacs-compat/compat ;; Package-Requires: ((emacs "24.4") (seq "2.23")) ;; Keywords: lisp, maint @@ -50,9 +50,9 @@ ;; time and runtime, but only if needed. (eval-when-compile (defmacro compat--maybe-require () - (when (version< emacs-version "29.1") - (require 'compat-29) - '(require 'compat-29)))) + (when (version< emacs-version "30.0.50") + (require 'compat-30) + '(require 'compat-30)))) (compat--maybe-require) ;;;; Macros for extended compatibility function calls diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compat-29.1.4.5/compat.texi new/compat-30.0.0.0/compat.texi --- old/compat-29.1.4.5/compat.texi 2024-03-16 11:54:18.000000000 +0100 +++ new/compat-30.0.0.0/compat.texi 2024-07-08 20:22:28.000000000 +0200 @@ -31,7 +31,7 @@ @finalout @titlepage @title "Compat" Manual -@subtitle For version 29.1.4.5 +@subtitle For version 30.0.0.0 @author Philip Kaludercic, Daniel Mendler @page @vskip 0pt plus 1filll @@ -46,7 +46,7 @@ This manual documents the usage of the "Compat" Emacs lisp library, the forward-compatibility library for Emacs Lisp, corresponding to -version 29.1.4.5. +version 30.0.0.0. @insertcopying @end ifnottex @@ -108,7 +108,7 @@ corresponds to the current Emacs release. @example -;; Package-Requires: ((emacs "24.4") (compat "29.1.4.5")) +;; Package-Requires: ((emacs "24.4") (compat "30.0.0.0")) @end example There is no need to depend on @code{emacs 24.4} specifically. One can @@ -532,26 +532,6 @@ @xref{Bool-Vectors,,,elisp}. @end defun -@subsection Extended Definitions -These functions must be called explicitly via @code{compat-call}, -since their calling convention or behavior was extended in Emacs 25.1: - -@defun compat-call@ sort sequence predicate -This function sorts @var{sequence} stably. Note that this function -doesn't work for all sequences; it may be used only for lists and -vectors. If @var{sequence} is a list, it is modified destructively. -This functions returns the sorted @var{sequence} and compares elements -using @var{predicate}. A stable sort is one in which elements with -equal sort keys maintain their relative order before and after the -sort. Stability is important when successive sorts are used to order -elements according to different criteria. - -@xref{Sequence Functions,,,elisp}. - -The compatibility version adds support for vectors to be sorted, not -just lists. -@end defun - @subsection Missing Definitions Compat does not provide support for the following Lisp features implemented in 25.1: @@ -2152,13 +2132,6 @@ to @code{subrp}. @end defun -@c based on lisp/subr.el -@defun subr-native-elisp-p object -Return @code{t} if @var{object} if the object is native compiled lisp. -If native compilation is not available, this function always returns -@code{nil}. -@end defun - @c copied from lispref/compile.texi @defun native-comp-available-p This function returns non-@code{nil} if the running Emacs process has @@ -3340,6 +3313,347 @@ Support for symbols with position information. @end itemize +@node Emacs 30.1 +@section Emacs 30.1 + +@subsection Added Definitions +The following functions and macros are implemented in Emacs +30.1. These functions are made available by Compat on Emacs versions +older than 30.1. Note that due to upstream changes, it might happen +that there will be the need for changes, so use these functions with +care. + +@c copied from lispref/nonascii.texi +@defun char-to-name char +This function returns the Unicode name of @var{char}. It returns +@code{nil} if @var{char} is not a character or has no Unicode name. +@end defun + +@c copied from lispref/symbols.texi +@defun obarray-clear obarray +This function removes all symbols from @var{obarray}. +@end defun + +@c copied from lispref/functions.texi +@defun closurep object +This function returns @code{t} if @var{object} is a closure, which is +a particular kind of function object. Currently closures are used +for all byte-code functions and all interpreted functions. +@end defun + +@c copied from lispref/functions.texi +@defun interpreted-function-p object +This function returns @code{t} if @var{object} is an interpreted function. +@end defun + +@c based on lisp/subr.el +@defun primitive-function-p object +Return @code{t} if @var{object} is a built-in primitive function. +This excludes special forms, since they are not functions. +@end defun + +@c copied from lispref/sequences.texi +@defun value< a b +This function returns non-@code{nil} if @var{a} comes before @var{b} +in the standard sorting order; this means that it returns @code{nil} +when @var{b} comes before @var{a}, or if they are equal or unordered. + +The arguments @var{a} and @var{b} must have the same type. +Specifically: + +@itemize @bullet +@item +Numbers are compared using @code{<}. +@item +Strings are compared using @code{string<} and symbols are compared by +comparing their names as strings. +@item +Conses, lists, vectors and records are compared lexicographically. +This means that the two sequences are compared element-wise from left +to right until they differ, and the result is then that of +@code{value<} on the first pair of differing elements. If one +sequence runs out of elements before the other, the shorter sequence +comes before the longer. +@item +Markers are compared first by buffer, then by position. +@item +Buffers and processes are compared by comparing their names as +strings. Dead buffers (whose name is @code{nil}) will compare before +any live buffer. +@item +Other types are considered unordered and the return value will be +@code{nil}. +@end itemize + +Examples: +@example +(value< -4 3.5) @result{} t +(value< "dog" "cat") @result{} nil +(value< 'yip 'yip) @result{} nil +(value< '(3 2) '(3 2 0)) @result{} t +(value< [3 2 "a"] [3 2 "b"]) @result{} t +@end example + +@noindent +Note that @code{nil} is treated as either a symbol or an empty list, +depending on what it is compared against: + +@example +(value< nil '(0)) @result{} t +(value< 'nib nil) @result{} t +@end example + +@noindent +There is no limit to the length of sequences (lists, vectors and so +on) that can be compared, but @code{value<} may fail with an error if +used to compare circular or deeply nested data structures. +@end defun + +@c based on lispref/lists.texi +@defun drop n list +This function is an alias for @code{nthcdr}. It returns the @var{n}th +@sc{cdr} of @var{list}. In other words, it skips past the first +@var{n} links of @var{list} and returns what follows. +@end defun + +@defun get-truename-buffer filename +Return the buffer with @code{file-truename} equal to @var{filename} (a string). +If there is no such live buffer, return nil. +See also @code{find-buffer-visiting}. +@end defun + +@defun find-buffer variable value +Return the buffer with buffer-local @var{variable} equal to @var{value}. +If there is no such live buffer, return nil. +@end defun + +@c copied from lispref/loading.texi +@defun require-with-check feature &optional filename noerror +This function works like @code{require}, except if @var{feature} is +already loaded (i.e.@: is already a member of the list in +@code{features}, see below). If @var{feature} is already loaded, this +function checks if @var{feature} was provided by a file different from +@var{filename}, and if so, it by default signals an error. If the +value of the optional argument @var{noerror} is @code{reload}, the +function doesn't signal an error, but instead forcibly reloads +@var{filename}; if @var{noerror} is some other non-@code{nil} value, +the function emits a warning about @var{feature} being already +provided by another file. +@end defun + +@defun merge-ordered-lists lists &optional error-function +Merge @var{lists} in a consistent order. @var{lists} is a list of +lists of elements. Merge them into a single list containing the same +elements (removing duplicates), obeying their relative positions in +each list. The order of the (sub)lists determines the final order in +those cases where the order within the sublists does not impose a +unique choice. Equality of elements is tested with @code{eql}. + +If a consistent order does not exist, call @var{error-function} with a +remaining list of lists that we do not know how to merge. It should +return the candidate to use to continue the merge, which has to be the +head of one of the lists. By default we choose the head of the first +list. +@end defun + +@defvar completion-lazy-hilit +If non-nil, request lazy highlighting of completion candidates. + +Lisp programs (a.k.a. "front ends") that present completion candidates +may opt to bind this variable to a non-nil value when calling +functions (such as @code{completion-all-completions}) which produce +completion candidates. This tells the underlying completion styles +that they do not need to fontify (i.e., propertize with the +@code{face} property) completion candidates in a way that highlights +the matching parts. Then it is the front end which presents the +candidates that becomes responsible for this fontification. The front +end does that by calling the function @code{completion-lazy-hilit} on +each completion candidate that is to be displayed to the user. + +Note that only some completion styles take advantage of this variable +for optimization purposes. Other styles will ignore the hint and +fontify eagerly as usual. It is still safe for a front end to call +@code{completion-lazy-hilit} in these situations. + +To author a completion style that takes advantage of this variable, +see @code{completion-lazy-hilit-fn} and +@code{completion-pcm--hilit-commonality}. +@end defvar + +@defvar completion-lazy-hilit-fn +Fontification function set by lazy-highlighting completions styles. +When a given style wants to enable support for +@code{completion-lazy-hilit} (which see), that style should set this +variable to a function of one argument. It will be called with each +completion candidate, a string, to be displayed to the user, and +should destructively propertize these strings with the @code{face} +property. +@end defvar + +@defun completion-lazy-hilit str +Return a copy of completion candidate @var{str} that is +face-propertized. See documentation of the variable +@code{completion-lazy-hilit} for more details. +@end defun + +@defmac static-if condition then-form else-forms... +Test @var{condition} at macro-expansion time. If its value is +non-@code{nil}, expand the macro to @var{then-form}, otherwise expand +it to @var{else-forms} enclosed in a @code{progn}. @var{else-forms} +may be empty. + +Here is an example of its use from CC Mode, which prevents a +@code{defadvice} form being compiled in newer versions of Emacs: +@example +@group +(static-if (boundp 'comment-line-break-function) + (progn) + (defvar c-inside-line-break-advice nil) + (defadvice indent-new-comment-line (around c-line-break-advice + activate preactivate) + "Call `c-indent-new-comment-line' if in CC Mode." + (if (or c-inside-line-break-advice + (not c-buffer-is-cc-mode)) + ad-do-it + (let ((c-inside-line-break-advice t)) + (c-indent-new-comment-line (ad-get-arg 0)))))) +@end group +@end example +@end defmac + +@subsection Extended Definitions +These functions must be called explicitly via @code{compat-call}, +since their calling convention or behavior was extended in Emacs 30.1: + +@c copied from lisp/sequences.texi +@defun compat-call@ sort sequence &rest keyword-args +This function sorts @var{sequence}, which must be a list or vector, +and returns a sorted sequence of the same type. The sort is stable, +which means that elements with equal sort keys maintain their relative +order. It takes the following optional keyword arguments: + +@table @code +@item :key @var{keyfunc} +Use @var{keyfunc}, a function that takes a single element from +@var{sequence} and returns its key value, to generate the keys used in +comparison. If this argument is absent or if @var{keyfunc} is +@code{nil} then @code{identity} is assumed; that is, the elements +themselves are used as sorting keys. + +@item :lessp @var{predicate} +Use @var{predicate} to order the keys. @var{predicate} is a function +that takes two sort keys as arguments and returns non-@code{nil} if +the first should come before the second. If this argument is absent +or @var{predicate} is @code{nil}, then @code{value<} is used, which is +applicable to many different Lisp types and generally sorts in +ascending order. + +For consistency, any predicate must obey the following rules: +@itemize @bullet +@item +It must be @dfn{antisymmetric}: it cannot both order @var{a} before +@var{b} and @var{b} before @var{a}. +@item +It must be @dfn{transitive}: if it orders @var{a} before @var{b} and +@var{b} before @var{c}, then it must also order @var{a} before @var{c}. +@end itemize + +@item :reverse @var{flag} +If @var{flag} is non-@code{nil}, the sorting order is reversed. With +the default @code{:lessp} predicate this means sorting in descending order. + +@item :in-place @var{flag} +If @var{flag} is non-@code{nil}, then @var{sequence} is sorted +in-place (destructively) and returned. If @code{nil}, or if this +argument is not given, a sorted copy of the input is returned and +@var{sequence} itself remains unmodified. In-place sorting is +slightly faster, but the original sequence is lost. +@end table + +If the default behaviour is not suitable for your needs, it is usually +easier and faster to supply a new @code{:key} function than a +different @code{:lessp} predicate. For example, consider sorting +these strings: + +@example +@group +(setq numbers '("one" "two" "three" "four" "five" "six")) +(sort numbers) + @result{} ("five" "four" "one" "six" "three" "two") +@end group +@end example + +You can sort the strings by length instead by supplying a different key +function: + +@example +@group +(sort numbers :key #'length) + @result{} ("one" "two" "six" "four" "five" "three") +@end group +@end example + +@noindent +Note how strings of the same length keep their original order, thanks to +the sorting stability. Now suppose you want to sort by length, but use +the string contents to break ties. The easiest way is to specify a key +function that transforms an element to a value that is sorted this way. +Since @code{value<} orders compound objects (conses, lists, +vectors and records) lexicographically, you could do: + +@example +@group +(sort numbers :key (lambda (x) (cons (length x) x))) + @result{} ("one" "six" "two" "five" "four" "three") +@end group +@end example + +@noindent +because @code{(3 . "six")} is ordered before @code{(3 . "two")} and so on. + +For compatibility with previous versions of Emacs, the @code{sort} +function can also be called using the fixed two-argument form: + +@example +(@code{sort} @var{sequence} @var{predicate}) +@end example + +@noindent +where @var{predicate} is the @code{:lessp} argument. When using this +form, sorting is always done in-place. +@end defun + +@c based on lisp/minibuffer.el +@defun compat-call@ completion-metadata-get metadata prop +Get property @var{prop} from completion @var{metadata}. If the +metadata specifies a completion category, the variables +@code{completion-category-overrides} and +@code{completion-category-defaults} take precedence for +category-specific overrides. If the completion metadata does not +specify the property, the @code{completion-extra-properties} plist is +consulted. Note that the keys of the +@code{completion-extra-properties} plist are keyword symbols, not +plain symbols. +@end defun + +@c copied from lispref/lists.texi +@defun compat-call@ copy-tree tree &optional vectors-and-records +This function returns a copy of the tree @var{tree}. If @var{tree} is a +cons cell, this makes a new cons cell with the same @sc{car} and +@sc{cdr}, then recursively copies the @sc{car} and @sc{cdr} in the +same way. + +Normally, when @var{tree} is anything other than a cons cell, +@code{copy-tree} simply returns @var{tree}. However, if +@var{vectors-and-records} is non-@code{nil}, it copies vectors and records +too (and operates recursively on their elements). The @var{tree} +argument must not contain cycles. +@end defun + +@subsection Missing Definitions +Compat does not provide support for the following Lisp features +implemented in 30.1: + @node Development @chapter Development
