Mercurial > hg > xemacs-beta
comparison src/extents.c @ 2506:8c96bdabcaf9
[xemacs-hg @ 2005-01-26 05:11:01 by ben]
implement next-single-char-property-change and friends
extents.c, extents.h, indent.c, syntax.c: Implement next/previous-single-char-property-change and make
next/previous-single-property-change work like in FSF.
author | ben |
---|---|
date | Wed, 26 Jan 2005 05:11:12 +0000 |
parents | 3d8143fc88e1 |
children | 9f70af3ac939 |
comparison
equal
deleted
inserted
replaced
2505:3e5a2d0d57e1 | 2506:8c96bdabcaf9 |
---|---|
1 /* Copyright (c) 1994, 1995 Free Software Foundation, Inc. | 1 /* Copyright (c) 1994, 1995 Free Software Foundation, Inc. |
2 Copyright (c) 1995 Sun Microsystems, Inc. | 2 Copyright (c) 1995 Sun Microsystems, Inc. |
3 Copyright (c) 1995, 1996, 2000, 2002, 2003 Ben Wing. | 3 Copyright (c) 1995, 1996, 2000, 2002, 2003, 2004, 2005 Ben Wing. |
4 | 4 |
5 This file is part of XEmacs. | 5 This file is part of XEmacs. |
6 | 6 |
7 XEmacs is free software; you can redistribute it and/or modify it | 7 XEmacs is free software; you can redistribute it and/or modify it |
8 under the terms of the GNU General Public License as published by the | 8 under the terms of the GNU General Public License as published by the |
7079 Fput_text_property (from, to, prop, val, Qnil); | 7079 Fput_text_property (from, to, prop, val, Qnil); |
7080 return Qnil; /* important! */ | 7080 return Qnil; /* important! */ |
7081 } | 7081 } |
7082 | 7082 |
7083 Bytexpos | 7083 Bytexpos |
7084 next_single_property_change (Bytexpos pos, Lisp_Object prop, | 7084 next_previous_single_property_change (Bytexpos pos, Lisp_Object prop, |
7085 Lisp_Object object, Bytexpos limit) | 7085 Lisp_Object object, Bytexpos limit, |
7086 Boolint next, Boolint text_props_only) | |
7086 { | 7087 { |
7087 Lisp_Object extent, value; | 7088 Lisp_Object extent, value; |
7088 int limit_was_nil; | 7089 int limit_was_nil; |
7089 | 7090 enum extent_at_flag at_flag = next ? EXTENT_AT_AFTER : EXTENT_AT_BEFORE; |
7090 if (limit < 0) | 7091 if (limit < 0) |
7091 { | 7092 { |
7092 limit = buffer_or_string_accessible_end_byte (object); | 7093 limit = (next ? buffer_or_string_accessible_end_byte : |
7094 buffer_or_string_accessible_begin_byte) (object); | |
7093 limit_was_nil = 1; | 7095 limit_was_nil = 1; |
7094 } | 7096 } |
7095 else | 7097 else |
7096 limit_was_nil = 0; | 7098 limit_was_nil = 0; |
7097 | 7099 |
7098 extent = extent_at (pos, object, prop, 0, EXTENT_AT_AFTER, 0); | 7100 /* Retrieve initial property value to compare against */ |
7101 extent = extent_at (pos, object, prop, 0, at_flag, 0); | |
7102 /* If we only want text-prop extents, ignore all others */ | |
7103 if (text_props_only && !NILP (extent) && | |
7104 NILP (Fextent_property (extent, Qtext_prop, Qnil))) | |
7105 extent = Qnil; | |
7099 if (!NILP (extent)) | 7106 if (!NILP (extent)) |
7100 value = Fextent_property (extent, prop, Qnil); | 7107 value = Fextent_property (extent, prop, Qnil); |
7101 else | 7108 else |
7102 value = Qnil; | 7109 value = Qnil; |
7103 | 7110 |
7104 while (1) | 7111 while (1) |
7105 { | 7112 { |
7106 pos = extent_find_end_of_run (object, pos, 1); | 7113 pos = (next ? extent_find_end_of_run : extent_find_beginning_of_run) |
7107 if (pos >= limit) | 7114 (object, pos, 1); |
7108 break; /* property is the same all the way to the end */ | 7115 if (next ? pos >= limit : pos <= limit) |
7109 extent = extent_at (pos, object, prop, 0, EXTENT_AT_AFTER, 0); | 7116 break; /* property is the same all the way to the beginning/end */ |
7117 extent = extent_at (pos, object, prop, 0, at_flag, 0); | |
7118 /* If we only want text-prop extents, ignore all others */ | |
7119 if (text_props_only && !NILP (extent) && | |
7120 NILP (Fextent_property (extent, Qtext_prop, Qnil))) | |
7121 extent = Qnil; | |
7110 if ((NILP (extent) && !NILP (value)) || | 7122 if ((NILP (extent) && !NILP (value)) || |
7111 (!NILP (extent) && !EQ (value, | 7123 (!NILP (extent) && !EQ (value, |
7112 Fextent_property (extent, prop, Qnil)))) | 7124 Fextent_property (extent, prop, Qnil)))) |
7113 return pos; | 7125 return pos; |
7114 } | 7126 } |
7117 return -1; | 7129 return -1; |
7118 else | 7130 else |
7119 return limit; | 7131 return limit; |
7120 } | 7132 } |
7121 | 7133 |
7122 Bytexpos | 7134 static Lisp_Object |
7123 previous_single_property_change (Bytexpos pos, Lisp_Object prop, | 7135 next_previous_single_property_change_fn (Lisp_Object pos, Lisp_Object prop, |
7124 Lisp_Object object, Bytexpos limit) | 7136 Lisp_Object object, Lisp_Object limit, |
7125 { | 7137 Boolint next, Boolint text_props_only) |
7126 Lisp_Object extent, value; | 7138 { |
7127 int limit_was_nil; | 7139 Bytexpos xpos; |
7128 | 7140 Bytexpos blim; |
7129 if (limit < 0) | 7141 |
7130 { | 7142 object = decode_buffer_or_string (object); |
7131 limit = buffer_or_string_accessible_begin_byte (object); | 7143 xpos = get_buffer_or_string_pos_byte (object, pos, 0); |
7132 limit_was_nil = 1; | 7144 blim = !NILP (limit) ? get_buffer_or_string_pos_byte (object, limit, 0) : -1; |
7133 } | 7145 blim = next_previous_single_property_change (xpos, prop, object, blim, |
7146 next, text_props_only); | |
7147 | |
7148 if (blim < 0) | |
7149 return Qnil; | |
7134 else | 7150 else |
7135 limit_was_nil = 0; | 7151 return make_int (buffer_or_string_bytexpos_to_charxpos (object, blim)); |
7136 | |
7137 extent = extent_at (pos, object, prop, 0, EXTENT_AT_BEFORE, 0); | |
7138 if (!NILP (extent)) | |
7139 value = Fextent_property (extent, prop, Qnil); | |
7140 else | |
7141 value = Qnil; | |
7142 | |
7143 while (1) | |
7144 { | |
7145 pos = extent_find_beginning_of_run (object, pos, 1); | |
7146 if (pos <= limit) | |
7147 break; /* property is the same all the way to the end */ | |
7148 extent = extent_at (pos, object, prop, 0, EXTENT_AT_BEFORE, 0); | |
7149 if ((NILP (extent) && !NILP (value)) || | |
7150 (!NILP (extent) && !EQ (value, | |
7151 Fextent_property (extent, prop, Qnil)))) | |
7152 return pos; | |
7153 } | |
7154 | |
7155 if (limit_was_nil) | |
7156 return -1; | |
7157 else | |
7158 return limit; | |
7159 } | 7152 } |
7160 | 7153 |
7161 DEFUN ("next-single-property-change", Fnext_single_property_change, | 7154 DEFUN ("next-single-property-change", Fnext_single_property_change, |
7162 2, 4, 0, /* | 7155 2, 4, 0, /* |
7163 Return the position of next property change for a specific property. | 7156 Return the position of next property change for a specific property. |
7173 past position LIMIT; return LIMIT if nothing is found before LIMIT. | 7166 past position LIMIT; return LIMIT if nothing is found before LIMIT. |
7174 If two or more extents with conflicting non-nil values for PROP overlap | 7167 If two or more extents with conflicting non-nil values for PROP overlap |
7175 a particular character, it is undefined which value is considered to be | 7168 a particular character, it is undefined which value is considered to be |
7176 the value of PROP. (Note that this situation will not happen if you always | 7169 the value of PROP. (Note that this situation will not happen if you always |
7177 use the text-property primitives.) | 7170 use the text-property primitives.) |
7171 | |
7172 This function looks only at extents created using the text-property primitives. | |
7173 To look at all extents, use `next-single-char-property-change'. | |
7178 */ | 7174 */ |
7179 (pos, prop, object, limit)) | 7175 (pos, prop, object, limit)) |
7180 { | 7176 { |
7181 Bytexpos xpos; | 7177 return next_previous_single_property_change_fn (pos, prop, object, limit, |
7182 Bytexpos blim; | 7178 1, 1); |
7183 | |
7184 object = decode_buffer_or_string (object); | |
7185 xpos = get_buffer_or_string_pos_byte (object, pos, 0); | |
7186 blim = !NILP (limit) ? get_buffer_or_string_pos_byte (object, limit, 0) : -1; | |
7187 | |
7188 blim = next_single_property_change (xpos, prop, object, blim); | |
7189 | |
7190 if (blim < 0) | |
7191 return Qnil; | |
7192 else | |
7193 return make_int (buffer_or_string_bytexpos_to_charxpos (object, blim)); | |
7194 } | 7179 } |
7195 | 7180 |
7196 DEFUN ("previous-single-property-change", Fprevious_single_property_change, | 7181 DEFUN ("previous-single-property-change", Fprevious_single_property_change, |
7197 2, 4, 0, /* | 7182 2, 4, 0, /* |
7198 Return the position of next property change for a specific property. | 7183 Return the position of next property change for a specific property. |
7208 past position LIMIT; return LIMIT if nothing is found until LIMIT. | 7193 past position LIMIT; return LIMIT if nothing is found until LIMIT. |
7209 If two or more extents with conflicting non-nil values for PROP overlap | 7194 If two or more extents with conflicting non-nil values for PROP overlap |
7210 a particular character, it is undefined which value is considered to be | 7195 a particular character, it is undefined which value is considered to be |
7211 the value of PROP. (Note that this situation will not happen if you always | 7196 the value of PROP. (Note that this situation will not happen if you always |
7212 use the text-property primitives.) | 7197 use the text-property primitives.) |
7198 | |
7199 This function looks only at extents created using the text-property primitives. | |
7200 To look at all extents, use `next-single-char-property-change'. | |
7213 */ | 7201 */ |
7214 (pos, prop, object, limit)) | 7202 (pos, prop, object, limit)) |
7215 { | 7203 { |
7216 Bytexpos xpos; | 7204 return next_previous_single_property_change_fn (pos, prop, object, limit, |
7217 Bytexpos blim; | 7205 0, 1); |
7218 | 7206 } |
7219 object = decode_buffer_or_string (object); | 7207 |
7220 xpos = get_buffer_or_string_pos_byte (object, pos, 0); | 7208 DEFUN ("next-single-char-property-change", Fnext_single_char_property_change, |
7221 blim = !NILP (limit) ? get_buffer_or_string_pos_byte (object, limit, 0) : -1; | 7209 2, 4, 0, /* |
7222 | 7210 Return the position of next property change for a specific property. |
7223 blim = previous_single_property_change (xpos, prop, object, blim); | 7211 Scans characters forward from POS till it finds a change in the PROP |
7224 | 7212 property, then returns the position of the change. The optional third |
7225 if (blim < 0) | 7213 argument OBJECT is the buffer or string to scan (defaults to the current |
7226 return Qnil; | 7214 buffer). |
7227 else | 7215 The property values are compared with `eq'. |
7228 return make_int (buffer_or_string_bytexpos_to_charxpos (object, blim)); | 7216 Return nil if the property is constant all the way to the end of OBJECT. |
7217 If the value is non-nil, it is a position greater than POS, never equal. | |
7218 | |
7219 If the optional fourth argument LIMIT is non-nil, don't search | |
7220 past position LIMIT; return LIMIT if nothing is found before LIMIT. | |
7221 If two or more extents with conflicting non-nil values for PROP overlap | |
7222 a particular character, it is undefined which value is considered to be | |
7223 the value of PROP. (Note that this situation will not happen if you always | |
7224 use the text-property primitives.) | |
7225 | |
7226 This function looks at all extents. To look at only extents created using the | |
7227 text-property primitives, use `next-single-char-property-change'. | |
7228 */ | |
7229 (pos, prop, object, limit)) | |
7230 { | |
7231 return next_previous_single_property_change_fn (pos, prop, object, limit, | |
7232 1, 0); | |
7233 } | |
7234 | |
7235 DEFUN ("previous-single-char-property-change", | |
7236 Fprevious_single_char_property_change, | |
7237 2, 4, 0, /* | |
7238 Return the position of next property change for a specific property. | |
7239 Scans characters backward from POS till it finds a change in the PROP | |
7240 property, then returns the position of the change. The optional third | |
7241 argument OBJECT is the buffer or string to scan (defaults to the current | |
7242 buffer). | |
7243 The property values are compared with `eq'. | |
7244 Return nil if the property is constant all the way to the start of OBJECT. | |
7245 If the value is non-nil, it is a position less than POS, never equal. | |
7246 | |
7247 If the optional fourth argument LIMIT is non-nil, don't search back | |
7248 past position LIMIT; return LIMIT if nothing is found until LIMIT. | |
7249 If two or more extents with conflicting non-nil values for PROP overlap | |
7250 a particular character, it is undefined which value is considered to be | |
7251 the value of PROP. (Note that this situation will not happen if you always | |
7252 use the text-property primitives.) | |
7253 | |
7254 This function looks at all extents. To look at only extents created using the | |
7255 text-property primitives, use `next-single-char-property-change'. | |
7256 */ | |
7257 (pos, prop, object, limit)) | |
7258 { | |
7259 return next_previous_single_property_change_fn (pos, prop, object, limit, | |
7260 0, 0); | |
7229 } | 7261 } |
7230 | 7262 |
7231 #ifdef MEMORY_USAGE_STATS | 7263 #ifdef MEMORY_USAGE_STATS |
7232 | 7264 |
7233 int | 7265 int |
7362 DEFSUBR (Fadd_nonduplicable_text_properties); | 7394 DEFSUBR (Fadd_nonduplicable_text_properties); |
7363 DEFSUBR (Fremove_text_properties); | 7395 DEFSUBR (Fremove_text_properties); |
7364 DEFSUBR (Ftext_prop_extent_paste_function); | 7396 DEFSUBR (Ftext_prop_extent_paste_function); |
7365 DEFSUBR (Fnext_single_property_change); | 7397 DEFSUBR (Fnext_single_property_change); |
7366 DEFSUBR (Fprevious_single_property_change); | 7398 DEFSUBR (Fprevious_single_property_change); |
7399 DEFSUBR (Fnext_single_char_property_change); | |
7400 DEFSUBR (Fprevious_single_char_property_change); | |
7367 } | 7401 } |
7368 | 7402 |
7369 void | 7403 void |
7370 reinit_vars_of_extents (void) | 7404 reinit_vars_of_extents (void) |
7371 { | 7405 { |