"Compat" Manual
***************

This manual documents the usage of the "Compat" Emacs lisp library, the
forward-compatibility library for Emacs Lisp, corresponding to version
28.1.2.0.

   Copyright © 2022 Free Software Foundation, Inc.

     Permission is granted to copy, distribute and/or modify this
     document under the terms of the GNU Free Documentation License,
     Version 1.3 or any later version published by the Free Software
     Foundation; with no Invariant Sections, with the Front-Cover Texts
     being “A GNU Manual,” and with the Back-Cover Texts as in (a)
     below.  A copy of the license is included in the section entitled
     “GNU Free Documentation License.”

     (a) The FSF’s Back-Cover Text is: “You have the freedom to copy and
     modify this GNU manual.”

— The Detailed Node Listing —

Introduction

Usage

Support

1 Introduction
**************

1.1 Overview
============

The objective of Compat is to provide "forwards compatibility" library
for Emacs Lisp.  That is to say by using Compat, an Elisp package does
not have to make the decision to either use new and useful functionality
or support old versions of Emacs.

   Version 24.3 is chosen as the oldest version, because this is the
newest version on CentOS 7.  It is intended to preserve compatibility
for at least as the Centos 7 reaches EOL
(https://wiki.centos.org/About/Product), 2024.

   If you are developing a package with Compat in mind, consider loading
‘compat-help‘ (on your system, not in a package) to get relevant notes
inserted into the help buffers of functions that are implemented or
advised in Compat.

   Note that Compat provides a few prefixed function, ie.  functions
with a ‘compat-’ prefix.  These are used to provide extended
functionality for commands that are already defined (‘sort’, ‘assoc’,
‘seq’, ...).  It might be possible to transform these into advised
functions later on, so that the modified functionality is accessible
without a prefix.  Feedback on this point is appreciated.

1.2 Usage
=========

The intended use-case for this library is for package developers to add
as a dependency in the header:

     ;; Package-Requires: ((emacs "24.3") (compat "28.1.2.0"))

   and later on a

     (require 'compat)

   This will load all non-prefixed definitions (functions and macros
with a leading ‘compat-‘).  To load these, an additional

     (require 'compat-XY) ; e.g. 26

   will be necessary, to load compatibility code for Emacs version XY.

   It is recommended to subscribe to the compat-announce
(https://lists.sr.ht/~pkal/compat-announce) mailing list to be notified
when new versions are released or relevant changes are made.

1.2.1 Additional libraries
--------------------------

These libraries are packages with Compat, but are disabled by default.
To use them you can use ‘M-x load-library’:

compat-help
     Add notes to ‘*Help*’ buffer, if a compatibility definition has
     something to warn you about.
compat-font-lock
     Highlight functions that are implemented as compatibility
     definitions.

1.3 Intentions
==============

The library intends to provide support back until Emacs 24.3.  The
intended audience are package developers that are interested in using
newer developments, without having to break compatibility.

   Sadly, total backwards compatibility cannot be provided for technical
reasons.  These might include:

   • An existing function or macro was extended by some new
     functionality.  To support these cases, the function or macro would
     have to be advised.  As this is usually regarded as invasive and is
     shown to be a significant overhead, even when the new feature is
     not used, this approach is not used.

     As a compromise, prefixed functions and macros (starting with a
     ‘compat-’ prefix) can be provided.

   • New functionality was implemented in the core, and depends on
     external libraries that cannot be reasonably duplicated in the
     scope of a compatibility library.

   • New functionality depends on an entire new, non-trivial library.
     Sometimes these are provided via ELPA (xref, project, ...), but
     other times it would be infeasible to duplicate an entire library
     within Compat while also providing the necessary backwards
     compatibility.

   • It just wasn’t added, and there is no good reason (though good
     excuses might exist).  If you happen to find such a function, see
     reporting it would be much appreciated.

     Always begin by assuming that this might be the case, unless proven
     otherwise.

2 Support
*********

This section goes into the features that Compat manages and doesn’t
manage to provide for each Emacs version.

2.1 Emacs 24.4
==============

The following functions and macros implemented in 24.4, and are provided
by Compat by default:

 -- Macro: with-eval-after-load
     See (elisp) Hooks for Loading (elisp).

 -- Function: special-form-p
     See (elisp) Special Forms (elisp).

 -- Function: macrop
     See (elisp) Simple Macro (elisp).

 -- Function: string-suffix-p
     See (elisp) Text Comparison (elisp).

 -- Function: delete-consecutive-dups
     Defined in ‘subr.el’.

 -- Function: define-error
     See (elisp) Error Symbols (elisp).

 -- Function: bool-vector-exclusive-or
     See (elisp) Bool-Vectors (elisp).

 -- Function: bool-vector-union
     See (elisp) Bool-Vectors (elisp).

 -- Function: bool-vector-intersection
     See (elisp) Bool-Vectors (elisp).

 -- Function: bool-vector-not
     See (elisp) Bool-Vectors (elisp).

 -- Function: bool-vector-subsetp
     See (elisp) Bool-Vectors (elisp).

 -- Function: bool-vector-count-consecutive
     See (elisp) Bool-Vectors (elisp).

 -- Function: bool-vector-count-population
     See (elisp) Bool-Vectors (elisp).

 -- Function: completion-table-merge
     See (elisp) Basic Completion (elisp).

 -- Function: completion-table-with-cache
     See (elisp) Programmed Completion (elisp).

 -- Function: face-spec-set
     See (elisp) Defining Faces (elisp).

   These functions are prefixed with ‘compat’ prefix, and are only
loaded when ‘compat-24’ is required:

 -- Function: compat-=
 -- Function: compat-<
 -- Function: compat->
 -- Function: compat-<=
 -- Function: compat->=
     See (elisp) Comparison of Numbers (elisp).

     Allows for more than two arguments to be compared.

 -- Function: compat-split-string
     See (elisp) Creating Strings (elisp).

     Takes optional argument TRIM.

   Compat does not provide support for the following Lisp features
implemented in 24.4:

   • Allowing the second optional argument to ‘eval’ to specify a
     lexical environment.
   • The ‘define-alternatives’ macro.
   • Support for the ‘defalias-fset-function’ symbol property.
   • The ‘group-gid’ and ‘groupd-read-gid’ functions.
   • The ‘pre-redisplay-function’ hook.
   • Allowing for ‘with-demoted-errors’ to take a additional argument
     ‘format’.
   • The ‘face-spec-set’ function.
   • The ‘add-face-text-property’ function.
   • No ‘tty-setup-hook’ hook.
   • The ‘get-pos-property’ function.
   • The ‘define-advice’ macro.
   • Support for generators.
   • The ‘string-trim’, ‘string-trim-left’ and ‘string-trim-right’
     functions.  These are instead provided as prefixed function as part
     of Emacs 26.1 support.

2.2 Emacs 24.5
==============

No special support for 24.5 was deemed necessary.

2.3 Emacs 25.1
==============

The following functions and macros implemented in 25.1, and are provided
by Compat by default:

 -- Function: format-message
     See (elisp) Formatting Strings (elisp).

 -- Function: directory-name-p
     See (elisp) Directory Names (elisp).

 -- Function: string-greaterp
     See (elisp) Text Comparison (elisp).

 -- Macro: with-file-modes
     See (elisp) Changing Files (elisp).

 -- Function: alist-get
     See (elisp) Association Lists (elisp).

 -- Macro: if-let
     Defined in ‘subr-x.el’.

 -- Macro: when-let
     Defined in ‘subr-x.el’.

 -- Macro: thread-first
     Defined in ‘subr-x.el’.

 -- Macro: thread-last
     Defined in ‘subr-x.el’.

 -- Function: macroexpand-1
     See (elisp) Expansion (elisp).

 -- Function: directory-files-recursively
     See (elisp) Contents of Directories (elisp).

 -- Function: bool-vector
     See (elisp) Bool-Vectors (elisp).

   These functions are prefixed with ‘compat’ prefix, and are only
loaded when ‘compat-25’ is required:

 -- Function: compat-sort
     See (elisp) Sequence Functions (elisp).

     Adds support for vectors to be sorted, next to just lists.

   Compat does not provide support for the following Lisp features
implemented in 25.1:

   • New ‘pcase’ patterns.
   • The hook ‘prefix-command-echo-keystrokes-functions’ and
     ‘prefix-command-preserve-state-hook’.
   • The hook ‘pre-redisplay-functions’.
   • The function ‘make-process’.
   • Support for the variable ‘inhibit-message’.
   • The ‘define-inline’ functionality.
   • The functions ‘string-collate-lessp’ and ‘string-collate-equalp’.
   • Support for ‘alist-get’ as a generalised variable.
   • The function ‘funcall-interactivly’.
   • The function ‘buffer-substring-with-bidi-context’.
   • The function ‘font-info’.
   • The function ‘default-font-width’.
   • The function ‘window-font-height’ and ‘window-font-width’.
   • The function ‘window-max-chars-per-line’.
   • The function ‘set-binary-mode’.
   • The functions ‘bufferpos-to-filepos’ and ‘filepos-to-bufferpos’.

   Note that the changes in Emacs 25.2 and 25.3 are also included here,
for the sake of simplicity.

2.4 Emacs 26.1
==============

The following functions and macros implemented in 26.1, and are provided
by Compat by default:

 -- Function: func-arity
     See (elisp) What Is a Function (elisp).

 -- Function: mapcan
     See (elisp) Mapping Functions (elisp).

 -- Function: cXXXr
 -- Function: cXXXXr
     See (elisp) List Elements (elisp).

 -- Variable: gensym-counter
     See ‘gensym’.

 -- Function: gensym
     See (elisp) Creating Symbols (elisp).

 -- Function: make-nearby-temp-file
     See (elisp) Unique File Names (elisp).

 -- Variable: mounted-file-systems
     Defined in ‘files.el’.

 -- Function: temporary-file-directory
     See (elisp) Unique File Names (elisp).

 -- Macro: if-let*
     Defined in ‘subr-x.el’.

 -- Macro: when-let*
     Defined in ‘subr-x.el’.

 -- Macro: and-let*
     Defined in ‘subr-x.el’.

     **Please Note:** The implementation provided by Compat does not
     include a bug that was observed with Emacs 26 (see
     <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=31840>).

 -- Function: file-local-name
     See (elisp) Magic File Names (elisp).

 -- Function: file-name-quoted-p
     See (elisp) File Name Expansion (elisp).

 -- Function: file-name-quote
     See (elisp) File Name Expansion (elisp).

 -- Function: image-property
     Defined in ‘image.el’.

     This function can also be used as a generalised variable.  To use
     this you need to explicitly require ‘compat-26’.

 -- Function: file-attribute-type
     See (elisp) File Attributes (elisp).

 -- Function: file-attribute-link-number
     See (elisp) File Attributes (elisp).

 -- Function: file-attribute-user-id
     See (elisp) File Attributes (elisp).

 -- Function: file-attribute-group-id
     See (elisp) File Attributes (elisp).

 -- Function: file-attribute-access-time
     See (elisp) File Attributes (elisp).

 -- Function: file-attribute-modification-time
     See (elisp) File Attributes (elisp).

 -- Function: file-attribute-status-change-time
     See (elisp) File Attributes (elisp).

 -- Function: file-attribute-size
     See (elisp) File Attributes (elisp).

 -- Function: file-attribute-modes
     See (elisp) File Attributes (elisp).

 -- Function: file-attribute-inode-number
     See (elisp) File Attributes (elisp).

 -- Function: file-attribute-device-number
     See (elisp) File Attributes (elisp).

 -- Function: file-attribute-collect
     Defined in ‘files.el’.

   These functions are prefixed with ‘compat’ prefix, and are only
loaded when ‘compat-26’ is required:

 -- Function: compat-assoc
     See (elisp) Association Lists (elisp).

     Handle the optional argument TESTFN.

 -- Function: compat-line-number-at-pos
     See (elisp) Text Lines (elisp).

     Handle the optional argument ABSOLUTE.

 -- Function: compat-alist-get
     See (elisp) Association Lists (elisp).

     Handle the optional argument TESTFN.  Can also be used as a
     generalised variable.

 -- Function: compat-string-trim-left
     See (elisp) Creating Strings (elisp).

     Handles the optional argument REGEXP.

 -- Function: compat-string-trim-right
     See (elisp) Creating Strings (elisp).

     Handles the optional argument REGEXP.

 -- Function: compat-string-trim
     See (elisp) Creating Strings (elisp).

     Handles the optional arguments TRIM-LEFT and TRIM-RIGHT.

   Compat does not provide support for the following Lisp features
implemented in 26.1:

   • The function ‘secure-hash-algorithms’.
   • The function ‘gnutls-avalaible-p’.
   • Support for records and record functions.
   • The function ‘mapbacktrace’.
   • The function ‘file-name-case-insensitive-p’.
   • The file-attributes constructors.
   • The function ‘read-multiple-choice’.
   • The additional elements of ‘parse-partial-sexp’.
   • The function ‘add-variable-watcher’.
   • The function ‘undo-amalgamate-change-group’.
   • The function ‘char-from-name’
   • Signalling errors when ‘length’ or ‘member’ deal with list cycles.
   • The function ‘frame-list-z-order’.
   • The function ‘frame-restack’.
   • Support for side windows and atomic windows.
   • All changes related to ‘display-buffer’.
   • The function ‘window-swap-states’.

   Note that the changes in Emacs 26.2 and 26.3 are also included here,
for the sake of simplicity.

2.5 Emacs 27.1
==============

The following functions and macros implemented in 27.1, and are provided
by Compat by default:

 -- Function: proper-list-p
     See (elisp) List-related Predicates (elisp).

 -- Function: string-distance
     See (elisp) Text Comparison (elisp).

 -- Function: json-serialize
     See (elisp) Parsing JSON (elisp).

 -- Function: json-insert
     See (elisp) Parsing JSON (elisp).

 -- Function: json-parse-string
     See (elisp) Parsing JSON (elisp).

 -- Function: json-parse-buffer
     See (elisp) Parsing JSON (elisp).

 -- Macro: ignore-error
     See (elisp) Handling Errors (elisp).

 -- Macro: dolist-with-progress-reporter
     See (elisp) Progress (elisp).

 -- Function: flatten-tree
     See (elisp) Building Lists (elisp).

 -- Function: xor
     See (elisp) Combining Conditions (elisp).

 -- Variable: regexp-unmatchable
     Defined in ‘subr.el’.

 -- Function: decoded-time-second
     Defined in ‘simple.el’.

 -- Function: decoded-time-minute
     Defined in ‘simple.el’.

 -- Function: decoded-time-hour
     Defined in ‘simple.el’.

 -- Function: decoded-time-day
     Defined in ‘simple.el’.

 -- Function: decoded-time-month
     Defined in ‘simple.el’.

 -- Function: decoded-time-year
     Defined in ‘simple.el’.

 -- Function: decoded-time-weekday
     Defined in ‘simple.el’.

 -- Function: decoded-time-dst
     Defined in ‘simple.el’.

 -- Function: decoded-time-zone
     Defined in ‘simple.el’.

 -- Function: package-get-version
     Defined in ‘package.el’.

 -- Function: time-equal-p
     See (elisp) Time Calculations (elisp).

 -- Function: date-days-in-month
     See (elisp) Time Calculations (elisp).

 -- Function: exec-path
     See (elisp) Subprocess Creation (elisp).

     This function requires the ‘time-date’ feature to be loaded.

   These functions are prefixed with ‘compat’ prefix, and are only
loaded when ‘compat-27’ is required:

 -- Function: compat-recenter
     See (elisp) Textual Scrolling (elisp).

     Adds the optional argument REDISPLAY.

 -- Function: compat-lookup-key
     See (elisp) Low-Level Key Binding (elisp).

     Allows KEYMAP to be a list of keymaps.

 -- Macro: compat-setq-local
     See (elisp) Creating Buffer-Local (elisp).

     Allow for more than one variable to be set.

 -- Function: compat-regexp-opt
     See (elisp) Regexp Functions (elisp).

     Handle an empty list of strings.

 -- Function: compat-file-size-human-readable
     Defined in ‘files.el’.

     Handle the optional third (SPACE) and forth (UNIT) arguments.

 -- Function: compat-assoc-delete-all
     See (elisp) Association Lists (elisp).

     Handle the optional third (TESTFN) argument.

 -- Function: compat-executable-find
     See (elisp) Locating Files (elisp).

     Handle the optional second (REMOTE) argument.

 -- Function: compat-dired-get-marked-files
     Defined in ‘dired.el’

     Handles the optional fifth (ERROR) argument.

   Compat does not provide support for the following Lisp features
implemented in 27.1:

   • Bigint support.
   • The function ‘time-convert’.
   • All ‘iso8601-*’ functions.
   • The macro ‘benchmark-progn’.
   • The function ‘read-char-from-minibuffer’.
   • The minor mode ‘reveal-mode’.
   • The macro ‘with-suppressed-warnings’.
   • Support for ‘condition-case’ to handle t.
   • The functions ‘major-mode-suspend’ and ‘major-mode-restore’.
   • The function ‘provided-mode-derived-p’.
   • The function ‘file-system-info’.
   • The more consistent treatment of NaN values.
   • The function ‘ring-resize’.
   • The function ‘group-name’.
   • Additional ‘format-spec’ modifiers.
   • Support for additional body forms for
     ‘define-globalized-minor-mode’.
   • The macro ‘with-connection-local-variables’ and related
     functionality.

   Note that the changes in Emacs 27.2 are also included here, for the
sake of simplicity.

2.6 Emacs 28.1
==============

The following functions and macros implemented in 28.1, and are provided
by Compat by default:

 -- Function: string-search
     See (elisp) Text Comparison (elisp).

 -- Function: length=
     See (elisp) Sequence Functions (elisp).

 -- Function: length<
     See (elisp) Sequence Functions (elisp).

 -- Function: length>
     See (elisp) Sequence Functions (elisp).

 -- Function: file-name-concat
     See (elisp) Directory Names (elisp).

 -- Function: garbage-collect-maybe
     Defined in ‘alloc.c’.

 -- Function: string-replace
     See (elisp) Search and Replace (elisp).

 -- Function: always
     See (elisp) Calling Functions (elisp).

 -- Function: insert-into-buffer
     See (elisp) Insertion (elisp).

 -- Function: replace-regexp-in-region
     See (elisp) Search and Replace (elisp).

 -- Function: replace-string-in-region
     See (elisp) Search and Replace (elisp).

 -- Function: buffer-local-boundp
     See (elisp) Creating Buffer-Local (elisp).

 -- Function: with-existing-directory
     See (elisp) Testing Accessibility (elisp).

 -- Macro: dlet
     See (elisp) Local Variables (elisp).

 -- Function: ensure-list
     See (elisp) Building Lists (elisp).

 -- Function: string-clean-whitespace
     See (elisp) Creating Strings (elisp).

 -- Function: string-fill
     See (elisp) Creating Strings (elisp).

 -- Function: string-lines
     See (elisp) Creating Strings (elisp).

 -- Function: string-pad
     See (elisp) Creating Strings (elisp).

 -- Function: string-chop-newline
     See (elisp) Creating Strings (elisp).

 -- Macro: named-let
     See (elisp) Local Variables (elisp).

 -- Function: file-name-with-extension
     See (elisp) File Name Components (elisp).

 -- Function: directory-empty-p
     See (elisp) Contents of Directories (elisp).

 -- Function: format-prompt
     See (elisp) Text from Minibuffer (elisp).

 -- Function: thing-at-mouse
     Defined in ‘thingatpt.el’.

 -- Function: macroexp-file-name
     Defined in ‘macroexp’.

 -- Macro: with-environment-variables
     See (elisp) System Environment (elisp).

 -- Function: button-buttonize
     Defined in ‘button.el’.

 -- Function: make-directory-autoloads
     See (elisp) Autoload (elisp).

 -- Function: color-values-from-color-spec
     Defined in ‘xfaces.c’.

 -- Function: file-modes-number-to-symbolic
     See (elisp) Changing Files (elisp).

 -- Function: file-backup-file-names
     See (elisp) Backup Names (elisp).

 -- Function: make-lock-file-name
     Defined in ‘files.el’.

 -- Function: null-device
     Defined in ‘files.el’.

 -- Function: decoded-time-period
     Defined in ‘time-data.el’.

 -- Function: subr-primitive-p
     Defined in ‘subr.el’.

   These functions are prefixed with ‘compat’ prefix, and are only
loaded when ‘compat-28’ is required:

 -- Function: compat-unlock-buffer
     See (elisp) File Locks (elisp).

     Handle ‘file-error’ conditions.

 -- Function: compat-string-width
     See (elisp) Size of Displayed Text (elisp).

     Handle optional arguments FROM and TO.

 -- Function: compat-json-serialize
     See (elisp) Parsing JSON (elisp).

     Handle primitive, top-level JSON values.

 -- Function: compat-json-insert
     See (elisp) Parsing JSON (elisp).

     Handle primitive, top-level JSON values.

 -- Function: compat-json-parse-string
     See (elisp) Parsing JSON (elisp).

     Handle primitive, top-level JSON values.

 -- Function: compat-json-parse-buffer
     See (elisp) Parsing JSON (elisp).

     Handle primitive, top-level JSON values.

 -- Function: compat-count-windows
     Defined in ‘window.el’.

     Handle optional argument ALL-FRAMES.

   Compat does not provide support for the following Lisp features
implemented in 28.1:

   • Support for ‘interactive’ or ‘declare’ to list applicable modes.
   • Support for ‘:interactive’ argument to ‘define-minor-mode’ and
     ‘define-derived-mode’.
   • Support for ‘:predicate’ argument to
     ‘define-globalized-minor-mode’.
   • "Success handler" for ‘condition-case’.
   • The function ‘benchmark-call’.
   • Support for the ‘natnum’ defcustom type.
   • The function ‘macroexp-compiling-p’.
   • The function ‘macroexp-warn-and-return’.
   • Additional Edebug keywords.
   • Shorthand support.
   • The function ‘custom-add-choice’.
   • The function ‘decoded-time-period’.
   • The function ‘dom-print’.
   • The function ‘dom-remove-attribute’.
   • The function ‘dns-query-asynchronous’.
   • The function ‘get-locale-names’.
   • The function ‘json-avaliable-p’.
   • The function ‘mail-header-parse-addresses-lax’.
   • The function ‘mail-header-parse-address-lax’.
   • The function ‘make-separator-line’.
   • The function ‘num-processors’.
   • The function ‘object-intervals’.
   • The function ‘process-lines-ignore-status’.
   • The function ‘require-theme’.
   • The function ‘syntax-class-to-char’.
   • The function ‘null-device’ and ‘path-separator’.

3 Development
*************

Compat is developed on SourceHut (https://sr.ht/~pkal/compat).  A
restricted GitHub mirror (https://github.com/phikal/compat.el) is also
maintained.

   Patches and comments can be sent to the development mailing list
(https://lists.sr.ht/~pkal/compat-devel) (~pkal/compat-devel@lists.sr.ht
<~pkal/compat-devel@lists.sr.ht>).  Bug reports are best sent to the
issue tracker (https://todo.sr.ht/~pkal/compat) (~pkal/compat@todo.sr.ht
<~pkal/compat@todo.sr.ht>).  The GitHub mirror can also be used to
submit patches.  These may include issues in the compatibility code,
missing definitions or performance issues.

   Please note that as a GNU ELPA package, Compat requires contributors
to have signed the FSF copyright assignment
(https://www.gnu.org/software/emacs/manual/html_node/emacs/Copyright-Assignment.html),
before any non-trivial contribution (roughly 15 lines of code) can be
applied.