aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer.h
diff options
context:
space:
mode:
authorAndreas Politz2017-02-07 17:56:50 +0100
committerAndreas Politz2017-10-04 22:32:26 +0200
commit8d7bdfa3fca076b34aaf86548d3243bee11872ad (patch)
tree419c7897f336ad206bb9e99824f35819ba9796c1 /src/buffer.h
parentf204e6e1a418073bd1e24a83947f1f3c53581c7f (diff)
downloademacs-8d7bdfa3fca076b34aaf86548d3243bee11872ad.tar.gz
emacs-8d7bdfa3fca076b34aaf86548d3243bee11872ad.zip
Provide a new tree data-structure for overlays.
* src/itree.c (interval_generator_narrow, interval_generator_next) (interval_node_init, interval_node_begin) (interval_node_end, interval_node_set_region) (interval_tree_create, interval_tree_clear) (interval_tree_init, interval_tree_destroy) (interval_tree_size, interval_tree_insert) (interval_tree_contains, interval_tree_remove) (interval_tree_validate, interval_tree_iter_start) (interval_tree_iter_finish, interval_tree_iter_next) (interval_tree_iter_ensure_space, interval_tree_max_height) (interval_tree_insert_gap, interval_tree_delete_gap) (interval_generator_create, interval_generator_reset) (interval_generator_ensure_space, interval_node_intersects) (interval_generator_next, interval_generator_narrow) (interval_generator_destroy, interval_stack_create) (interval_stack_destroy, interval_stack_clear) (interval_stack_ensure_space, interval_stack_push) (interval_stack_push_flagged, interval_stack_pop) (interval_tree_update_limit, interval_tree_inherit_offset) (interval_tree_propagate_limit, interval_tree_rotate_left) (interval_tree_rotate_right, interval_tree_insert_fix) (interval_tree_remove_fix, interval_tree_transplant) (interval_tree_subtree_min): New file and new functions. * src/itree.h: New file. * configure.ac: Create Makefile for manual overlay tests. * src/Makefile.in: Add itree.o target. * src/alloc.c (build_overlay, mark_overlay, mark_buffer) (sweep_misc, sweep_buffers): Adapt to new tree data-structure. * src/buffer.c (overlays_in, overlays_at): Remove unused arguments prev_ptr and change_req, adapt to new data-structure and reuse code. (copy_overlays, drop_overlays, delete_all_overlays) (reset_buffer, kill-buffer, buffer-swap-text, next_overlay_change) (previous_overlay_change, mouse_face_overlay_overlaps) (disable_line_numbers_overlay_at_eob, overlay_touches_p) (overlay_strings, adjust_overlays_for_insert) (adjust_overlays_for_delete, overlayp, make-overlay, move-overlay) (delete-overlay, overlay-start, overlay-end, overlay-buffer) (overlay-properties, overlays-at, overlays-in) (next-overlay-change, previous-overlay-change, overlay-put) (overlay-get, report_overlay_modification, evaporate_overlays) (init_buffer_once): Adapt to changes and tree data-structure. (overlay-lists, overlay-recenter): Funtions are now obsolete, but kept anyway. (set_buffer_overlays_before, set_buffer_overlays_after) (recenter_overlay_lists,fix_start_end_in_overlays,fix_overlays_before) (unchain_overlay,): Removed functions of the old list data-structure. (swap_buffer_overlays, make_sortvec_item): New functions. (sort_overlays): Adapt to changes and tree data-structure. (sortvec): Moved to buffer.h . (make_lispy_interval_node, overlay_tree, overlay-tree) [ITREE_DEBUG]: New debugging functions. * src/buffer.h (overlays_before, overlays_after): Removed struct member of the list data-structure. (overlays): Added tree struct member. (sortvec): Moved here from buffer.c . (GET_OVERLAYS_AT): Adapt to changes. (set_buffer_intervals, OVERLAY_START, OVERLAY_END, OVERLAY_PLIST): Adapt to tree data-structure. (OVERLAY_POSITION): Removed macro of the list data-structure. (OVERLAY_REAR_ADVANCE_P, OVERLAY_FRONT_ADVANCE_P): New macros. (overlay_start, overlay_end) (set_overlay_region, maybe_alloc_buffer_overlays) (free_buffer_overlays, add_buffer_overlay) (remove_buffer_overlay, buffer_overlay_iter_start) (buffer_overlay_iter_next, buffer_overlay_iter_finish) (buffer_overlay_iter_narrow): New functions. (compare_overlays, make_sortvec_item): Export functions. * src/editfns.c (overlays_around): Reuse overlays_in. (get-pos-property): Adapt to tree data-structure. (transpose-regions): Remove call to deleted function. * src/fileio.c: (insert-file-contents): Remove references to deleted struct member. * src/fns.c (internal_equal): Adapt to tree data-structure. * src/indent.c (check_display_width): Adapt to tree data-structure. (skip_invisible): Remove call to deleted function. * src/insdel.c (adjust_markers_for_insert): Remove calls to deleted functions. * src/intervals.c (adjust_for_invis_intang): Adapt to tree data-structure. * src/keyboard.c (adjust_point_for_property): Adapt to tree data-structure. * src/lisp.h (Lisp_Overlay): Modified struct layout. * src/print.c (temp_output_buffer_setup, print_object): Adapt to tree data-structure. * src/textprop.c (get_char_property_and_overlay): Adapt to tree data-structure. Take advantage of the new data-structure. * src/window.h (overlay_matches_window): New function. * src/xdisp.h (next_overlay_change): Removed function. Use next-overlay-change, which does not use xmalloc anymore. (handle_single_display_spec, load_overlay_strings) (back_to_previous_visible_line_start, note_mouse_highlight): Adapt to tree data-structure. (move_it_to, display_line): Remove calls to deleted functions. * src/xfaces.c (face_at_buffer_position): Adapt to changes and tree data-structure. * test/src/buffer-tests.el: Many tests regarding overlays added. * test/manual/noverlay/itree-tests.c: New file with tests of the tree data-structure on the C level. * test/manual/noverlay/Makefile.in: New file. * test/manual/noverlay/check-sanitize.sh: New file. * test/manual/noverlay/emacs-compat.h: New file. * test/manual/noverlay/.gitignore: New file. * test/manual/noverlay/overlay-perf.el: New file providing performance tests. * test/manual/noverlay/many-errors.h: New file.
Diffstat (limited to 'src/buffer.h')
-rw-r--r--src/buffer.h161
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
30INLINE_HEADER_BEGIN 31INLINE_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
892struct sortvec
893{
894 Lisp_Object overlay;
895 ptrdiff_t beg, end;
896 EMACS_INT priority;
897 EMACS_INT spriority; /* Secondary priority. */
898};
899
899INLINE bool 900INLINE bool
900BUFFERP (Lisp_Object a) 901BUFFERP (Lisp_Object a)
901{ 902{
@@ -1109,8 +1110,11 @@ extern void delete_all_overlays (struct buffer *);
1109extern void reset_buffer (struct buffer *); 1110extern void reset_buffer (struct buffer *);
1110extern void compact_buffer (struct buffer *); 1111extern void compact_buffer (struct buffer *);
1111extern void evaporate_overlays (ptrdiff_t); 1112extern void evaporate_overlays (ptrdiff_t);
1112extern ptrdiff_t overlays_at (EMACS_INT, bool, Lisp_Object **, 1113extern ptrdiff_t overlays_at (ptrdiff_t, bool, Lisp_Object **, ptrdiff_t *, ptrdiff_t *);
1113 ptrdiff_t *, ptrdiff_t *, ptrdiff_t *, bool); 1114extern ptrdiff_t overlays_in (ptrdiff_t, ptrdiff_t, bool, Lisp_Object **,
1115 ptrdiff_t *, bool, ptrdiff_t *);
1116extern ptrdiff_t previous_overlay_change (ptrdiff_t);
1117extern ptrdiff_t next_overlay_change (ptrdiff_t);
1114extern ptrdiff_t sort_overlays (Lisp_Object *, ptrdiff_t, struct window *); 1118extern ptrdiff_t sort_overlays (Lisp_Object *, ptrdiff_t, struct window *);
1115extern void recenter_overlay_lists (struct buffer *, ptrdiff_t); 1119extern void recenter_overlay_lists (struct buffer *, ptrdiff_t);
1116extern ptrdiff_t overlay_strings (ptrdiff_t, struct window *, unsigned char **); 1120extern 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)
1208INLINE bool 1210INLINE bool
1209buffer_has_overlays (void) 1211buffer_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. */ 1254INLINE ptrdiff_t
1255overlay_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
1262INLINE ptrdiff_t
1263overlay_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
1270INLINE void
1271set_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
1279INLINE void
1280maybe_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
1289INLINE void
1290free_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
1300INLINE void
1301add_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
1309INLINE void
1310remove_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
1318INLINE void
1319buffer_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
1326INLINE struct interval_node*
1327buffer_overlay_iter_next (struct buffer *b)
1328{
1329 if (! b->overlays)
1330 return NULL;
1331 return interval_tree_iter_next (b->overlays);
1332}
1333
1334INLINE void
1335buffer_overlay_iter_finish (struct buffer *b)
1336{
1337 if (b->overlays)
1338 interval_tree_iter_finish (b->overlays);
1339}
1340
1341INLINE void
1342buffer_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
1406INLINE_HEADER_END 1510INLINE_HEADER_END
1407 1511
1512int compare_overlays (const void *v1, const void *v2);
1513void make_sortvec_item (struct sortvec *item, Lisp_Object overlay);
1514
1408#endif /* EMACS_BUFFER_H */ 1515#endif /* EMACS_BUFFER_H */