diff options
| author | Richard M. Stallman | 1993-03-01 08:56:22 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1993-03-01 08:56:22 +0000 |
| commit | 323a7ad4fd811dd71425e2fed7ebafb9daaaed72 (patch) | |
| tree | 4b318e26704372b6ee776c76609adf812abd1369 /src | |
| parent | 16032db6875c2840f8b51f86ccb1658940795910 (diff) | |
| download | emacs-323a7ad4fd811dd71425e2fed7ebafb9daaaed72.tar.gz emacs-323a7ad4fd811dd71425e2fed7ebafb9daaaed72.zip | |
(intervals_equal): Handle one arg null and other not.
(set_point): Considerable rewrite. Handle intervals both
before and after the old and new point values.
Redo handling of invisible intervals, and of motion hooks.
(textget): New function.
(graft_intervals_into_buffer):
create_root_interval needs Lisp object arg.
Set tree to new root interval.
Don't test TREE_LENGTH if buffer has no intervals.
Rearrange code to copy properties so that it really
does merge the inserted ones into the inherited ones.
(traverse_intervals): Pass `arg' on recursive calls.
(split_interval_left): Use new_length as basis for length of new.
(traverse_intervals): New arg ARG.
Diffstat (limited to 'src')
| -rw-r--r-- | src/intervals.c | 303 |
1 files changed, 141 insertions, 162 deletions
diff --git a/src/intervals.c b/src/intervals.c index f00b79cdfd3..b9b4c5f838e 100644 --- a/src/intervals.c +++ b/src/intervals.c | |||
| @@ -91,7 +91,8 @@ copy_properties (source, target) | |||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | /* Merge the properties of interval SOURCE into the properties | 93 | /* Merge the properties of interval SOURCE into the properties |
| 94 | of interval TARGET. */ | 94 | of interval TARGET. That is to say, each property in SOURCE |
| 95 | is added to TARGET if TARGET has no such property as yet. */ | ||
| 95 | 96 | ||
| 96 | static void | 97 | static void |
| 97 | merge_properties (source, target) | 98 | merge_properties (source, target) |
| @@ -135,6 +136,9 @@ intervals_equal (i0, i1) | |||
| 135 | if (DEFAULT_INTERVAL_P (i0) && DEFAULT_INTERVAL_P (i1)) | 136 | if (DEFAULT_INTERVAL_P (i0) && DEFAULT_INTERVAL_P (i1)) |
| 136 | return 1; | 137 | return 1; |
| 137 | 138 | ||
| 139 | if (DEFAULT_INTERVAL_P (i0) || DEFAULT_INTERVAL_P (i1)) | ||
| 140 | return 0; | ||
| 141 | |||
| 138 | i1_len = XFASTINT (Flength (i1->plist)); | 142 | i1_len = XFASTINT (Flength (i1->plist)); |
| 139 | if (i1_len & 0x1) /* Paranoia -- plists are always even */ | 143 | if (i1_len & 0x1) /* Paranoia -- plists are always even */ |
| 140 | abort (); | 144 | abort (); |
| @@ -186,12 +190,12 @@ traverse_intervals (tree, position, depth, function, arg) | |||
| 186 | if (NULL_INTERVAL_P (tree)) | 190 | if (NULL_INTERVAL_P (tree)) |
| 187 | return; | 191 | return; |
| 188 | 192 | ||
| 189 | traverse_intervals (tree->left, position, depth + 1, function); | 193 | traverse_intervals (tree->left, position, depth + 1, function, arg); |
| 190 | position += LEFT_TOTAL_LENGTH (tree); | 194 | position += LEFT_TOTAL_LENGTH (tree); |
| 191 | tree->position = position; | 195 | tree->position = position; |
| 192 | (*function) (tree, arg); | 196 | (*function) (tree, arg); |
| 193 | position += LENGTH (tree); | 197 | position += LENGTH (tree); |
| 194 | traverse_intervals (tree->right, position, depth + 1, function); | 198 | traverse_intervals (tree->right, position, depth + 1, function, arg); |
| 195 | } | 199 | } |
| 196 | 200 | ||
| 197 | #if 0 | 201 | #if 0 |
| @@ -422,7 +426,7 @@ split_interval_left (interval, offset) | |||
| 422 | new->left = interval->left; | 426 | new->left = interval->left; |
| 423 | new->left->parent = new; | 427 | new->left->parent = new; |
| 424 | interval->left = new; | 428 | interval->left = new; |
| 425 | new->total_length = LENGTH (new) + LEFT_TOTAL_LENGTH (new); | 429 | new->total_length = new_length + LEFT_TOTAL_LENGTH (new); |
| 426 | 430 | ||
| 427 | return new; | 431 | return new; |
| 428 | } | 432 | } |
| @@ -1105,19 +1109,15 @@ graft_intervals_into_buffer (source, position, buffer) | |||
| 1105 | int position; | 1109 | int position; |
| 1106 | struct buffer *buffer; | 1110 | struct buffer *buffer; |
| 1107 | { | 1111 | { |
| 1108 | register INTERVAL under, over, this; | 1112 | register INTERVAL under, over, this, prev; |
| 1109 | register INTERVAL tree = buffer->intervals; | 1113 | register INTERVAL tree = buffer->intervals; |
| 1114 | int middle; | ||
| 1110 | 1115 | ||
| 1111 | /* If the new text has no properties, it becomes part of whatever | 1116 | /* If the new text has no properties, it becomes part of whatever |
| 1112 | interval it was inserted into. */ | 1117 | interval it was inserted into. */ |
| 1113 | if (NULL_INTERVAL_P (source)) | 1118 | if (NULL_INTERVAL_P (source)) |
| 1114 | return; | 1119 | return; |
| 1115 | 1120 | ||
| 1116 | /* Paranoia -- the text has already been added, so this buffer | ||
| 1117 | should be of non-zero length. */ | ||
| 1118 | if (TOTAL_LENGTH (tree) == 0) | ||
| 1119 | abort (); | ||
| 1120 | |||
| 1121 | if (NULL_INTERVAL_P (tree)) | 1121 | if (NULL_INTERVAL_P (tree)) |
| 1122 | { | 1122 | { |
| 1123 | /* The inserted text constitutes the whole buffer, so | 1123 | /* The inserted text constitutes the whole buffer, so |
| @@ -1131,139 +1131,78 @@ graft_intervals_into_buffer (source, position, buffer) | |||
| 1131 | } | 1131 | } |
| 1132 | 1132 | ||
| 1133 | /* Create an interval tree in which to place a copy | 1133 | /* Create an interval tree in which to place a copy |
| 1134 | of the intervals of the inserted string. */ | 1134 | of the intervals of the inserted string. */ |
| 1135 | { | 1135 | { |
| 1136 | Lisp_Object buf; | 1136 | Lisp_Object buf; |
| 1137 | XSET (buf, Lisp_Buffer, buffer); | 1137 | XSET (buf, Lisp_Buffer, buffer); |
| 1138 | create_root_interval (buffer); | 1138 | tree = create_root_interval (buf); |
| 1139 | } | 1139 | } |
| 1140 | } | 1140 | } |
| 1141 | else | 1141 | else |
| 1142 | if (TOTAL_LENGTH (tree) == TOTAL_LENGTH (source)) | 1142 | if (TOTAL_LENGTH (tree) == TOTAL_LENGTH (source)) |
| 1143 | /* If the buffer contains only the new string, but | ||
| 1144 | there was already some interval tree there, then it may be | ||
| 1145 | some zero length intervals. Eventually, do something clever | ||
| 1146 | about inserting properly. For now, just waste the old intervals. */ | ||
| 1147 | { | ||
| 1148 | buffer->intervals = reproduce_tree (source, tree->parent); | ||
| 1149 | /* Explicitly free the old tree here. */ | ||
| 1143 | 1150 | ||
| 1144 | /* If the buffer contains only the new string, but | 1151 | return; |
| 1145 | there was already some interval tree there, then it may be | 1152 | } |
| 1146 | some zero length intervals. Eventually, do something clever | 1153 | else |
| 1147 | about inserting properly. For now, just waste the old intervals. */ | 1154 | /* Paranoia -- the text has already been added, so this buffer |
| 1148 | { | 1155 | should be of non-zero length. */ |
| 1149 | buffer->intervals = reproduce_tree (source, tree->parent); | 1156 | if (TOTAL_LENGTH (tree) == 0) |
| 1150 | /* Explicitly free the old tree here. */ | 1157 | abort (); |
| 1151 | |||
| 1152 | return; | ||
| 1153 | } | ||
| 1154 | 1158 | ||
| 1155 | this = under = find_interval (tree, position); | 1159 | this = under = find_interval (tree, position); |
| 1156 | if (NULL_INTERVAL_P (under)) /* Paranoia */ | 1160 | if (NULL_INTERVAL_P (under)) /* Paranoia */ |
| 1157 | abort (); | 1161 | abort (); |
| 1158 | over = find_interval (source, 1); | 1162 | over = find_interval (source, 1); |
| 1159 | 1163 | ||
| 1160 | /* Insertion between intervals */ | 1164 | /* Here for insertion in the middle of an interval. |
| 1161 | if (position == under->position) | 1165 | Split off an equivalent interval to the right, |
| 1162 | { | 1166 | then don't bother with it any more. */ |
| 1163 | /* First interval -- none precede it. */ | ||
| 1164 | if (position == 1) | ||
| 1165 | { | ||
| 1166 | if (! FRONT_STICKY_P (under)) | ||
| 1167 | /* The inserted string keeps its own properties. */ | ||
| 1168 | while (! NULL_INTERVAL_P (over)) | ||
| 1169 | { | ||
| 1170 | position = LENGTH (over) + 1; | ||
| 1171 | this = split_interval_left (this, position); | ||
| 1172 | copy_properties (over, this); | ||
| 1173 | over = next_interval (over); | ||
| 1174 | } | ||
| 1175 | else | ||
| 1176 | /* This string "sticks" to the first interval, `under', | ||
| 1177 | which means it gets those properties. */ | ||
| 1178 | while (! NULL_INTERVAL_P (over)) | ||
| 1179 | { | ||
| 1180 | position = LENGTH (over) + 1; | ||
| 1181 | this = split_interval_left (this, position); | ||
| 1182 | copy_properties (under, this); | ||
| 1183 | if (MERGE_INSERTIONS (under)) | ||
| 1184 | merge_properties (over, this); | ||
| 1185 | over = next_interval (over); | ||
| 1186 | } | ||
| 1187 | } | ||
| 1188 | else | ||
| 1189 | { | ||
| 1190 | INTERVAL prev = previous_interval (under); | ||
| 1191 | if (NULL_INTERVAL_P (prev)) | ||
| 1192 | abort (); | ||
| 1193 | |||
| 1194 | if (END_STICKY_P (prev)) | ||
| 1195 | { | ||
| 1196 | if (FRONT_STICKY_P (under)) | ||
| 1197 | /* The intervals go inbetween as the two sticky | ||
| 1198 | properties cancel each other. Should we change | ||
| 1199 | this policy? */ | ||
| 1200 | while (! NULL_INTERVAL_P (over)) | ||
| 1201 | { | ||
| 1202 | position = LENGTH (over) + 1; | ||
| 1203 | this = split_interval_left (this, position); | ||
| 1204 | copy_properties (over, this); | ||
| 1205 | over = next_interval (over); | ||
| 1206 | } | ||
| 1207 | else | ||
| 1208 | /* The intervals stick to prev */ | ||
| 1209 | while (! NULL_INTERVAL_P (over)) | ||
| 1210 | { | ||
| 1211 | position = LENGTH (over) + 1; | ||
| 1212 | this = split_interval_left (this, position); | ||
| 1213 | copy_properties (prev, this); | ||
| 1214 | if (MERGE_INSERTIONS (prev)) | ||
| 1215 | merge_properties (over, this); | ||
| 1216 | over = next_interval (over); | ||
| 1217 | } | ||
| 1218 | } | ||
| 1219 | else | ||
| 1220 | { | ||
| 1221 | if (FRONT_STICKY_P (under)) | ||
| 1222 | /* The inserted text "sticks" to the interval `under', | ||
| 1223 | which means it gets those properties. */ | ||
| 1224 | while (! NULL_INTERVAL_P (over)) | ||
| 1225 | { | ||
| 1226 | position = LENGTH (over) + 1; | ||
| 1227 | this = split_interval_left (this, position); | ||
| 1228 | copy_properties (under, this); | ||
| 1229 | if (MERGE_INSERTIONS (under)) | ||
| 1230 | merge_properties (over, this); | ||
| 1231 | over = next_interval (over); | ||
| 1232 | } | ||
| 1233 | else | ||
| 1234 | /* The intervals go inbetween */ | ||
| 1235 | while (! NULL_INTERVAL_P (over)) | ||
| 1236 | { | ||
| 1237 | position = LENGTH (over) + 1; | ||
| 1238 | this = split_interval_left (this, position); | ||
| 1239 | copy_properties (over, this); | ||
| 1240 | over = next_interval (over); | ||
| 1241 | } | ||
| 1242 | } | ||
| 1243 | } | ||
| 1244 | |||
| 1245 | buffer->intervals = balance_intervals (buffer->intervals); | ||
| 1246 | return; | ||
| 1247 | } | ||
| 1248 | |||
| 1249 | /* Here for insertion in the middle of an interval. */ | ||
| 1250 | 1167 | ||
| 1251 | if (TOTAL_LENGTH (source) < LENGTH (this)) | 1168 | if (position > under->position) |
| 1252 | { | 1169 | { |
| 1253 | INTERVAL end_unchanged | 1170 | INTERVAL end_unchanged |
| 1254 | = split_interval_right (this, TOTAL_LENGTH (source) + 1); | 1171 | = split_interval_left (this, position - under->position + 1); |
| 1255 | copy_properties (under, end_unchanged); | 1172 | copy_properties (under, end_unchanged); |
| 1173 | under->position = position; | ||
| 1174 | prev = 0; | ||
| 1175 | middle = 1; | ||
| 1256 | } | 1176 | } |
| 1177 | else | ||
| 1178 | { | ||
| 1179 | prev = previous_interval (under); | ||
| 1180 | if (prev && !END_STICKY_P (prev)) | ||
| 1181 | prev = 0; | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | /* Insertion is now at beginning of UNDER. */ | ||
| 1257 | 1185 | ||
| 1258 | position = position - tree->position + 1; | 1186 | /* The inserted text "sticks" to the interval `under', |
| 1187 | which means it gets those properties. */ | ||
| 1259 | while (! NULL_INTERVAL_P (over)) | 1188 | while (! NULL_INTERVAL_P (over)) |
| 1260 | { | 1189 | { |
| 1261 | this = split_interval_right (under, position); | 1190 | position = LENGTH (over) + 1; |
| 1191 | if (position < LENGTH (under)) | ||
| 1192 | this = split_interval_left (under, position); | ||
| 1193 | else | ||
| 1194 | this = under; | ||
| 1262 | copy_properties (over, this); | 1195 | copy_properties (over, this); |
| 1263 | if (MERGE_INSERTIONS (under)) | 1196 | /* Insertion at the end of an interval, PREV, |
| 1197 | inherits from PREV if PREV is sticky at the end. */ | ||
| 1198 | if (prev && ! FRONT_STICKY_P (under) | ||
| 1199 | && MERGE_INSERTIONS (prev)) | ||
| 1200 | merge_properties (prev, this); | ||
| 1201 | /* Maybe it inherits from the following interval | ||
| 1202 | if that is sticky at the front. */ | ||
| 1203 | else if ((FRONT_STICKY_P (under) || middle) | ||
| 1204 | && MERGE_INSERTIONS (under)) | ||
| 1264 | merge_properties (under, this); | 1205 | merge_properties (under, this); |
| 1265 | |||
| 1266 | position = LENGTH (over) + 1; | ||
| 1267 | over = next_interval (over); | 1206 | over = next_interval (over); |
| 1268 | } | 1207 | } |
| 1269 | 1208 | ||
| @@ -1271,18 +1210,32 @@ graft_intervals_into_buffer (source, position, buffer) | |||
| 1271 | return; | 1210 | return; |
| 1272 | } | 1211 | } |
| 1273 | 1212 | ||
| 1213 | textget (plist, prop) | ||
| 1214 | Lisp_Object plist; | ||
| 1215 | register Lisp_Object prop; | ||
| 1216 | { | ||
| 1217 | register Lisp_Object tail; | ||
| 1218 | |||
| 1219 | for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail))) | ||
| 1220 | { | ||
| 1221 | register Lisp_Object tem; | ||
| 1222 | tem = Fcar (tail); | ||
| 1223 | if (EQ (prop, tem)) | ||
| 1224 | return Fcar (Fcdr (tail)); | ||
| 1225 | } | ||
| 1226 | return Qnil; | ||
| 1227 | } | ||
| 1228 | |||
| 1274 | /* Set point in BUFFER to POSITION. If the target position is in | 1229 | /* Set point in BUFFER to POSITION. If the target position is in |
| 1275 | an invisible interval which is not displayed with a special glyph, | 1230 | after an invisible character which is not displayed with a special glyph, |
| 1276 | skip intervals until we find one. Point may be at the first | 1231 | move back to an ok place to display. */ |
| 1277 | position of an invisible interval, if it is displayed with a | ||
| 1278 | special glyph. */ | ||
| 1279 | 1232 | ||
| 1280 | void | 1233 | void |
| 1281 | set_point (position, buffer) | 1234 | set_point (position, buffer) |
| 1282 | register int position; | 1235 | register int position; |
| 1283 | register struct buffer *buffer; | 1236 | register struct buffer *buffer; |
| 1284 | { | 1237 | { |
| 1285 | register INTERVAL to, from, target; | 1238 | register INTERVAL to, from, toprev, fromprev, target; |
| 1286 | register int iposition = position; | 1239 | register int iposition = position; |
| 1287 | int buffer_point; | 1240 | int buffer_point; |
| 1288 | register Lisp_Object obj; | 1241 | register Lisp_Object obj; |
| @@ -1306,62 +1259,88 @@ set_point (position, buffer) | |||
| 1306 | if (position == BUF_Z (buffer)) | 1259 | if (position == BUF_Z (buffer)) |
| 1307 | iposition = position - 1; | 1260 | iposition = position - 1; |
| 1308 | 1261 | ||
| 1262 | /* Set TO to the interval containing the char after POSITION, | ||
| 1263 | and TOPREV to the interval containing the char before POSITION. | ||
| 1264 | Either one may be null. They may be equal. */ | ||
| 1309 | to = find_interval (buffer->intervals, iposition); | 1265 | to = find_interval (buffer->intervals, iposition); |
| 1310 | buffer_point =(BUF_PT (buffer) == BUF_Z (buffer) | 1266 | if (to->position == position) |
| 1311 | ? BUF_Z (buffer) - 1 | 1267 | toprev = previous_interval (to); |
| 1312 | : BUF_PT (buffer)); | 1268 | else if (iposition != position) |
| 1269 | toprev = to, to = 0; | ||
| 1270 | else | ||
| 1271 | toprev = to; | ||
| 1272 | |||
| 1273 | buffer_point = (BUF_PT (buffer) == BUF_Z (buffer) | ||
| 1274 | ? BUF_Z (buffer) - 1 | ||
| 1275 | : BUF_PT (buffer)); | ||
| 1313 | 1276 | ||
| 1277 | /* Set FROM to the interval containing the char after PT, | ||
| 1278 | and FROMPREV to the interval containing the char before PT. | ||
| 1279 | Either one may be null. They may be equal. */ | ||
| 1314 | /* We could cache this and save time. */ | 1280 | /* We could cache this and save time. */ |
| 1315 | from = find_interval (buffer->intervals, buffer_point); | 1281 | from = find_interval (buffer->intervals, buffer_point); |
| 1316 | 1282 | if (from->position == BUF_PT (buffer)) | |
| 1317 | if (NULL_INTERVAL_P (to) || NULL_INTERVAL_P (from)) | 1283 | fromprev = previous_interval (from); |
| 1318 | abort (); /* Paranoia */ | 1284 | else if (buffer_point != BUF_PT (buffer)) |
| 1285 | fromprev = from, from = 0; | ||
| 1286 | else | ||
| 1287 | fromprev = from; | ||
| 1319 | 1288 | ||
| 1320 | /* Moving within an interval */ | 1289 | /* Moving within an interval */ |
| 1321 | if (to == from && INTERVAL_VISIBLE_P (to)) | 1290 | if (to == from && toprev == fromprev && INTERVAL_VISIBLE_P (to)) |
| 1322 | { | 1291 | { |
| 1323 | buffer->text.pt = position; | 1292 | buffer->text.pt = position; |
| 1324 | return; | 1293 | return; |
| 1325 | } | 1294 | } |
| 1326 | 1295 | ||
| 1327 | /* Here for the case of moving into another interval. */ | 1296 | /* If the new position is after an invisible character, |
| 1328 | 1297 | move back over all such. */ | |
| 1329 | target = to; | 1298 | while (! NULL_INTERVAL_P (toprev) |
| 1330 | while (! INTERVAL_VISIBLE_P (to) && ! DISPLAY_INVISIBLE_GLYPH (to) | 1299 | && ! INTERVAL_VISIBLE_P (toprev) |
| 1331 | && ! NULL_INTERVAL_P (to)) | 1300 | && ! DISPLAY_INVISIBLE_GLYPH (toprev)) |
| 1332 | to = (backwards ? previous_interval (to) : next_interval (to)); | ||
| 1333 | if (NULL_INTERVAL_P (to)) | ||
| 1334 | return; | ||
| 1335 | |||
| 1336 | /* Here we know we are actually moving to another interval. */ | ||
| 1337 | if (INTERVAL_VISIBLE_P (to)) | ||
| 1338 | { | 1301 | { |
| 1339 | /* If we skipped some intervals, go to the closest point | 1302 | to = toprev; |
| 1340 | in the interval we've stopped at. */ | 1303 | toprev = previous_interval (toprev); |
| 1341 | if (to != target) | 1304 | position = to->position; |
| 1342 | buffer->text.pt = (backwards | ||
| 1343 | ? to->position + LENGTH (to) - 1 | ||
| 1344 | : to->position); | ||
| 1345 | else | ||
| 1346 | buffer->text.pt = position; | ||
| 1347 | } | 1305 | } |
| 1348 | else | 1306 | |
| 1349 | buffer->text.pt = to->position; | 1307 | buffer->text.pt = position; |
| 1350 | 1308 | ||
| 1351 | /* We run point-left and point-entered hooks here, iff the | 1309 | /* We run point-left and point-entered hooks here, iff the |
| 1352 | two intervals are not equivalent. These hooks take | 1310 | two intervals are not equivalent. These hooks take |
| 1353 | (old_point, new_point) as arguments. */ | 1311 | (old_point, new_point) as arguments. */ |
| 1354 | if (! intervals_equal (from, to)) | 1312 | if (! intervals_equal (from, to) |
| 1313 | || ! intervals_equal (fromprev, toprev)) | ||
| 1355 | { | 1314 | { |
| 1356 | Lisp_Object val; | 1315 | Lisp_Object leave_after, leave_before, enter_after, enter_before; |
| 1316 | |||
| 1317 | if (fromprev) | ||
| 1318 | leave_after = textget (fromprev->plist, Qpoint_left); | ||
| 1319 | else | ||
| 1320 | leave_after = Qnil; | ||
| 1321 | if (from) | ||
| 1322 | leave_before = textget (from->plist, Qpoint_left); | ||
| 1323 | else | ||
| 1324 | leave_before = Qnil; | ||
| 1325 | |||
| 1326 | if (toprev) | ||
| 1327 | enter_after = textget (toprev->plist, Qpoint_entered); | ||
| 1328 | else | ||
| 1329 | enter_after = Qnil; | ||
| 1330 | if (to) | ||
| 1331 | enter_before = textget (to->plist, Qpoint_entered); | ||
| 1332 | else | ||
| 1333 | enter_before = Qnil; | ||
| 1357 | 1334 | ||
| 1358 | val = Fget (Qpoint_left, from->plist); | 1335 | if (! EQ (leave_before, enter_before) && !NILP (leave_before)) |
| 1359 | if (! NILP (val)) | 1336 | call2 (leave_before, old_position, position); |
| 1360 | call2 (val, old_position, position); | 1337 | if (! EQ (leave_after, enter_after) && !NILP (leave_after)) |
| 1338 | call2 (leave_after, old_position, position); | ||
| 1361 | 1339 | ||
| 1362 | val = Fget (Qpoint_entered, to->plist); | 1340 | if (! EQ (enter_before, leave_before) && !NILP (enter_before)) |
| 1363 | if (! NILP (val)) | 1341 | call2 (enter_before, old_position, position); |
| 1364 | call2 (val, old_position, position); | 1342 | if (! EQ (enter_after, leave_after) && !NILP (enter_after)) |
| 1343 | call2 (enter_after, old_position, position); | ||
| 1365 | } | 1344 | } |
| 1366 | } | 1345 | } |
| 1367 | 1346 | ||