diff options
Diffstat (limited to 'devdocs/elisp/property-search.html')
| -rw-r--r-- | devdocs/elisp/property-search.html | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/devdocs/elisp/property-search.html b/devdocs/elisp/property-search.html new file mode 100644 index 00000000..269c6d85 --- /dev/null +++ b/devdocs/elisp/property-search.html @@ -0,0 +1,66 @@ + <h4 class="subsection">Text Property Search Functions</h4> <p>In typical use of text properties, most of the time several or many consecutive characters have the same value for a property. Rather than writing your programs to examine characters one by one, it is much faster to process chunks of text that have the same property value. </p> <p>Here are functions you can use to do this. They use <code>eq</code> for comparing property values. In all cases, <var>object</var> defaults to the current buffer. </p> <p>For good performance, it’s very important to use the <var>limit</var> argument to these functions, especially the ones that search for a single property—otherwise, they may spend a long time scanning to the end of the buffer, if the property you are interested in does not change. </p> <p>These functions do not move point; instead, they return a position (or <code>nil</code>). Remember that a position is always between two characters; the position returned by these functions is between two characters with different properties. </p> <dl> <dt id="next-property-change">Function: <strong>next-property-change</strong> <em>pos &optional object limit</em> +</dt> <dd> +<p>The function scans the text forward from position <var>pos</var> in the string or buffer <var>object</var> until it finds a change in some text property, then returns the position of the change. In other words, it returns the position of the first character beyond <var>pos</var> whose properties are not identical to those of the character just after <var>pos</var>. </p> <p>If <var>limit</var> is non-<code>nil</code>, then the scan ends at position <var>limit</var>. If there is no property change before that point, this function returns <var>limit</var>. </p> <p>The value is <code>nil</code> if the properties remain unchanged all the way to the end of <var>object</var> and <var>limit</var> is <code>nil</code>. If the value is non-<code>nil</code>, it is a position greater than or equal to <var>pos</var>. The value equals <var>pos</var> only when <var>limit</var> equals <var>pos</var>. </p> <p>Here is an example of how to scan the buffer by chunks of text within which all properties are constant: </p> <div class="example"> <pre class="example">(while (not (eobp)) + (let ((plist (text-properties-at (point))) + (next-change + (or (next-property-change (point) (current-buffer)) + (point-max)))) + <span class="roman">Process text from point to <var>next-change</var>…</span> + (goto-char next-change))) +</pre> +</div> </dd> +</dl> <dl> <dt id="previous-property-change">Function: <strong>previous-property-change</strong> <em>pos &optional object limit</em> +</dt> <dd><p>This is like <code>next-property-change</code>, but scans back from <var>pos</var> instead of forward. If the value is non-<code>nil</code>, it is a position less than or equal to <var>pos</var>; it equals <var>pos</var> only if <var>limit</var> equals <var>pos</var>. </p></dd> +</dl> <dl> <dt id="next-single-property-change">Function: <strong>next-single-property-change</strong> <em>pos prop &optional object limit</em> +</dt> <dd> +<p>The function scans text for a change in the <var>prop</var> property, then returns the position of the change. The scan goes forward from position <var>pos</var> in the string or buffer <var>object</var>. In other words, this function returns the position of the first character beyond <var>pos</var> whose <var>prop</var> property differs from that of the character just after <var>pos</var>. </p> <p>If <var>limit</var> is non-<code>nil</code>, then the scan ends at position <var>limit</var>. If there is no property change before that point, <code>next-single-property-change</code> returns <var>limit</var>. </p> <p>The value is <code>nil</code> if the property remains unchanged all the way to the end of <var>object</var> and <var>limit</var> is <code>nil</code>. If the value is non-<code>nil</code>, it is a position greater than or equal to <var>pos</var>; it equals <var>pos</var> only if <var>limit</var> equals <var>pos</var>. </p> +</dd> +</dl> <dl> <dt id="previous-single-property-change">Function: <strong>previous-single-property-change</strong> <em>pos prop &optional object limit</em> +</dt> <dd><p>This is like <code>next-single-property-change</code>, but scans back from <var>pos</var> instead of forward. If the value is non-<code>nil</code>, it is a position less than or equal to <var>pos</var>; it equals <var>pos</var> only if <var>limit</var> equals <var>pos</var>. </p></dd> +</dl> <dl> <dt id="next-char-property-change">Function: <strong>next-char-property-change</strong> <em>pos &optional limit</em> +</dt> <dd><p>This is like <code>next-property-change</code> except that it considers overlay properties as well as text properties, and if no change is found before the end of the buffer, it returns the maximum buffer position rather than <code>nil</code> (in this sense, it resembles the corresponding overlay function <code>next-overlay-change</code>, rather than <code>next-property-change</code>). There is no <var>object</var> operand because this function operates only on the current buffer. It returns the next address at which either kind of property changes. </p></dd> +</dl> <dl> <dt id="previous-char-property-change">Function: <strong>previous-char-property-change</strong> <em>pos &optional limit</em> +</dt> <dd><p>This is like <code>next-char-property-change</code>, but scans back from <var>pos</var> instead of forward, and returns the minimum buffer position if no change is found. </p></dd> +</dl> <dl> <dt id="next-single-char-property-change">Function: <strong>next-single-char-property-change</strong> <em>pos prop &optional object limit</em> +</dt> <dd><p>This is like <code>next-single-property-change</code> except that it considers overlay properties as well as text properties, and if no change is found before the end of the <var>object</var>, it returns the maximum valid position in <var>object</var> rather than <code>nil</code>. Unlike <code>next-char-property-change</code>, this function <em>does</em> have an <var>object</var> operand; if <var>object</var> is not a buffer, only text-properties are considered. </p></dd> +</dl> <dl> <dt id="previous-single-char-property-change">Function: <strong>previous-single-char-property-change</strong> <em>pos prop &optional object limit</em> +</dt> <dd><p>This is like <code>next-single-char-property-change</code>, but scans back from <var>pos</var> instead of forward, and returns the minimum valid position in <var>object</var> if no change is found. </p></dd> +</dl> <dl> <dt id="text-property-any">Function: <strong>text-property-any</strong> <em>start end prop value &optional object</em> +</dt> <dd> +<p>This function returns non-<code>nil</code> if at least one character between <var>start</var> and <var>end</var> has a property <var>prop</var> whose value is <var>value</var>. More precisely, it returns the position of the first such character. Otherwise, it returns <code>nil</code>. </p> <p>The optional fifth argument, <var>object</var>, specifies the string or buffer to scan. Positions are relative to <var>object</var>. The default for <var>object</var> is the current buffer. </p> +</dd> +</dl> <dl> <dt id="text-property-not-all">Function: <strong>text-property-not-all</strong> <em>start end prop value &optional object</em> +</dt> <dd> +<p>This function returns non-<code>nil</code> if at least one character between <var>start</var> and <var>end</var> does not have a property <var>prop</var> with value <var>value</var>. More precisely, it returns the position of the first such character. Otherwise, it returns <code>nil</code>. </p> <p>The optional fifth argument, <var>object</var>, specifies the string or buffer to scan. Positions are relative to <var>object</var>. The default for <var>object</var> is the current buffer. </p> +</dd> +</dl> <dl> <dt id="text-property-search-forward">Function: <strong>text-property-search-forward</strong> <em>prop &optional value predicate not-current</em> +</dt> <dd> +<p>Search for the next region that has text property <var>prop</var> set to <var>value</var> according to <var>predicate</var>. </p> <p>This function is modeled after <code>search-forward</code> and friends in that it moves point, but it returns a structure that describes the match instead of returning it in <code>match-beginning</code> and friends. </p> <p>If the text property can’t be found, the function returns <code>nil</code>. If it’s found, point is placed at the end of the region that has this text property match, and a <code>prop-match</code> structure is returned. </p> <p><var>predicate</var> can either be <code>t</code> (which is a synonym for <code>equal</code>), <code>nil</code> (which means “not equal”), or a predicate that will be called with two parameters: The first is <var>value</var>, and the second is the value of the text property we’re inspecting. </p> <p>If <var>not-current</var>, if point is in a region where we have a match, then skip past that and find the next instance instead. </p> <p>The <code>prop-match</code> structure has the following accessors: <code>prop-match-beginning</code> (the start of the match), <code>prop-match-end</code> (the end of the match), and <code>prop-match-value</code> (the value of <var>property</var> at the start of the match). </p> <p>In the examples below, imagine that you’re in a buffer that looks like this: </p> <div class="example"> <pre class="example">This is a bold and here's bolditalic and this is the end. +</pre> +</div> <p>That is, the “bold” words are the <code>bold</code> face, and the “italic” word is in the <code>italic</code> face. </p> <p>With point at the start: </p> <div class="lisp"> <pre class="lisp">(while (setq match (text-property-search-forward 'face 'bold t)) + (push (buffer-substring (prop-match-beginning match) + (prop-match-end match)) + words)) +</pre> +</div> <p>This will pick out all the words that use the <code>bold</code> face. </p> <div class="lisp"> <pre class="lisp">(while (setq match (text-property-search-forward 'face nil t)) + (push (buffer-substring (prop-match-beginning match) + (prop-match-end match)) + words)) +</pre> +</div> <p>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")</samp>’ (only reversed, since we used <code>push</code>). </p> <div class="lisp"> <pre class="lisp">(while (setq match (text-property-search-forward 'face nil nil)) + (push (buffer-substring (prop-match-beginning match) + (prop-match-end match)) + words)) +</pre> +</div> <p>This will pick out all the regions where <code>face</code> is set to something, but this is split up into where the properties change, so the result here will be ‘<samp>("bold" "bold" "italic")</samp>’. </p> <p>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</code>. </p> <div class="lisp"> <pre class="lisp">(while (setq match (text-property-search-forward 'shr-url nil nil)) + (push (prop-match-value match) urls)) +</pre> +</div> <p>This will give you a list of all those URLs. </p> </dd> +</dl> <dl> <dt id="text-property-search-backward">Function: <strong>text-property-search-backward</strong> <em>prop &optional value predicate not-current</em> +</dt> <dd><p>This is just like <code>text-property-search-backward</code>, but searches backward instead. Point is placed at the beginning of the matched region instead of the end, though. </p></dd> +</dl><div class="_attribution"> + <p class="_attribution-p"> + Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br> + <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Property-Search.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Property-Search.html</a> + </p> +</div> |
