annotate lisp/text-props.el @ 5577:0b6e7ae1e78f

Update a comment with a better understanding of the optimizer, bytecomp.el lisp/ChangeLog addition: 2011-10-04 Aidan Kehoe <kehoea@parhasard.net> * bytecomp.el (byte-compile-funcall): Correct a comment here, explaining why the optimizer doesn't expand (funcall #'(lambda ...)) in some contexts with inline labels, and why it's reasonable to do it here.
author Aidan Kehoe <kehoea@parhasard.net>
date Tue, 04 Oct 2011 09:02:14 +0100
parents 308d34e9f07d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 ;;; text-props.el --- implements properties of characters
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 ;; Copyright (C) 1993-4, 1997 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4 ;; Copyright (C) 1995 Amdahl Corporation.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5 ;; Copyright (C) 1995 Ben Wing.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 ;; Author: Jamie Zawinski <jwz@jwz.org>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 ;; Maintainer: XEmacs Development Team
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 ;; Keywords: extensions, wp, faces, dumped
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 ;; This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 1275
diff changeset
13 ;; XEmacs is free software: you can redistribute it and/or modify it
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 1275
diff changeset
14 ;; under the terms of the GNU General Public License as published by the
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 1275
diff changeset
15 ;; Free Software Foundation, either version 3 of the License, or (at your
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 1275
diff changeset
16 ;; option) any later version.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 1275
diff changeset
18 ;; XEmacs is distributed in the hope that it will be useful, but WITHOUT
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 1275
diff changeset
19 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 1275
diff changeset
20 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 1275
diff changeset
21 ;; for more details.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 ;; You should have received a copy of the GNU General Public License
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 1275
diff changeset
24 ;; along with XEmacs. If not, see <http://www.gnu.org/licenses/>.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 ;;; Synched up with: Not in FSF.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 ;;; Commentary:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 ;; This file is dumped with XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 ;; This is a nearly complete implementation of the FSF19 text properties API.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 ;; Please let me know if you notice any differences in behavior between
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 ;; this implementation and the FSF implementation.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 ;; However, keep in mind that this interface has been implemented because it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 ;; is useful. Compatibility with code written for FSF19 is a secondary goal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 ;; to having a clean and useful interface.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 ;; The cruftier parts of the FSF API, such as the special handling of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 ;; properties like `mouse-face', `front-sticky', and other properties whose
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 ;; value is a list of names of *other* properties set at this position, are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 ;; not implemented. The reason for this is that if you feel you need that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 ;; kind of functionality, it's a good hint that you should be using extents
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 ;; instead of text properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 ;; When should I use Text Properties, and when should I use Extents?
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 ;; ==================================================================
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 ;; If you are putting a `button' or `hyperlink' of some kind into a buffer,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 ;; the most natural interface is one which deals with properties of regions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 ;; with explicit endpoints that behave more-or-less like markers. That is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 ;; what `make-extent', `extent-at', and `extent-property' are for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 ;; If you are dealing with styles of text, where things do not have explicit
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 ;; endpoints (as is done in font-lock.el and shell-font.el) or if you want to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 ;; partition a buffer (that is, change some attribute of a range from one
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 ;; value to another without disturbing the properties outside of that range)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 ;; then an interface that deals with properties of characters may be most
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 ;; natural.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 ;; Another way of thinking of it is, do you care where the endpoints of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 ;; region are? If you do, then you should use extents. If it's ok for the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 ;; region to become divided, and for two regions with identical properties to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 ;; be merged into one region, then you might want to use text properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 ;; Some applications want the attributes they add to be copied by the killing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 ;; and yanking commands, and some do not. This is orthogonal to whether text
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 ;; properties or extents are used. Remember that text properties are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 ;; implemented in terms of extents, so anything you can do with one you can
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 ;; do with the other. It's just a matter of which way of creating and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 ;; managing them is most appropriate to your application.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 ;; Implementation details:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 ;; =======================
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 ;; This package uses extents with a non-nil 'text-prop property. It assumes
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 ;; free reign over the endpoints of any extent with that property. It will
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 ;; not alter any extent which does not have that property.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 ;; Right now, the text-property functions create one extent for each distinct
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 ;; property; that is, if a range of text has two text-properties on it, there
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 ;; will be two extents. As the set of text-properties is going to be small,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 ;; this is probably not a big deal. It would be possible to share extents.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 ;; One tricky bit is that undo/kill/yank must be made to not fragment things:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 ;; these extents must not be allowed to overlap. We accomplish this by using
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 ;; a custom `paste-function' property on the extents.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 ;; shell-font.el and font-lock.el could put-text-property to attach fonts to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 ;; the buffer. However, what these packages are interested in is the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 ;; efficient extent partitioning behavior which this code exhibits, not the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 ;; duplicability aspect of it. In fact, either of these packages could be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 ;; implemented by creating a one-character non-expandable extent for each
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 ;; character in the buffer, except that that would be extremely wasteful of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 ;; memory. (Redisplay performance would be fine, however.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 ;; If these packages were to use put-text-property to make the extents, then
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 ;; when one copied text from a shell buffer or a font-locked source buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 ;; and pasted it somewhere else (a sendmail buffer, or a buffer not in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 ;; font-lock mode) then the fonts would follow, and there's no easy way to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 ;; get rid of them (other than pounding out a call to put-text-property by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 ;; hand.) This is annoying. Maybe it wouldn't be so annoying if there was a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 ;; more general set of commands for handling styles of text (in fact, if
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 ;; there were such a thing, copying the fonts would probably be exactly what
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 ;; one wanted) but we aren't there yet. So these packages use the interface
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 ;; of `put-nonduplicable-text-property' which is the same, except that it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 ;; doesn't make duplicable extents.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 ;; `put-text-property' and `put-nonduplicable-text-property' don't get along:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 ;; they will interfere with each other, reusing each others' extents without
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 ;; checking that the "duplicableness" is correct. This is a bug, but it's
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 ;; one that I don't care enough to fix this right now.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 ;;; Code:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 (defun set-text-properties (start end props &optional buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 "You should NEVER use this function. It is ideologically blasphemous.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 It is provided only to ease porting of broken FSF Emacs programs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 Instead, use `remove-text-properties' to remove the specific properties
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 you do not want.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 Completely replace properties of text from START to END.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 The third argument PROPS is the new property list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 The optional fourth argument, BUFFER-OR-STRING,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 is the string or buffer containing the text."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 (map-extents #'(lambda (extent ignored)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 ;; #### dmoore - shouldn't this use
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 ;; (extent-start-position extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 ;; (extent-end-position extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 (remove-text-properties start end
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 (list (extent-property extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 'text-prop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 buffer-or-string start end nil nil 'text-prop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 (add-text-properties start end props buffer-or-string))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 ;;; The following functions can probably stay in lisp, since they're so simple.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 ;(defun get-text-property (pos prop &optional buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 ; "Returns the value of the PROP property at the given position."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 ; (let ((e (extent-at pos buffer prop)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 ; (if e
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 ; (extent-property e prop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 ; nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 (defun extent-properties-at-1 (position buffer-or-string text-props-only)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 (let ((extent nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 (props nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 new-props)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 (while (setq extent (extent-at position buffer-or-string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 (if text-props-only 'text-prop nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 (if text-props-only
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 ;; Only return the one prop which the `text-prop' property points at.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 (let ((prop (extent-property extent 'text-prop)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 (setq new-props (list prop (extent-property extent prop))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 ;; Return all the properties...
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 (setq new-props (extent-properties extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 ;; ...but! Don't return the `begin-glyph' or `end-glyph' properties
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 ;; unless the position is exactly at the appropriate endpoint. Yeah,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 ;; this is kind of a kludge.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 ;; #### Bug, this doesn't work for end-glyphs (on end-open extents)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 ;; because we've already passed the extent with the glyph by the time
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 ;; it's appropriate to return the glyph. We could return the end
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 ;; glyph one character early I guess... But then next-property-change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 ;; would have to stop one character early as well. It could back up
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 ;; when it hit an end-glyph...
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 ;; #### Another bug, if there are multiple glyphs at the same position,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 ;; we only see the first one.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 (cond ((or (extent-begin-glyph extent) (extent-end-glyph extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 (if (/= position (if (extent-property extent 'begin-glyph)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 (extent-start-position extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 (extent-end-position extent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 (let ((rest new-props)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 prev)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 (cond ((or (eq (car rest) 'begin-glyph)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 (eq (car rest) 'end-glyph))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 (if prev
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 (setcdr prev (cdr (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 (setq new-props (cdr (cdr new-props))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 (setq rest nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 (setq prev rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 rest (cdr rest))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 (cond ((null props)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 (setq props new-props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 (while new-props
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 (or (getf props (car new-props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 (setq props (cons (car new-props)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 (cons (car (cdr new-props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 props))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 (setq new-props (cdr (cdr new-props)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 (defun extent-properties-at (position &optional object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 "Return the properties of the character at the given position in OBJECT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 OBJECT is either a string or a buffer. The properties of overlapping
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 extents are merged. The returned value is a property list, some of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 which may be shared with other structures. You must not modify it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 If POSITION is at the end of OBJECT, the value is nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 This returns all properties on all extents.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 See also `text-properties-at'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 (extent-properties-at-1 position object nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 (defun text-properties-at (position &optional object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 "Return the properties of the character at the given position in OBJECT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 OBJECT is either a string or a buffer. The properties of overlapping
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 extents are merged. The returned value is a property list, some of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 which may be shared with other structures. You must not modify it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 If POSITION is at the end of OBJECT, the value is nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 This returns only those properties added with `put-text-property'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 See also `extent-properties-at'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 (extent-properties-at-1 position object t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 (defun text-property-any (start end prop value &optional buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 "Check text from START to END to see if PROP is ever `eq' to VALUE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 If so, return the position of the first character whose PROP is `eq'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 to VALUE. Otherwise return nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 The optional fifth argument, BUFFER-OR-STRING, is the buffer or string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 containing the text and defaults to the current buffer."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 (while (and start (< start end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 (not (eq value (get-text-property start prop buffer-or-string))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 (setq start (next-single-property-change start prop buffer-or-string end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 ;; we have to insert a special check for end due to the illogical
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 ;; definition of next-single-property-change (blame FSF for this).
1275
57b76886836d [xemacs-hg @ 2003-02-08 02:29:52 by ben]
ben
parents: 428
diff changeset
235 (if (and start (>= start end)) nil start))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 (defun text-property-not-all (start end prop value &optional buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 "Check text from START to END to see if PROP is ever not `eq' to VALUE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 If so, return the position of the first character whose PROP is not
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 `eq' to VALUE. Otherwise, return nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 The optional fifth argument, BUFFER-OR-STRING, is the buffer or string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 containing the text and defaults to the current buffer."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 (if (not (eq value (get-text-property start prop buffer-or-string)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 start
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 (let ((retval (next-single-property-change start prop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 buffer-or-string end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 ;; we have to insert a special check for end due to the illogical
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 ;; definition of previous-single-property-change (blame FSF for this).
1275
57b76886836d [xemacs-hg @ 2003-02-08 02:29:52 by ben]
ben
parents: 428
diff changeset
249 (if (and retval (>= retval end)) nil retval))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 ;; Older versions that only work sometimes (when VALUE is non-nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 ;; for text-property-any, and maybe only when VALUE is nil for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 ;; text-property-not-all). They might be faster in those cases,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 ;; but that's not obvious.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 ;(defun text-property-any (start end prop value &optional buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 ; "Check text from START to END to see if PROP is ever `eq' to VALUE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 ;If so, return the position of the first character whose PROP is `eq'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 ;to VALUE. Otherwise return nil."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 ; ;; #### what should (text-property-any x y 'foo nil) return when there
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 ; ;; is no foo property between x and y? Either t or nil seems sensible,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 ; ;; since a character with a property of nil is indistinguishable from
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 ; ;; a character without that property set.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 ; (map-extents
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 ; #'(lambda (e ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 ; (if (eq value (extent-property e prop))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 ; ;; return non-nil to stop mapping
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 ; (max start (extent-start-position e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 ; nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 ; nil start end buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 ;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 ;(defun text-property-not-all (start end prop value &optional buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 ; "Check text from START to END to see if PROP is ever not `eq' to VALUE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 ;If so, return the position of the first character whose PROP is not
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 ;`eq' to VALUE. Otherwise, return nil."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 ; (let (maxend)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 ; (map-extents
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 ; #'(lambda (e ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 ; ;;### no, actually, this is harder. We need to collect all props
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 ; ;; for a given character, and then determine whether no extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 ; ;; contributes the given value. Doing this without consing lots
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 ; ;; of lists is the tricky part.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 ; (if (eq value (extent-property e prop))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 ; (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 ; (setq maxend (extent-end-position e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 ; nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 ; (max start maxend)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 ; nil start end buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 (defun next-property-change (pos &optional buffer-or-string limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 "Return the position of next property change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 Scans forward from POS in BUFFER-OR-STRING (defaults to the current buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 until it finds a change in some text property, then returns the position of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 the change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 Returns nil if the properties remain unchanged all the way to the end.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 If the value is non-nil, it is a position greater than POS, never equal.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 If the optional third argument LIMIT is non-nil, don't search
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 past position LIMIT; return LIMIT if nothing is found before LIMIT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 If two or more extents with conflicting non-nil values for a property overlap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 a particular character, it is undefined which value is considered to be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 the value of the property. (Note that this situation will not happen if
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 you always use the text-property primitives.)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 (let ((limit-was-nil (null limit)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 (or limit (setq limit (if (bufferp buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 (point-max buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 (length buffer-or-string))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 (let ((value (extent-properties-at pos buffer-or-string)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 (while
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 (and (< (setq pos (next-extent-change pos buffer-or-string)) limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 (plists-eq value (extent-properties-at pos buffer-or-string)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 (if (< pos limit) pos
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 (if limit-was-nil nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 limit))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 (defun previous-property-change (pos &optional buffer-or-string limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 "Return the position of previous property change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 Scans backward from POS in BUFFER-OR-STRING (defaults to the current buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 until it finds a change in some text property, then returns the position of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 the change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 Returns nil if the properties remain unchanged all the way to the beginning.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 If the value is non-nil, it is a position less than POS, never equal.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 If the optional third argument LIMIT is non-nil, don't search back
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 past position LIMIT; return LIMIT if nothing is found until LIMIT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 If two or more extents with conflicting non-nil values for a property overlap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 a particular character, it is undefined which value is considered to be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 the value of the property. (Note that this situation will not happen if
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 you always use the text-property primitives.)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 (let ((limit-was-nil (null limit)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 (or limit (setq limit (if (bufferp buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 (point-min buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 (let ((value (extent-properties-at (1- pos) buffer-or-string)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 (while
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 (and (> (setq pos (previous-extent-change pos buffer-or-string))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 (plists-eq value (extent-properties-at (1- pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 buffer-or-string)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 (if (> pos limit) pos
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 (if limit-was-nil nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 limit))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 (defun text-property-bounds (pos prop &optional object at-flag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 "Return the bounds of property PROP at POS.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 This returns a cons (START . END) of the largest region of text containing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 POS which has a non-nil value for PROP. The return value is nil if POS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 does not have a non-nil value for PROP. OBJECT specifies the buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 or string to search in. Optional arg AT-FLAG controls what \"at POS\"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 means, and has the same meaning as for `extent-at'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 (or object (setq object (current-buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 (and (get-char-property pos prop object at-flag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 (let ((begin (if (stringp object) 0 (point-min object)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 (end (if (stringp object) (length object) (point-max object))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 (cons (previous-single-property-change (1+ pos) prop object begin)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 (next-single-property-change pos prop object end)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 (defun next-text-property-bounds (count pos prop &optional object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 "Return the COUNTth bounded property region of property PROP after POS.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 If COUNT is less than zero, search backwards. This returns a cons
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 \(START . END) of the COUNTth maximal region of text that begins after POS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 \(starts before POS) and has a non-nil value for PROP. If there aren't
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 that many regions, nil is returned. OBJECT specifies the buffer or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 string to search in."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 (or object (setq object (current-buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 (let ((begin (if (stringp object) 0 (point-min object)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 (end (if (stringp object) (length object) (point-max object))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 (catch 'hit-end
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 (if (> count 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 (while (> count 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 (if (>= pos end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 (throw 'hit-end nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 (and (get-char-property pos prop object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 (setq pos (next-single-property-change pos prop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 object end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 (setq pos (next-single-property-change pos prop object end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 (setq count (1- count)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 (and (< pos end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 (cons pos (next-single-property-change pos prop object end))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 (while (< count 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 (if (<= pos begin)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 (throw 'hit-end nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 (and (get-char-property (1- pos) prop object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 (setq pos (previous-single-property-change pos prop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 object begin)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 (setq pos (previous-single-property-change pos prop object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 begin)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 (setq count (1+ count)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 (and (> pos begin)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 (cons (previous-single-property-change pos prop object begin)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 pos))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 ;(defun detach-all-extents (&optional buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 ; (map-extents #'(lambda (x i) (detach-extent x) nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 ; buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 (provide 'text-props)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 ;;; text-props.el ends here