compat.el (3991B)
1 ;;; compat.el --- Emacs Lisp Compatibility Library -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2021-2024 Free Software Foundation, Inc. 4 5 ;; Author: Philip Kaludercic <philipk@posteo.net>, Daniel Mendler <mail@daniel-mendler.de> 6 ;; Maintainer: Compat Development <~pkal/compat-devel@lists.sr.ht> 7 ;; Version: 30.0.0.0 8 ;; URL: https://github.com/emacs-compat/compat 9 ;; Package-Requires: ((emacs "24.4") (seq "2.23")) 10 ;; Keywords: lisp, maint 11 12 ;; This program is free software; you can redistribute it and/or modify 13 ;; it under the terms of the GNU General Public License as published by 14 ;; the Free Software Foundation, either version 3 of the License, or 15 ;; (at your option) any later version. 16 17 ;; This program is distributed in the hope that it will be useful, 18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 ;; GNU General Public License for more details. 21 22 ;; You should have received a copy of the GNU General Public License 23 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 24 25 ;;; Commentary: 26 27 ;; Compat is the Elisp forwards compatibility library, which provides 28 ;; definitions introduced in newer Emacs versions. The definitions 29 ;; are only installed if necessary for your current Emacs version. If 30 ;; Compat is compiled on a recent version of Emacs, all of the 31 ;; definitions are disabled at compile time, such that no negative 32 ;; performance impact is incurred. The provided compatibility 33 ;; implementations of functions and macros are at least subsets of the 34 ;; actual implementations. Be sure to read the documentation string 35 ;; and the Compat manual. 36 ;; 37 ;; Not every function provided in newer versions of Emacs is provided 38 ;; here. Some depend on new features from the C core, others cannot 39 ;; be implemented to a meaningful degree. Please consult the Compat 40 ;; manual for details regarding the usage of the Compat library and 41 ;; the provided functionality. 42 43 ;; The main audience for this library are not regular users, but 44 ;; package maintainers. Therefore no commands, user-facing modes or 45 ;; user options are implemented here. 46 47 ;;; Code: 48 49 ;; Ensure that the newest compatibility layer is required at compile 50 ;; time and runtime, but only if needed. 51 (eval-when-compile 52 (defmacro compat--maybe-require () 53 (when (version< emacs-version "30.0.50") 54 (require 'compat-30) 55 '(require 'compat-30)))) 56 (compat--maybe-require) 57 58 ;;;; Macros for extended compatibility function calls 59 60 (defmacro compat-function (fun) 61 "Return compatibility function symbol for FUN. 62 63 If the Emacs version provides a sufficiently recent version of 64 FUN, the symbol FUN is returned itself. Otherwise the macro 65 returns the symbol of a compatibility function which supports the 66 behavior and calling convention of the current stable Emacs 67 version. For example Compat 29.1 will provide compatibility 68 functions which implement the behavior and calling convention of 69 Emacs 29.1. 70 71 See also `compat-call' to directly call compatibility functions." 72 (let ((compat (intern (format "compat--%s" fun)))) 73 `#',(if (fboundp compat) compat fun))) 74 75 (defmacro compat-call (fun &rest args) 76 "Call compatibility function or macro FUN with ARGS. 77 78 A good example function is `plist-get' which was extended with an 79 additional predicate argument in Emacs 29.1. The compatibility 80 function, which supports this additional argument, can be 81 obtained via (compat-function plist-get) and called 82 via (compat-call plist-get plist prop predicate). It is not 83 possible to directly call (plist-get plist prop predicate) on 84 Emacs older than 29.1, since the original `plist-get' function 85 does not yet support the predicate argument. Note that the 86 Compat library never overrides existing functions. 87 88 See also `compat-function' to lookup compatibility functions." 89 (let ((compat (intern (format "compat--%s" fun)))) 90 `(,(if (fboundp compat) compat fun) ,@args))) 91 92 (provide 'compat) 93 ;;; compat.el ends here