Skip to content

Emacs 29.1

2.5.1 Added Definitions

The following functions and macros are implemented in Emacs 29.1. These functions are made available by Compat on Emacs versions older than 29.1. Note that due to upstream changes, it might happen that there will be the need for changes, so use these functions with care.

The defcustom type key introduced in Emacs 29.1 is made available by Compat.

Variable: untrusted-content

Non-nil means that current buffer originated from an untrusted source. Email clients and some other modes may set this non-nil to mark the buffer contents as untrusted. This variable might be subject to change without notice.

Variable: lisp-directory

This variable holds a string naming the directory which holds Emacs’s own *.el and *.elc files. This is usually the place where those files are located in the Emacs installation tree, unless Emacs is run from its build directory in which case it points to the lisp subdirectory in the source directory from which Emacs was built.

Function: count-sentences start end

Count sentences in current buffer from start to end.

Function: readablep object

This predicate says whether object has readable syntax, i.e., it can be written out and then read back by the Emacs Lisp reader. If it can’t, this function returns nil; if it can, this function returns a printed representation (via prin1).

Function: substitute-quotes string

This function works like substitute-command-keys, but only replaces quote characters.

Function: get-scratch-buffer-create

Return the *scratch* buffer, creating a new one if needed.

Function: use-region-noncontiguous-p

Return non-nil for a non-contiguous region if use-region-p.

Function: use-region-end

Return the end of the region if use-region-p.

Function: use-region-beginning

Return the start of the region if use-region-p.

Macro: buffer-local-set-state variable value...

Minor modes often set buffer-local variables that affect some features in Emacs. When a minor mode is switched off, the mode is expected to restore the previous state of these variables. This convenience macro helps with doing that: It works much like setq-local, but returns an object that can be used to restore these values back to their previous values/states (using the companion function buffer-local-restore-state).

Function: delete-line

Delete the current line.

Function: list-of-strings-p object

Return t if object is nil or a list of strings.

Function: plistp object

Non-nil if and only if object is a valid plist.

Macro: with-memoization place code…

This macro provides a simple way to do memoization. code is evaluated and then stashed in place. If place’s value is non-nil, return that value instead of evaluating code.

Special Form: with-restriction start end [:label label] body

This special form saves the current bounds of the accessible portion of the buffer, sets the accessible portion to start at start and end at end, evaluates the body forms, and restores the saved bounds. In that case it is equivalent to

emacs-lisp
(save-restriction
  (narrow-to-region start end)
  body)

When the optional argument label, a symbol, is present, the narrowing is labeled. A labeled narrowing differs from a non-labeled one in several ways:

  • During the evaluation of the body form, narrow-to-region and widen can be used only within the start and end limits.
  • To lift the restriction introduced by with-restriction and gain access to other portions of the buffer, use without-restriction with the same label argument. (Another way to gain access to other portions of the buffer is to use an indirect buffer (see (elisp)Indirect Buffers).)
  • Labeled narrowings can be nested.
  • Labeled narrowings can only be used in Lisp programs: they are never visible on display, and never interfere with narrowings set by the user.

If you use with-restriction with the optional label argument, we recommend documenting the label in the doc strings of the functions which use it, so that other Lisp programs your code calls could lift the labeled narrowing if and when it needs.

Special Form: without-restriction [:label label] body

This special form saves the current bounds of the accessible portion of the buffer, widens the buffer, evaluates the body forms, and restores the saved bounds. In that case it is equivalent to

emacs-lisp
(save-restriction
  (widen)
  body)

When the optional argument label is present, the narrowing set by with-restriction with the same label argument is lifted.

Function: pos-bol &optional count

Like line-beginning-position, but ignores fields (and is more efficient).

Function: pos-eol &optional count

Like line-end-position, but ignores fields (and is more efficient).

Function: char-uppercase-p char

Return non-nil if char is an uppercase character according to Unicode.

Macro: with-delayed-message (timeout message) body…

Sometimes it’s unclear whether an operation will take a long time to execute or not, or it can be inconvenient to implement a progress reporter. This macro can be used in those situations.

emacs-lisp
(with-delayed-message (2 (format "Gathering data for %s" entry))
  (setq data (gather-data entry)))

In this example, if the body takes more than two seconds to execute, the message will be displayed. If it takes a shorter time than that, the message won’t be displayed. In either case, the body is evaluated as normally, and the return value of the final element in the body is the return value of the macro.

