diff options
Diffstat (limited to 'src/buffer.h')
| -rw-r--r-- | src/buffer.h | 161 |
1 files changed, 134 insertions, 27 deletions
diff --git a/src/buffer.h b/src/buffer.h index ac7c5a54679..ef31ad1ed9d 100644 --- a/src/buffer.h +++ b/src/buffer.h | |||
| @@ -26,6 +26,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 26 | 26 | ||
| 27 | #include "character.h" | 27 | #include "character.h" |
| 28 | #include "lisp.h" | 28 | #include "lisp.h" |
| 29 | #include "itree.h" | ||
| 29 | 30 | ||
| 30 | INLINE_HEADER_BEGIN | 31 | INLINE_HEADER_BEGIN |
| 31 | 32 | ||
| @@ -877,16 +878,8 @@ struct buffer | |||
| 877 | /* Non-zero whenever the narrowing is changed in this buffer. */ | 878 | /* Non-zero whenever the narrowing is changed in this buffer. */ |
| 878 | bool_bf clip_changed : 1; | 879 | bool_bf clip_changed : 1; |
| 879 | 880 | ||
| 880 | /* List of overlays that end at or before the current center, | 881 | /* The inveral tree containing this buffer's overlays. */ |
| 881 | in order of end-position. */ | 882 | struct interval_tree *overlays; |
| 882 | struct Lisp_Overlay *overlays_before; | ||
| 883 | |||
| 884 | /* List of overlays that end after the current center, | ||
| 885 | in order of start-position. */ | ||
| 886 | struct Lisp_Overlay *overlays_after; | ||
| 887 | |||
| 888 | /* Position where the overlay lists are centered. */ | ||
| 889 | ptrdiff_t overlay_center; | ||
| 890 | 883 | ||
| 891 | /* Changes in the buffer are recorded here for undo, and t means | 884 | /* Changes in the buffer are recorded here for undo, and t means |
| 892 | don't record anything. This information belongs to the base | 885 | don't record anything. This information belongs to the base |
| @@ -896,6 +889,14 @@ struct buffer | |||
| 896 | Lisp_Object undo_list_; | 889 | Lisp_Object undo_list_; |
| 897 | }; | 890 | }; |
| 898 | 891 | ||
| 892 | struct sortvec | ||
| 893 | { | ||
| 894 | Lisp_Object overlay; | ||
| 895 | ptrdiff_t beg, end; | ||
| 896 | EMACS_INT priority; | ||
| 897 | EMACS_INT spriority; /* Secondary priority. */ | ||
| 898 | }; | ||
| 899 | |||
| 899 | INLINE bool | 900 | INLINE bool |
| 900 | BUFFERP (Lisp_Object a) | 901 | BUFFERP (Lisp_Object a) |
| 901 | { | 902 | { |
| @@ -1109,8 +1110,11 @@ extern void delete_all_overlays (struct buffer *); | |||
| 1109 | extern void reset_buffer (struct buffer *); | 1110 | extern void reset_buffer (struct buffer *); |
| 1110 | extern void compact_buffer (struct buffer *); | 1111 | extern void compact_buffer (struct buffer *); |
| 1111 | extern void evaporate_overlays (ptrdiff_t); | 1112 | extern void evaporate_overlays (ptrdiff_t); |
| 1112 | extern ptrdiff_t overlays_at (EMACS_INT, bool, Lisp_Object **, | 1113 | extern ptrdiff_t overlays_at (ptrdiff_t, bool, Lisp_Object **, ptrdiff_t *, ptrdiff_t *); |
| 1113 | ptrdiff_t *, ptrdiff_t *, ptrdiff_t *, bool); | 1114 | extern ptrdiff_t overlays_in (ptrdiff_t, ptrdiff_t, bool, Lisp_Object **, |
| 1115 | ptrdiff_t *, bool, ptrdiff_t *); | ||
| 1116 | extern ptrdiff_t previous_overlay_change (ptrdiff_t); | ||
| 1117 | extern ptrdiff_t next_overlay_change (ptrdiff_t); | ||
| 1114 | extern ptrdiff_t sort_overlays (Lisp_Object *, ptrdiff_t, struct window *); | 1118 | extern ptrdiff_t sort_overlays (Lisp_Object *, ptrdiff_t, struct window *); |
| 1115 | extern void recenter_overlay_lists (struct buffer *, ptrdiff_t); | 1119 | extern void recenter_overlay_lists (struct buffer *, ptrdiff_t); |
| 1116 | extern ptrdiff_t overlay_strings (ptrdiff_t, struct window *, unsigned char **); | 1120 | extern ptrdiff_t overlay_strings (ptrdiff_t, struct window *, unsigned char **); |
| @@ -1162,18 +1166,16 @@ record_unwind_current_buffer (void) | |||
| 1162 | If NEXTP is non-NULL, return next overlay there. | 1166 | If NEXTP is non-NULL, return next overlay there. |
| 1163 | See overlay_at arg CHANGE_REQ for meaning of CHRQ arg. */ | 1167 | See overlay_at arg CHANGE_REQ for meaning of CHRQ arg. */ |
| 1164 | 1168 | ||
| 1165 | #define GET_OVERLAYS_AT(posn, overlays, noverlays, nextp, chrq) \ | 1169 | #define GET_OVERLAYS_AT(posn, overlays, noverlays, next) \ |
| 1166 | do { \ | 1170 | do { \ |
| 1167 | ptrdiff_t maxlen = 40; \ | 1171 | ptrdiff_t maxlen = 40; \ |
| 1168 | SAFE_NALLOCA (overlays, 1, maxlen); \ | 1172 | SAFE_NALLOCA (overlays, 1, maxlen); \ |
| 1169 | (noverlays) = overlays_at (posn, false, &(overlays), &maxlen, \ | 1173 | (noverlays) = overlays_at (posn, false, &(overlays), &maxlen, next); \ |
| 1170 | nextp, NULL, chrq); \ | ||
| 1171 | if ((noverlays) > maxlen) \ | 1174 | if ((noverlays) > maxlen) \ |
| 1172 | { \ | 1175 | { \ |
| 1173 | maxlen = noverlays; \ | 1176 | maxlen = noverlays; \ |
| 1174 | SAFE_NALLOCA (overlays, 1, maxlen); \ | 1177 | SAFE_NALLOCA (overlays, 1, maxlen); \ |
| 1175 | (noverlays) = overlays_at (posn, false, &(overlays), &maxlen, \ | 1178 | (noverlays) = overlays_at (posn, false, &(overlays), &maxlen, next); \ |
| 1176 | nextp, NULL, chrq); \ | ||
| 1177 | } \ | 1179 | } \ |
| 1178 | } while (false) | 1180 | } while (false) |
| 1179 | 1181 | ||
| @@ -1208,7 +1210,8 @@ set_buffer_intervals (struct buffer *b, INTERVAL i) | |||
| 1208 | INLINE bool | 1210 | INLINE bool |
| 1209 | buffer_has_overlays (void) | 1211 | buffer_has_overlays (void) |
| 1210 | { | 1212 | { |
| 1211 | return current_buffer->overlays_before || current_buffer->overlays_after; | 1213 | return current_buffer->overlays |
| 1214 | && (interval_tree_size (current_buffer->overlays) > 0); | ||
| 1212 | } | 1215 | } |
| 1213 | 1216 | ||
| 1214 | /* Return character code of multi-byte form at byte position POS. If POS | 1217 | /* Return character code of multi-byte form at byte position POS. If POS |
| @@ -1248,23 +1251,124 @@ buffer_window_count (struct buffer *b) | |||
| 1248 | 1251 | ||
| 1249 | /* Overlays */ | 1252 | /* Overlays */ |
| 1250 | 1253 | ||
| 1251 | /* Return the marker that stands for where OV starts in the buffer. */ | 1254 | INLINE ptrdiff_t |
| 1255 | overlay_start (struct Lisp_Overlay *ov) | ||
| 1256 | { | ||
| 1257 | if (! ov->buffer) | ||
| 1258 | return -1; | ||
| 1259 | return interval_node_begin (ov->buffer->overlays, ov->interval); | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | INLINE ptrdiff_t | ||
| 1263 | overlay_end (struct Lisp_Overlay *ov) | ||
| 1264 | { | ||
| 1265 | if (! ov->buffer) | ||
| 1266 | return -1; | ||
| 1267 | return interval_node_end (ov->buffer->overlays, ov->interval); | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | INLINE void | ||
| 1271 | set_overlay_region (struct Lisp_Overlay *ov, ptrdiff_t begin, ptrdiff_t end) | ||
| 1272 | { | ||
| 1273 | eassert (ov->buffer); | ||
| 1274 | begin = clip_to_bounds (BEG, begin, ov->buffer->text->z); | ||
| 1275 | end = clip_to_bounds (begin, end, ov->buffer->text->z); | ||
| 1276 | interval_node_set_region (ov->buffer->overlays, ov->interval, begin, end); | ||
| 1277 | } | ||
| 1278 | |||
| 1279 | INLINE void | ||
| 1280 | maybe_alloc_buffer_overlays (struct buffer *b) | ||
| 1281 | { | ||
| 1282 | if (! b->overlays) | ||
| 1283 | b->overlays = interval_tree_create (); | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | /* FIXME: Actually this does not free any overlay, but the tree | ||
| 1287 | only. --ap */ | ||
| 1288 | |||
| 1289 | INLINE void | ||
| 1290 | free_buffer_overlays (struct buffer *b) | ||
| 1291 | { | ||
| 1292 | eassert (! b->overlays || 0 == interval_tree_size (b->overlays)); | ||
| 1293 | if (b->overlays) | ||
| 1294 | { | ||
| 1295 | interval_tree_destroy (b->overlays); | ||
| 1296 | b->overlays = NULL; | ||
| 1297 | } | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | INLINE void | ||
| 1301 | add_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov) | ||
| 1302 | { | ||
| 1303 | eassert (! ov->buffer); | ||
| 1304 | maybe_alloc_buffer_overlays (b); | ||
| 1305 | ov->buffer = b; | ||
| 1306 | interval_tree_insert (b->overlays, ov->interval); | ||
| 1307 | } | ||
| 1308 | |||
| 1309 | INLINE void | ||
| 1310 | remove_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov) | ||
| 1311 | { | ||
| 1312 | eassert (b->overlays); | ||
| 1313 | eassert (ov->buffer == b); | ||
| 1314 | interval_tree_remove (ov->buffer->overlays, ov->interval); | ||
| 1315 | ov->buffer = NULL; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | INLINE void | ||
| 1319 | buffer_overlay_iter_start (struct buffer *b, ptrdiff_t begin, ptrdiff_t end, | ||
| 1320 | enum interval_tree_order order) | ||
| 1321 | { | ||
| 1322 | if (b->overlays) | ||
| 1323 | interval_tree_iter_start (b->overlays, begin, end, order); | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | INLINE struct interval_node* | ||
| 1327 | buffer_overlay_iter_next (struct buffer *b) | ||
| 1328 | { | ||
| 1329 | if (! b->overlays) | ||
| 1330 | return NULL; | ||
| 1331 | return interval_tree_iter_next (b->overlays); | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | INLINE void | ||
| 1335 | buffer_overlay_iter_finish (struct buffer *b) | ||
| 1336 | { | ||
| 1337 | if (b->overlays) | ||
| 1338 | interval_tree_iter_finish (b->overlays); | ||
| 1339 | } | ||
| 1340 | |||
| 1341 | INLINE void | ||
| 1342 | buffer_overlay_iter_narrow (struct buffer *b, ptrdiff_t begin, ptrdiff_t end) | ||
| 1343 | { | ||
| 1344 | if (b->overlays) | ||
| 1345 | interval_tree_iter_narrow (b->overlays, begin, end); | ||
| 1346 | } | ||
| 1252 | 1347 | ||
| 1253 | #define OVERLAY_START(OV) XOVERLAY (OV)->start | 1348 | /* Return the start of OV in its buffer, or -1 if OV is not associated |
| 1349 | with any buffer. */ | ||
| 1254 | 1350 | ||
| 1255 | /* Return the marker that stands for where OV ends in the buffer. */ | 1351 | #define OVERLAY_START(OV) (overlay_start (XOVERLAY (OV))) |
| 1256 | 1352 | ||
| 1257 | #define OVERLAY_END(OV) XOVERLAY (OV)->end | 1353 | /* Return the end of OV in its buffer, or -1. */ |
| 1354 | |||
| 1355 | #define OVERLAY_END(OV) (overlay_end (XOVERLAY (OV))) | ||
| 1258 | 1356 | ||
| 1259 | /* Return the plist of overlay OV. */ | 1357 | /* Return the plist of overlay OV. */ |
| 1260 | 1358 | ||
| 1261 | #define OVERLAY_PLIST(OV) XOVERLAY (OV)->plist | 1359 | #define OVERLAY_PLIST(OV) (XOVERLAY (OV)->plist) |
| 1360 | |||
| 1361 | /* Return the buffer of overlay OV. */ | ||
| 1362 | |||
| 1363 | #define OVERLAY_BUFFER(OV) (XOVERLAY (OV)->buffer) | ||
| 1262 | 1364 | ||
| 1263 | /* Return the actual buffer position for the marker P. | 1365 | /* Return true, if OV's rear-advance is set. */ |
| 1264 | We assume you know which buffer it's pointing into. */ | ||
| 1265 | 1366 | ||
| 1266 | #define OVERLAY_POSITION(P) \ | 1367 | #define OVERLAY_REAR_ADVANCE_P(OV) (XOVERLAY (OV)->interval->rear_advance) |
| 1267 | (MARKERP (P) ? marker_position (P) : (emacs_abort (), 0)) | 1368 | |
| 1369 | /* Return true, if OV's front-advance is set. */ | ||
| 1370 | |||
| 1371 | #define OVERLAY_FRONT_ADVANCE_P(OV) (XOVERLAY (OV)->interval->front_advance) | ||
| 1268 | 1372 | ||
| 1269 | 1373 | ||
| 1270 | /*********************************************************************** | 1374 | /*********************************************************************** |
| @@ -1405,4 +1509,7 @@ lowercasep (int c) | |||
| 1405 | 1509 | ||
| 1406 | INLINE_HEADER_END | 1510 | INLINE_HEADER_END |
| 1407 | 1511 | ||
| 1512 | int compare_overlays (const void *v1, const void *v2); | ||
| 1513 | void make_sortvec_item (struct sortvec *item, Lisp_Object overlay); | ||
| 1514 | |||
| 1408 | #endif /* EMACS_BUFFER_H */ | 1515 | #endif /* EMACS_BUFFER_H */ |