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 {