diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/textprop.c | 107 |
1 files changed, 97 insertions, 10 deletions
diff --git a/src/textprop.c b/src/textprop.c index 3c62f0ad230..13d2b4edd9a 100644 --- a/src/textprop.c +++ b/src/textprop.c | |||
| @@ -122,14 +122,6 @@ validate_interval_range (object, begin, end, force) | |||
| 122 | return NULL_INTERVAL; | 122 | return NULL_INTERVAL; |
| 123 | 123 | ||
| 124 | searchpos = XINT (*begin); | 124 | searchpos = XINT (*begin); |
| 125 | if (searchpos == BUF_Z (b)) | ||
| 126 | searchpos--; | ||
| 127 | #if 0 | ||
| 128 | /* Special case for point-max: return the interval for the | ||
| 129 | last character. */ | ||
| 130 | if (*begin == *end && *begin == BUF_Z (b)) | ||
| 131 | *begin -= 1; | ||
| 132 | #endif | ||
| 133 | } | 125 | } |
| 134 | else | 126 | else |
| 135 | { | 127 | { |
| @@ -149,8 +141,6 @@ validate_interval_range (object, begin, end, force) | |||
| 149 | return NULL_INTERVAL; | 141 | return NULL_INTERVAL; |
| 150 | 142 | ||
| 151 | searchpos = XINT (*begin); | 143 | searchpos = XINT (*begin); |
| 152 | if (searchpos > s->size) | ||
| 153 | searchpos--; | ||
| 154 | } | 144 | } |
| 155 | 145 | ||
| 156 | if (NULL_INTERVAL_P (i)) | 146 | if (NULL_INTERVAL_P (i)) |
| @@ -1005,6 +995,102 @@ is the string or buffer containing the text.") | |||
| 1005 | } | 995 | } |
| 1006 | #endif /* 0 */ | 996 | #endif /* 0 */ |
| 1007 | 997 | ||
| 998 | /* I don't think this is the right interface to export; how often do you | ||
| 999 | want to do something like this, other than when you're copying objects | ||
| 1000 | around? | ||
| 1001 | |||
| 1002 | I think it would be better to have a pair of functions, one which | ||
| 1003 | returns the text properties of a region as a list of ranges and | ||
| 1004 | plists, and another which applies such a list to another object. */ | ||
| 1005 | |||
| 1006 | /* DEFUN ("copy-text-properties", Fcopy_text_properties, | ||
| 1007 | Scopy_text_properties, 5, 6, 0, | ||
| 1008 | "Add properties from SRC-START to SRC-END of SRC at DEST-POS of DEST.\n\ | ||
| 1009 | SRC and DEST may each refer to strings or buffers.\n\ | ||
| 1010 | Optional sixth argument PROP causes only that property to be copied.\n\ | ||
| 1011 | Properties are copied to DEST as if by `add-text-properties'.\n\ | ||
| 1012 | Return t if any property value actually changed, nil otherwise.") */ | ||
| 1013 | |||
| 1014 | Lisp_Object | ||
| 1015 | copy_text_properties (start, end, src, pos, dest, prop) | ||
| 1016 | Lisp_Object start, end, src, pos, dest, prop; | ||
| 1017 | { | ||
| 1018 | INTERVAL i; | ||
| 1019 | Lisp_Object res; | ||
| 1020 | Lisp_Object stuff; | ||
| 1021 | Lisp_Object plist; | ||
| 1022 | int s, e, e2, p, len, modified = 0; | ||
| 1023 | |||
| 1024 | i = validate_interval_range (src, &start, &end, soft); | ||
| 1025 | if (NULL_INTERVAL_P (i)) | ||
| 1026 | return Qnil; | ||
| 1027 | |||
| 1028 | CHECK_NUMBER_COERCE_MARKER (pos, 0); | ||
| 1029 | { | ||
| 1030 | Lisp_Object dest_start, dest_end; | ||
| 1031 | |||
| 1032 | dest_start = pos; | ||
| 1033 | XFASTINT (dest_end) = XINT (dest_start) + (XINT (end) - XINT (start)); | ||
| 1034 | /* Apply this to a copy of pos; it will try to increment its arguments, | ||
| 1035 | which we don't want. */ | ||
| 1036 | validate_interval_range (dest, &dest_start, &dest_end, soft); | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | s = XINT (start); | ||
| 1040 | e = XINT (end); | ||
| 1041 | p = XINT (pos); | ||
| 1042 | |||
| 1043 | stuff = Qnil; | ||
| 1044 | |||
| 1045 | while (s < e) | ||
| 1046 | { | ||
| 1047 | e2 = i->position + LENGTH (i); | ||
| 1048 | if (e2 > e) | ||
| 1049 | e2 = e; | ||
| 1050 | len = e2 - s; | ||
| 1051 | |||
| 1052 | plist = i->plist; | ||
| 1053 | if (! NILP (prop)) | ||
| 1054 | while (! NILP (plist)) | ||
| 1055 | { | ||
| 1056 | if (EQ (Fcar (plist), prop)) | ||
| 1057 | { | ||
| 1058 | plist = Fcons (prop, Fcons (Fcar (Fcdr (plist)), Qnil)); | ||
| 1059 | break; | ||
| 1060 | } | ||
| 1061 | plist = Fcdr (Fcdr (plist)); | ||
| 1062 | } | ||
| 1063 | if (! NILP (plist)) | ||
| 1064 | { | ||
| 1065 | /* Must defer modifications to the interval tree in case src | ||
| 1066 | and dest refer to the same string or buffer. */ | ||
| 1067 | stuff = Fcons (Fcons (make_number (p), | ||
| 1068 | Fcons (make_number (p + len), | ||
| 1069 | Fcons (plist, Qnil))), | ||
| 1070 | stuff); | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | i = next_interval (i); | ||
| 1074 | if (NULL_INTERVAL_P (i)) | ||
| 1075 | break; | ||
| 1076 | |||
| 1077 | p += len; | ||
| 1078 | s = i->position; | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | while (! NILP (stuff)) | ||
| 1082 | { | ||
| 1083 | res = Fcar (stuff); | ||
| 1084 | res = Fadd_text_properties (Fcar (res), Fcar (Fcdr (res)), | ||
| 1085 | Fcar (Fcdr (Fcdr (res))), dest); | ||
| 1086 | if (! NILP (res)) | ||
| 1087 | modified++; | ||
| 1088 | stuff = Fcdr (stuff); | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | return modified ? Qt : Qnil; | ||
| 1092 | } | ||
| 1093 | |||
| 1008 | void | 1094 | void |
| 1009 | syms_of_textprop () | 1095 | syms_of_textprop () |
| 1010 | { | 1096 | { |
| @@ -1058,6 +1144,7 @@ percentage by which the left interval tree should not differ from the right."); | |||
| 1058 | defsubr (&Sset_text_properties); | 1144 | defsubr (&Sset_text_properties); |
| 1059 | defsubr (&Sremove_text_properties); | 1145 | defsubr (&Sremove_text_properties); |
| 1060 | /* defsubr (&Serase_text_properties); */ | 1146 | /* defsubr (&Serase_text_properties); */ |
| 1147 | /* defsubr (&Scopy_text_properties); */ | ||
| 1061 | } | 1148 | } |
| 1062 | 1149 | ||
| 1063 | #else | 1150 | #else |