diff options
Diffstat (limited to 'doc/lispref/text.texi')
-rw-r--r-- | doc/lispref/text.texi | 479 |
1 files changed, 467 insertions, 12 deletions
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 477b8fce719..825827095b4 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -61,6 +61,8 @@ the character after point. * Checksum/Hash:: Computing cryptographic hashes. * GnuTLS Cryptography:: Cryptographic algorithms imported from GnuTLS. * Parsing HTML/XML:: Parsing HTML and XML. +* Parsing JSON:: Parsing and generating JSON values. +* JSONRPC:: JSON Remote Procedure Call protocol * Atomic Changes:: Installing several buffer changes atomically. * Change Hooks:: Supplying functions to be run when text is changed. @end menu @@ -3184,6 +3186,95 @@ buffer to scan. Positions are relative to @var{object}. The default for @var{object} is the current buffer. @end defun +@defun text-property-search-forward prop &optional value predicate not-current +Search for the next region that has text property @var{prop} set to +@var{value} according to @var{predicate}. + +This function is modelled after @code{search-forward} and friends in +that it moves point, but it returns a structure that describes the +match instead of returning it in @code{match-beginning} and friends. + +If the text property can't be found, the function returns @code{nil}. +If it's found, point is placed at the end of the region that has this +text property match, and a @code{prop-match} structure is returned. + +@var{predicate} can either be @code{t} (which is a synonym for +@code{equal}), @code{nil} (which means ``not equal''), or a predicate +that will be called with two parameters: The first is @var{value}, and +the second is the value of the text property we're inspecting. + +If @var{not-current}, if point is in a region where we have a match, +then skip past that and find the next instance instead. + +The @code{prop-match} structure has the following accessors: +@code{prop-match-beginning} (the start of the match), +@code{prop-match-end} (the end of the match), and +@code{prop-match-value} (the value of @var{property} at the start of +the match). + +In the examples below, imagine that you're in a buffer that looks like +this: + +@example +This is a bold and here's bolditalic and this is the end. +@end example + +That is, the ``bold'' words are the @code{bold} face, and the +``italic'' word is in the @code{italic} face. + +With point at the start: + +@lisp +(while (setq match (text-property-search-forward 'face 'bold t)) + (push (buffer-substring (prop-match-beginning match) + (prop-match-end match)) + words)) +@end lisp + +This will pick out all the words that use the @code{bold} face. + +@lisp +(while (setq match (text-property-search-forward 'face nil t)) + (push (buffer-substring (prop-match-beginning match) + (prop-match-end match)) + words)) +@end lisp + +This will pick out all the bits that have no face properties, which +will result in the list @samp{("This is a " "and here's " "and this is +the end")} (only reversed, since we used @code{push}). + +@lisp +(while (setq match (text-property-search-forward 'face nil nil)) + (push (buffer-substring (prop-match-beginning match) + (prop-match-end match)) + words)) +@end lisp + +This will pick out all the regions where @code{face} is set to +something, but this is split up into where the properties change, so +the result here will be @samp{("bold" "bold" "italic")}. + +For a more realistic example where you might use this, consider that +you have a buffer where certain sections represent URLs, and these are +tagged with @code{shr-url}. + +@lisp +(while (setq match (text-property-search-forward 'shr-url nil nil)) + (push (prop-match-value match) urls)) +@end lisp + +This will give you a list of all those URLs. + +@end defun + +@defun text-property-search-backward prop &optional value predicate not-current +This is just like @code{text-property-search-backward}, but searches +backward instead. Point is placed at the beginning of the matched +region instead of the end, though. +@end defun + + @node Special Properties @subsection Properties with Special Meanings @@ -3235,6 +3326,17 @@ foreground or background color, similar to @code{(:foreground @var{color-name})} or @code{(:background @var{color-name})}. This form is supported for backward compatibility only, and should be avoided. + +@item +A cons cell of the form @w{@code{(:filtered @var{filter} +@var{face-spec})}}, that specifies the face given by @var{face-spec}, +but only if @var{filter} matches when the face is used for display. +The @var{face-spec} can use any of the forms mentioned above. The +@var{filter} should be of the form @w{@code{(:window @var{param} +@var{value})}}, which matches for windows whose parameter @var{param} +is @code{eq} to @var{value}. If the variable +@code{face-filters-always-match} is non-@code{nil}, all face filters +are deemed to have matched. @end itemize Font Lock mode (@pxref{Font Lock Mode}) works in most buffers by @@ -3609,6 +3711,12 @@ string to display, which is passed through The GNU Emacs Manual}) provides an example. @end defvar +@defvar face-filters-always-match +If this variable is non-@code{nil}, face filters that specify +attributes applied only when certain conditions are met will be deemed +to match always. +@end defvar + @node Format Properties @subsection Formatted Text Properties @@ -4521,9 +4629,9 @@ It should be somewhat more efficient on larger buffers than @cindex symmetric cipher @cindex cipher, symmetric -If compiled with GnuTLS, Emacs offers built-in cryptographic support. -Following the GnuTLS API terminology, the available tools are digests, -MACs, symmetric ciphers, and AEAD ciphers. + If compiled with GnuTLS, Emacs offers built-in cryptographic +support. Following the GnuTLS API terminology, the available tools +are digests, MACs, symmetric ciphers, and AEAD ciphers. The terms used herein, such as IV (Initialization Vector), require some familiarity with cryptography and will not be defined in detail. @@ -4541,7 +4649,7 @@ structure of the GnuTLS library. @cindex format of gnutls cryptography inputs @cindex gnutls cryptography inputs format -The inputs to GnuTLS cryptographic functions can be specified in + The inputs to GnuTLS cryptographic functions can be specified in several ways, both as primitive Emacs Lisp types or as lists. The list form is currently similar to how @code{md5} and @@ -4708,8 +4816,15 @@ IV used. @section Parsing HTML and XML @cindex parsing html -When Emacs is compiled with libxml2 support, the following functions -are available to parse HTML or XML text into Lisp object trees. + Emacs can be compiled with built-in libxml2 support. + +@defun libxml-available-p +This function returns non-@code{nil} if built-in libxml2 support is +available in this Emacs session. +@end defun + +When libxml2 support is available, the following functions can be used +to parse HTML or XML text into Lisp object trees. @defun libxml-parse-html-region start end &optional base-url discard-comments This function parses the text between @var{start} and @var{end} as @@ -4721,7 +4836,10 @@ The optional argument @var{base-url}, if non-@code{nil}, should be a string specifying the base URL for relative URLs occurring in links. If the optional argument @var{discard-comments} is non-@code{nil}, -then the parse tree is created without any comments. +any top-level comment is discarded. (This argument is obsolete and +will be removed in future Emacs versions. To remove comments, use the +@code{xml-remove-comments} utility function on the data before you +call the parsing function.) In the parse tree, each HTML node is represented by a list in which the first element is a symbol representing the node name, the second @@ -4776,9 +4894,9 @@ about syntax). @cindex DOM @cindex Document Object Model -The @acronym{DOM} returned by @code{libxml-parse-html-region} (and the -other @acronym{XML} parsing functions) is a tree structure where each -node has a node name (called a @dfn{tag}), and optional key/value + The @acronym{DOM} returned by @code{libxml-parse-html-region} (and +the other @acronym{XML} parsing functions) is a tree structure where +each node has a node name (called a @dfn{tag}), and optional key/value @dfn{attribute} list, and then a list of @dfn{child nodes}. The child nodes are either strings or @acronym{DOM} objects. @@ -4896,6 +5014,319 @@ textual nodes that just contain white-space. @end table +@node Parsing JSON +@section Parsing and generating JSON values +@cindex JSON +@cindex JavaScript Object Notation + + When Emacs is compiled with @acronym{JSON} (@dfn{JavaScript Object +Notation}) support, it provides several functions to convert +between Lisp objects and JSON values. Any JSON value can be converted +to a Lisp object, but not vice versa. Specifically: + +@itemize +@item +JSON uses three keywords: @code{true}, @code{null}, @code{false}. +@code{true} is represented by the symbol @code{t}. By default, the +remaining two are represented, respectively, by the symbols +@code{:null} and @code{:false}. + +@item +JSON only has floating-point numbers. They can represent both Lisp +integers and Lisp floating-point numbers. + +@item +JSON strings are always Unicode strings encoded in UTF-8. Lisp +strings can contain non-Unicode characters. + +@item +JSON has only one sequence type, the array. JSON arrays are +represented using Lisp vectors. + +@item +JSON has only one map type, the object. JSON objects are represented +using Lisp hashtables, alists or plists. When an alist or plist +contains several elements with the same key, Emacs uses only the first +element for serialization, in accordance with the behavior of +@code{assq}. +@end itemize + +@noindent +Note that @code{nil}, being both a valid alist and a valid plist, +represents @code{@{@}}, the empty JSON object; not @code{null}, +@code{false}, or an empty array, all of which are different JSON +values. + + If some Lisp object can't be represented in JSON, the serialization +functions will signal an error of type @code{wrong-type-argument}. +The parsing functions can also signal the following errors: + +@table @code +@item json-end-of-file +Signaled when encountering a premature end of the input text. + +@item json-trailing-content +Signaled when encountering unexpected input after the first JSON +object parsed. + +@item json-parse-error +Signaled when encountering invalid JSON syntax. +@end table + + Only top-level values (arrays and objects) can be serialized to +JSON. The subobjects within these top-level values can be of any +type. Likewise, the parsing functions will only return vectors, +hashtables, alists, and plists. + +@defun json-serialize object &rest args +This function returns a new Lisp string which contains the JSON +representation of @var{object}. The argument @var{args} is a list of +keyword/argument pairs. The following keywords are accepted: + +@table @code +@item :null-object +The value decides which Lisp object to use to represent the JSON +keyword @code{null}. It defaults to the symbol @code{:null}. + +@item :false-object +The value decides which Lisp object to use to represent the JSON +keyword @code{false}. It defaults to the symbol @code{:false}. +@end table + +@end defun + +@defun json-insert object &rest args +This function inserts the JSON representation of @var{object} into the +current buffer before point. The argument @var{args} are interpreted +as in @code{json-parse-string}. +@end defun + +@defun json-parse-string string &rest args +This function parses the JSON value in @var{string}, which must be a +Lisp string. The argument @var{args} is a list of keyword/argument +pairs. The following keywords are accepted: + +@table @code +@item :object-type +The value decides which Lisp object to use for representing the +key-value mappings of a JSON object. It can be either +@code{hash-table}, the default, to make hashtables with strings as +keys; @code{alist} to use alists with symbols as keys; or @code{plist} +to use plists with keyword symbols as keys. + +@item :null-object +The value decides which Lisp object to use to represent the JSON +keyword @code{null}. It defaults to the symbol @code{:null}. + +@item :false-object +The value decides which Lisp object to use to represent the JSON +keyword @code{false}. It defaults to the symbol @code{:false}. +@end table + +@end defun + +@defun json-parse-buffer &rest args +This function reads the next JSON value from the current buffer, +starting at point. It moves point to the position immediately after +the value if a value could be read and converted to Lisp; otherwise it +doesn't move point. The arguments @var{args} are interpreted as in +@code{json-parse-string}. +@end defun + +@node JSONRPC +@section JSONRPC communication +@cindex JSON remote procedure call protocol + +The @code{jsonrpc} library implements the @acronym{JSONRPC} +specification, version 2.0, as it is described in +@uref{http://www.jsonrpc.org/}. As the name suggests, JSONRPC is a +generic @code{Remote Procedure Call} protocol designed around +@acronym{JSON} objects, which you can convert to and from Lisp objects +(@pxref{Parsing JSON}). + +@menu +* JSONRPC Overview:: +* Process-based JSONRPC connections:: +* JSONRPC JSON object format:: +* JSONRPC deferred requests:: +@end menu + +@node JSONRPC Overview +@subsection Overview + +Quoting from the @uref{http://www.jsonrpc.org/, spec}, JSONRPC "is +transport agnostic in that the concepts can be used within the same +process, over sockets, over http, or in many various message passing +environments." + +To model this agnosticism, the @code{jsonrpc} library uses objects of +a @code{jsonrpc-connection} class, which represent a connection the +remote JSON endpoint (for details on Emacs's object system, +@pxref{Top,EIEIO,,eieio,EIEIO}). In modern object-oriented parlance, +this class is ``abstract'', i.e. the actual class of a useful +connection object used is always a subclass of it. Nevertheless, we +can define two distinct API's around the @code{jsonrpc-connection} +class: + +@enumerate + +@item A user interface for building JSONRPC applications + +In this scenario, the JSONRPC application instantiates +@code{jsonrpc-connection} objects of one of its concrete subclasses +using @code{make-instance}. To initiate a contact to the remote +endpoint, the JSONRPC application passes this object to the functions +@code{jsonrpc-notify'}, @code{jsonrpc-request} and +@code{jsonrpc-async-request}. For handling remotely initiated +contacts, which generally come in asynchronously, the instantiation +should include @code{:request-dispatcher} and +@code{:notification-dispatcher} initargs, which are both functions of +3 arguments: the connection object; a symbol naming the JSONRPC method +invoked remotely; and a JSONRPC "params" object. + +The function passed as @code{:request-dispatcher} is responsible for +handling the remote endpoint's requests, which expect a reply from the +local endpoint (in this case, the program you're building). Inside +that function, you may either return locally (normally) or non-locally +(error). A local return value must be a Lisp object serializable as +JSON (@pxref{Parsing JSON}). This determines a success response, and +the object is forwarded to the server as the JSONRPC "result" object. +A non-local return, achieved by calling the function +@code{jsonrpc-error}, causes an error response to be sent to the +server. The details of the accompanying JSONRPC "error" are filled +out with whatever was passed to @code{jsonrpc-error}. A non-local +return triggered by an unexpected error of any other type also causes +an error response to be sent (unless you have set +@code{debug-on-error}, in which case this should land you in the +debugger, @pxref{Error Debugging}). + +@item A inheritance interface for building JSONRPC transport implementations + +In this scenario, @code{jsonrpc-connection} is subclassed to implement +a different underlying transport strategy (for details on how to +subclass, @pxref{Inheritance,Inheritance,,eieio}). Users of the +application-building interface can then instantiate objects of this +concrete class (using the @code{make-instance} function) and connect +to JSONRPC endpoints using that strategy. + +This API has mandatory and optional parts. + +To allow its users to initiate JSONRPC contacts (notifications or +requests) or reply to endpoint requests, the method +@code{jsonrpc-connection-send} must be implemented for the subclass. + +Likewise, for handling the three types of remote contacts (requests, +notifications and responses to local requests) the transport +implementation must arrange for the function +@code{jsonrpc-connection-receive} to be called after noticing a new +JSONRPC message on the wire (whatever that "wire" may be). + +Finally, and optionally, the @code{jsonrpc-connection} subclass should +implement @code{jsonrpc-shutdown} and @code{jsonrpc-running-p} if +these concepts apply to the transport. If they do, then any system +resources (e.g. processes, timers, etc..) used listen for messages on +the wire should be released in @code{jsonrpc-shutdown}, i.e. they +should only be needed while @code{jsonrpc-running-p} is non-nil. + +@end enumerate + +@node Process-based JSONRPC connections +@subsection Process-based JSONRPC connections + +For convenience, the @code{jsonrpc} library comes built-in with a +@code{jsonrpc-process-connection} transport implementation that can +talk to local subprocesses (using the standard input and standard +output); or TCP hosts (using sockets); or any other remote endpoint +that Emacs's process object can represent (@pxref{Processes}). + +Using this transport, the JSONRPC messages are encoded on the wire as +plain text and prefaced by some basic HTTP-style enveloping headers, +such as ``Content-Length''. + +For an example of an application using this transport scheme on top of +JSONRPC, see the +@uref{https://microsoft.github.io/language-server-protocol/specification, +Language Server Protocol}. + +Along with the mandatory @code{:request-dispatcher} and +@code{:notification-dispatcher} initargs, users of the +@code{jsonrpc-process-connection} class should pass the following +initargs as keyword-value pairs to @code{make-instance}: + +@table @code +@item :process +Value must be a live process object or a function of no arguments +producing one such object. If passed a process object, that is +expected to contain an pre-established connection; otherwise, the +function is called immediately after the object is made. + +@item :on-shutdown +Value must be a function of a single argument, the +@code{jsonrpc-process-connection} object. The function is called +after the underlying process object has been deleted (either +deliberately by @code{jsonrpc-shutdown} or unexpectedly, because of +some external cause). +@end table + +@node JSONRPC JSON object format +@subsection JSON object format + +JSON objects are exchanged as Lisp plists (@pxref{Parsing JSON}): +JSON-compatible plists are handed to the dispatcher functions and, +likewise, JSON-compatible plists should be given to +@code{jsonrpc-notify}, @code{jsonrpc-request} and +@code{jsonrpc-async-request}. + +To facilitate handling plists, this library make liberal use of +@code{cl-lib} library and suggests (but doesn't force) its clients to +do the same. A macro @code{jsonrpc-lambda} can be used to create a +lambda for destructuring a JSON-object like in this example: + +@example +(jsonrpc-async-request + myproc :frobnicate `(:foo "trix") + :success-fn (jsonrpc-lambda (&key bar baz &allow-other-keys) + (message "Server replied back with %s and %s!" + bar baz)) + :error-fn (jsonrpc-lambda (&key code message _data) + (message "Sadly, server reports %s: %s" + code message))) +@end example + +@node JSONRPC deferred requests +@subsection Deferred requests + +In many @acronym{RPC} situations, synchronization between the two +communicating endpoints is a matter of correctly designing the RPC +application: when synchronization is needed, requests (which are +blocking) should be used; when it isn't, notifications should suffice. +However, when Emacs acts as one of these endpoints, asynchronous +events (e.g. timer- or process-related) may be triggered while there +is still uncertainty about the state of the remote endpoint. +Furthermore, acting on these events may only sometimes demand +synchronization, depending on the event's specific nature. + +The @code{:deferred} keyword argument to @code{jsonrpc-request} and +@code{jsonrpc-async-request} is designed to let the caller indicate +that the specific request needs synchronization and its actual +issuance may be delayed to the future, until some condition is +satisfied. Specifying @code{:deferred} for a request doesn't mean it +@emph{will} be delayed, only that it @emph{can} be. If the request +isn't sent immediately, @code{jsonrpc} will make renewed efforts to +send it at certain key times during communication, such as when +receiving or sending other messages to the endpoint. + +Before any attempt to send the request, the application-specific +conditions are checked. Since the @code{jsonrpc} library can't known +what these conditions are, the programmer may use the +@code{jsonrpc-connection-ready-p} generic function (@pxref{Generic +Functions}) to specify them. The default method for this function +returns @code{t}, but you can add overriding methods that return +@code{nil} in some situations, based on the arguments passed to it, +which are the @code{jsonrpc-connection} object (@pxref{JSONRPC +Overview}) and whichever value you passed as the @code{:deferred} +keyword argument. + @node Atomic Changes @section Atomic Change Groups @cindex atomic changes @@ -5041,8 +5472,8 @@ making. When that happens, the arguments to individual changes are made, but won't necessarily be the minimal such region, and the arguments to each successive call of @code{after-change-functions} will then delimit the part of text being -changed exactly. In general, we advise to use either before- or the -after-change hooks, but not both. +changed exactly. In general, we advise using either the before- or +the after-change hook, but not both. @defmac combine-after-change-calls body@dots{} The macro executes @var{body} normally, but arranges to call the @@ -5066,6 +5497,30 @@ because it may lead to inefficient behavior for some change hook functions. @end defmac +@defmac combine-change-calls beg end body@dots{} +This executes @var{body} normally, except any buffer changes it makes +do not trigger the calls to @code{before-change-functions} and +@code{after-change-functions}. Instead there is a single call of each +of these hooks for the region enclosed by @var{beg} and @var{end}, the +parameters supplied to @code{after-change-functions} reflecting the +changes made to the size of the region by @var{body}. + +The result of this macro is the result returned by @var{body}. + +This macro is useful when a function makes a possibly large number of +repetitive changes to the buffer, and the change hooks would otherwise +take a long time to run, were they to be run for each individual +buffer modification. Emacs itself uses this macro, for example, in +the commands @code{comment-region} and @code{uncomment-region}. + +@strong{Warning:} You must not alter the values of +@code{before-change-functions} or @code{after-change-function} within +@var{body}. + +@strong{Warning:} You must not make any buffer changes outside of the +region specified by @var{beg} and @var{end}. +@end defmac + @defvar first-change-hook This variable is a normal hook that is run whenever a buffer is changed that was previously in the unmodified state. |