annotate lisp/text-props.el @ 5318:203dcac81dae

Provide some milquetoast compatibility in our errors, type-error, program-error 2010-12-30 Aidan Kehoe <kehoea@parhasard.net> * cl.el: Provde the Common Lisp program-error, type-error as error symbols. This doesn't nearly go far enough for anyone using the Common Lisp errors.
author Aidan Kehoe <kehoea@parhasard.net>
date Thu, 30 Dec 2010 00:15:37 +0000
parents 57b76886836d
children 308d34e9f07d
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 ;; XEmacs is free software; you can redistribute it and/or modify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 ;; it under the terms of the GNU General Public License as published by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 ;; the Free Software Foundation; either version 2, or (at your option)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 ;; any later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 ;; XEmacs is distributed in the hope that it will be useful,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 ;; GNU General Public License for more details.
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 ;; along with XEmacs; see the file COPYING. If not, write to the Free
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 ;; 02111-1307, USA.
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 ;;; Synched up with: Not in FSF.
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 ;;; Commentary:
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 file is dumped with XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 ;; This is a nearly complete implementation of the FSF19 text properties API.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 ;; Please let me know if you notice any differences in behavior between
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 ;; this implementation and the FSF implementation.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 ;; However, keep in mind that this interface has been implemented because it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 ;; is useful. Compatibility with code written for FSF19 is a secondary goal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 ;; to having a clean and useful interface.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 ;; 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
43 ;; properties like `mouse-face', `front-sticky', and other properties whose
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 ;; 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
45 ;; 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
46 ;; 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
47 ;; instead of text properties.
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 ;; When should I use Text Properties, and when should I use Extents?
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 ;; ==================================================================
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 ;; 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
53 ;; the most natural interface is one which deals with properties of regions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 ;; with explicit endpoints that behave more-or-less like markers. That is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 ;; what `make-extent', `extent-at', and `extent-property' are for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 ;; 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
58 ;; 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
59 ;; 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
60 ;; value to another without disturbing the properties outside of that range)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 ;; then an interface that deals with properties of characters may be most
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 ;; natural.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 ;; 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
65 ;; 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
66 ;; region to become divided, and for two regions with identical properties to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 ;; 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
68
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 ;; 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
70 ;; 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
71 ;; properties or extents are used. Remember that text properties are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 ;; 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
73 ;; 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
74 ;; managing them is most appropriate to your application.
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 ;; Implementation details:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 ;; =======================
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 ;; 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
80 ;; 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
81 ;; not alter any extent which does not have that property.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 ;; Right now, the text-property functions create one extent for each distinct
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 ;; 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
85 ;; 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
86 ;; 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
87
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 ;; 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
89 ;; 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
90 ;; a custom `paste-function' property on the extents.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 ;; 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
93 ;; the buffer. However, what these packages are interested in is the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 ;; efficient extent partitioning behavior which this code exhibits, not the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 ;; duplicability aspect of it. In fact, either of these packages could be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 ;; implemented by creating a one-character non-expandable extent for each
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 ;; character in the buffer, except that that would be extremely wasteful of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 ;; memory. (Redisplay performance would be fine, however.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 ;; 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
101 ;; 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
102 ;; 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
103 ;; 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
104 ;; 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
105 ;; 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
106 ;; 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
107 ;; 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
108 ;; 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
109 ;; of `put-nonduplicable-text-property' which is the same, except that it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 ;; doesn't make duplicable extents.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 ;; `put-text-property' and `put-nonduplicable-text-property' don't get along:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 ;; they will interfere with each other, reusing each others' extents without
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 ;; 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
115 ;; one that I don't care enough to fix this right now.
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 ;;; Code:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 (defun set-text-properties (start end props &optional buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 "You should NEVER use this function. It is ideologically blasphemous.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 It is provided only to ease porting of broken FSF Emacs programs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 Instead, use `remove-text-properties' to remove the specific properties
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 you do not want.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 Completely replace properties of text from START to END.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 The third argument PROPS is the new property list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 The optional fourth argument, BUFFER-OR-STRING,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 is the string or buffer containing the text."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 (map-extents #'(lambda (extent ignored)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 ;; #### dmoore - shouldn't this use
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 ;; (extent-start-position extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 ;; (extent-end-position extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 (remove-text-properties start end
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 (list (extent-property extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 'text-prop)
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)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 buffer-or-string start end nil nil 'text-prop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 (add-text-properties start end props buffer-or-string))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141
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 ;;; 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
144
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 ;(defun get-text-property (pos prop &optional buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 ; "Returns the value of the PROP property at the given position."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 ; (let ((e (extent-at pos buffer prop)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 ; (if e
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 ; (extent-property e prop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 ; nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 (defun extent-properties-at-1 (position buffer-or-string text-props-only)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 (let ((extent nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 (props nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 new-props)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 (while (setq extent (extent-at position buffer-or-string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 (if text-props-only 'text-prop nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 (if text-props-only
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 ;; Only return the one prop which the `text-prop' property points at.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 (let ((prop (extent-property extent 'text-prop)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 (setq new-props (list prop (extent-property extent prop))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 ;; Return all the properties...
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 (setq new-props (extent-properties extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 ;; ...but! Don't return the `begin-glyph' or `end-glyph' properties
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 ;; unless the position is exactly at the appropriate endpoint. Yeah,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 ;; this is kind of a kludge.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 ;; #### Bug, this doesn't work for end-glyphs (on end-open extents)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 ;; 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
170 ;; it's appropriate to return the glyph. We could return the end
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 ;; glyph one character early I guess... But then next-property-change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 ;; 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
173 ;; when it hit an end-glyph...
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 ;; #### Another bug, if there are multiple glyphs at the same position,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 ;; we only see the first one.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 (cond ((or (extent-begin-glyph extent) (extent-end-glyph extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 (if (/= position (if (extent-property extent 'begin-glyph)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 (extent-start-position extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 (extent-end-position extent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 (let ((rest new-props)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 prev)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 (cond ((or (eq (car rest) 'begin-glyph)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 (eq (car rest) 'end-glyph))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 (if prev
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 (setcdr prev (cdr (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 (setq new-props (cdr (cdr new-props))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 (setq rest nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 (setq prev rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 rest (cdr rest))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 (cond ((null props)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 (setq props new-props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 (while new-props
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 (or (getf props (car new-props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 (setq props (cons (car new-props)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 (cons (car (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 (setq new-props (cdr (cdr new-props)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 (defun extent-properties-at (position &optional object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 "Return the properties of the character at the given position in OBJECT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 OBJECT is either a string or a buffer. The properties of overlapping
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 extents are merged. The returned value is a property list, some of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 which may be shared with other structures. You must not modify it.
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 If POSITION is at the end of OBJECT, the value is nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 This returns all properties on all extents.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 See also `text-properties-at'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 (extent-properties-at-1 position object nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 (defun text-properties-at (position &optional object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 "Return the properties of the character at the given position in OBJECT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 OBJECT is either a string or a buffer. The properties of overlapping
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 extents are merged. The returned value is a property list, some of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 which may be shared with other structures. You must not modify it.
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 If POSITION is at the end of OBJECT, the value is nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 This returns only those properties added with `put-text-property'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 See also `extent-properties-at'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 (extent-properties-at-1 position object t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 (defun text-property-any (start end prop value &optional buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 "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
228 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
229 to VALUE. Otherwise return nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 The optional fifth argument, BUFFER-OR-STRING, is the buffer or string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 containing the text and defaults to the current buffer."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 (while (and start (< start end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 (not (eq value (get-text-property start prop buffer-or-string))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 (setq start (next-single-property-change start prop buffer-or-string end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 ;; 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
236 ;; 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
237 (if (and start (>= start end)) nil start))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 (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
240 "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
241 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
242 `eq' to VALUE. Otherwise, return nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 The optional fifth argument, BUFFER-OR-STRING, is the buffer or string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 containing the text and defaults to the current buffer."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 (if (not (eq value (get-text-property start prop buffer-or-string)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 start
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 (let ((retval (next-single-property-change start prop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 buffer-or-string end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 ;; 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
250 ;; 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
251 (if (and retval (>= retval end)) nil retval))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 ;; Older versions that only work sometimes (when VALUE is non-nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 ;; for text-property-any, and maybe only when VALUE is nil for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 ;; text-property-not-all). They might be faster in those cases,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 ;; but that's not obvious.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 ;(defun text-property-any (start end prop value &optional buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 ; "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
260 ;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
261 ;to VALUE. Otherwise return nil."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 ; ;; #### what should (text-property-any x y 'foo nil) return when there
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 ; ;; 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
264 ; ;; since a character with a property of nil is indistinguishable from
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 ; ;; a character without that property set.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 ; (map-extents
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 ; #'(lambda (e ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 ; (if (eq value (extent-property e prop))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 ; ;; return non-nil to stop mapping
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 ; (max start (extent-start-position e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 ; nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 ; nil start end buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 ;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 ;(defun text-property-not-all (start end prop value &optional buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 ; "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
276 ;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
277 ;`eq' to VALUE. Otherwise, return nil."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 ; (let (maxend)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 ; (map-extents
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 ; #'(lambda (e ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 ; ;;### no, actually, this is harder. We need to collect all props
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 ; ;; for a given character, and then determine whether no extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 ; ;; contributes the given value. Doing this without consing lots
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 ; ;; of lists is the tricky part.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 ; (if (eq value (extent-property e prop))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 ; (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 ; (setq maxend (extent-end-position e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 ; nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 ; (max start maxend)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 ; nil start end buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 (defun next-property-change (pos &optional buffer-or-string limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 "Return the position of next property change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 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
295 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
296 the change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 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
298 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
299 If the optional third argument LIMIT is non-nil, don't search
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 past position LIMIT; return LIMIT if nothing is found before LIMIT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 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
302 a particular character, it is undefined which value is considered to be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 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
304 you always use the text-property primitives.)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 (let ((limit-was-nil (null limit)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 (or limit (setq limit (if (bufferp buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 (point-max buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 (length buffer-or-string))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 (let ((value (extent-properties-at pos buffer-or-string)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 (while
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 (and (< (setq pos (next-extent-change pos buffer-or-string)) limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 (plists-eq value (extent-properties-at pos buffer-or-string)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 (if (< pos limit) pos
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 (if limit-was-nil nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 limit))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 (defun previous-property-change (pos &optional buffer-or-string limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 "Return the position of previous property change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 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
320 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
321 the change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 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
323 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
324 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
325 past position LIMIT; return LIMIT if nothing is found until LIMIT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 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
327 a particular character, it is undefined which value is considered to be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 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
329 you always use the text-property primitives.)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 (let ((limit-was-nil (null limit)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 (or limit (setq limit (if (bufferp buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 (point-min buffer-or-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 (let ((value (extent-properties-at (1- pos) buffer-or-string)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 (while
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 (and (> (setq pos (previous-extent-change pos buffer-or-string))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 (plists-eq value (extent-properties-at (1- pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 buffer-or-string)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 (if (> pos limit) pos
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 (if limit-was-nil nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 limit))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 (defun text-property-bounds (pos prop &optional object at-flag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 "Return the bounds of property PROP at POS.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 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
347 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
348 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
349 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
350 means, and has the same meaning as for `extent-at'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 (or object (setq object (current-buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 (and (get-char-property pos prop object at-flag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 (let ((begin (if (stringp object) 0 (point-min object)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 (end (if (stringp object) (length object) (point-max object))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 (cons (previous-single-property-change (1+ pos) prop object begin)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 (next-single-property-change pos prop object end)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 (defun next-text-property-bounds (count pos prop &optional object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 "Return the COUNTth bounded property region of property PROP after POS.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 If COUNT is less than zero, search backwards. This returns a cons
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 \(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
362 \(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
363 that many regions, nil is returned. OBJECT specifies the buffer or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 string to search in."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 (or object (setq object (current-buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 (let ((begin (if (stringp object) 0 (point-min object)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 (end (if (stringp object) (length object) (point-max object))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 (catch 'hit-end
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 (if (> count 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 (while (> count 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 (if (>= pos end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 (throw 'hit-end nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 (and (get-char-property pos prop object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 (setq pos (next-single-property-change pos prop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 object end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 (setq pos (next-single-property-change pos prop object end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 (setq count (1- count)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 (and (< pos end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 (cons pos (next-single-property-change pos prop object end))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 (while (< count 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 (if (<= pos begin)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 (throw 'hit-end nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 (and (get-char-property (1- pos) prop object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 (setq pos (previous-single-property-change pos prop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 object begin)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 (setq pos (previous-single-property-change pos prop object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 begin)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 (setq count (1+ count)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 (and (> pos begin)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 (cons (previous-single-property-change pos prop object begin)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 pos))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 ;(defun detach-all-extents (&optional buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 ; (map-extents #'(lambda (x i) (detach-extent x) nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 ; buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397
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 (provide 'text-props)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 ;;; text-props.el ends here