The message element is evaluated before body, and is always evaluated, whether the message is displayed or not.

Function: funcall-with-delayed-message timeout message function

Like funcall, but display message if function takes longer than timeout. timeout is a number of seconds, and can be an integer or a floating point number.

If function takes less time to execute than timeout seconds, message is not displayed.

Function: buttonize string callback &optional data help-echo

Sometimes it’s more convenient to make a string into a button without inserting it into a buffer immediately, for instance when creating data structures that may then, later, be inserted into a buffer. This function makes string into such a string, and callback will be called when the user clicks on the button. The optional data parameter will be used as the parameter when callback is called. If nil, the button is used as the parameter instead.

Function: buttonize-region start end callback &optional data help-echo

Make the region between start and end into a button. When clicked, callback will be called with the data as the function argument. If data isn’t present (or is nil), the button itself will be used instead as the function argument. If help-echo, use that as the help-echo property.

Function: get-display-property position prop &optional object properties

This convenience function can be used to get a specific display property, no matter whether the display property is a vector, a list or a simple property. This is like get-text-property (see Examining Properties), but works on the display property only.

position is the position in the buffer or string to examine, and prop is the display property to return. The optional object argument should be either a string or a buffer, and defaults to the current buffer. If the optional properties argument is non-nil, it should be a display property, and in that case, position and object are ignored. (This can be useful if you’ve already gotten the display property with get-char-property, for instance (see Examining Properties).

Function: add-display-text-property start end prop value &optional object

Add display property prop with value to the text from start to end. If any text in the region has a non-nil display property, those properties are retained.

If object is non-nil, it should be a string or a buffer. If nil, this defaults to the current buffer.

Function: take n list

This function returns the n first elements of list. Essentially, it returns the part of list that nthcdr skips.

take returns list if shorter than n elements; it returns nil if n is zero or negative.

emacs-lisp
(take 3 '(a b c d))
     ⇒ (a b c)
emacs-lisp
(take 10 '(a b c d))
     ⇒ (a b c d)
emacs-lisp
(take 0 '(a b c d))
nil

Function: ntake n list

This is a version of take that works by destructively modifying the list structure of the argument. That makes it faster, but the original value of list may be lost.

ntake returns list unmodified if shorter than n elements; it returns nil if n is zero or negative. Otherwise, it returns list truncated to its first n elements.

This means that it is usually a good idea to use the return value and not just rely on the truncation effect unless n is known to be positive.

Function: compiled-function-p object

This function returns t if object is a function object that is not in the form of ELisp source code but something like machine code or byte code instead. More specifically it returns t if the function is built-in, or byte-compiled, or natively-compiled, or a function loaded from a dynamic module.

Function: function-alias-p object &optional noerror

Checks whether object is a function alias. If it is, it returns a list of symbols representing the function alias chain, else nil. For instance, if a is an alias for b, and b is an alias for c:

emacs-lisp
(function-alias-p 'a)
    ⇒ (b c)

If there’s a loop in the definitions, an error will be signalled. If noerror is non-nil, the non-looping parts of the chain is returned instead.

Function: string-equal-ignore-case string1 string2

string-equal-ignore-case compares strings ignoring case differences, like char-equal when case-fold-search is t.

See (elisp)Text Comparison.

Function: string-split string &optional separators omit-nulls trim

string-split is an alias for the function split-string. The name follows the convention of other string functions.

See (elisp)Creating Strings.

Function: buffer-match-p condition buffer-or-name &optional arg

This function checks if a buffer designated by buffer-or-name satisfies a condition. Optional third argument arg is passed to the predicate function in condition. A condition can be one of the following:

  • A string, interpreted as a regular expression. The buffer satisfies the condition if the regular expression matches the buffer name.

  • A predicate function, which should return non-nil if the buffer matches. If the function expects one argument, it is called with buffer-or-name as the argument; if it expects 2 arguments, the first argument is buffer-or-name and the second is arg (or nil if arg is omitted).

  • A cons-cell (oper . expr) where oper is one of

    not

    Satisfied if expr doesn’t satisfy buffer-match-p with the same buffer and arg.

    or

    Satisfied if expr is a list and any condition in expr satisfies buffer-match-p, with the same buffer and arg.

    and

    Satisfied if expr is a list and all conditions in expr satisfy buffer-match-p, with the same buffer and arg.

    derived-mode

    Satisfied if the buffer’s major mode derives from expr.

    major-mode

    Satisfied if the buffer’s major mode is equal to expr. Prefer using derived-mode instead when both can work.

  • t Satisfied by any buffer. A convenient alternative to "" (empty string), (and) (empty conjunction) or always.

See (elisp)Buffer List.

Function: match-buffers condition &optional buffers arg

This function returns a list of all buffers that satisfy a condition, as defined for buffer-match-p. By default all buffers are considered, but this can be restricted via the second optional buffer-list argument. Optional third argument arg will be used by condition in the same way as buffer-match-p does.

See (elisp)Buffer List.

Function: string-glyph-split string

When character compositions are in effect, sequence of characters can be composed for display to form grapheme clusters, for example to display accented characters, or ligatures, or Emoji, or when complex text shaping requires that for some scripts. When that happens, characters no longer map in a simple way to display columns, and display layout decisions with such strings, such as truncating too wide strings, can be a complex job. This function helps in performing such jobs: it splits up its argument string into a list of substrings, where each substring produces a single grapheme cluster that should be displayed as a unit. Lisp programs can then use this list to construct visually-valid substrings of string which will look correctly on display, or compute the width of any substring of string by adding the width of its constituents in the returned list, etc.

For instance, if you want to display a string without the first glyph, you can say:

emacs-lisp
(apply #'insert (cdr (string-glyph-split string))))

See (elisp)Size of Displayed Text.

Macro: with-buffer-unmodified-if-unchanged &rest body…

Evaluate body like progn, but change buffer-modified status only if buffer text changes. If the buffer was unmodified before execution of body, and buffer text after execution of body is identical to what it was before, ensure that buffer is still marked unmodified afterwards.

Note that only changes in the raw byte sequence of the buffer text, as stored in the internal representation, are monitored for the purpose of detecting the lack of changes in buffer text. Any other changes that are normally perceived as "buffer modifications", such as changes in text properties, buffer-file-coding-system, buffer multibyteness, etc. – will not be noticed, and the buffer will still be marked unmodified, effectively ignoring those changes.

Function: file-attribute-file-identifier

Return the fields (inodenum device) as a list from attributes generated by file-attributes.

See (elisp)File Attributes.

Function: file-name-split filename

This function splits a file name into its components, and can be thought of as the inverse of string-join with the appropriate directory separator. For example,

emacs-lisp
(file-name-split "/tmp/foo.txt")
    ⇒ ("" "tmp" "foo.txt")
(string-join (file-name-split "/tmp/foo.txt") "/")
"/tmp/foo.txt"

Function: file-name-parent-directory filename

This function returns the directory name of the parent directory of filename. If filename is at the root directory of the filesystem, it returns nil. A relative filename is assumed to be relative to default-directory, and the return value will also be relative in that case. If the return value is non-nil, it ends in a slash.

See (elisp)Directory Names.

Function: file-has-changed-p file &optional tag

This function returns non-nil if the time stamp of filename has changed since the last call. When called for the first time for some filename, it records the last modification time and size of the file, and returns non-nil when filename exists. Thereafter, when called for the same filename, it compares the current time stamp and size with the recorded ones, and returns non-nil only if either the time stamp or the size (or both) are different. This is useful when a Lisp program wants to re-read a file whenever it changes. With an optional argument tag, which must be a symbol, the size and modification time comparisons are limited to calls with the same tag.

See (elisp)File Attributes.

Function: directory-abbrev-make-regexp directory

Create a regexp to match directory for directory-abbrev-alist.

Function: directory-abbrev-apply filename

Apply the abbreviations in directory-abbrev-alist to filename. Note that when calling this, you should set case-fold-search as appropriate for the filesystem used for filename.

Function: key-valid-p keys

Say whether keys is a valid key. A key is a string consisting of one or more key strokes. The key strokes are separated by single space characters.

Each key stroke is either a single character, or the name of an event, surrounded by angle brackets. In addition, any key stroke may be preceded by one or more modifier keys. Finally, a limited number of characters have a special shorthand syntax.

Here’s some example key sequences.

f

The key f.

S o m

A three key sequence of the keys S, o and m.

C-c o

A two key sequence of the keys c with the control modifier and then the key o.

H-<left>

The key named "left" with the hyper modifier.

M-RET

The "return" key with a meta modifier.

C-M-<space>

The "space" key with both the control and meta modifiers.

These are the characters that have shorthand syntax: NUL, RET, TAB, LFD, ESC, SPC, DEL.

Modifiers have to be specified in this order

lisp
Alt (A)-Control (C)-Hyper (H)-Meta (M)-Shift (s)-Super (s)

Function: key-parse keys

Convert keys to the internal Emacs key representation. See key-valid-p for a description of valid key sequences. Examples include f, C-c C-c, H-<left>, M-RET or C-M-<return>.

Function: keymap-set keymap key definition

This function sets the binding for key in keymap. (If key is more than one event long, the change is actually made in another keymap reached from keymap.) The argument binding can be any Lisp object, but only certain types are meaningful. (For a list of meaningful types, see (elisp)Key Lookup.) The value returned by keymap-set is binding.

If key is <t>, this sets the default binding in keymap. When an event has no binding of its own, the Emacs command loop uses the keymap’s default binding, if there is one.

Every prefix of key must be a prefix key (i.e., bound to a keymap) or undefined; otherwise an error is signaled. If some prefix of key is undefined, then keymap-set defines it as a prefix key so that the rest of key can be defined as specified.

If there was previously no binding for key in keymap, the new binding is added at the beginning of keymap. The order of bindings in a keymap makes no difference for keyboard input, but it does matter for menu keymaps (see (elisp)Menu Keymaps).

See (elisp)Changing Key Bindings.

Function: keymap-global-set key command

This function sets the binding of key in the current global map to binding.

emacs-lisp
(keymap-global-set key binding)

(keymap-set (current-global-map) key binding)

See (elisp)Key Binding Commands.

Function: keymap-local-set key command

This function sets the binding of key in the current local keymap to binding.

emacs-lisp
(keymap-local-set key binding)

(keymap-set (current-local-map) key binding)

See (elisp)Key Binding Commands.

Function: keymap-global-unset key &optional remove

This function removes the binding of key from the current global map.

One use of this function is in preparation for defining a longer key that uses key as a prefix—which would not be allowed if key has a non-prefix binding. For example:

emacs-lisp
(keymap-global-unset "C-l")
nil
emacs-lisp
(keymap-global-set "C-l C-l" 'redraw-display)
nil

See (elisp)Key Binding Commands.

Function: keymap-local-unset key &optional remove

This function removes the binding of key from the current local map.

See (elisp)Key Binding Commands.

Function: keymap-substitute keymap olddef newdef &optional oldmap prefix

Replace olddef with newdef for any keys in keymap now defined as olddef. In other words, olddef is replaced with newdef wherever it appears. Alternatively, if optional fourth argument oldmap is specified, we redefine in keymap as newdef those keys that are defined as olddef in oldmap.

Function: keymap-lookup keymap key &optional accept-default no-remap position

This function returns the definition of key in keymap. All the other functions described in this chapter that look up keys use keymap-lookup. Here are examples:

emacs-lisp
(keymap-lookup (current-global-map) "C-x C-f")
    ⇒ find-file
emacs-lisp
(keymap-lookup (current-global-map) "C-x C-f 1 2 3 4 5")
2

See (elisp)Functions for Key Lookup.

Function: keymap-local-lookup keys &optional accept-default

Like keymap-lookup, but restricting the search for commands bound to keys to the current local keymap.

Function: keymap-global-lookup keys &optional accept-default

Like keymap-lookup, but restricting the search for commands bound to keys to the current global keymap.

Function: define-keymap &rest definitions

You can create a keymap with the functions described above, and then use keymap-set (see (elisp)Changing Key Bindings) to specify key bindings in that map. When writing modes, however, you frequently have to bind a large number of keys at once, and using keymap-set on them all can be tedious and error-prone. Instead you can use define-keymap, which creates a keymap and binds a number of keys. Here’s a very basic example:

emacs-lisp
(define-keymap
  "n" #'forward-line
  "f" #'previous-line
  "C-c C-c" #'quit-window)

This function creates a new sparse keymap, defines the keystrokes in pairs, and returns the new keymap.

pairs is a list of alternating key bindings and key definitions, as accepted by keymap-set. In addition, the key can be the special symbol :menu, in which case the definition should be a menu definition as accepted by easy-menu-define (see (elisp)Easy Menu). Here’s a brief example of this usage:

emacs-lisp
(define-keymap :full t
  "g" #'eww-reload
  :menu '("Eww"
          ["Exit" quit-window t]
          ["Reload" eww-reload t]))

A number of keywords can be used before the key/definition pairs to change features of the new keymap. If any of the feature keywords is missing from the define-keymap call, the default value for that feature is nil. Here’s a list of the available feature keywords:

:full

If non-nil, create a char-table keymap (as from make-keymap) instead of a sparse keymap (as from make-sparse-keymap (see (elisp)Creating Keymaps). A sparse keymap is the default.

:parent

If non-nil, the value should be a keymap to use as the parent (see (elisp)Inheritance and Keymaps).

:keymap

If non-nil, the value should be a keymap. Instead of creating a new keymap, the specified keymap is modified instead.

:suppress

If non-nil, the keymap will be suppressed with suppress-keymap (see (elisp)Changing Key Bindings). By default, digits and the minus sign are exempt from suppressing, but if the value is nodigits, this suppresses digits and minus-sign like it does with other characters.

:name

If non-nil, the value should be a string to use as the menu for the keymap if you use it as a menu with x-popup-menu (see (elisp)Pop-Up Menus).

:prefix

If non-nil, the value should be a symbol to be used as a prefix command (see (elisp)Prefix Keys). If this is the case, this symbol is returned by define-keymap instead of the map itself.

Function: defvar-keymap (variable-name &rest defs)

By far, the most common thing to do with a keymap is to bind it to a variable. This is what virtually all modes do—a mode called foo almost always has a variable called foo-mode-map.

This macro defines name as a variable, passes options and pairs to define-keymap, and uses the result as the default value for the variable.

options is like the keywords in define-keymap, but there’s an additional :doc keyword that provides the doc string for the defined variable.

Here’s an example:

emacs-lisp
(defvar-keymap eww-textarea-map
  :parent text-mode-map
  "RET" #'forward-line
  "TAB" #'shr-next-link)

Macro: while-let spec then-forms...

Like when-let, but repeat until a binding in spec is nil. The return value is always nil.

This is comparable to and-let*.

Function: window-configuration-equal-p config1 config2

This function says whether two window configurations have the same window layout, but ignores the values of point and the saved scrolling positions—it can return t even if those aspects differ.

Macro: ert-with-temp-file name &rest body

Bind name to the name of a new temporary file and evaluate body. Delete the temporary file after body exits normally or non-locally. name will be bound to the file name of the temporary file. See the docstring for supported keyword arguments.

Macro: ert-with-temp-directory name &rest body

Bind name to the name of a new temporary directory and evaluate body. Delete the temporary directory after body exits normally or non-locally.

name is bound to the directory name, not the directory file name. (In other words, it will end with the directory delimiter; on Unix-like systems, it will end with "/".)

The same keyword arguments are supported as in ert-with-temp-file (which see), except for :text.

Function: cl-constantly value

Return a function that takes any number of arguments, but returns value.

Macro: cl-with-gensyms names… body

This macro expands to code that executes body with each of the variables in names bound to a fresh uninterned symbol, or gensym, in Common Lisp parlance. For macros requiring more than one gensym, use of cl-with-gensyms shortens the code and renders one’s intentions clearer. Compare:

emacs-lisp
(defmacro my-macro (foo)
  (let ((bar (gensym "bar"))
        (baz (gensym "baz"))
        (quux (gensym "quux")))
    `(let ((,bar (+ ...)))
       ...)))

(defmacro my-macro (foo)
  (cl-with-gensyms (bar baz quux)
    `(let ((,bar (+ ...)))
       ...)))

Macro: cl-once-only ((variable form)…) body

This macro is primarily to help the macro programmer ensure that forms supplied by the user of the macro are evaluated just once by its expansion even though the result of evaluating the form is to occur more than once. Less often, this macro is used to ensure that forms supplied by the macro programmer are evaluated just once.

Each variable may be used to refer to the result of evaluating form in body. cl-once-only binds each variable to a fresh uninterned symbol during the evaluation of body. Then, cl-once-only wraps the final expansion in code to evaluate each form and bind the result to the corresponding uninterned symbol. Thus, when the macro writer substitutes the value for variable into the expansion they are effectively referring to the result of evaluating form, rather than form itself. Another way to put this is that each variable is bound to an expression for the (singular) result of evaluating form.

The most common case is where variable is one of the arguments to the macro being written, so (variable variable) may be abbreviated to just variable.

For example, consider this macro:

emacs-lisp
(defmacro my-list (x y &rest forms)
  (let ((x-result (gensym))
        (y-result (gensym)))
    `(let ((,x-result ,x)
           (,y-result ,y))
       (list ,x-result ,y-result ,x-result ,y-result
             (progn ,@forms))))

In a call like (my-list (pop foo) …) the intermediate binding to x-result ensures that the pop is not done twice. But as a result the code is rather complex: the reader must keep track of how x-result really just means the first parameter of the call to the macro, and the required use of multiple gensyms to avoid variable capture by (progn ,@forms) obscures things further. cl-once-only takes care of these details:

emacs-lisp
(defmacro my-list (x y &rest forms)
  (cl-once-only (x y)
    `(list ,x ,y ,x ,y
           (progn ,@forms))))

2.5.2 Extended Definitions

These functions must be called explicitly via compat-call, since their calling convention or behavior was extended in Emacs 29.1:

Function: compat-call set-transient-map keymap &optional keep-pred on-exit message timeout

This function adds keymap as a transient keymap, which takes precedence over other keymaps for one (or more) subsequent keys.

Normally, keymap is used just once, to look up the very next key. If the optional argument keep-pred is t, the map stays active as long as the user types keys defined in keymap; when the user types a key that is not in keymap, the transient keymap is deactivated and normal key lookup continues for that key.

The keep-pred argument can also be a function. In that case, the function is called with no arguments, prior to running each command, while keymap is active; it should return non-nil if keymap should stay active.

The optional argument on-exit, if non-nil, specifies a function that is called, with no arguments, after keymap is deactivated.

The optional argument message specifies the message to display after activating the transient map. If message is a string, it is the format string for the message, and any ‘%k’ specifier in that string is replaced with the list of keys from the transient map. Any other non-nil value of message stands for the default message format ‘Repeat with %k’.

If the optional argument timeout is non-nil, it should be a number that specifies how many seconds of idle time to wait before deactivating keymap. The value of the variable set-transient-map-timeout, if non-nil, overrides the value of this argument.

This function works by adding and removing keymap from the variable overriding-terminal-local-map, which takes precedence over all other active keymaps (see (Searching Keymaps)elisp).

Function: compat-call string-lines string &optional omit-nulls keep-newlines

Split string into a list of strings on newline boundaries. If the optional argument omit-nulls is non-nil, remove empty lines from the results. If the optional argument keep-newlines is non-nil, don’t remove the trailing newlines from the result strings.

See (elisp)Creating Strings.

Function: compat-call define-key

This function is like keymap-set (see (elisp)Changing Key Bindings, but understands only the legacy key syntaxes.

In addition, this function also has a remove argument. If it is non-nil, the definition will be removed. This is almost the same as setting the definition to nil, but makes a difference if the keymap has a parent, and key is shadowing the same binding in the parent. With remove, subsequent lookups will return the binding in the parent, whereas with a nil definition the lookups will return nil.

See (elisp)Low-Level Key Binding.

This compatibility version handles the optional argument remove.

Function: compat-call plist-get plist prop &optional predicate

This returns the value of the property property stored in the property list plist. Comparisons are done with predicate, and defaults to eq. It accepts a malformed plist argument. If property is not found in the plist, it returns nil.

See (elisp)Plist Access.

This compatibility version handles the optional argument predicate. This is a generalized variable (see (elisp)Generalized Variables) that can be used to change a value with setf.

Function: compat-call plist-put plist prop val &optional predicate

This stores value as the value of the property property in the property list plist. Comparisons are done with predicate, and defaults to eq. It may modify plist destructively, or it may construct a new list structure without altering the old. The function returns the modified property list, so you can store that back in the place where you got plist.

See (elisp)Plist Access.

This compatibility version handles the optional argument predicate.

Function: compat-call plist-member plist prop &optional predicate

This returns non-nil if plist contains the given property. Comparisons are done with predicate, and defaults to eq. Unlike plist-get, this allows you to distinguish between a missing property and a property with the value nil. The value is actually the tail of plist whose car is property.

See (elisp)Plist Access.

This compatibility version handles the optional argument predicate.

2.5.3 Missing Definitions

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