aboutsummaryrefslogtreecommitdiff
path: root/compat.texi
diff options
context:
space:
mode:
authorDaniel Mendler <mail@daniel-mendler.de>2024-05-17 13:34:02 +0200
committerDaniel Mendler <mail@daniel-mendler.de>2024-05-17 14:13:42 +0200
commit8190769d9eb9258dd8361bd322d90228dc586770 (patch)
tree14565f14a34fc607775c6d611b4efdee95c58bd6 /compat.texi
parentcce243609e04610d4d385ebde68b168e50cbf4f2 (diff)
compat-30: Add value< and sort with keyword arguments
Diffstat (limited to 'compat.texi')
-rw-r--r--compat.texi175
1 files changed, 155 insertions, 20 deletions
diff --git a/compat.texi b/compat.texi
index 825f348..4177b56 100644
--- a/compat.texi
+++ b/compat.texi
@@ -532,26 +532,6 @@ arguments, @var{objects}.
@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:
@@ -3350,6 +3330,63 @@ 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/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
@@ -3466,6 +3503,104 @@ Here is an example of its use from CC Mode, which prevents a
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