This source file includes following definitions.
- CHECK_OVERLAY
- fix_position
- bset_abbrev_mode
- bset_abbrev_table
- bset_auto_fill_function
- bset_auto_save_file_format
- bset_auto_save_file_name
- bset_backed_up
- bset_begv_marker
- bset_bidi_display_reordering
- bset_bidi_paragraph_start_re
- bset_bidi_paragraph_separate_re
- bset_buffer_file_coding_system
- bset_case_fold_search
- bset_ctl_arrow
- bset_cursor_in_non_selected_windows
- bset_cursor_type
- bset_display_table
- bset_extra_line_spacing
- bset_ts_parser_list
- bset_file_format
- bset_file_truename
- bset_fringe_cursor_alist
- bset_fringe_indicator_alist
- bset_fringes_outside_margins
- bset_header_line_format
- bset_tab_line_format
- bset_indicate_buffer_boundaries
- bset_indicate_empty_lines
- bset_invisibility_spec
- bset_left_fringe_width
- bset_major_mode
- bset_local_minor_modes
- bset_mark
- bset_mode_line_format
- bset_mode_name
- bset_name
- bset_overwrite_mode
- bset_pt_marker
- bset_right_fringe_width
- bset_save_length
- bset_scroll_bar_width
- bset_scroll_bar_height
- bset_scroll_down_aggressively
- bset_scroll_up_aggressively
- bset_selective_display
- bset_selective_display_ellipses
- bset_vertical_scroll_bar_type
- bset_horizontal_scroll_bar_type
- bset_word_wrap
- bset_zv_marker
- nsberror
- DEFUN
- DEFUN
- assoc_ignore_text_properties
- DEFUN
- DEFUN
- get_truename_buffer
- run_buffer_list_update_hook
- add_buffer_overlay
- copy_overlays
- valid_per_buffer_idx
- clone_per_buffer_values
- record_buffer_markers
- fetch_buffer_markers
- remove_buffer_overlay
- drop_overlay
- delete_all_overlays
- free_buffer_overlays
- set_overlays_multibyte
- reset_buffer
- reset_buffer_local_variables
- DEFUN
- DEFUN
- DEFUN
- buffer_local_value
- buffer_lisp_local_variables
- buffer_local_variables_1
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- candidate_buffer
- other_buffer_safely
- DEFUN
- compact_buffer
- DEFUN
- record_buffer
- DEFUN
- DEFUN
- DEFUN
- set_buffer_internal_1
- set_buffer_internal_2
- set_buffer_temp
- DEFUN
- restore_buffer
- set_buffer_if_live
- DEFUN
- DEFUN
- validate_region
- advance_to_char_boundary
- swap_buffer_overlays
- DEFUN
- DEFUN
- DEFUN
- overlays_in
- overlays_at
- next_overlay_change
- previous_overlay_change
- mouse_face_overlay_overlaps
- disable_line_numbers_overlay_at_eob
- overlay_touches_p
- compare_overlays
- make_sortvec_item
- sort_overlays
- cmp_for_strings
- record_overlay_string
- overlay_strings
- adjust_overlays_for_insert
- adjust_overlays_for_delete_in_buffer
- adjust_overlays_for_delete
- DEFUN
- modify_overlay
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- add_overlay_mod_hooklist
- report_overlay_modification
- call_overlay_mod_hooks
- mmap_init
- mmap_free_1
- mmap_enlarge
- mmap_alloc
- mmap_free
- mmap_realloc
- alloc_buffer_text
- enlarge_buffer_text
- free_buffer_text
- init_buffer_once
- init_buffer
- defvar_per_buffer
- make_lispy_itree_node
- overlay_tree
- DEFUN
- syms_of_buffer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <sys/param.h>
25 #include <errno.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29
30 #include <verify.h>
31
32 #include "lisp.h"
33 #include "intervals.h"
34 #include "process.h"
35 #include "systime.h"
36 #include "window.h"
37 #include "commands.h"
38 #include "character.h"
39 #include "buffer.h"
40 #include "region-cache.h"
41 #include "indent.h"
42 #include "blockinput.h"
43 #include "keymap.h"
44 #include "frame.h"
45 #include "xwidget.h"
46 #include "itree.h"
47 #include "pdumper.h"
48
49 #ifdef WINDOWSNT
50 #include "w32heap.h"
51 #endif
52
53
54
55
56
57
58
59
60 struct buffer buffer_defaults;
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 struct buffer buffer_local_flags;
80
81
82
83
84 struct buffer buffer_local_symbols;
85
86
87
88
89 #define PER_BUFFER_SYMBOL(OFFSET) \
90 (*(Lisp_Object *)((OFFSET) + (char *) &buffer_local_symbols))
91
92
93 #define OVERLAY_COUNT_MAX \
94 ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, \
95 min (PTRDIFF_MAX, SIZE_MAX) / word_size))
96
97
98
99 static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
100
101
102
103 static int last_per_buffer_idx;
104
105 static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay,
106 bool after, Lisp_Object arg1,
107 Lisp_Object arg2, Lisp_Object arg3);
108 static void reset_buffer_local_variables (struct buffer *, bool);
109
110
111
112
113 Lisp_Object Vbuffer_alist;
114
115 static Lisp_Object QSFundamental;
116
117 static void alloc_buffer_text (struct buffer *, ptrdiff_t);
118 static void free_buffer_text (struct buffer *b);
119 static void copy_overlays (struct buffer *, struct buffer *);
120 static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t);
121 static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool);
122 static Lisp_Object buffer_local_variables_1 (struct buffer *buf, int offset, Lisp_Object sym);
123
124 static void
125 CHECK_OVERLAY (Lisp_Object x)
126 {
127 CHECK_TYPE (OVERLAYP (x), Qoverlayp, x);
128 }
129
130
131
132
133
134
135
136 EMACS_INT
137 fix_position (Lisp_Object pos)
138 {
139 if (FIXNUMP (pos))
140 return XFIXNUM (pos);
141 if (MARKERP (pos))
142 return marker_position (pos);
143 CHECK_TYPE (BIGNUMP (pos), Qinteger_or_marker_p, pos);
144 return !NILP (Fnatnump (pos)) ? MOST_POSITIVE_FIXNUM : MOST_NEGATIVE_FIXNUM;
145 }
146
147
148
149 static void
150 bset_abbrev_mode (struct buffer *b, Lisp_Object val)
151 {
152 b->abbrev_mode_ = val;
153 }
154 static void
155 bset_abbrev_table (struct buffer *b, Lisp_Object val)
156 {
157 b->abbrev_table_ = val;
158 }
159 static void
160 bset_auto_fill_function (struct buffer *b, Lisp_Object val)
161 {
162 b->auto_fill_function_ = val;
163 }
164 static void
165 bset_auto_save_file_format (struct buffer *b, Lisp_Object val)
166 {
167 b->auto_save_file_format_ = val;
168 }
169 static void
170 bset_auto_save_file_name (struct buffer *b, Lisp_Object val)
171 {
172 b->auto_save_file_name_ = val;
173 }
174 static void
175 bset_backed_up (struct buffer *b, Lisp_Object val)
176 {
177 b->backed_up_ = val;
178 }
179 static void
180 bset_begv_marker (struct buffer *b, Lisp_Object val)
181 {
182 b->begv_marker_ = val;
183 }
184 static void
185 bset_bidi_display_reordering (struct buffer *b, Lisp_Object val)
186 {
187 b->bidi_display_reordering_ = val;
188 }
189 static void
190 bset_bidi_paragraph_start_re (struct buffer *b, Lisp_Object val)
191 {
192 b->bidi_paragraph_start_re_ = val;
193 }
194 static void
195 bset_bidi_paragraph_separate_re (struct buffer *b, Lisp_Object val)
196 {
197 b->bidi_paragraph_separate_re_ = val;
198 }
199 static void
200 bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val)
201 {
202 b->buffer_file_coding_system_ = val;
203 }
204 static void
205 bset_case_fold_search (struct buffer *b, Lisp_Object val)
206 {
207 b->case_fold_search_ = val;
208 }
209 static void
210 bset_ctl_arrow (struct buffer *b, Lisp_Object val)
211 {
212 b->ctl_arrow_ = val;
213 }
214 static void
215 bset_cursor_in_non_selected_windows (struct buffer *b, Lisp_Object val)
216 {
217 b->cursor_in_non_selected_windows_ = val;
218 }
219 static void
220 bset_cursor_type (struct buffer *b, Lisp_Object val)
221 {
222 b->cursor_type_ = val;
223 }
224 static void
225 bset_display_table (struct buffer *b, Lisp_Object val)
226 {
227 b->display_table_ = val;
228 }
229 static void
230 bset_extra_line_spacing (struct buffer *b, Lisp_Object val)
231 {
232 b->extra_line_spacing_ = val;
233 }
234 #ifdef HAVE_TREE_SITTER
235 static void
236 bset_ts_parser_list (struct buffer *b, Lisp_Object val)
237 {
238 b->ts_parser_list_ = val;
239 }
240 #endif
241 static void
242 bset_file_format (struct buffer *b, Lisp_Object val)
243 {
244 b->file_format_ = val;
245 }
246 static void
247 bset_file_truename (struct buffer *b, Lisp_Object val)
248 {
249 b->file_truename_ = val;
250 }
251 static void
252 bset_fringe_cursor_alist (struct buffer *b, Lisp_Object val)
253 {
254 b->fringe_cursor_alist_ = val;
255 }
256 static void
257 bset_fringe_indicator_alist (struct buffer *b, Lisp_Object val)
258 {
259 b->fringe_indicator_alist_ = val;
260 }
261 static void
262 bset_fringes_outside_margins (struct buffer *b, Lisp_Object val)
263 {
264 b->fringes_outside_margins_ = val;
265 }
266 static void
267 bset_header_line_format (struct buffer *b, Lisp_Object val)
268 {
269 b->header_line_format_ = val;
270 }
271 static void
272 bset_tab_line_format (struct buffer *b, Lisp_Object val)
273 {
274 b->tab_line_format_ = val;
275 }
276 static void
277 bset_indicate_buffer_boundaries (struct buffer *b, Lisp_Object val)
278 {
279 b->indicate_buffer_boundaries_ = val;
280 }
281 static void
282 bset_indicate_empty_lines (struct buffer *b, Lisp_Object val)
283 {
284 b->indicate_empty_lines_ = val;
285 }
286 static void
287 bset_invisibility_spec (struct buffer *b, Lisp_Object val)
288 {
289 b->invisibility_spec_ = val;
290 }
291 static void
292 bset_left_fringe_width (struct buffer *b, Lisp_Object val)
293 {
294 b->left_fringe_width_ = val;
295 }
296 static void
297 bset_major_mode (struct buffer *b, Lisp_Object val)
298 {
299 b->major_mode_ = val;
300 }
301 static void
302 bset_local_minor_modes (struct buffer *b, Lisp_Object val)
303 {
304 b->local_minor_modes_ = val;
305 }
306 static void
307 bset_mark (struct buffer *b, Lisp_Object val)
308 {
309 b->mark_ = val;
310 }
311 static void
312 bset_mode_line_format (struct buffer *b, Lisp_Object val)
313 {
314 b->mode_line_format_ = val;
315 }
316 static void
317 bset_mode_name (struct buffer *b, Lisp_Object val)
318 {
319 b->mode_name_ = val;
320 }
321 static void
322 bset_name (struct buffer *b, Lisp_Object val)
323 {
324 b->name_ = val;
325 }
326 static void
327 bset_overwrite_mode (struct buffer *b, Lisp_Object val)
328 {
329 b->overwrite_mode_ = val;
330 }
331 static void
332 bset_pt_marker (struct buffer *b, Lisp_Object val)
333 {
334 b->pt_marker_ = val;
335 }
336 static void
337 bset_right_fringe_width (struct buffer *b, Lisp_Object val)
338 {
339 b->right_fringe_width_ = val;
340 }
341 static void
342 bset_save_length (struct buffer *b, Lisp_Object val)
343 {
344 b->save_length_ = val;
345 }
346 static void
347 bset_scroll_bar_width (struct buffer *b, Lisp_Object val)
348 {
349 b->scroll_bar_width_ = val;
350 }
351 static void
352 bset_scroll_bar_height (struct buffer *b, Lisp_Object val)
353 {
354 b->scroll_bar_height_ = val;
355 }
356 static void
357 bset_scroll_down_aggressively (struct buffer *b, Lisp_Object val)
358 {
359 b->scroll_down_aggressively_ = val;
360 }
361 static void
362 bset_scroll_up_aggressively (struct buffer *b, Lisp_Object val)
363 {
364 b->scroll_up_aggressively_ = val;
365 }
366 static void
367 bset_selective_display (struct buffer *b, Lisp_Object val)
368 {
369 b->selective_display_ = val;
370 }
371 static void
372 bset_selective_display_ellipses (struct buffer *b, Lisp_Object val)
373 {
374 b->selective_display_ellipses_ = val;
375 }
376 static void
377 bset_vertical_scroll_bar_type (struct buffer *b, Lisp_Object val)
378 {
379 b->vertical_scroll_bar_type_ = val;
380 }
381 static void
382 bset_horizontal_scroll_bar_type (struct buffer *b, Lisp_Object val)
383 {
384 b->horizontal_scroll_bar_type_ = val;
385 }
386 static void
387 bset_word_wrap (struct buffer *b, Lisp_Object val)
388 {
389 b->word_wrap_ = val;
390 }
391 static void
392 bset_zv_marker (struct buffer *b, Lisp_Object val)
393 {
394 b->zv_marker_ = val;
395 }
396
397 void
398 nsberror (Lisp_Object spec)
399 {
400 if (STRINGP (spec))
401 error ("No buffer named %s", SDATA (spec));
402 error ("Invalid buffer argument");
403 }
404
405 DEFUN ("buffer-live-p", Fbuffer_live_p, Sbuffer_live_p, 1, 1, 0,
406 doc:
407 )
408 (Lisp_Object object)
409 {
410 return ((BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object)))
411 ? Qt : Qnil);
412 }
413
414 DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0,
415 doc:
416
417
418 )
419 (Lisp_Object frame)
420 {
421 Lisp_Object general;
422 general = Fmapcar (Qcdr, Vbuffer_alist);
423
424 if (FRAMEP (frame))
425 {
426 Lisp_Object framelist, prevlist, tail;
427
428 framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
429 prevlist = Fnreverse (Fcopy_sequence
430 (XFRAME (frame)->buried_buffer_list));
431
432
433
434 tail = framelist;
435 while (CONSP (tail))
436 {
437 general = Fdelq (XCAR (tail), general);
438 tail = XCDR (tail);
439 }
440 tail = prevlist;
441 while (CONSP (tail))
442 {
443 general = Fdelq (XCAR (tail), general);
444 tail = XCDR (tail);
445 }
446
447 return CALLN (Fnconc, framelist, general, prevlist);
448 }
449 else
450 return general;
451 }
452
453
454
455
456 static Lisp_Object
457 assoc_ignore_text_properties (Lisp_Object key, Lisp_Object list)
458 {
459 Lisp_Object tail;
460 for (tail = list; CONSP (tail); tail = XCDR (tail))
461 {
462 Lisp_Object elt = XCAR (tail);
463 if (!NILP (Fstring_equal (Fcar (elt), key)))
464 return elt;
465 }
466 return Qnil;
467 }
468
469 DEFUN ("get-buffer", Fget_buffer, Sget_buffer, 1, 1, 0,
470 doc:
471
472
473 )
474 (register Lisp_Object buffer_or_name)
475 {
476 if (BUFFERP (buffer_or_name))
477 return buffer_or_name;
478 CHECK_STRING (buffer_or_name);
479
480 return Fcdr (assoc_ignore_text_properties (buffer_or_name, Vbuffer_alist));
481 }
482
483 DEFUN ("get-file-buffer", Fget_file_buffer, Sget_file_buffer, 1, 1, 0,
484 doc:
485
486
487 )
488 (register Lisp_Object filename)
489 {
490 register Lisp_Object tail, buf, handler;
491
492 CHECK_STRING (filename);
493 filename = Fexpand_file_name (filename, Qnil);
494
495
496
497 handler = Ffind_file_name_handler (filename, Qget_file_buffer);
498 if (!NILP (handler))
499 {
500 Lisp_Object handled_buf = call2 (handler, Qget_file_buffer,
501 filename);
502 return BUFFERP (handled_buf) ? handled_buf : Qnil;
503 }
504
505 FOR_EACH_LIVE_BUFFER (tail, buf)
506 {
507 if (!STRINGP (BVAR (XBUFFER (buf), filename))) continue;
508 if (!NILP (Fstring_equal (BVAR (XBUFFER (buf), filename), filename)))
509 return buf;
510 }
511 return Qnil;
512 }
513
514 Lisp_Object
515 get_truename_buffer (register Lisp_Object filename)
516 {
517 register Lisp_Object tail, buf;
518
519 FOR_EACH_LIVE_BUFFER (tail, buf)
520 {
521 if (!STRINGP (BVAR (XBUFFER (buf), file_truename))) continue;
522 if (!NILP (Fstring_equal (BVAR (XBUFFER (buf), file_truename), filename)))
523 return buf;
524 }
525 return Qnil;
526 }
527
528
529
530
531 static void
532 run_buffer_list_update_hook (struct buffer *buf)
533 {
534 eassert (buf);
535 if (! (NILP (Vrun_hooks) || buf->inhibit_buffer_hooks))
536 call1 (Vrun_hooks, Qbuffer_list_update_hook);
537 }
538
539 DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 2, 0,
540 doc:
541
542
543
544
545
546
547
548
549
550
551
552
553 )
554 (register Lisp_Object buffer_or_name, Lisp_Object inhibit_buffer_hooks)
555 {
556 register Lisp_Object buffer, name;
557 register struct buffer *b;
558
559 buffer = Fget_buffer (buffer_or_name);
560 if (!NILP (buffer))
561 return buffer;
562
563 if (SCHARS (buffer_or_name) == 0)
564 error ("Empty string for buffer name is not allowed");
565
566 b = allocate_buffer ();
567
568
569 b->text = &b->own_text;
570 b->base_buffer = NULL;
571
572 b->indirections = 0;
573
574 b->window_count = 0;
575
576 memset (&b->local_flags, 0, sizeof (b->local_flags));
577
578 BUF_GAP_SIZE (b) = 20;
579 block_input ();
580
581
582 alloc_buffer_text (b, BUF_GAP_SIZE (b) + 1);
583 unblock_input ();
584 if (! BUF_BEG_ADDR (b))
585 buffer_memory_full (BUF_GAP_SIZE (b) + 1);
586
587 b->pt = BEG;
588 b->begv = BEG;
589 b->zv = BEG;
590 b->pt_byte = BEG_BYTE;
591 b->begv_byte = BEG_BYTE;
592 b->zv_byte = BEG_BYTE;
593
594 BUF_GPT (b) = BEG;
595 BUF_GPT_BYTE (b) = BEG_BYTE;
596
597 BUF_Z (b) = BEG;
598 BUF_Z_BYTE (b) = BEG_BYTE;
599 BUF_MODIFF (b) = 1;
600 BUF_CHARS_MODIFF (b) = 1;
601 BUF_OVERLAY_MODIFF (b) = 1;
602 BUF_SAVE_MODIFF (b) = 1;
603 BUF_COMPACT (b) = 1;
604 set_buffer_intervals (b, NULL);
605 BUF_UNCHANGED_MODIFIED (b) = 1;
606 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1;
607 BUF_END_UNCHANGED (b) = 0;
608 BUF_BEG_UNCHANGED (b) = 0;
609 *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0;
610 b->text->inhibit_shrinking = false;
611 b->text->redisplay = false;
612
613 b->newline_cache = 0;
614 b->width_run_cache = 0;
615 b->bidi_paragraph_cache = 0;
616 bset_width_table (b, Qnil);
617 b->prevent_redisplay_optimizations_p = 1;
618
619
620
621 bset_pt_marker (b, Qnil);
622 bset_begv_marker (b, Qnil);
623 bset_zv_marker (b, Qnil);
624
625 name = Fcopy_sequence (buffer_or_name);
626 set_string_intervals (name, NULL);
627 bset_name (b, name);
628
629 b->inhibit_buffer_hooks = !NILP (inhibit_buffer_hooks);
630 bset_undo_list (b, SREF (name, 0) != ' ' ? Qnil : Qt);
631
632 reset_buffer (b);
633 reset_buffer_local_variables (b, 1);
634
635 bset_mark (b, Fmake_marker ());
636 BUF_MARKERS (b) = NULL;
637
638
639 XSETBUFFER (buffer, b);
640 Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buffer)));
641
642 run_buffer_list_update_hook (b);
643
644 return buffer;
645 }
646
647 static void
648 add_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov,
649 ptrdiff_t begin, ptrdiff_t end)
650 {
651 eassert (! ov->buffer);
652 if (! b->overlays)
653 b->overlays = itree_create ();
654 ov->buffer = b;
655 itree_insert (b->overlays, ov->interval, begin, end);
656 }
657
658
659
660 static void
661 copy_overlays (struct buffer *from, struct buffer *to)
662 {
663 eassert (to && ! to->overlays);
664 struct itree_node *node;
665
666 ITREE_FOREACH (node, from->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
667 {
668 Lisp_Object ov = node->data;
669 Lisp_Object copy = build_overlay (node->front_advance,
670 node->rear_advance,
671 Fcopy_sequence (OVERLAY_PLIST (ov)));
672 add_buffer_overlay (to, XOVERLAY (copy), node->begin, node->end);
673 }
674 }
675
676 bool
677 valid_per_buffer_idx (int idx)
678 {
679 return 0 <= idx && idx < last_per_buffer_idx;
680 }
681
682
683
684
685
686
687
688
689 static void
690 clone_per_buffer_values (struct buffer *from, struct buffer *to)
691 {
692 int offset;
693
694 FOR_EACH_PER_BUFFER_OBJECT_AT (offset)
695 {
696 Lisp_Object obj;
697
698
699 if (offset == PER_BUFFER_VAR_OFFSET (name))
700 continue;
701
702 obj = per_buffer_value (from, offset);
703 if (MARKERP (obj) && XMARKER (obj)->buffer == from)
704 {
705 struct Lisp_Marker *m = XMARKER (obj);
706
707 obj = build_marker (to, m->charpos, m->bytepos);
708 XMARKER (obj)->insertion_type = m->insertion_type;
709 }
710
711 set_per_buffer_value (to, offset, obj);
712 }
713
714 memcpy (to->local_flags, from->local_flags, sizeof to->local_flags);
715
716 copy_overlays (from, to);
717
718
719
720 bset_local_var_alist (to, buffer_lisp_local_variables (from, 1));
721 }
722
723
724
725
726
727 static void
728 record_buffer_markers (struct buffer *b)
729 {
730 if (! NILP (BVAR (b, pt_marker)))
731 {
732 Lisp_Object buffer;
733
734 eassert (!NILP (BVAR (b, begv_marker)));
735 eassert (!NILP (BVAR (b, zv_marker)));
736
737 XSETBUFFER (buffer, b);
738 set_marker_both (BVAR (b, pt_marker), buffer, b->pt, b->pt_byte);
739 set_marker_both (BVAR (b, begv_marker), buffer, b->begv, b->begv_byte);
740 set_marker_both (BVAR (b, zv_marker), buffer, b->zv, b->zv_byte);
741 }
742 }
743
744
745
746
747
748 static void
749 fetch_buffer_markers (struct buffer *b)
750 {
751 if (! NILP (BVAR (b, pt_marker)))
752 {
753 Lisp_Object m;
754
755 eassert (!NILP (BVAR (b, begv_marker)));
756 eassert (!NILP (BVAR (b, zv_marker)));
757
758 m = BVAR (b, pt_marker);
759 SET_BUF_PT_BOTH (b, marker_position (m), marker_byte_position (m));
760
761 m = BVAR (b, begv_marker);
762 SET_BUF_BEGV_BOTH (b, marker_position (m), marker_byte_position (m));
763
764 m = BVAR (b, zv_marker);
765 SET_BUF_ZV_BOTH (b, marker_position (m), marker_byte_position (m));
766 }
767 }
768
769
770 DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, Smake_indirect_buffer,
771 2, 4,
772 "bMake indirect buffer (to buffer): \nBName of indirect buffer: ",
773 doc:
774
775
776
777
778
779
780
781
782
783
784 )
785 (Lisp_Object base_buffer, Lisp_Object name, Lisp_Object clone,
786 Lisp_Object inhibit_buffer_hooks)
787 {
788 Lisp_Object buf, tem;
789 struct buffer *b;
790
791 CHECK_STRING (name);
792 buf = Fget_buffer (name);
793 if (!NILP (buf))
794 error ("Buffer name `%s' is in use", SDATA (name));
795
796 tem = base_buffer;
797 base_buffer = Fget_buffer (base_buffer);
798 if (NILP (base_buffer))
799 error ("No such buffer: `%s'", SDATA (tem));
800 if (!BUFFER_LIVE_P (XBUFFER (base_buffer)))
801 error ("Base buffer has been killed");
802
803 if (SCHARS (name) == 0)
804 error ("Empty string for buffer name is not allowed");
805
806 b = allocate_buffer ();
807
808
809
810 b->base_buffer = (XBUFFER (base_buffer)->base_buffer
811 ? XBUFFER (base_buffer)->base_buffer
812 : XBUFFER (base_buffer));
813
814
815 b->text = b->base_buffer->text;
816
817 b->indirections = -1;
818
819 b->base_buffer->indirections++;
820
821 b->window_count = -1;
822
823 memset (&b->local_flags, 0, sizeof (b->local_flags));
824
825 b->pt = b->base_buffer->pt;
826 b->begv = b->base_buffer->begv;
827 b->zv = b->base_buffer->zv;
828 b->pt_byte = b->base_buffer->pt_byte;
829 b->begv_byte = b->base_buffer->begv_byte;
830 b->zv_byte = b->base_buffer->zv_byte;
831 b->inhibit_buffer_hooks = !NILP (inhibit_buffer_hooks);
832
833 b->newline_cache = 0;
834 b->width_run_cache = 0;
835 b->bidi_paragraph_cache = 0;
836 bset_width_table (b, Qnil);
837
838 name = Fcopy_sequence (name);
839 set_string_intervals (name, NULL);
840 bset_name (b, name);
841
842
843 bset_undo_list (b, BVAR (b->base_buffer, undo_list));
844
845 reset_buffer (b);
846 reset_buffer_local_variables (b, 1);
847
848
849 XSETBUFFER (buf, b);
850 Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buf)));
851
852 bset_mark (b, Fmake_marker ());
853
854
855 bset_enable_multibyte_characters
856 (b, BVAR (b->base_buffer, enable_multibyte_characters));
857
858
859 if (NILP (BVAR (b->base_buffer, pt_marker)))
860 {
861 eassert (NILP (BVAR (b->base_buffer, begv_marker)));
862 eassert (NILP (BVAR (b->base_buffer, zv_marker)));
863
864 bset_pt_marker (b->base_buffer,
865 build_marker (b->base_buffer, b->base_buffer->pt,
866 b->base_buffer->pt_byte));
867
868 bset_begv_marker (b->base_buffer,
869 build_marker (b->base_buffer, b->base_buffer->begv,
870 b->base_buffer->begv_byte));
871
872 bset_zv_marker (b->base_buffer,
873 build_marker (b->base_buffer, b->base_buffer->zv,
874 b->base_buffer->zv_byte));
875
876 XMARKER (BVAR (b->base_buffer, zv_marker))->insertion_type = 1;
877 }
878
879 if (NILP (clone))
880 {
881
882 bset_pt_marker (b, build_marker (b, b->pt, b->pt_byte));
883 bset_begv_marker (b, build_marker (b, b->begv, b->begv_byte));
884 bset_zv_marker (b, build_marker (b, b->zv, b->zv_byte));
885 XMARKER (BVAR (b, zv_marker))->insertion_type = 1;
886 }
887 else
888 {
889 struct buffer *old_b = current_buffer;
890
891 clone_per_buffer_values (b->base_buffer, b);
892 bset_filename (b, Qnil);
893 bset_file_truename (b, Qnil);
894 bset_display_count (b, make_fixnum (0));
895 bset_backed_up (b, Qnil);
896 bset_local_minor_modes (b, Qnil);
897 bset_auto_save_file_name (b, Qnil);
898 set_buffer_internal_1 (b);
899 Fset (intern ("buffer-save-without-query"), Qnil);
900 Fset (intern ("buffer-file-number"), Qnil);
901 if (!NILP (Flocal_variable_p (Qbuffer_stale_function, base_buffer)))
902 Fkill_local_variable (Qbuffer_stale_function);
903
904
905
906 run_hook (Qclone_indirect_buffer_hook);
907 set_buffer_internal_1 (old_b);
908 }
909
910 run_buffer_list_update_hook (b);
911
912 return buf;
913 }
914
915 static void
916 remove_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov)
917 {
918 eassert (b->overlays);
919 eassert (ov->buffer == b);
920 itree_remove (ov->buffer->overlays, ov->interval);
921 ov->buffer = NULL;
922 }
923
924
925
926 static void
927 drop_overlay (struct Lisp_Overlay *ov)
928 {
929 if (! ov->buffer)
930 return;
931
932 modify_overlay (ov->buffer, overlay_start (ov), overlay_end (ov));
933 remove_buffer_overlay (ov->buffer, ov);
934 }
935
936
937
938 void
939 delete_all_overlays (struct buffer *b)
940 {
941 struct itree_node *node;
942
943 if (! b->overlays)
944 return;
945
946
947
948
949 ITREE_FOREACH (node, b->overlays, PTRDIFF_MIN, PTRDIFF_MAX, POST_ORDER)
950 {
951 modify_overlay (b, node->begin, node->end);
952 XOVERLAY (node->data)->buffer = NULL;
953 node->parent = NULL;
954 node->left = NULL;
955 node->right = NULL;
956 }
957 itree_clear (b->overlays);
958 }
959
960 static void
961 free_buffer_overlays (struct buffer *b)
962 {
963
964 if (b->overlays)
965 {
966 itree_destroy (b->overlays);
967 b->overlays = NULL;
968 }
969 }
970
971
972
973
974
975
976
977
978 static void
979 set_overlays_multibyte (bool multibyte)
980 {
981 if (! current_buffer->overlays || Z == Z_BYTE)
982 return;
983
984 struct itree_node **nodes = NULL;
985 struct itree_tree *tree = current_buffer->overlays;
986 const intmax_t size = itree_size (tree);
987
988
989
990
991 USE_SAFE_ALLOCA;
992 SAFE_NALLOCA (nodes, 1, size);
993 {
994 struct itree_node *node, **cursor = nodes;
995 ITREE_FOREACH (node, tree, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
996 *(cursor++) = node;
997 }
998
999 for (int i = 0; i < size; ++i, ++nodes)
1000 {
1001 struct itree_node * const node = *nodes;
1002
1003 if (multibyte)
1004 {
1005 ptrdiff_t begin = itree_node_begin (tree, node);
1006 ptrdiff_t end = itree_node_end (tree, node);
1007
1008
1009
1010 while (begin < Z_BYTE
1011 && !CHAR_HEAD_P (FETCH_BYTE (begin)))
1012 begin++;
1013 while (end < Z_BYTE
1014 && !CHAR_HEAD_P (FETCH_BYTE (end)))
1015 end++;
1016 itree_node_set_region (tree, node, BYTE_TO_CHAR (begin),
1017 BYTE_TO_CHAR (end));
1018 }
1019 else
1020 {
1021 itree_node_set_region (tree, node, CHAR_TO_BYTE (node->begin),
1022 CHAR_TO_BYTE (node->end));
1023 }
1024 }
1025 SAFE_FREE ();
1026 }
1027
1028
1029
1030
1031
1032
1033
1034
1035 void
1036 reset_buffer (register struct buffer *b)
1037 {
1038 bset_filename (b, Qnil);
1039 bset_file_truename (b, Qnil);
1040 bset_directory (b, current_buffer ? BVAR (current_buffer, directory) : Qnil);
1041 b->modtime = make_timespec (0, UNKNOWN_MODTIME_NSECS);
1042 b->modtime_size = -1;
1043 XSETFASTINT (BVAR (b, save_length), 0);
1044 b->last_window_start = 1;
1045
1046 b->clip_changed = 0;
1047 b->prevent_redisplay_optimizations_p = 1;
1048 b->long_line_optimizations_p = 0;
1049 bset_backed_up (b, Qnil);
1050 bset_local_minor_modes (b, Qnil);
1051 BUF_AUTOSAVE_MODIFF (b) = 0;
1052 b->auto_save_failure_time = 0;
1053 bset_auto_save_file_name (b, Qnil);
1054 bset_read_only (b, Qnil);
1055 b->overlays = NULL;
1056 bset_mark_active (b, Qnil);
1057 bset_point_before_scroll (b, Qnil);
1058 bset_file_format (b, Qnil);
1059 bset_auto_save_file_format (b, Qt);
1060 bset_last_selected_window (b, Qnil);
1061 bset_display_count (b, make_fixnum (0));
1062 bset_display_time (b, Qnil);
1063 bset_enable_multibyte_characters
1064 (b, BVAR (&buffer_defaults, enable_multibyte_characters));
1065 bset_cursor_type (b, BVAR (&buffer_defaults, cursor_type));
1066 bset_extra_line_spacing (b, BVAR (&buffer_defaults, extra_line_spacing));
1067 #ifdef HAVE_TREE_SITTER
1068 bset_ts_parser_list (b, Qnil);
1069 #endif
1070
1071 b->display_error_modiff = 0;
1072 }
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082 static void
1083 reset_buffer_local_variables (struct buffer *b, bool permanent_too)
1084 {
1085 int offset, i;
1086
1087
1088
1089
1090
1091 bset_major_mode (b, Qfundamental_mode);
1092 bset_keymap (b, Qnil);
1093 bset_mode_name (b, QSFundamental);
1094
1095
1096
1097 if (! (CHAR_TABLE_P (XCHAR_TABLE (Vascii_downcase_table)->extras[0])
1098 && CHAR_TABLE_P (XCHAR_TABLE (Vascii_downcase_table)->extras[1])
1099 && CHAR_TABLE_P (XCHAR_TABLE (Vascii_downcase_table)->extras[2])))
1100 Fset_standard_case_table (Vascii_downcase_table);
1101
1102 bset_downcase_table (b, Vascii_downcase_table);
1103 bset_upcase_table (b, XCHAR_TABLE (Vascii_downcase_table)->extras[0]);
1104 bset_case_canon_table (b, XCHAR_TABLE (Vascii_downcase_table)->extras[1]);
1105 bset_case_eqv_table (b, XCHAR_TABLE (Vascii_downcase_table)->extras[2]);
1106 bset_invisibility_spec (b, Qt);
1107
1108
1109 if (permanent_too)
1110 bset_local_var_alist (b, Qnil);
1111 else
1112 {
1113 Lisp_Object tmp, last = Qnil;
1114 Lisp_Object buffer;
1115 XSETBUFFER (buffer, b);
1116
1117 for (tmp = BVAR (b, local_var_alist); CONSP (tmp); tmp = XCDR (tmp))
1118 {
1119 Lisp_Object local_var = XCAR (XCAR (tmp));
1120 Lisp_Object prop = Fget (local_var, Qpermanent_local);
1121 Lisp_Object sym = local_var;
1122
1123
1124 if (XSYMBOL (local_var)->u.s.trapped_write == SYMBOL_TRAPPED_WRITE)
1125 notify_variable_watchers (local_var, Qnil,
1126 Qmakunbound, Fcurrent_buffer ());
1127
1128 eassert (XSYMBOL (sym)->u.s.redirect == SYMBOL_LOCALIZED);
1129
1130
1131 if (BASE_EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
1132 {
1133
1134
1135 swap_in_global_binding (XSYMBOL (sym));
1136 }
1137
1138 if (!NILP (prop))
1139 {
1140
1141 last = tmp;
1142 if (EQ (prop, Qpermanent_local_hook))
1143 {
1144
1145
1146 Lisp_Object list, newlist;
1147 list = XCDR (XCAR (tmp));
1148 if (!CONSP (list))
1149 newlist = list;
1150 else
1151 for (newlist = Qnil; CONSP (list); list = XCDR (list))
1152 {
1153 Lisp_Object elt = XCAR (list);
1154
1155
1156
1157 if (EQ (elt, Qt)
1158 || (SYMBOLP (elt)
1159 && !NILP (Fget (elt, Qpermanent_local_hook))))
1160 newlist = Fcons (elt, newlist);
1161 }
1162 newlist = Fnreverse (newlist);
1163 if (XSYMBOL (local_var)->u.s.trapped_write
1164 == SYMBOL_TRAPPED_WRITE)
1165 notify_variable_watchers (local_var, newlist,
1166 Qmakunbound, Fcurrent_buffer ());
1167 XSETCDR (XCAR (tmp), newlist);
1168 continue;
1169 }
1170 }
1171
1172 else if (NILP (last))
1173 bset_local_var_alist (b, XCDR (tmp));
1174 else
1175 XSETCDR (last, XCDR (tmp));
1176 }
1177 }
1178
1179 for (i = 0; i < last_per_buffer_idx; ++i)
1180 if (permanent_too || buffer_permanent_local_flags[i] == 0)
1181 SET_PER_BUFFER_VALUE_P (b, i, 0);
1182
1183
1184 FOR_EACH_PER_BUFFER_OBJECT_AT (offset)
1185 {
1186 int idx = PER_BUFFER_IDX (offset);
1187 if ((idx > 0
1188 && (permanent_too
1189 || buffer_permanent_local_flags[idx] == 0)))
1190 set_per_buffer_value (b, offset, per_buffer_default (offset));
1191 }
1192 }
1193
1194
1195
1196
1197
1198 DEFUN ("generate-new-buffer-name", Fgenerate_new_buffer_name,
1199 Sgenerate_new_buffer_name, 1, 2, 0,
1200 doc:
1201
1202
1203
1204
1205
1206
1207
1208
1209 )
1210 (Lisp_Object name, Lisp_Object ignore)
1211 {
1212 Lisp_Object genbase;
1213
1214 CHECK_STRING (name);
1215
1216 if ((!NILP (ignore) && !NILP (Fstring_equal (name, ignore)))
1217 || NILP (Fget_buffer (name)))
1218 return name;
1219
1220 if (SREF (name, 0) != ' ')
1221 genbase = name;
1222 else
1223 {
1224 enum { bug_52711 = true };
1225 char number[bug_52711 ? INT_BUFSIZE_BOUND (int) + 1 : sizeof "-999999"];
1226 EMACS_INT r = get_random ();
1227 eassume (0 <= r);
1228 int i = r % 1000000;
1229 AUTO_STRING_WITH_LEN (lnumber, number, sprintf (number, "-%d", i));
1230 genbase = concat2 (name, lnumber);
1231 if (NILP (Fget_buffer (genbase)))
1232 return genbase;
1233 }
1234
1235 for (ptrdiff_t count = 2; ; count++)
1236 {
1237 char number[INT_BUFSIZE_BOUND (ptrdiff_t) + sizeof "<>"];
1238 AUTO_STRING_WITH_LEN (lnumber, number,
1239 sprintf (number, "<%"pD"d>", count));
1240 Lisp_Object gentemp = concat2 (genbase, lnumber);
1241 if (!NILP (Fstring_equal (gentemp, ignore))
1242 || NILP (Fget_buffer (gentemp)))
1243 return gentemp;
1244 }
1245 }
1246
1247
1248 DEFUN ("buffer-name", Fbuffer_name, Sbuffer_name, 0, 1, 0,
1249 doc:
1250
1251 )
1252 (register Lisp_Object buffer)
1253 {
1254 return BVAR (decode_buffer (buffer), name);
1255 }
1256
1257 DEFUN ("buffer-file-name", Fbuffer_file_name, Sbuffer_file_name, 0, 1, 0,
1258 doc:
1259 )
1260 (register Lisp_Object buffer)
1261 {
1262 return BVAR (decode_buffer (buffer), filename);
1263 }
1264
1265 DEFUN ("buffer-base-buffer", Fbuffer_base_buffer, Sbuffer_base_buffer,
1266 0, 1, 0,
1267 doc:
1268
1269 )
1270 (register Lisp_Object buffer)
1271 {
1272 struct buffer *base = decode_buffer (buffer)->base_buffer;
1273 return base ? (XSETBUFFER (buffer, base), buffer) : Qnil;
1274 }
1275
1276 DEFUN ("buffer-local-value", Fbuffer_local_value,
1277 Sbuffer_local_value, 2, 2, 0,
1278 doc:
1279
1280 )
1281 (register Lisp_Object variable, register Lisp_Object buffer)
1282 {
1283 register Lisp_Object result = buffer_local_value (variable, buffer);
1284
1285 if (BASE_EQ (result, Qunbound))
1286 xsignal1 (Qvoid_variable, variable);
1287
1288 return result;
1289 }
1290
1291
1292
1293
1294
1295 Lisp_Object
1296 buffer_local_value (Lisp_Object variable, Lisp_Object buffer)
1297 {
1298 register struct buffer *buf;
1299 register Lisp_Object result;
1300 struct Lisp_Symbol *sym;
1301
1302 CHECK_SYMBOL (variable);
1303 CHECK_BUFFER (buffer);
1304 buf = XBUFFER (buffer);
1305 sym = XSYMBOL (variable);
1306
1307 start:
1308 switch (sym->u.s.redirect)
1309 {
1310 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1311 case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break;
1312 case SYMBOL_LOCALIZED:
1313 {
1314 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1315 XSETSYMBOL (variable, sym);
1316 result = assq_no_quit (variable, BVAR (buf, local_var_alist));
1317 if (!NILP (result))
1318 {
1319 if (blv->fwd.fwdptr)
1320 {
1321 Lisp_Object current_alist_element = blv->valcell;
1322
1323
1324
1325
1326
1327
1328 XSETCDR (current_alist_element,
1329 do_symval_forwarding (blv->fwd));
1330 }
1331
1332 result = XCDR (result);
1333 }
1334 else
1335 result = Fdefault_value (variable);
1336 break;
1337 }
1338 case SYMBOL_FORWARDED:
1339 {
1340 lispfwd fwd = SYMBOL_FWD (sym);
1341 if (BUFFER_OBJFWDP (fwd))
1342 result = per_buffer_value (buf, XBUFFER_OBJFWD (fwd)->offset);
1343 else
1344 result = Fdefault_value (variable);
1345 break;
1346 }
1347 default: emacs_abort ();
1348 }
1349
1350 return result;
1351 }
1352
1353
1354
1355
1356
1357
1358
1359 static Lisp_Object
1360 buffer_lisp_local_variables (struct buffer *buf, bool clone)
1361 {
1362 Lisp_Object result = Qnil;
1363 Lisp_Object tail;
1364 for (tail = BVAR (buf, local_var_alist); CONSP (tail); tail = XCDR (tail))
1365 {
1366 Lisp_Object val, elt;
1367
1368 elt = XCAR (tail);
1369
1370
1371
1372
1373
1374
1375 val = find_symbol_value (XCAR (elt));
1376
1377 if (buf != current_buffer)
1378 val = XCDR (elt);
1379
1380 result = Fcons (!clone && BASE_EQ (val, Qunbound)
1381 ? XCAR (elt)
1382 : Fcons (XCAR (elt), val),
1383 result);
1384 }
1385
1386 return result;
1387 }
1388
1389
1390
1391
1392
1393
1394 static Lisp_Object
1395 buffer_local_variables_1 (struct buffer *buf, int offset, Lisp_Object sym)
1396 {
1397 int idx = PER_BUFFER_IDX (offset);
1398 if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
1399 && SYMBOLP (PER_BUFFER_SYMBOL (offset)))
1400 {
1401 sym = NILP (sym) ? PER_BUFFER_SYMBOL (offset) : sym;
1402 Lisp_Object val = per_buffer_value (buf, offset);
1403 return BASE_EQ (val, Qunbound) ? sym : Fcons (sym, val);
1404 }
1405 return Qnil;
1406 }
1407
1408 DEFUN ("buffer-local-variables", Fbuffer_local_variables,
1409 Sbuffer_local_variables, 0, 1, 0,
1410 doc:
1411
1412
1413
1414 )
1415 (Lisp_Object buffer)
1416 {
1417 struct buffer *buf = decode_buffer (buffer);
1418 Lisp_Object result = buffer_lisp_local_variables (buf, 0);
1419 Lisp_Object tem;
1420
1421
1422 {
1423 int offset;
1424
1425 FOR_EACH_PER_BUFFER_OBJECT_AT (offset)
1426 {
1427 tem = buffer_local_variables_1 (buf, offset, Qnil);
1428 if (!NILP (tem))
1429 result = Fcons (tem, result);
1430 }
1431 }
1432
1433 tem = buffer_local_variables_1 (buf, PER_BUFFER_VAR_OFFSET (undo_list),
1434 intern ("buffer-undo-list"));
1435 if (!NILP (tem))
1436 result = Fcons (tem, result);
1437
1438 return result;
1439 }
1440
1441 DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p,
1442 0, 1, 0,
1443 doc:
1444
1445
1446
1447 )
1448 (Lisp_Object buffer)
1449 {
1450 struct buffer *buf = decode_buffer (buffer);
1451 if (BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf))
1452 {
1453 if (BUF_AUTOSAVE_MODIFF (buf) == BUF_MODIFF (buf))
1454 return Qautosaved;
1455 else
1456 return Qt;
1457 }
1458 else
1459 return Qnil;
1460 }
1461
1462 DEFUN ("force-mode-line-update", Fforce_mode_line_update,
1463 Sforce_mode_line_update, 0, 1, 0,
1464 doc:
1465
1466
1467 )
1468 (Lisp_Object all)
1469 {
1470 if (!NILP (all))
1471 {
1472 update_mode_lines = 10;
1473
1474 current_buffer->prevent_redisplay_optimizations_p = true;
1475 }
1476 else if (buffer_window_count (current_buffer))
1477 {
1478 bset_update_mode_line (current_buffer);
1479 current_buffer->prevent_redisplay_optimizations_p = true;
1480 }
1481 return all;
1482 }
1483
1484 DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p,
1485 1, 1, 0,
1486 doc:
1487
1488
1489
1490
1491
1492 )
1493 (Lisp_Object flag)
1494 {
1495 Frestore_buffer_modified_p (flag);
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508 return Fforce_mode_line_update (Qnil);
1509 }
1510
1511 DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p,
1512 Srestore_buffer_modified_p, 1, 1, 0,
1513 doc:
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523 )
1524 (Lisp_Object flag)
1525 {
1526
1527
1528
1529
1530 struct buffer *b = current_buffer->base_buffer
1531 ? current_buffer->base_buffer
1532 : current_buffer;
1533
1534 if (!inhibit_modification_hooks)
1535 {
1536 Lisp_Object fn = BVAR (b, file_truename);
1537
1538 if (!NILP (fn) && ! NILP (BVAR (b, filename)))
1539 {
1540 bool already = SAVE_MODIFF < MODIFF;
1541 if (!already && !NILP (flag))
1542 Flock_file (fn);
1543 else if (already && NILP (flag))
1544 Funlock_file (fn);
1545 }
1546 }
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558 if (NILP (flag))
1559
1560 SAVE_MODIFF = MODIFF;
1561 else
1562 {
1563
1564
1565
1566 if (SAVE_MODIFF >= MODIFF)
1567 SAVE_MODIFF = modiff_incr (&MODIFF, 1);
1568 if (EQ (flag, Qautosaved))
1569 BUF_AUTOSAVE_MODIFF (b) = MODIFF;
1570 }
1571 return flag;
1572 }
1573
1574 DEFUN ("buffer-modified-tick", Fbuffer_modified_tick, Sbuffer_modified_tick,
1575 0, 1, 0,
1576 doc:
1577
1578
1579 )
1580 (Lisp_Object buffer)
1581 {
1582 return modiff_to_integer (BUF_MODIFF (decode_buffer (buffer)));
1583 }
1584
1585 DEFUN ("internal--set-buffer-modified-tick",
1586 Finternal__set_buffer_modified_tick, Sinternal__set_buffer_modified_tick,
1587 1, 2, 0,
1588 doc:
1589 )
1590 (Lisp_Object tick, Lisp_Object buffer)
1591 {
1592 CHECK_FIXNUM (tick);
1593 BUF_MODIFF (decode_buffer (buffer)) = XFIXNUM (tick);
1594 return Qnil;
1595 }
1596
1597 DEFUN ("buffer-chars-modified-tick", Fbuffer_chars_modified_tick,
1598 Sbuffer_chars_modified_tick, 0, 1, 0,
1599 doc:
1600
1601
1602
1603
1604
1605
1606 )
1607 (Lisp_Object buffer)
1608 {
1609 return modiff_to_integer (BUF_CHARS_MODIFF (decode_buffer (buffer)));
1610 }
1611
1612 DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2,
1613 "(list (read-string \"Rename buffer (to new name): \" \
1614 nil 'buffer-name-history (buffer-name (current-buffer))) \
1615 current-prefix-arg)",
1616 doc:
1617
1618
1619
1620
1621
1622
1623 )
1624 (register Lisp_Object newname, Lisp_Object unique)
1625 {
1626 register Lisp_Object tem, buf;
1627 Lisp_Object requestedname = newname;
1628
1629 CHECK_STRING (newname);
1630
1631 if (SCHARS (newname) == 0)
1632 error ("Empty string is invalid as a buffer name");
1633
1634 tem = Fget_buffer (newname);
1635 if (!NILP (tem))
1636 {
1637
1638
1639
1640
1641 if (NILP (unique) && XBUFFER (tem) == current_buffer)
1642 return BVAR (current_buffer, name);
1643 if (!NILP (unique))
1644 newname = Fgenerate_new_buffer_name (newname,
1645 BVAR (current_buffer, name));
1646 else
1647 error ("Buffer name `%s' is in use", SDATA (newname));
1648 }
1649
1650 bset_name (current_buffer, newname);
1651
1652
1653
1654 bset_update_mode_line (current_buffer);
1655
1656 XSETBUFFER (buf, current_buffer);
1657 Fsetcar (Frassq (buf, Vbuffer_alist), newname);
1658 if (NILP (BVAR (current_buffer, filename))
1659 && !NILP (BVAR (current_buffer, auto_save_file_name)))
1660 call0 (intern ("rename-auto-save-file"));
1661
1662 run_buffer_list_update_hook (current_buffer);
1663
1664 call2 (intern ("uniquify--rename-buffer-advice"),
1665 requestedname, unique);
1666
1667
1668 return BVAR (current_buffer, name);
1669 }
1670
1671
1672
1673 static bool
1674 candidate_buffer (Lisp_Object b, Lisp_Object buffer)
1675 {
1676 return (BUFFERP (b) && !BASE_EQ (b, buffer)
1677 && BUFFER_LIVE_P (XBUFFER (b))
1678 && !BUFFER_HIDDEN_P (XBUFFER (b)));
1679 }
1680
1681 DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0,
1682 doc:
1683
1684
1685
1686
1687
1688
1689
1690
1691 )
1692 (Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
1693 {
1694 struct frame *f = decode_live_frame (frame);
1695 Lisp_Object tail = f->buffer_list, pred = f->buffer_predicate;
1696 Lisp_Object buf, notsogood = Qnil;
1697
1698
1699 for (; CONSP (tail); tail = XCDR (tail))
1700 {
1701 buf = XCAR (tail);
1702 if (candidate_buffer (buf, buffer)
1703
1704
1705 && (NILP (pred) || !NILP (call1 (pred, buf))))
1706 {
1707 if (!NILP (visible_ok)
1708 || NILP (Fget_buffer_window (buf, Qvisible)))
1709 return buf;
1710 else if (NILP (notsogood))
1711 notsogood = buf;
1712 }
1713 }
1714
1715
1716 FOR_EACH_LIVE_BUFFER (tail, buf)
1717 {
1718 if (candidate_buffer (buf, buffer)
1719
1720
1721 && (NILP (pred) || !NILP (call1 (pred, buf))))
1722 {
1723 if (!NILP (visible_ok)
1724 || NILP (Fget_buffer_window (buf, Qvisible)))
1725 return buf;
1726 else if (NILP (notsogood))
1727 notsogood = buf;
1728 }
1729 }
1730
1731 if (!NILP (notsogood))
1732 return notsogood;
1733 else
1734 return safe_call (1, Qget_scratch_buffer_create);
1735 }
1736
1737
1738
1739
1740
1741 Lisp_Object
1742 other_buffer_safely (Lisp_Object buffer)
1743 {
1744 Lisp_Object tail, buf;
1745
1746 FOR_EACH_LIVE_BUFFER (tail, buf)
1747 if (candidate_buffer (buf, buffer))
1748 return buf;
1749
1750
1751
1752
1753
1754
1755 buf = safe_call (1, Qget_scratch_buffer_create);
1756 if (NILP (buf))
1757 {
1758 AUTO_STRING (scratch, "*scratch*");
1759 buf = Fget_buffer_create (scratch, Qnil);
1760 Fset_buffer_major_mode (buf);
1761 }
1762 return buf;
1763 }
1764
1765 DEFUN ("buffer-enable-undo", Fbuffer_enable_undo, Sbuffer_enable_undo,
1766 0, 1, "",
1767 doc:
1768 )
1769 (register Lisp_Object buffer)
1770 {
1771 Lisp_Object real_buffer;
1772
1773 if (NILP (buffer))
1774 XSETBUFFER (real_buffer, current_buffer);
1775 else
1776 {
1777 real_buffer = Fget_buffer (buffer);
1778 if (NILP (real_buffer))
1779 nsberror (buffer);
1780 }
1781
1782 if (EQ (BVAR (XBUFFER (real_buffer), undo_list), Qt))
1783 bset_undo_list (XBUFFER (real_buffer), Qnil);
1784
1785 return Qnil;
1786 }
1787
1788
1789
1790 void
1791 compact_buffer (struct buffer *buffer)
1792 {
1793 BUFFER_CHECK_INDIRECTION (buffer);
1794
1795
1796
1797 if (BUFFER_LIVE_P (buffer)
1798 && (buffer->base_buffer == NULL)
1799 && (BUF_COMPACT (buffer) != BUF_MODIFF (buffer)))
1800 {
1801
1802
1803
1804
1805 if (!EQ (BVAR(buffer, undo_list), Qt))
1806 truncate_undo_list (buffer);
1807
1808
1809 if (!buffer->text->inhibit_shrinking)
1810 {
1811
1812
1813
1814 ptrdiff_t size = clip_to_bounds (GAP_BYTES_MIN,
1815 BUF_Z_BYTE (buffer) / 10,
1816 GAP_BYTES_DFL);
1817 if (BUF_GAP_SIZE (buffer) > size)
1818 make_gap_1 (buffer, -(BUF_GAP_SIZE (buffer) - size));
1819 }
1820 BUF_COMPACT (buffer) = BUF_MODIFF (buffer);
1821 }
1822 }
1823
1824 DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ",
1825 doc:
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841 )
1842 (Lisp_Object buffer_or_name)
1843 {
1844 Lisp_Object buffer;
1845 struct buffer *b;
1846 Lisp_Object tem;
1847 struct Lisp_Marker *m;
1848
1849 if (NILP (buffer_or_name))
1850 buffer = Fcurrent_buffer ();
1851 else
1852 buffer = Fget_buffer (buffer_or_name);
1853 if (NILP (buffer))
1854 nsberror (buffer_or_name);
1855
1856 b = XBUFFER (buffer);
1857
1858
1859 if (!BUFFER_LIVE_P (b))
1860 return Qnil;
1861
1862 if (thread_check_current_buffer (b))
1863 return Qnil;
1864
1865
1866 {
1867 specpdl_ref count = SPECPDL_INDEX ();
1868 bool modified;
1869
1870 record_unwind_protect_excursion ();
1871 set_buffer_internal (b);
1872
1873
1874
1875 if (!b->inhibit_buffer_hooks)
1876 {
1877 tem = CALLN (Frun_hook_with_args_until_failure,
1878 Qkill_buffer_query_functions);
1879 if (NILP (tem))
1880 return unbind_to (count, Qnil);
1881 }
1882
1883
1884 modified = !NILP (BVAR (b, filename))
1885 && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
1886
1887
1888 if (INTERACTIVE && modified)
1889 {
1890
1891
1892 if (NILP (call1 (Qkill_buffer__possibly_save, buffer)))
1893 return unbind_to (count, Qnil);
1894
1895 modified = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
1896 }
1897
1898
1899 if (modified
1900 && kill_buffer_delete_auto_save_files
1901 && delete_auto_save_files
1902 && !NILP (Frecent_auto_save_p ())
1903 && STRINGP (BVAR (b, auto_save_file_name))
1904 && !NILP (Ffile_exists_p (BVAR (b, auto_save_file_name)))
1905
1906
1907 && NILP (Fstring_equal (BVAR (b, auto_save_file_name),
1908 BVAR (b, filename))))
1909 {
1910 tem = do_yes_or_no_p (build_string ("Delete auto-save file? "));
1911 if (!NILP (tem))
1912 call0 (intern ("delete-auto-save-file-if-necessary"));
1913 }
1914
1915
1916 if (!BUFFER_LIVE_P (b))
1917 return unbind_to (count, Qt);
1918
1919
1920 if (!b->inhibit_buffer_hooks)
1921 run_hook (Qkill_buffer_hook);
1922 unbind_to (count, Qnil);
1923 }
1924
1925
1926 if (!BUFFER_LIVE_P (b))
1927 return Qt;
1928
1929
1930
1931
1932
1933
1934 if (BASE_EQ (buffer, XWINDOW (minibuf_window)->contents))
1935 return Qnil;
1936
1937
1938
1939
1940
1941 if (!b->base_buffer && b->indirections > 0)
1942 {
1943 Lisp_Object tail, other;
1944
1945 FOR_EACH_LIVE_BUFFER (tail, other)
1946 if (XBUFFER (other)->base_buffer == b)
1947 Fkill_buffer (other);
1948
1949
1950 if (!BUFFER_LIVE_P (b))
1951 return Qt;
1952 }
1953
1954
1955
1956
1957
1958 replace_buffer_in_windows (buffer);
1959
1960
1961 if (!BUFFER_LIVE_P (b))
1962 return Qt;
1963
1964
1965
1966 if (b == current_buffer)
1967 {
1968 tem = Fother_buffer (buffer, Qnil, Qnil);
1969 Fset_buffer (tem);
1970 if (b == current_buffer)
1971 return Qnil;
1972 }
1973
1974
1975
1976 XSETBUFFER (tem, current_buffer);
1977 if (EQ (tem, XWINDOW (minibuf_window)->contents)
1978 && BASE_EQ (buffer, Fother_buffer (buffer, Qnil, Qnil)))
1979 return Qnil;
1980
1981
1982
1983
1984 unlock_buffer (b);
1985
1986 kill_buffer_processes (buffer);
1987 kill_buffer_xwidgets (buffer);
1988
1989
1990
1991 if (!BUFFER_LIVE_P (b))
1992 return Qt;
1993
1994
1995
1996 frames_discard_buffer (buffer);
1997
1998 clear_charpos_cache (b);
1999
2000 tem = Vinhibit_quit;
2001 Vinhibit_quit = Qt;
2002
2003
2004 bset_undo_list (b, Qnil);
2005
2006 Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
2007
2008 replace_buffer_in_windows_safely (buffer);
2009 Vinhibit_quit = tem;
2010
2011 if (b->base_buffer)
2012 {
2013 INTERVAL i;
2014
2015
2016
2017 struct Lisp_Marker **mp = &BUF_MARKERS (b);
2018 while ((m = *mp))
2019 {
2020 if (m->buffer == b)
2021 {
2022 m->buffer = NULL;
2023 *mp = m->next;
2024 }
2025 else
2026 mp = &m->next;
2027 }
2028
2029 i = buffer_intervals (b);
2030 if (i)
2031 {
2032 Lisp_Object owner;
2033 XSETBUFFER (owner, b->base_buffer);
2034 set_interval_object (i, owner);
2035 }
2036 }
2037 else
2038 {
2039
2040
2041 for (m = BUF_MARKERS (b); m; )
2042 {
2043 struct Lisp_Marker *next = m->next;
2044 m->buffer = 0;
2045 m->next = NULL;
2046 m = next;
2047 }
2048 BUF_MARKERS (b) = NULL;
2049 set_buffer_intervals (b, NULL);
2050
2051
2052 }
2053 delete_all_overlays (b);
2054 free_buffer_overlays (b);
2055
2056
2057
2058
2059
2060 reset_buffer_local_variables (b, 1);
2061
2062 bset_name (b, Qnil);
2063
2064 block_input ();
2065 if (b->base_buffer)
2066 {
2067
2068 eassert (b->indirections == -1);
2069 b->base_buffer->indirections--;
2070 eassert (b->base_buffer->indirections >= 0);
2071
2072 eassert (b->window_count == -1);
2073 }
2074 else
2075 {
2076
2077 eassert (b->window_count == 0);
2078
2079 free_buffer_text (b);
2080 }
2081
2082 if (b->newline_cache)
2083 {
2084 free_region_cache (b->newline_cache);
2085 b->newline_cache = 0;
2086 }
2087 if (b->width_run_cache)
2088 {
2089 free_region_cache (b->width_run_cache);
2090 b->width_run_cache = 0;
2091 }
2092 if (b->bidi_paragraph_cache)
2093 {
2094 free_region_cache (b->bidi_paragraph_cache);
2095 b->bidi_paragraph_cache = 0;
2096 }
2097 bset_width_table (b, Qnil);
2098 unblock_input ();
2099
2100 run_buffer_list_update_hook (b);
2101
2102 return Qt;
2103 }
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116 void
2117 record_buffer (Lisp_Object buffer)
2118 {
2119 Lisp_Object aelt, aelt_cons, tem;
2120 register struct frame *f = XFRAME (selected_frame);
2121
2122 CHECK_BUFFER (buffer);
2123
2124
2125
2126
2127 tem = Vinhibit_quit;
2128 Vinhibit_quit = Qt;
2129 aelt = Frassq (buffer, Vbuffer_alist);
2130 aelt_cons = Fmemq (aelt, Vbuffer_alist);
2131 Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
2132 XSETCDR (aelt_cons, Vbuffer_alist);
2133 Vbuffer_alist = aelt_cons;
2134 Vinhibit_quit = tem;
2135
2136
2137 fset_buffer_list (f, Fcons (buffer, Fdelq (buffer, f->buffer_list)));
2138 fset_buried_buffer_list (f, Fdelq (buffer, f->buried_buffer_list));
2139
2140 run_buffer_list_update_hook (XBUFFER (buffer));
2141 }
2142
2143
2144
2145
2146
2147
2148
2149
2150 DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal,
2151 1, 1, 0,
2152 doc: )
2153 (Lisp_Object buffer)
2154 {
2155 Lisp_Object aelt, aelt_cons, tem;
2156 register struct frame *f = XFRAME (selected_frame);
2157
2158 CHECK_BUFFER (buffer);
2159
2160
2161
2162
2163 tem = Vinhibit_quit;
2164 Vinhibit_quit = Qt;
2165 aelt = Frassq (buffer, Vbuffer_alist);
2166 aelt_cons = Fmemq (aelt, Vbuffer_alist);
2167 Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
2168 XSETCDR (aelt_cons, Qnil);
2169 Vbuffer_alist = nconc2 (Vbuffer_alist, aelt_cons);
2170 Vinhibit_quit = tem;
2171
2172
2173 fset_buffer_list (f, Fdelq (buffer, f->buffer_list));
2174 fset_buried_buffer_list
2175 (f, Fcons (buffer, Fdelq (buffer, f->buried_buffer_list)));
2176
2177 run_buffer_list_update_hook (XBUFFER (buffer));
2178
2179 return Qnil;
2180 }
2181
2182 DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0,
2183 doc:
2184
2185
2186
2187 )
2188 (Lisp_Object buffer)
2189 {
2190 Lisp_Object function;
2191
2192 CHECK_BUFFER (buffer);
2193
2194 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
2195 error ("Attempt to set major mode for a dead buffer");
2196
2197 if (strcmp (SSDATA (BVAR (XBUFFER (buffer), name)), "*scratch*") == 0)
2198 function = find_symbol_value (intern ("initial-major-mode"));
2199 else
2200 {
2201 function = BVAR (&buffer_defaults, major_mode);
2202 if (NILP (function)
2203 && NILP (Fget (BVAR (current_buffer, major_mode), Qmode_class)))
2204 function = BVAR (current_buffer, major_mode);
2205 }
2206
2207 if (NILP (function))
2208
2209
2210 return Qnil;
2211
2212 specpdl_ref count = SPECPDL_INDEX ();
2213
2214
2215
2216
2217 record_unwind_current_buffer ();
2218
2219 Fset_buffer (buffer);
2220 call0 (function);
2221
2222 return unbind_to (count, Qnil);
2223 }
2224
2225 DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
2226 doc: )
2227 (void)
2228 {
2229 register Lisp_Object buf;
2230 XSETBUFFER (buf, current_buffer);
2231 return buf;
2232 }
2233
2234
2235
2236
2237 void
2238 set_buffer_internal_1 (register struct buffer *b)
2239 {
2240 #ifdef USE_MMAP_FOR_BUFFERS
2241 if (b->text->beg == NULL)
2242 enlarge_buffer_text (b, 0);
2243 #endif
2244
2245 if (current_buffer == b)
2246 return;
2247
2248 set_buffer_internal_2 (b);
2249 }
2250
2251
2252
2253
2254 void set_buffer_internal_2 (register struct buffer *b)
2255 {
2256 register struct buffer *old_buf;
2257 register Lisp_Object tail;
2258
2259 BUFFER_CHECK_INDIRECTION (b);
2260
2261 old_buf = current_buffer;
2262 current_buffer = b;
2263 last_known_column_point = -1;
2264
2265 if (old_buf)
2266 {
2267
2268
2269 if (old_buf->base_buffer)
2270 bset_undo_list (old_buf->base_buffer, BVAR (old_buf, undo_list));
2271
2272
2273
2274 record_buffer_markers (old_buf);
2275 }
2276
2277
2278
2279 if (b->base_buffer)
2280 bset_undo_list (b, BVAR (b->base_buffer, undo_list));
2281
2282
2283
2284 fetch_buffer_markers (b);
2285
2286
2287
2288
2289 do
2290 {
2291 for (tail = BVAR (b, local_var_alist); CONSP (tail); tail = XCDR (tail))
2292 {
2293 Lisp_Object var = XCAR (XCAR (tail));
2294 struct Lisp_Symbol *sym = XSYMBOL (var);
2295 if (sym->u.s.redirect == SYMBOL_LOCALIZED
2296 && SYMBOL_BLV (sym)->fwd.fwdptr)
2297
2298
2299 Fsymbol_value (var);
2300 }
2301 }
2302
2303 while (b != old_buf && (b = old_buf, b));
2304 }
2305
2306
2307
2308
2309 void
2310 set_buffer_temp (struct buffer *b)
2311 {
2312 register struct buffer *old_buf;
2313
2314 if (current_buffer == b)
2315 return;
2316
2317 old_buf = current_buffer;
2318 current_buffer = b;
2319
2320
2321
2322 record_buffer_markers (old_buf);
2323
2324
2325
2326 fetch_buffer_markers (b);
2327 }
2328
2329 DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0,
2330 doc:
2331
2332
2333
2334
2335
2336 )
2337 (register Lisp_Object buffer_or_name)
2338 {
2339 register Lisp_Object buffer;
2340 buffer = Fget_buffer (buffer_or_name);
2341 if (NILP (buffer))
2342 nsberror (buffer_or_name);
2343 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
2344 error ("Selecting deleted buffer");
2345 set_buffer_internal (XBUFFER (buffer));
2346 return buffer;
2347 }
2348
2349 void
2350 restore_buffer (Lisp_Object buffer_or_name)
2351 {
2352 Fset_buffer (buffer_or_name);
2353 }
2354
2355
2356
2357 void
2358 set_buffer_if_live (Lisp_Object buffer)
2359 {
2360 if (BUFFER_LIVE_P (XBUFFER (buffer)))
2361 set_buffer_internal (XBUFFER (buffer));
2362 }
2363
2364 DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
2365 Sbarf_if_buffer_read_only, 0, 1, 0,
2366 doc:
2367
2368 )
2369 (Lisp_Object position)
2370 {
2371 if (NILP (position))
2372 XSETFASTINT (position, PT);
2373 else
2374 CHECK_FIXNUM (position);
2375
2376 if (!NILP (BVAR (current_buffer, read_only))
2377 && NILP (Vinhibit_read_only)
2378 && NILP (Fget_text_property (position, Qinhibit_read_only, Qnil)))
2379 xsignal1 (Qbuffer_read_only, Fcurrent_buffer ());
2380 return Qnil;
2381 }
2382
2383 DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*",
2384 doc:
2385
2386 )
2387 (void)
2388 {
2389 labeled_restrictions_remove_in_current_buffer ();
2390 Fwiden ();
2391
2392 del_range (BEG, Z);
2393
2394 current_buffer->last_window_start = 1;
2395
2396
2397
2398 XSETFASTINT (BVAR (current_buffer, save_length), 0);
2399 return Qnil;
2400 }
2401
2402 void
2403 validate_region (Lisp_Object *b, Lisp_Object *e)
2404 {
2405 EMACS_INT beg = fix_position (*b), end = fix_position (*e);
2406
2407 if (end < beg)
2408 {
2409 EMACS_INT tem = beg; beg = end; end = tem;
2410 }
2411
2412 if (! (BEGV <= beg && end <= ZV))
2413 args_out_of_range_3 (Fcurrent_buffer (), *b, *e);
2414
2415 *b = make_fixnum (beg);
2416 *e = make_fixnum (end);
2417 }
2418
2419
2420
2421
2422 ptrdiff_t
2423 advance_to_char_boundary (ptrdiff_t byte_pos)
2424 {
2425 int c;
2426
2427 if (byte_pos == BEG)
2428
2429 return BEG;
2430
2431 c = FETCH_BYTE (byte_pos);
2432 if (! CHAR_HEAD_P (c))
2433 {
2434
2435
2436 ptrdiff_t orig_byte_pos = byte_pos;
2437
2438 do
2439 {
2440 byte_pos--;
2441 c = FETCH_BYTE (byte_pos);
2442 }
2443 while (! CHAR_HEAD_P (c) && byte_pos > BEG);
2444 byte_pos += next_char_len (byte_pos);
2445 if (byte_pos < orig_byte_pos)
2446 byte_pos = orig_byte_pos;
2447
2448
2449
2450 }
2451
2452 return byte_pos;
2453 }
2454
2455 static void
2456 swap_buffer_overlays (struct buffer *buffer, struct buffer *other)
2457 {
2458 struct itree_node *node;
2459
2460 ITREE_FOREACH (node, buffer->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
2461 XOVERLAY (node->data)->buffer = other;
2462
2463 ITREE_FOREACH (node, other->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
2464 XOVERLAY (node->data)->buffer = buffer;
2465
2466
2467 void *tmp = buffer->overlays;
2468 buffer->overlays = other->overlays;
2469 other->overlays = tmp;
2470 }
2471
2472 DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
2473 1, 1, 0,
2474 doc:
2475
2476 )
2477 (Lisp_Object buffer)
2478 {
2479 struct buffer *other_buffer;
2480 CHECK_BUFFER (buffer);
2481 other_buffer = XBUFFER (buffer);
2482
2483 if (!BUFFER_LIVE_P (other_buffer))
2484 error ("Cannot swap a dead buffer's text");
2485
2486
2487
2488
2489
2490
2491
2492 if (other_buffer->base_buffer
2493 || current_buffer->base_buffer)
2494 error ("Cannot swap indirect buffers's text");
2495
2496 {
2497 Lisp_Object tail, other;
2498 FOR_EACH_LIVE_BUFFER (tail, other)
2499 if (XBUFFER (other)->base_buffer == other_buffer
2500 || XBUFFER (other)->base_buffer == current_buffer)
2501 error ("One of the buffers to swap has indirect buffers");
2502 }
2503
2504 #define swapfield(field, type) \
2505 do { \
2506 type tmp##field = other_buffer->field; \
2507 other_buffer->field = current_buffer->field; \
2508 current_buffer->field = tmp##field; \
2509 } while (0)
2510 #define swapfield_(field, type) \
2511 do { \
2512 type tmp##field = BVAR (other_buffer, field); \
2513 bset_##field (other_buffer, BVAR (current_buffer, field)); \
2514 bset_##field (current_buffer, tmp##field); \
2515 } while (0)
2516
2517 swapfield (own_text, struct buffer_text);
2518 eassert (current_buffer->text == ¤t_buffer->own_text);
2519 eassert (other_buffer->text == &other_buffer->own_text);
2520 #ifdef REL_ALLOC
2521 r_alloc_reset_variable ((void **) ¤t_buffer->own_text.beg,
2522 (void **) &other_buffer->own_text.beg);
2523 r_alloc_reset_variable ((void **) &other_buffer->own_text.beg,
2524 (void **) ¤t_buffer->own_text.beg);
2525 #endif
2526
2527 swapfield (pt, ptrdiff_t);
2528 swapfield (pt_byte, ptrdiff_t);
2529 swapfield (begv, ptrdiff_t);
2530 swapfield (begv_byte, ptrdiff_t);
2531 swapfield (zv, ptrdiff_t);
2532 swapfield (zv_byte, ptrdiff_t);
2533 eassert (!current_buffer->base_buffer);
2534 eassert (!other_buffer->base_buffer);
2535 swapfield (indirections, ptrdiff_t);
2536 current_buffer->clip_changed = 1; other_buffer->clip_changed = 1;
2537 swapfield (newline_cache, struct region_cache *);
2538 swapfield (width_run_cache, struct region_cache *);
2539 swapfield (bidi_paragraph_cache, struct region_cache *);
2540 current_buffer->prevent_redisplay_optimizations_p = 1;
2541 other_buffer->prevent_redisplay_optimizations_p = 1;
2542 swapfield (long_line_optimizations_p, bool_bf);
2543 swapfield_ (undo_list, Lisp_Object);
2544 swapfield_ (mark, Lisp_Object);
2545 swapfield_ (mark_active, Lisp_Object);
2546 swapfield_ (enable_multibyte_characters, Lisp_Object);
2547 swapfield_ (bidi_display_reordering, Lisp_Object);
2548 swapfield_ (bidi_paragraph_direction, Lisp_Object);
2549 swapfield_ (bidi_paragraph_separate_re, Lisp_Object);
2550 swapfield_ (bidi_paragraph_start_re, Lisp_Object);
2551
2552
2553 swapfield_ (pt_marker, Lisp_Object);
2554 swapfield_ (begv_marker, Lisp_Object);
2555 swapfield_ (zv_marker, Lisp_Object);
2556 bset_point_before_scroll (current_buffer, Qnil);
2557 bset_point_before_scroll (other_buffer, Qnil);
2558
2559 modiff_incr (¤t_buffer->text->modiff, 1);
2560 modiff_incr (&other_buffer->text->modiff, 1);
2561 modiff_incr (¤t_buffer->text->chars_modiff, 1);
2562 modiff_incr (&other_buffer->text->chars_modiff, 1);
2563 modiff_incr (¤t_buffer->text->overlay_modiff, 1);
2564 modiff_incr (&other_buffer->text->overlay_modiff, 1);
2565 current_buffer->text->beg_unchanged = current_buffer->text->gpt;
2566 current_buffer->text->end_unchanged = current_buffer->text->gpt;
2567 other_buffer->text->beg_unchanged = other_buffer->text->gpt;
2568 other_buffer->text->end_unchanged = other_buffer->text->gpt;
2569 swap_buffer_overlays (current_buffer, other_buffer);
2570 {
2571 struct Lisp_Marker *m;
2572 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
2573 if (m->buffer == other_buffer)
2574 m->buffer = current_buffer;
2575 else
2576
2577
2578 eassert (!m->buffer);
2579 for (m = BUF_MARKERS (other_buffer); m; m = m->next)
2580 if (m->buffer == current_buffer)
2581 m->buffer = other_buffer;
2582 else
2583
2584
2585 eassert (!m->buffer);
2586 }
2587 {
2588
2589
2590
2591 Lisp_Object w = selected_window, ws = Qnil;
2592 Lisp_Object buf1, buf2;
2593 XSETBUFFER (buf1, current_buffer); XSETBUFFER (buf2, other_buffer);
2594
2595 while (NILP (Fmemq (w, ws)))
2596 {
2597 ws = Fcons (w, ws);
2598 if (MARKERP (XWINDOW (w)->pointm)
2599 && (BASE_EQ (XWINDOW (w)->contents, buf1)
2600 || BASE_EQ (XWINDOW (w)->contents, buf2)))
2601 Fset_marker (XWINDOW (w)->pointm,
2602 make_fixnum
2603 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))),
2604 XWINDOW (w)->contents);
2605
2606 if (MARKERP (XWINDOW (w)->old_pointm)
2607 && (BASE_EQ (XWINDOW (w)->contents, buf1)
2608 || BASE_EQ (XWINDOW (w)->contents, buf2)))
2609 Fset_marker (XWINDOW (w)->old_pointm,
2610 make_fixnum
2611 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))),
2612 XWINDOW (w)->contents);
2613 if (MARKERP (XWINDOW (w)->start)
2614 && (BASE_EQ (XWINDOW (w)->contents, buf1)
2615 || BASE_EQ (XWINDOW (w)->contents, buf2)))
2616 Fset_marker (XWINDOW (w)->start,
2617 make_fixnum
2618 (XBUFFER (XWINDOW (w)->contents)->last_window_start),
2619 XWINDOW (w)->contents);
2620 w = Fnext_window (w, Qt, Qt);
2621 }
2622 }
2623
2624 if (current_buffer->text->intervals)
2625 (eassert (BASE_EQ (current_buffer->text->intervals->up.obj, buffer)),
2626 XSETBUFFER (current_buffer->text->intervals->up.obj, current_buffer));
2627 if (other_buffer->text->intervals)
2628 (eassert (BASE_EQ (other_buffer->text->intervals->up.obj,
2629 Fcurrent_buffer ())),
2630 XSETBUFFER (other_buffer->text->intervals->up.obj, other_buffer));
2631
2632 return Qnil;
2633 }
2634
2635 DEFUN ("set-buffer-multibyte", Fset_buffer_multibyte, Sset_buffer_multibyte,
2636 1, 1, 0,
2637 doc:
2638
2639
2640
2641
2642
2643
2644
2645 )
2646 (Lisp_Object flag)
2647 {
2648 struct Lisp_Marker *tail, *markers;
2649 Lisp_Object btail, other;
2650 ptrdiff_t begv, zv;
2651 bool narrowed = (BEG != BEGV || Z != ZV);
2652 bool modified_p = !NILP (Fbuffer_modified_p (Qnil));
2653 Lisp_Object old_undo = BVAR (current_buffer, undo_list);
2654
2655 if (current_buffer->base_buffer)
2656 error ("Cannot do `set-buffer-multibyte' on an indirect buffer");
2657
2658
2659 if (NILP (flag) == NILP (BVAR (current_buffer, enable_multibyte_characters)))
2660 return flag;
2661
2662
2663
2664 bset_undo_list (current_buffer, Qt);
2665
2666
2667 clear_charpos_cache (current_buffer);
2668
2669 if (NILP (flag))
2670 begv = BEGV_BYTE, zv = ZV_BYTE;
2671 else
2672 begv = BEGV, zv = ZV;
2673
2674 if (narrowed)
2675 error ("Changing multibyteness in a narrowed buffer");
2676
2677 invalidate_buffer_caches (current_buffer, BEGV, ZV);
2678
2679 if (NILP (flag))
2680 {
2681 ptrdiff_t pos, stop;
2682 unsigned char *p;
2683
2684
2685
2686 set_intervals_multibyte (false);
2687 set_overlays_multibyte (false);
2688
2689 bset_enable_multibyte_characters (current_buffer, Qnil);
2690
2691 Z = Z_BYTE;
2692 BEGV = BEGV_BYTE;
2693 ZV = ZV_BYTE;
2694 GPT = GPT_BYTE;
2695 TEMP_SET_PT_BOTH (PT_BYTE, PT_BYTE);
2696
2697
2698 for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
2699 tail->charpos = tail->bytepos;
2700
2701
2702 pos = BEG;
2703 stop = GPT;
2704 p = BEG_ADDR;
2705 while (1)
2706 {
2707 if (pos == stop)
2708 {
2709 if (pos == Z)
2710 break;
2711 p = GAP_END_ADDR;
2712 stop = Z;
2713 }
2714 if (ASCII_CHAR_P (*p))
2715 p++, pos++;
2716 else if (CHAR_BYTE8_HEAD_P (*p))
2717 {
2718 int bytes, c = string_char_and_length (p, &bytes);
2719
2720
2721
2722 bytes--;
2723 del_range_2 (pos, pos, pos + bytes, pos + bytes, 0);
2724 p = GAP_END_ADDR;
2725 *p++ = c;
2726 pos++;
2727 if (begv > pos)
2728 begv -= bytes;
2729 if (zv > pos)
2730 zv -= bytes;
2731 stop = Z;
2732 }
2733 else
2734 {
2735 int bytes = BYTES_BY_CHAR_HEAD (*p);
2736 p += bytes, pos += bytes;
2737 }
2738 }
2739 }
2740 else
2741 {
2742 ptrdiff_t pt = PT;
2743 ptrdiff_t pos, stop;
2744 unsigned char *p, *pend;
2745
2746
2747
2748
2749
2750 if (EQ (flag, Qt)
2751 && GPT_BYTE > 1 && GPT_BYTE < Z_BYTE
2752 && ! CHAR_HEAD_P (*(GAP_END_ADDR)))
2753 {
2754 unsigned char *q = GPT_ADDR - 1;
2755
2756 while (! CHAR_HEAD_P (*q) && q > BEG_ADDR) q--;
2757 if (LEADING_CODE_P (*q))
2758 {
2759 ptrdiff_t new_gpt = GPT_BYTE - (GPT_ADDR - q);
2760
2761 move_gap_both (new_gpt, new_gpt);
2762 }
2763 }
2764
2765
2766
2767 pos = BEG;
2768 stop = GPT;
2769 p = BEG_ADDR;
2770 pend = GPT_ADDR;
2771 while (1)
2772 {
2773 int bytes;
2774
2775 if (pos == stop)
2776 {
2777 if (pos == Z)
2778 break;
2779 p = GAP_END_ADDR;
2780 pend = Z_ADDR;
2781 stop = Z;
2782 }
2783
2784 if (ASCII_CHAR_P (*p))
2785 p++, pos++;
2786 else if (EQ (flag, Qt)
2787 && 0 < (bytes = multibyte_length (p, pend, true, false)))
2788 p += bytes, pos += bytes;
2789 else
2790 {
2791 unsigned char tmp[MAX_MULTIBYTE_LENGTH];
2792 int c;
2793
2794 c = BYTE8_TO_CHAR (*p);
2795 bytes = CHAR_STRING (c, tmp);
2796 *p = tmp[0];
2797 TEMP_SET_PT_BOTH (pos + 1, pos + 1);
2798 bytes--;
2799 insert_1_both ((char *) tmp + 1, bytes, bytes, 1, 0, 0);
2800
2801 pos = GPT;
2802 p = GAP_END_ADDR;
2803 if (pos <= begv)
2804 begv += bytes;
2805 if (pos <= zv)
2806 zv += bytes;
2807 if (pos <= pt)
2808 pt += bytes;
2809 pend = Z_ADDR;
2810 stop = Z;
2811 }
2812 }
2813
2814 if (pt != PT)
2815 TEMP_SET_PT (pt);
2816
2817
2818
2819 bset_enable_multibyte_characters (current_buffer, Qt);
2820
2821 GPT_BYTE = advance_to_char_boundary (GPT_BYTE);
2822 GPT = chars_in_text (BEG_ADDR, GPT_BYTE - BEG_BYTE) + BEG;
2823
2824 Z = chars_in_text (GAP_END_ADDR, Z_BYTE - GPT_BYTE) + GPT;
2825
2826 BEGV_BYTE = advance_to_char_boundary (BEGV_BYTE);
2827 if (BEGV_BYTE > GPT_BYTE)
2828 BEGV = chars_in_text (GAP_END_ADDR, BEGV_BYTE - GPT_BYTE) + GPT;
2829 else
2830 BEGV = chars_in_text (BEG_ADDR, BEGV_BYTE - BEG_BYTE) + BEG;
2831
2832 ZV_BYTE = advance_to_char_boundary (ZV_BYTE);
2833 if (ZV_BYTE > GPT_BYTE)
2834 ZV = chars_in_text (GAP_END_ADDR, ZV_BYTE - GPT_BYTE) + GPT;
2835 else
2836 ZV = chars_in_text (BEG_ADDR, ZV_BYTE - BEG_BYTE) + BEG;
2837
2838 {
2839 ptrdiff_t byte = advance_to_char_boundary (PT_BYTE);
2840 ptrdiff_t position;
2841
2842 if (byte > GPT_BYTE)
2843 position = chars_in_text (GAP_END_ADDR, byte - GPT_BYTE) + GPT;
2844 else
2845 position = chars_in_text (BEG_ADDR, byte - BEG_BYTE) + BEG;
2846 TEMP_SET_PT_BOTH (position, byte);
2847 }
2848
2849 tail = markers = BUF_MARKERS (current_buffer);
2850
2851
2852
2853
2854 BUF_MARKERS (current_buffer) = NULL;
2855
2856 for (; tail; tail = tail->next)
2857 {
2858 tail->bytepos = advance_to_char_boundary (tail->bytepos);
2859 tail->charpos = BYTE_TO_CHAR (tail->bytepos);
2860 }
2861
2862
2863
2864 if (BUF_MARKERS (current_buffer))
2865 emacs_abort ();
2866
2867 BUF_MARKERS (current_buffer) = markers;
2868
2869
2870
2871
2872
2873
2874 set_intervals_multibyte (true);
2875 set_overlays_multibyte (true);
2876 }
2877
2878 if (!EQ (old_undo, Qt))
2879 {
2880
2881 bset_undo_list (current_buffer,
2882 Fcons (list3 (Qapply,
2883 intern ("set-buffer-multibyte"),
2884 NILP (flag) ? Qt : Qnil),
2885 old_undo));
2886 }
2887
2888 current_buffer->prevent_redisplay_optimizations_p = 1;
2889
2890
2891 if (buffer_window_count (current_buffer))
2892 windows_or_buffers_changed = 10;
2893
2894
2895
2896 FOR_EACH_LIVE_BUFFER (btail, other)
2897 {
2898 struct buffer *o = XBUFFER (other);
2899 if (o->base_buffer == current_buffer && BUFFER_LIVE_P (o))
2900 {
2901 BVAR (o, enable_multibyte_characters)
2902 = BVAR (current_buffer, enable_multibyte_characters);
2903 o->prevent_redisplay_optimizations_p = true;
2904 }
2905 }
2906
2907
2908 if (!modified_p && !NILP (Fbuffer_modified_p (Qnil)))
2909 Fset_buffer_modified_p (Qnil);
2910
2911
2912 {
2913 Lisp_Object process;
2914
2915 process = Fget_buffer_process (Fcurrent_buffer ());
2916 if (PROCESSP (process))
2917 setup_process_coding_systems (process);
2918 }
2919
2920 return flag;
2921 }
2922
2923 DEFUN ("kill-all-local-variables", Fkill_all_local_variables,
2924 Skill_all_local_variables, 0, 1, 0,
2925 doc:
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941 )
2942 (Lisp_Object kill_permanent)
2943 {
2944 run_hook (Qchange_major_mode_hook);
2945
2946
2947
2948 reset_buffer_local_variables (current_buffer, !NILP (kill_permanent));
2949
2950
2951
2952 bset_update_mode_line (current_buffer);
2953
2954 return Qnil;
2955 }
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983 ptrdiff_t
2984 overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend,
2985 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
2986 bool empty, bool trailing,
2987 ptrdiff_t *next_ptr)
2988 {
2989 ptrdiff_t idx = 0;
2990 ptrdiff_t len = *len_ptr;
2991 ptrdiff_t next = ZV;
2992 Lisp_Object *vec = *vec_ptr;
2993 struct itree_node *node;
2994
2995
2996
2997 ptrdiff_t search_end = ZV;
2998 if (end >= ZV && (empty || trailing))
2999 ++search_end;
3000
3001 ITREE_FOREACH (node, current_buffer->overlays, beg, search_end,
3002 ASCENDING)
3003 {
3004 if (node->begin > end)
3005 {
3006 next = min (next, node->begin);
3007 break;
3008 }
3009 else if (node->begin == end)
3010 {
3011 next = node->begin;
3012 if ((! empty || end < ZV) && beg < end)
3013 break;
3014 if (empty && node->begin != node->end)
3015 continue;
3016 }
3017
3018 if (! empty && node->begin == node->end)
3019 continue;
3020
3021 if (extend && idx == len)
3022 {
3023 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
3024 sizeof *vec);
3025 *vec_ptr = vec;
3026 len = *len_ptr;
3027 }
3028 if (idx < len)
3029 vec[idx] = node->data;
3030
3031 idx++;
3032 }
3033 if (next_ptr)
3034 *next_ptr = next ? next : ZV;
3035
3036 return idx;
3037 }
3038
3039
3040
3041
3042
3043
3044
3045 ptrdiff_t
3046 overlays_at (ptrdiff_t pos, bool extend,
3047 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
3048 ptrdiff_t *next_ptr)
3049 {
3050 return overlays_in (pos, pos + 1, extend, vec_ptr, len_ptr,
3051 false, true, next_ptr);
3052 }
3053
3054 ptrdiff_t
3055 next_overlay_change (ptrdiff_t pos)
3056 {
3057 ptrdiff_t next = ZV;
3058 struct itree_node *node;
3059
3060 ITREE_FOREACH (node, current_buffer->overlays, pos, next, ASCENDING)
3061 {
3062 if (node->begin > pos)
3063 {
3064
3065
3066 eassert (node->begin < next);
3067 next = node->begin;
3068 break;
3069 }
3070 else if (node->begin < node->end && node->end < next)
3071 {
3072 next = node->end;
3073 ITREE_FOREACH_NARROW (pos, next);
3074 }
3075 }
3076
3077 return next;
3078 }
3079
3080 ptrdiff_t
3081 previous_overlay_change (ptrdiff_t pos)
3082 {
3083 struct itree_node *node;
3084 ptrdiff_t prev = BEGV;
3085
3086 ITREE_FOREACH (node, current_buffer->overlays, prev, pos, DESCENDING)
3087 {
3088 if (node->end < pos)
3089 prev = node->end;
3090 else
3091 prev = max (prev, node->begin);
3092 ITREE_FOREACH_NARROW (prev, pos);
3093 }
3094
3095 return prev;
3096 }
3097
3098
3099
3100
3101 bool
3102 mouse_face_overlay_overlaps (Lisp_Object overlay)
3103 {
3104 ptrdiff_t start = OVERLAY_START (overlay);
3105 ptrdiff_t end = OVERLAY_END (overlay);
3106 ptrdiff_t n, i, size;
3107 Lisp_Object *v, tem;
3108 Lisp_Object vbuf[10];
3109 USE_SAFE_ALLOCA;
3110
3111 size = ARRAYELTS (vbuf);
3112 v = vbuf;
3113 n = overlays_in (start, end, 0, &v, &size, true, false, NULL);
3114 if (n > size)
3115 {
3116 SAFE_NALLOCA (v, 1, n);
3117 overlays_in (start, end, 0, &v, &n, true, false, NULL);
3118 }
3119
3120 for (i = 0; i < n; ++i)
3121 if (!EQ (v[i], overlay)
3122 && (tem = Foverlay_get (overlay, Qmouse_face),
3123 !NILP (tem)))
3124 break;
3125
3126 SAFE_FREE ();
3127 return i < n;
3128 }
3129
3130
3131
3132 Lisp_Object
3133 disable_line_numbers_overlay_at_eob (void)
3134 {
3135 ptrdiff_t n, i, size;
3136 Lisp_Object *v, tem = Qnil;
3137 Lisp_Object vbuf[10];
3138 USE_SAFE_ALLOCA;
3139
3140 size = ARRAYELTS (vbuf);
3141 v = vbuf;
3142 n = overlays_in (ZV, ZV, 0, &v, &size, false, false, NULL);
3143 if (n > size)
3144 {
3145 SAFE_NALLOCA (v, 1, n);
3146 overlays_in (ZV, ZV, 0, &v, &n, false, false, NULL);
3147 }
3148
3149 for (i = 0; i < n; ++i)
3150 if ((tem = Foverlay_get (v[i], Qdisplay_line_numbers_disable),
3151 !NILP (tem)))
3152 break;
3153
3154 SAFE_FREE ();
3155 return tem;
3156 }
3157
3158
3159
3160
3161
3162
3163 bool
3164 overlay_touches_p (ptrdiff_t pos)
3165 {
3166 struct itree_node *node;
3167
3168
3169
3170 ITREE_FOREACH (node, current_buffer->overlays, pos - 1, pos + 1, DESCENDING)
3171 if (node->begin == pos || node->end == pos)
3172 return true;
3173 return false;
3174 }
3175
3176
3177 int
3178 compare_overlays (const void *v1, const void *v2)
3179 {
3180 const struct sortvec *s1 = v1;
3181 const struct sortvec *s2 = v2;
3182
3183
3184 if (s1->priority != s2->priority)
3185 return s1->priority < s2->priority ? -1 : 1;
3186
3187
3188 else if (s1->beg < s2->beg)
3189 return (s1->end < s2->end && s1->spriority > s2->spriority ? 1 : -1);
3190 else if (s1->beg > s2->beg)
3191 return (s1->end > s2->end && s1->spriority < s2->spriority ? -1 : 1);
3192 else if (s1->end != s2->end)
3193 return s2->end < s1->end ? -1 : 1;
3194 else if (s1->spriority != s2->spriority)
3195 return (s1->spriority < s2->spriority ? -1 : 1);
3196 else if (EQ (s1->overlay, s2->overlay))
3197 return 0;
3198 else
3199
3200
3201
3202
3203 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
3204 }
3205
3206 void
3207 make_sortvec_item (struct sortvec *item, Lisp_Object overlay)
3208 {
3209 Lisp_Object tem;
3210
3211 item->overlay = overlay;
3212 item->beg = OVERLAY_START (overlay);
3213 item->end = OVERLAY_END (overlay);
3214 tem = Foverlay_get (overlay, Qpriority);
3215 if (NILP (tem))
3216 {
3217 item->priority = 0;
3218 item->spriority = 0;
3219 }
3220 else if (FIXNUMP (tem))
3221 {
3222 item->priority = XFIXNUM (tem);
3223 item->spriority = 0;
3224 }
3225 else if (CONSP (tem))
3226 {
3227 Lisp_Object car = XCAR (tem);
3228 Lisp_Object cdr = XCDR (tem);
3229 item->priority = FIXNUMP (car) ? XFIXNUM (car) : 0;
3230 item->spriority = FIXNUMP (cdr) ? XFIXNUM (cdr) : 0;
3231 }
3232 }
3233
3234
3235
3236 ptrdiff_t
3237 sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w)
3238 {
3239 ptrdiff_t i, j;
3240 USE_SAFE_ALLOCA;
3241 struct sortvec *sortvec;
3242
3243 SAFE_NALLOCA (sortvec, 1, noverlays);
3244
3245
3246
3247 for (i = 0, j = 0; i < noverlays; i++)
3248 {
3249 Lisp_Object overlay;
3250
3251 overlay = overlay_vec[i];
3252 if (OVERLAYP (overlay)
3253 && OVERLAY_START (overlay) > 0
3254 && OVERLAY_END (overlay) > 0)
3255 {
3256
3257
3258 if (w && ! overlay_matches_window (w, overlay))
3259 continue;
3260 make_sortvec_item (sortvec + j, overlay);
3261 j++;
3262 }
3263 }
3264 noverlays = j;
3265
3266
3267
3268 if (noverlays > 1)
3269 qsort (sortvec, noverlays, sizeof (struct sortvec), compare_overlays);
3270
3271 for (i = 0; i < noverlays; i++)
3272 overlay_vec[i] = sortvec[i].overlay;
3273
3274 SAFE_FREE ();
3275 return (noverlays);
3276 }
3277
3278 struct sortstr
3279 {
3280 Lisp_Object string, string2;
3281 ptrdiff_t size;
3282 EMACS_INT priority;
3283 };
3284
3285 struct sortstrlist
3286 {
3287 struct sortstr *buf;
3288 ptrdiff_t size;
3289 ptrdiff_t used;
3290 ptrdiff_t bytes;
3291 };
3292
3293
3294
3295
3296
3297 static struct sortstrlist overlay_heads, overlay_tails;
3298 static unsigned char *overlay_str_buf;
3299
3300
3301 static ptrdiff_t overlay_str_len;
3302
3303
3304 static int
3305 cmp_for_strings (const void *as1, const void *as2)
3306 {
3307 struct sortstr const *s1 = as1;
3308 struct sortstr const *s2 = as2;
3309 if (s1->size != s2->size)
3310 return s2->size < s1->size ? -1 : 1;
3311 if (s1->priority != s2->priority)
3312 return s1->priority < s2->priority ? -1 : 1;
3313 return 0;
3314 }
3315
3316 static void
3317 record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
3318 Lisp_Object str2, Lisp_Object pri, ptrdiff_t size)
3319 {
3320 ptrdiff_t nbytes;
3321
3322 if (ssl->used == ssl->size)
3323 ssl->buf = xpalloc (ssl->buf, &ssl->size, 5, -1, sizeof *ssl->buf);
3324 ssl->buf[ssl->used].string = str;
3325 ssl->buf[ssl->used].string2 = str2;
3326 ssl->buf[ssl->used].size = size;
3327 ssl->buf[ssl->used].priority = (FIXNUMP (pri) ? XFIXNUM (pri) : 0);
3328 ssl->used++;
3329
3330 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
3331 nbytes = SCHARS (str);
3332 else if (! STRING_MULTIBYTE (str))
3333 nbytes = count_size_as_multibyte (SDATA (str),
3334 SBYTES (str));
3335 else
3336 nbytes = SBYTES (str);
3337
3338 if (INT_ADD_WRAPV (ssl->bytes, nbytes, &nbytes))
3339 memory_full (SIZE_MAX);
3340 ssl->bytes = nbytes;
3341
3342 if (STRINGP (str2))
3343 {
3344 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
3345 nbytes = SCHARS (str2);
3346 else if (! STRING_MULTIBYTE (str2))
3347 nbytes = count_size_as_multibyte (SDATA (str2),
3348 SBYTES (str2));
3349 else
3350 nbytes = SBYTES (str2);
3351
3352 if (INT_ADD_WRAPV (ssl->bytes, nbytes, &nbytes))
3353 memory_full (SIZE_MAX);
3354 ssl->bytes = nbytes;
3355 }
3356 }
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371 ptrdiff_t
3372 overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3373 {
3374 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
3375 struct itree_node *node;
3376
3377 overlay_heads.used = overlay_heads.bytes = 0;
3378 overlay_tails.used = overlay_tails.bytes = 0;
3379
3380 ITREE_FOREACH (node, current_buffer->overlays, pos - 1, pos + 1, DESCENDING)
3381 {
3382 Lisp_Object overlay = node->data;
3383 eassert (OVERLAYP (overlay));
3384
3385 ptrdiff_t startpos = node->begin;
3386 ptrdiff_t endpos = node->end;
3387
3388 if (endpos != pos && startpos != pos)
3389 continue;
3390 Lisp_Object window = Foverlay_get (overlay, Qwindow);
3391 if (WINDOWP (window) && XWINDOW (window) != w)
3392 continue;
3393 Lisp_Object str;
3394
3395
3396 if (startpos == pos
3397 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3398 record_overlay_string (&overlay_heads, str,
3399 (startpos == endpos
3400 ? Foverlay_get (overlay, Qafter_string)
3401 : Qnil),
3402 Foverlay_get (overlay, Qpriority),
3403 endpos - startpos);
3404 else if (endpos == pos
3405 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
3406 record_overlay_string (&overlay_tails, str, Qnil,
3407 Foverlay_get (overlay, Qpriority),
3408 endpos - startpos);
3409 }
3410
3411 if (overlay_tails.used > 1)
3412 qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr),
3413 cmp_for_strings);
3414 if (overlay_heads.used > 1)
3415 qsort (overlay_heads.buf, overlay_heads.used, sizeof (struct sortstr),
3416 cmp_for_strings);
3417 if (overlay_heads.bytes || overlay_tails.bytes)
3418 {
3419 Lisp_Object tem;
3420 ptrdiff_t i;
3421 unsigned char *p;
3422 ptrdiff_t total;
3423
3424 if (INT_ADD_WRAPV (overlay_heads.bytes, overlay_tails.bytes, &total))
3425 memory_full (SIZE_MAX);
3426 if (total > overlay_str_len)
3427 overlay_str_buf = xpalloc (overlay_str_buf, &overlay_str_len,
3428 total - overlay_str_len, -1, 1);
3429
3430 p = overlay_str_buf;
3431 for (i = overlay_tails.used; --i >= 0;)
3432 {
3433 ptrdiff_t nbytes;
3434 tem = overlay_tails.buf[i].string;
3435 nbytes = copy_text (SDATA (tem), p,
3436 SBYTES (tem),
3437 STRING_MULTIBYTE (tem), multibyte);
3438 p += nbytes;
3439 }
3440 for (i = 0; i < overlay_heads.used; ++i)
3441 {
3442 ptrdiff_t nbytes;
3443 tem = overlay_heads.buf[i].string;
3444 nbytes = copy_text (SDATA (tem), p,
3445 SBYTES (tem),
3446 STRING_MULTIBYTE (tem), multibyte);
3447 p += nbytes;
3448 tem = overlay_heads.buf[i].string2;
3449 if (STRINGP (tem))
3450 {
3451 nbytes = copy_text (SDATA (tem), p,
3452 SBYTES (tem),
3453 STRING_MULTIBYTE (tem), multibyte);
3454 p += nbytes;
3455 }
3456 }
3457 if (p != overlay_str_buf + total)
3458 emacs_abort ();
3459 if (pstr)
3460 *pstr = overlay_str_buf;
3461 return total;
3462 }
3463 return 0;
3464 }
3465
3466
3467 void
3468 adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length, bool before_markers)
3469 {
3470 if (!current_buffer->indirections)
3471 itree_insert_gap (current_buffer->overlays, pos, length, before_markers);
3472 else
3473 {
3474 struct buffer *base = current_buffer->base_buffer
3475 ? current_buffer->base_buffer
3476 : current_buffer;
3477 Lisp_Object tail, other;
3478 itree_insert_gap (base->overlays, pos, length, before_markers);
3479 FOR_EACH_LIVE_BUFFER (tail, other)
3480 if (XBUFFER (other)->base_buffer == base)
3481 itree_insert_gap (XBUFFER (other)->overlays, pos, length,
3482 before_markers);
3483 }
3484 }
3485
3486 static void
3487 adjust_overlays_for_delete_in_buffer (struct buffer * buf,
3488 ptrdiff_t pos, ptrdiff_t length)
3489 {
3490 Lisp_Object hit_list = Qnil;
3491 struct itree_node *node;
3492
3493
3494
3495
3496 itree_delete_gap (buf->overlays, pos, length);
3497
3498
3499
3500
3501 ITREE_FOREACH (node, buf->overlays, pos, pos, ASCENDING)
3502 {
3503 if (node->end == pos && node->begin == pos
3504 && ! NILP (Foverlay_get (node->data, Qevaporate)))
3505 hit_list = Fcons (node->data, hit_list);
3506 }
3507
3508 for (; CONSP (hit_list); hit_list = XCDR (hit_list))
3509 Fdelete_overlay (XCAR (hit_list));
3510 }
3511
3512 void
3513 adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
3514 {
3515 if (!current_buffer->indirections)
3516 adjust_overlays_for_delete_in_buffer (current_buffer, pos, length);
3517 else
3518 {
3519 struct buffer *base = current_buffer->base_buffer
3520 ? current_buffer->base_buffer
3521 : current_buffer;
3522 Lisp_Object tail, other;
3523 adjust_overlays_for_delete_in_buffer (base, pos, length);
3524 FOR_EACH_LIVE_BUFFER (tail, other)
3525 if (XBUFFER (other)->base_buffer == base)
3526 adjust_overlays_for_delete_in_buffer (XBUFFER (other), pos, length);
3527 }
3528 }
3529
3530
3531 DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
3532 doc: )
3533 (Lisp_Object object)
3534 {
3535 return (OVERLAYP (object) ? Qt : Qnil);
3536 }
3537
3538 DEFUN ("make-overlay", Fmake_overlay, Smake_overlay, 2, 5, 0,
3539 doc:
3540
3541
3542
3543
3544
3545
3546
3547 )
3548 (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer,
3549 Lisp_Object front_advance, Lisp_Object rear_advance)
3550 {
3551 Lisp_Object ov;
3552 struct buffer *b;
3553
3554 if (NILP (buffer))
3555 XSETBUFFER (buffer, current_buffer);
3556 else
3557 CHECK_BUFFER (buffer);
3558
3559 b = XBUFFER (buffer);
3560 if (! BUFFER_LIVE_P (b))
3561 error ("Attempt to create overlay in a dead buffer");
3562
3563 if (MARKERP (beg) && !BASE_EQ (Fmarker_buffer (beg), buffer))
3564 signal_error ("Marker points into wrong buffer", beg);
3565 if (MARKERP (end) && !BASE_EQ (Fmarker_buffer (end), buffer))
3566 signal_error ("Marker points into wrong buffer", end);
3567
3568 CHECK_FIXNUM_COERCE_MARKER (beg);
3569 CHECK_FIXNUM_COERCE_MARKER (end);
3570
3571 if (XFIXNUM (beg) > XFIXNUM (end))
3572 {
3573 Lisp_Object temp;
3574 temp = beg; beg = end; end = temp;
3575 }
3576
3577 ptrdiff_t obeg = clip_to_bounds (BUF_BEG (b), XFIXNUM (beg), BUF_Z (b));
3578 ptrdiff_t oend = clip_to_bounds (obeg, XFIXNUM (end), BUF_Z (b));
3579 ov = build_overlay (! NILP (front_advance),
3580 ! NILP (rear_advance), Qnil);
3581 add_buffer_overlay (b, XOVERLAY (ov), obeg, oend);
3582
3583
3584
3585
3586 return ov;
3587 }
3588
3589
3590
3591 static void
3592 modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
3593 {
3594 if (start > end)
3595 {
3596 ptrdiff_t temp = start;
3597 start = end;
3598 end = temp;
3599 }
3600
3601 BUF_COMPUTE_UNCHANGED (buf, start, end);
3602
3603 bset_redisplay (buf);
3604
3605 modiff_incr (&BUF_OVERLAY_MODIFF (buf), 1);
3606 }
3607
3608 DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
3609 doc:
3610
3611
3612 )
3613 (Lisp_Object overlay, Lisp_Object beg, Lisp_Object end, Lisp_Object buffer)
3614 {
3615 struct buffer *b, *ob = 0;
3616 Lisp_Object obuffer;
3617 specpdl_ref count = SPECPDL_INDEX ();
3618 ptrdiff_t o_beg UNINIT, o_end UNINIT;
3619
3620 CHECK_OVERLAY (overlay);
3621 if (NILP (buffer))
3622 buffer = Foverlay_buffer (overlay);
3623 if (NILP (buffer))
3624 XSETBUFFER (buffer, current_buffer);
3625 CHECK_BUFFER (buffer);
3626
3627 if (NILP (Fbuffer_live_p (buffer)))
3628 error ("Attempt to move overlay to a dead buffer");
3629
3630 if (MARKERP (beg) && !BASE_EQ (Fmarker_buffer (beg), buffer))
3631 signal_error ("Marker points into wrong buffer", beg);
3632 if (MARKERP (end) && !BASE_EQ (Fmarker_buffer (end), buffer))
3633 signal_error ("Marker points into wrong buffer", end);
3634
3635 CHECK_FIXNUM_COERCE_MARKER (beg);
3636 CHECK_FIXNUM_COERCE_MARKER (end);
3637
3638 if (XFIXNUM (beg) > XFIXNUM (end))
3639 {
3640 Lisp_Object temp;
3641 temp = beg; beg = end; end = temp;
3642 }
3643
3644 specbind (Qinhibit_quit, Qt);
3645
3646 obuffer = Foverlay_buffer (overlay);
3647 b = XBUFFER (buffer);
3648
3649 ptrdiff_t n_beg = clip_to_bounds (BUF_BEG (b), XFIXNUM (beg), BUF_Z (b));
3650 ptrdiff_t n_end = clip_to_bounds (n_beg, XFIXNUM (end), BUF_Z (b));
3651
3652 if (!NILP (obuffer))
3653 {
3654 ob = XBUFFER (obuffer);
3655
3656 o_beg = OVERLAY_START (overlay);
3657 o_end = OVERLAY_END (overlay);
3658 }
3659
3660 if (! BASE_EQ (buffer, obuffer))
3661 {
3662 if (! NILP (obuffer))
3663 remove_buffer_overlay (XBUFFER (obuffer), XOVERLAY (overlay));
3664 add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay), n_beg, n_end);
3665 }
3666 else
3667 itree_node_set_region (b->overlays, XOVERLAY (overlay)->interval,
3668 n_beg, n_end);
3669
3670
3671 if (!BASE_EQ (buffer, obuffer))
3672 {
3673
3674 if (ob)
3675 modify_overlay (ob, o_beg, o_end);
3676
3677
3678 modify_overlay (b, n_beg, n_end);
3679 }
3680 else
3681
3682 {
3683 if (o_beg == n_beg)
3684 modify_overlay (b, o_end, n_end);
3685 else if (o_end == n_end)
3686 modify_overlay (b, o_beg, n_beg);
3687 else
3688 modify_overlay (b, min (o_beg, n_beg), max (o_end, n_end));
3689 }
3690
3691
3692
3693 if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate)))
3694 {
3695
3696
3697
3698
3699
3700 drop_overlay (XOVERLAY (overlay));
3701 return unbind_to (count, overlay);
3702 }
3703
3704 return unbind_to (count, overlay);
3705 }
3706
3707 DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
3708 doc: )
3709 (Lisp_Object overlay)
3710 {
3711 struct buffer *b;
3712 specpdl_ref count = SPECPDL_INDEX ();
3713
3714 CHECK_OVERLAY (overlay);
3715
3716 b = OVERLAY_BUFFER (overlay);
3717 if (! b)
3718 return Qnil;
3719
3720 specbind (Qinhibit_quit, Qt);
3721
3722 drop_overlay (XOVERLAY (overlay));
3723
3724
3725
3726
3727
3728 if (!windows_or_buffers_changed
3729 && (!NILP (Foverlay_get (overlay, Qbefore_string))
3730 || !NILP (Foverlay_get (overlay, Qafter_string))))
3731 b->prevent_redisplay_optimizations_p = 1;
3732
3733 return unbind_to (count, Qnil);
3734 }
3735
3736 DEFUN ("delete-all-overlays", Fdelete_all_overlays, Sdelete_all_overlays, 0, 1, 0,
3737 doc:
3738
3739 )
3740 (Lisp_Object buffer)
3741 {
3742 delete_all_overlays (decode_buffer (buffer));
3743 return Qnil;
3744 }
3745
3746
3747
3748 DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
3749 doc: )
3750 (Lisp_Object overlay)
3751 {
3752 CHECK_OVERLAY (overlay);
3753 if (! OVERLAY_BUFFER (overlay))
3754 return Qnil;
3755
3756 return make_fixnum (OVERLAY_START (overlay));
3757 }
3758
3759 DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
3760 doc: )
3761 (Lisp_Object overlay)
3762 {
3763 CHECK_OVERLAY (overlay);
3764 if (! OVERLAY_BUFFER (overlay))
3765 return Qnil;
3766
3767 return make_fixnum (OVERLAY_END (overlay));
3768 }
3769
3770 DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
3771 doc:
3772 )
3773 (Lisp_Object overlay)
3774 {
3775 Lisp_Object buffer;
3776
3777 CHECK_OVERLAY (overlay);
3778
3779 if (! OVERLAY_BUFFER (overlay))
3780 return Qnil;
3781
3782 XSETBUFFER (buffer, OVERLAY_BUFFER (overlay));
3783
3784 return buffer;
3785 }
3786
3787 DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
3788 doc:
3789
3790 )
3791 (Lisp_Object overlay)
3792 {
3793 CHECK_OVERLAY (overlay);
3794
3795 return Fcopy_sequence (OVERLAY_PLIST (overlay));
3796 }
3797
3798
3799 DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 2, 0,
3800 doc:
3801
3802
3803
3804
3805 )
3806 (Lisp_Object pos, Lisp_Object sorted)
3807 {
3808 ptrdiff_t len, noverlays;
3809 Lisp_Object *overlay_vec;
3810 Lisp_Object result;
3811
3812 CHECK_FIXNUM_COERCE_MARKER (pos);
3813
3814 if (!buffer_has_overlays ())
3815 return Qnil;
3816
3817 len = 10;
3818
3819 overlay_vec = xmalloc (len * sizeof *overlay_vec);
3820
3821
3822
3823 noverlays = overlays_at (XFIXNUM (pos), true, &overlay_vec, &len, NULL);
3824
3825 if (!NILP (sorted))
3826 noverlays = sort_overlays (overlay_vec, noverlays,
3827 WINDOWP (sorted) ? XWINDOW (sorted) : NULL);
3828
3829
3830 result = Flist (noverlays, overlay_vec);
3831
3832
3833
3834
3835 if (!NILP (sorted))
3836 result = Fnreverse (result);
3837
3838 xfree (overlay_vec);
3839 return result;
3840 }
3841
3842 DEFUN ("overlays-in", Foverlays_in, Soverlays_in, 2, 2, 0,
3843 doc:
3844
3845
3846
3847
3848
3849
3850
3851 )
3852 (Lisp_Object beg, Lisp_Object end)
3853 {
3854 ptrdiff_t len, noverlays;
3855 Lisp_Object *overlay_vec;
3856 Lisp_Object result;
3857
3858 CHECK_FIXNUM_COERCE_MARKER (beg);
3859 CHECK_FIXNUM_COERCE_MARKER (end);
3860
3861 if (!buffer_has_overlays ())
3862 return Qnil;
3863
3864 len = 10;
3865 overlay_vec = xmalloc (len * sizeof *overlay_vec);
3866
3867
3868
3869 noverlays = overlays_in (XFIXNUM (beg), XFIXNUM (end), 1, &overlay_vec, &len,
3870 true, false, NULL);
3871
3872
3873 result = Flist (noverlays, overlay_vec);
3874
3875 xfree (overlay_vec);
3876 return result;
3877 }
3878
3879 DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change,
3880 1, 1, 0,
3881 doc:
3882
3883 )
3884 (Lisp_Object pos)
3885 {
3886 CHECK_FIXNUM_COERCE_MARKER (pos);
3887
3888 if (!buffer_has_overlays ())
3889 return make_fixnum (ZV);
3890
3891 return make_fixnum (next_overlay_change (XFIXNUM (pos)));
3892 }
3893
3894 DEFUN ("previous-overlay-change", Fprevious_overlay_change,
3895 Sprevious_overlay_change, 1, 1, 0,
3896 doc:
3897
3898 )
3899 (Lisp_Object pos)
3900 {
3901
3902 CHECK_FIXNUM_COERCE_MARKER (pos);
3903
3904 if (!buffer_has_overlays ())
3905 return make_fixnum (BEGV);
3906
3907 return make_fixnum (previous_overlay_change (XFIXNUM (pos)));
3908 }
3909
3910
3911
3912
3913 DEFUN ("overlay-lists", Foverlay_lists, Soverlay_lists, 0, 0, 0,
3914 doc:
3915
3916
3917
3918
3919 )
3920 (void)
3921 {
3922 Lisp_Object overlays = Qnil;
3923 struct itree_node *node;
3924
3925 ITREE_FOREACH (node, current_buffer->overlays, BEG, Z, DESCENDING)
3926 overlays = Fcons (node->data, overlays);
3927
3928 return Fcons (overlays, Qnil);
3929 }
3930
3931 DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
3932 doc:
3933
3934
3935
3936
3937
3938
3939 )
3940 (Lisp_Object pos)
3941 {
3942 CHECK_FIXNUM_COERCE_MARKER (pos);
3943
3944 return Qnil;
3945 }
3946
3947 DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0,
3948 doc: )
3949 (Lisp_Object overlay, Lisp_Object prop)
3950 {
3951 CHECK_OVERLAY (overlay);
3952 return lookup_char_property (XOVERLAY (overlay)->plist, prop, 0);
3953 }
3954
3955 DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
3956 doc:
3957 )
3958 (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value)
3959 {
3960 Lisp_Object tail;
3961 struct buffer *b;
3962 bool changed;
3963
3964 CHECK_OVERLAY (overlay);
3965
3966 b = OVERLAY_BUFFER (overlay);
3967
3968 for (tail = XOVERLAY (overlay)->plist;
3969 CONSP (tail) && CONSP (XCDR (tail));
3970 tail = XCDR (XCDR (tail)))
3971 if (EQ (XCAR (tail), prop))
3972 {
3973 changed = !EQ (XCAR (XCDR (tail)), value);
3974 XSETCAR (XCDR (tail), value);
3975 goto found;
3976 }
3977
3978 changed = !NILP (value);
3979 set_overlay_plist
3980 (overlay, Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist)));
3981 found:
3982 if (b)
3983 {
3984 if (changed)
3985 modify_overlay (b, OVERLAY_START (overlay),
3986 OVERLAY_END (overlay));
3987 if (EQ (prop, Qevaporate) && ! NILP (value)
3988 && (OVERLAY_START (overlay)
3989 == OVERLAY_END (overlay)))
3990 Fdelete_overlay (overlay);
3991 }
3992
3993 return value;
3994 }
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007 static Lisp_Object last_overlay_modification_hooks;
4008
4009
4010 static ptrdiff_t last_overlay_modification_hooks_used;
4011
4012
4013
4014
4015 static void
4016 add_overlay_mod_hooklist (Lisp_Object functionlist, Lisp_Object overlay)
4017 {
4018 ptrdiff_t oldsize = ASIZE (last_overlay_modification_hooks);
4019
4020 if (oldsize - 1 <= last_overlay_modification_hooks_used)
4021 last_overlay_modification_hooks =
4022 larger_vector (last_overlay_modification_hooks, 2, -1);
4023 ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
4024 functionlist); last_overlay_modification_hooks_used++;
4025 ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
4026 overlay); last_overlay_modification_hooks_used++;
4027 }
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043 void
4044 report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4045 Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
4046 {
4047
4048 bool insertion = (after ? XFIXNAT (arg3) == 0 : EQ (start, end));
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058 if (!after)
4059 {
4060 struct itree_node *node;
4061 EMACS_INT begin_arg = XFIXNUM (start);
4062 EMACS_INT end_arg = XFIXNUM (end);
4063
4064
4065 last_overlay_modification_hooks_used = 0;
4066
4067 if (! current_buffer->overlays)
4068 return;
4069 ITREE_FOREACH (node, current_buffer->overlays,
4070 begin_arg - (insertion ? 1 : 0),
4071 end_arg + (insertion ? 1 : 0),
4072 ASCENDING)
4073 {
4074 Lisp_Object overlay = node->data;
4075 ptrdiff_t obegin = OVERLAY_START (overlay);
4076 ptrdiff_t oend = OVERLAY_END (overlay);
4077
4078 if (insertion && (begin_arg == obegin
4079 || end_arg == obegin))
4080 {
4081 Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4082 if (!NILP (prop))
4083 add_overlay_mod_hooklist (prop, overlay);
4084 }
4085 if (insertion && (begin_arg == oend
4086 || end_arg == oend))
4087 {
4088 Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4089 if (!NILP (prop))
4090 add_overlay_mod_hooklist (prop, overlay);
4091 }
4092
4093
4094 if (! insertion || (end_arg > obegin && begin_arg < oend))
4095 {
4096 Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
4097 if (!NILP (prop))
4098 add_overlay_mod_hooklist (prop, overlay);
4099 }
4100 }
4101 }
4102 {
4103
4104
4105
4106 ptrdiff_t size = last_overlay_modification_hooks_used;
4107 Lisp_Object *copy;
4108 ptrdiff_t i;
4109
4110 USE_SAFE_ALLOCA;
4111 SAFE_ALLOCA_LISP (copy, size);
4112 memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
4113 size * word_size);
4114
4115 for (i = 0; i < size;)
4116 {
4117 Lisp_Object prop_i, overlay_i;
4118 prop_i = copy[i++];
4119 overlay_i = copy[i++];
4120
4121
4122
4123
4124 if (OVERLAY_BUFFER (overlay_i) == current_buffer)
4125 call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3);
4126 }
4127
4128 SAFE_FREE ();
4129 }
4130 }
4131
4132 static void
4133 call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, bool after,
4134 Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
4135 {
4136 while (CONSP (list))
4137 {
4138 if (NILP (arg3))
4139 call4 (XCAR (list), overlay, after ? Qt : Qnil, arg1, arg2);
4140 else
4141 call5 (XCAR (list), overlay, after ? Qt : Qnil, arg1, arg2, arg3);
4142 list = XCDR (list);
4143 }
4144 }
4145
4146
4147
4148
4149
4150
4151 #if defined USE_MMAP_FOR_BUFFERS && !defined WINDOWSNT
4152
4153 #include <sys/mman.h>
4154
4155 #ifndef MAP_ANON
4156 #ifdef MAP_ANONYMOUS
4157 #define MAP_ANON MAP_ANONYMOUS
4158 #else
4159 #define MAP_ANON 0
4160 #endif
4161 #endif
4162
4163 #ifndef MAP_FAILED
4164 #define MAP_FAILED ((void *) -1)
4165 #endif
4166
4167 #if MAP_ANON == 0
4168 #include <fcntl.h>
4169 #endif
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189 struct mmap_region
4190 {
4191
4192 size_t nbytes_specified;
4193
4194
4195 size_t nbytes_mapped;
4196
4197
4198
4199
4200 void **var;
4201
4202
4203 struct mmap_region *next, *prev;
4204 };
4205
4206
4207
4208 static struct mmap_region *mmap_regions;
4209
4210
4211
4212
4213 static int mmap_fd;
4214
4215
4216
4217 static int mmap_page_size;
4218
4219
4220
4221 static bool mmap_initialized_p;
4222
4223
4224
4225 #define ROUND(X, N) (((X) + (N) - 1) / (N) * (N))
4226
4227
4228
4229 #define MMAP_REGION_STRUCT_SIZE \
4230 ROUND (sizeof (struct mmap_region), MEM_ALIGN)
4231
4232
4233
4234
4235 #define MMAP_REGION(P) \
4236 ((struct mmap_region *) ((char *) (P) - MMAP_REGION_STRUCT_SIZE))
4237
4238
4239
4240
4241 #define MMAP_USER_AREA(P) \
4242 ((void *) ((char *) (P) + MMAP_REGION_STRUCT_SIZE))
4243
4244 #define MEM_ALIGN sizeof (double)
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254 #ifndef MMAP_ALLOCATED_P
4255 #define MMAP_ALLOCATED_P(start, end) 1
4256 #endif
4257
4258
4259
4260 static void
4261 mmap_init (void)
4262 {
4263 #if MAP_ANON == 0
4264
4265
4266 if (mmap_fd <= 0)
4267 {
4268
4269 mmap_fd = emacs_open_noquit ("/dev/zero", O_RDONLY, 0);
4270 if (mmap_fd == -1)
4271 fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
4272 }
4273 #endif
4274
4275 if (mmap_initialized_p)
4276 return;
4277 mmap_initialized_p = 1;
4278
4279 #if MAP_ANON != 0
4280 mmap_fd = -1;
4281 #endif
4282
4283 mmap_page_size = getpagesize ();
4284 }
4285
4286
4287
4288
4289 static void
4290 mmap_free_1 (struct mmap_region *r)
4291 {
4292 if (r->next)
4293 r->next->prev = r->prev;
4294 if (r->prev)
4295 r->prev->next = r->next;
4296 else
4297 mmap_regions = r->next;
4298
4299 if (munmap (r, r->nbytes_mapped) == -1)
4300 fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
4301 }
4302
4303
4304
4305
4306
4307 static bool
4308 mmap_enlarge (struct mmap_region *r, int npages)
4309 {
4310 char *region_end = (char *) r + r->nbytes_mapped;
4311 size_t nbytes;
4312 bool success = 0;
4313
4314 if (npages < 0)
4315 {
4316
4317 nbytes = - npages * mmap_page_size;
4318 if (munmap (region_end - nbytes, nbytes) == -1)
4319 fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
4320 else
4321 {
4322 r->nbytes_mapped -= nbytes;
4323 success = 1;
4324 }
4325 }
4326 else if (npages > 0)
4327 {
4328 nbytes = npages * mmap_page_size;
4329
4330
4331
4332
4333
4334 if (!MMAP_ALLOCATED_P (region_end, region_end + nbytes))
4335 {
4336 void *p;
4337
4338 p = mmap (region_end, nbytes, PROT_READ | PROT_WRITE,
4339 MAP_ANON | MAP_PRIVATE | MAP_FIXED, mmap_fd, 0);
4340 if (p == MAP_FAILED)
4341 ;
4342 else if (p != region_end)
4343 {
4344
4345
4346
4347 if (munmap (p, nbytes) == -1)
4348 fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
4349 }
4350 else
4351 {
4352 r->nbytes_mapped += nbytes;
4353 success = 1;
4354 }
4355 }
4356 }
4357
4358 return success;
4359 }
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371 static void *
4372 mmap_alloc (void **var, size_t nbytes)
4373 {
4374 void *p;
4375 size_t map;
4376
4377 mmap_init ();
4378
4379 map = ROUND (nbytes + MMAP_REGION_STRUCT_SIZE, mmap_page_size);
4380 p = mmap (NULL, map, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
4381 mmap_fd, 0);
4382
4383 if (p == MAP_FAILED)
4384 {
4385 if (errno != ENOMEM)
4386 fprintf (stderr, "mmap: %s\n", emacs_strerror (errno));
4387 p = NULL;
4388 }
4389 else
4390 {
4391 struct mmap_region *r = p;
4392
4393 r->nbytes_specified = nbytes;
4394 r->nbytes_mapped = map;
4395 r->var = var;
4396 r->prev = NULL;
4397 r->next = mmap_regions;
4398 if (r->next)
4399 r->next->prev = r;
4400 mmap_regions = r;
4401
4402 p = MMAP_USER_AREA (p);
4403 }
4404
4405 return *var = p;
4406 }
4407
4408
4409
4410
4411
4412 static void
4413 mmap_free (void **var)
4414 {
4415 mmap_init ();
4416
4417 if (*var)
4418 {
4419 mmap_free_1 (MMAP_REGION (*var));
4420 *var = NULL;
4421 }
4422 }
4423
4424
4425
4426
4427
4428
4429
4430 static void *
4431 mmap_realloc (void **var, size_t nbytes)
4432 {
4433 void *result;
4434
4435 mmap_init ();
4436
4437 if (*var == NULL)
4438 result = mmap_alloc (var, nbytes);
4439 else if (nbytes == 0)
4440 {
4441 mmap_free (var);
4442 result = mmap_alloc (var, nbytes);
4443 }
4444 else
4445 {
4446 struct mmap_region *r = MMAP_REGION (*var);
4447 size_t room = r->nbytes_mapped - MMAP_REGION_STRUCT_SIZE;
4448
4449 if (room < nbytes)
4450 {
4451
4452 void *old_ptr = *var;
4453
4454
4455
4456
4457 if (mmap_enlarge (r, (ROUND (nbytes - room, mmap_page_size)
4458 / mmap_page_size)))
4459 {
4460 r->nbytes_specified = nbytes;
4461 *var = result = old_ptr;
4462 }
4463 else if (mmap_alloc (var, nbytes))
4464 {
4465 memcpy (*var, old_ptr, r->nbytes_specified);
4466 mmap_free_1 (MMAP_REGION (old_ptr));
4467 result = *var;
4468 r = MMAP_REGION (result);
4469 r->nbytes_specified = nbytes;
4470 }
4471 else
4472 {
4473 *var = old_ptr;
4474 result = NULL;
4475 }
4476 }
4477 else if (room - nbytes >= mmap_page_size)
4478 {
4479
4480
4481
4482
4483
4484
4485 mmap_enlarge (r, - ((room - nbytes) / mmap_page_size));
4486 result = *var;
4487 r->nbytes_specified = nbytes;
4488 }
4489 else
4490 {
4491
4492 result = *var;
4493 r->nbytes_specified = nbytes;
4494 }
4495 }
4496
4497 return result;
4498 }
4499
4500
4501 #endif
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511 static void
4512 alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
4513 {
4514 void *p;
4515
4516 block_input ();
4517 #if defined USE_MMAP_FOR_BUFFERS
4518 p = mmap_alloc ((void **) &b->text->beg, nbytes);
4519 #elif defined REL_ALLOC
4520 p = r_alloc ((void **) &b->text->beg, nbytes);
4521 #else
4522 p = xmalloc (nbytes);
4523 #endif
4524
4525 if (p == NULL)
4526 {
4527 unblock_input ();
4528 memory_full (nbytes);
4529 }
4530
4531 b->text->beg = p;
4532 unblock_input ();
4533 }
4534
4535
4536
4537
4538 void
4539 enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
4540 {
4541 block_input ();
4542 void *p;
4543 unsigned char *old_beg = b->text->beg;
4544 ptrdiff_t old_nbytes =
4545 BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1;
4546 ptrdiff_t new_nbytes = old_nbytes + delta;
4547
4548 if (pdumper_object_p (old_beg))
4549 b->text->beg = NULL;
4550 else
4551 old_beg = NULL;
4552
4553 #if defined USE_MMAP_FOR_BUFFERS
4554 p = mmap_realloc ((void **) &b->text->beg, new_nbytes);
4555 #elif defined REL_ALLOC
4556 p = r_re_alloc ((void **) &b->text->beg, new_nbytes);
4557 #else
4558 p = xrealloc (b->text->beg, new_nbytes);
4559 #endif
4560 __lsan_ignore_object (p);
4561
4562 if (p == NULL)
4563 {
4564 if (old_beg)
4565 b->text->beg = old_beg;
4566 unblock_input ();
4567 memory_full (new_nbytes);
4568 }
4569
4570 if (old_beg)
4571 memcpy (p, old_beg, min (old_nbytes, new_nbytes));
4572
4573 BUF_BEG_ADDR (b) = p;
4574 unblock_input ();
4575 }
4576
4577
4578
4579
4580 static void
4581 free_buffer_text (struct buffer *b)
4582 {
4583 block_input ();
4584
4585 if (!pdumper_object_p (b->text->beg))
4586 {
4587 #if defined USE_MMAP_FOR_BUFFERS
4588 mmap_free ((void **) &b->text->beg);
4589 #elif defined REL_ALLOC
4590 r_alloc_free ((void **) &b->text->beg);
4591 #else
4592 xfree (b->text->beg);
4593 #endif
4594 }
4595
4596 BUF_BEG_ADDR (b) = NULL;
4597 unblock_input ();
4598 }
4599
4600
4601
4602
4603
4604
4605 void
4606 init_buffer_once (void)
4607 {
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619 int idx;
4620
4621
4622
4623 PDUMPER_REMEMBER_SCALAR (buffer_permanent_local_flags);
4624 memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags);
4625
4626
4627 memset (&buffer_local_flags, 0, sizeof buffer_local_flags);
4628 bset_filename (&buffer_local_flags, make_fixnum (-1));
4629 bset_directory (&buffer_local_flags, make_fixnum (-1));
4630 bset_backed_up (&buffer_local_flags, make_fixnum (-1));
4631 bset_save_length (&buffer_local_flags, make_fixnum (-1));
4632 bset_auto_save_file_name (&buffer_local_flags, make_fixnum (-1));
4633 bset_read_only (&buffer_local_flags, make_fixnum (-1));
4634 bset_major_mode (&buffer_local_flags, make_fixnum (-1));
4635 bset_local_minor_modes (&buffer_local_flags, make_fixnum (-1));
4636 bset_mode_name (&buffer_local_flags, make_fixnum (-1));
4637 bset_undo_list (&buffer_local_flags, make_fixnum (-1));
4638 bset_mark_active (&buffer_local_flags, make_fixnum (-1));
4639 bset_point_before_scroll (&buffer_local_flags, make_fixnum (-1));
4640 bset_file_truename (&buffer_local_flags, make_fixnum (-1));
4641 bset_invisibility_spec (&buffer_local_flags, make_fixnum (-1));
4642 bset_file_format (&buffer_local_flags, make_fixnum (-1));
4643 bset_auto_save_file_format (&buffer_local_flags, make_fixnum (-1));
4644 bset_display_count (&buffer_local_flags, make_fixnum (-1));
4645 bset_display_time (&buffer_local_flags, make_fixnum (-1));
4646 bset_enable_multibyte_characters (&buffer_local_flags, make_fixnum (-1));
4647
4648
4649
4650 bset_name (&buffer_local_flags, make_fixnum (0));
4651 bset_mark (&buffer_local_flags, make_fixnum (0));
4652 bset_local_var_alist (&buffer_local_flags, make_fixnum (0));
4653 bset_keymap (&buffer_local_flags, make_fixnum (0));
4654 bset_downcase_table (&buffer_local_flags, make_fixnum (0));
4655 bset_upcase_table (&buffer_local_flags, make_fixnum (0));
4656 bset_case_canon_table (&buffer_local_flags, make_fixnum (0));
4657 bset_case_eqv_table (&buffer_local_flags, make_fixnum (0));
4658 bset_width_table (&buffer_local_flags, make_fixnum (0));
4659 bset_pt_marker (&buffer_local_flags, make_fixnum (0));
4660 bset_begv_marker (&buffer_local_flags, make_fixnum (0));
4661 bset_zv_marker (&buffer_local_flags, make_fixnum (0));
4662 bset_last_selected_window (&buffer_local_flags, make_fixnum (0));
4663
4664 idx = 1;
4665 XSETFASTINT (BVAR (&buffer_local_flags, mode_line_format), idx); ++idx;
4666 XSETFASTINT (BVAR (&buffer_local_flags, abbrev_mode), idx); ++idx;
4667 XSETFASTINT (BVAR (&buffer_local_flags, overwrite_mode), idx); ++idx;
4668 XSETFASTINT (BVAR (&buffer_local_flags, case_fold_search), idx); ++idx;
4669 XSETFASTINT (BVAR (&buffer_local_flags, auto_fill_function), idx); ++idx;
4670 XSETFASTINT (BVAR (&buffer_local_flags, selective_display), idx); ++idx;
4671 XSETFASTINT (BVAR (&buffer_local_flags, selective_display_ellipses), idx); ++idx;
4672 XSETFASTINT (BVAR (&buffer_local_flags, tab_width), idx); ++idx;
4673 XSETFASTINT (BVAR (&buffer_local_flags, truncate_lines), idx);
4674
4675 buffer_permanent_local_flags[idx++] = 1;
4676 XSETFASTINT (BVAR (&buffer_local_flags, word_wrap), idx); ++idx;
4677 XSETFASTINT (BVAR (&buffer_local_flags, ctl_arrow), idx); ++idx;
4678 XSETFASTINT (BVAR (&buffer_local_flags, fill_column), idx); ++idx;
4679 XSETFASTINT (BVAR (&buffer_local_flags, left_margin), idx); ++idx;
4680 XSETFASTINT (BVAR (&buffer_local_flags, abbrev_table), idx); ++idx;
4681 XSETFASTINT (BVAR (&buffer_local_flags, display_table), idx); ++idx;
4682 XSETFASTINT (BVAR (&buffer_local_flags, syntax_table), idx); ++idx;
4683 XSETFASTINT (BVAR (&buffer_local_flags, cache_long_scans), idx); ++idx;
4684 XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx;
4685 XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); ++idx;
4686 XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); ++idx;
4687 XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_separate_re), idx); ++idx;
4688 XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_start_re), idx); ++idx;
4689 XSETFASTINT (BVAR (&buffer_local_flags, buffer_file_coding_system), idx);
4690
4691 buffer_permanent_local_flags[idx++] = 1;
4692 XSETFASTINT (BVAR (&buffer_local_flags, left_margin_cols), idx); ++idx;
4693 XSETFASTINT (BVAR (&buffer_local_flags, right_margin_cols), idx); ++idx;
4694 XSETFASTINT (BVAR (&buffer_local_flags, left_fringe_width), idx); ++idx;
4695 XSETFASTINT (BVAR (&buffer_local_flags, right_fringe_width), idx); ++idx;
4696 XSETFASTINT (BVAR (&buffer_local_flags, fringes_outside_margins), idx); ++idx;
4697 XSETFASTINT (BVAR (&buffer_local_flags, scroll_bar_width), idx); ++idx;
4698 XSETFASTINT (BVAR (&buffer_local_flags, scroll_bar_height), idx); ++idx;
4699 XSETFASTINT (BVAR (&buffer_local_flags, vertical_scroll_bar_type), idx); ++idx;
4700 XSETFASTINT (BVAR (&buffer_local_flags, horizontal_scroll_bar_type), idx); ++idx;
4701 XSETFASTINT (BVAR (&buffer_local_flags, indicate_empty_lines), idx); ++idx;
4702 XSETFASTINT (BVAR (&buffer_local_flags, indicate_buffer_boundaries), idx); ++idx;
4703 XSETFASTINT (BVAR (&buffer_local_flags, fringe_indicator_alist), idx); ++idx;
4704 XSETFASTINT (BVAR (&buffer_local_flags, fringe_cursor_alist), idx); ++idx;
4705 XSETFASTINT (BVAR (&buffer_local_flags, scroll_up_aggressively), idx); ++idx;
4706 XSETFASTINT (BVAR (&buffer_local_flags, scroll_down_aggressively), idx); ++idx;
4707 XSETFASTINT (BVAR (&buffer_local_flags, header_line_format), idx); ++idx;
4708 XSETFASTINT (BVAR (&buffer_local_flags, tab_line_format), idx); ++idx;
4709 XSETFASTINT (BVAR (&buffer_local_flags, cursor_type), idx); ++idx;
4710 XSETFASTINT (BVAR (&buffer_local_flags, extra_line_spacing), idx); ++idx;
4711 #ifdef HAVE_TREE_SITTER
4712 XSETFASTINT (BVAR (&buffer_local_flags, ts_parser_list), idx); ++idx;
4713 #endif
4714 XSETFASTINT (BVAR (&buffer_local_flags, cursor_in_non_selected_windows), idx); ++idx;
4715
4716
4717
4718 PDUMPER_REMEMBER_SCALAR (buffer_local_flags);
4719
4720
4721 if (idx >= MAX_PER_BUFFER_VARS)
4722 emacs_abort ();
4723 last_per_buffer_idx = idx;
4724 PDUMPER_REMEMBER_SCALAR (last_per_buffer_idx);
4725
4726
4727
4728 reset_buffer (&buffer_defaults);
4729 eassert (NILP (BVAR (&buffer_defaults, name)));
4730 reset_buffer_local_variables (&buffer_defaults, 1);
4731 eassert (NILP (BVAR (&buffer_local_symbols, name)));
4732 reset_buffer (&buffer_local_symbols);
4733 reset_buffer_local_variables (&buffer_local_symbols, 1);
4734
4735 buffer_defaults.text = &buffer_defaults.own_text;
4736 buffer_local_symbols.text = &buffer_local_symbols.own_text;
4737
4738 buffer_defaults.indirections = 0;
4739 buffer_local_symbols.indirections = 0;
4740
4741 buffer_defaults.window_count = 0;
4742 buffer_local_symbols.window_count = 0;
4743 set_buffer_intervals (&buffer_defaults, NULL);
4744 set_buffer_intervals (&buffer_local_symbols, NULL);
4745
4746 bset_name (&buffer_defaults, build_pure_c_string (" *buffer-defaults*"));
4747 bset_name (&buffer_local_symbols, build_pure_c_string (" *buffer-local-symbols*"));
4748 BUFFER_PVEC_INIT (&buffer_defaults);
4749 BUFFER_PVEC_INIT (&buffer_local_symbols);
4750
4751
4752
4753
4754
4755 bset_mode_line_format (&buffer_defaults, build_pure_c_string ("%-"));
4756 bset_header_line_format (&buffer_defaults, Qnil);
4757 bset_tab_line_format (&buffer_defaults, Qnil);
4758 bset_abbrev_mode (&buffer_defaults, Qnil);
4759 bset_overwrite_mode (&buffer_defaults, Qnil);
4760 bset_case_fold_search (&buffer_defaults, Qt);
4761 bset_auto_fill_function (&buffer_defaults, Qnil);
4762 bset_selective_display (&buffer_defaults, Qnil);
4763 bset_selective_display_ellipses (&buffer_defaults, Qt);
4764 bset_abbrev_table (&buffer_defaults, Qnil);
4765 bset_display_table (&buffer_defaults, Qnil);
4766 bset_undo_list (&buffer_defaults, Qnil);
4767 bset_mark_active (&buffer_defaults, Qnil);
4768 bset_file_format (&buffer_defaults, Qnil);
4769 bset_auto_save_file_format (&buffer_defaults, Qt);
4770 buffer_defaults.overlays = NULL;
4771
4772 XSETFASTINT (BVAR (&buffer_defaults, tab_width), 8);
4773 bset_truncate_lines (&buffer_defaults, Qnil);
4774 bset_word_wrap (&buffer_defaults, Qnil);
4775 bset_ctl_arrow (&buffer_defaults, Qt);
4776 bset_bidi_display_reordering (&buffer_defaults, Qt);
4777 bset_bidi_paragraph_direction (&buffer_defaults, Qnil);
4778 bset_bidi_paragraph_start_re (&buffer_defaults, Qnil);
4779 bset_bidi_paragraph_separate_re (&buffer_defaults, Qnil);
4780 bset_cursor_type (&buffer_defaults, Qt);
4781 bset_extra_line_spacing (&buffer_defaults, Qnil);
4782 #ifdef HAVE_TREE_SITTER
4783 bset_ts_parser_list (&buffer_defaults, Qnil);
4784 #endif
4785 bset_cursor_in_non_selected_windows (&buffer_defaults, Qt);
4786
4787 bset_enable_multibyte_characters (&buffer_defaults, Qt);
4788 bset_buffer_file_coding_system (&buffer_defaults, Qnil);
4789 XSETFASTINT (BVAR (&buffer_defaults, fill_column), 70);
4790 XSETFASTINT (BVAR (&buffer_defaults, left_margin), 0);
4791 bset_cache_long_scans (&buffer_defaults, Qt);
4792 bset_file_truename (&buffer_defaults, Qnil);
4793 XSETFASTINT (BVAR (&buffer_defaults, display_count), 0);
4794 XSETFASTINT (BVAR (&buffer_defaults, left_margin_cols), 0);
4795 XSETFASTINT (BVAR (&buffer_defaults, right_margin_cols), 0);
4796 bset_left_fringe_width (&buffer_defaults, Qnil);
4797 bset_right_fringe_width (&buffer_defaults, Qnil);
4798 bset_fringes_outside_margins (&buffer_defaults, Qnil);
4799 bset_scroll_bar_width (&buffer_defaults, Qnil);
4800 bset_scroll_bar_height (&buffer_defaults, Qnil);
4801 bset_vertical_scroll_bar_type (&buffer_defaults, Qt);
4802 bset_horizontal_scroll_bar_type (&buffer_defaults, Qt);
4803 bset_indicate_empty_lines (&buffer_defaults, Qnil);
4804 bset_indicate_buffer_boundaries (&buffer_defaults, Qnil);
4805 bset_fringe_indicator_alist (&buffer_defaults, Qnil);
4806 bset_fringe_cursor_alist (&buffer_defaults, Qnil);
4807 bset_scroll_up_aggressively (&buffer_defaults, Qnil);
4808 bset_scroll_down_aggressively (&buffer_defaults, Qnil);
4809 bset_display_time (&buffer_defaults, Qnil);
4810
4811
4812
4813
4814
4815
4816
4817 { verify (sizeof (EMACS_INT) == word_size); }
4818
4819 Vbuffer_alist = Qnil;
4820 current_buffer = 0;
4821 pdumper_remember_lv_ptr_raw (¤t_buffer, Lisp_Vectorlike);
4822
4823 QSFundamental = build_pure_c_string ("Fundamental");
4824
4825 DEFSYM (Qfundamental_mode, "fundamental-mode");
4826 bset_major_mode (&buffer_defaults, Qfundamental_mode);
4827
4828 DEFSYM (Qmode_class, "mode-class");
4829 DEFSYM (Qprotected_field, "protected-field");
4830
4831 DEFSYM (Qpermanent_local, "permanent-local");
4832 DEFSYM (Qkill_buffer_hook, "kill-buffer-hook");
4833 Fput (Qkill_buffer_hook, Qpermanent_local, Qt);
4834
4835
4836 Vprin1_to_string_buffer =
4837 Fget_buffer_create (build_pure_c_string (" prin1"), Qt);
4838 Vbuffer_alist = Qnil;
4839
4840 Fset_buffer (Fget_buffer_create (build_pure_c_string ("*scratch*"), Qnil));
4841
4842 inhibit_modification_hooks = 0;
4843 }
4844
4845 void
4846 init_buffer (void)
4847 {
4848 Lisp_Object temp;
4849
4850 #ifdef USE_MMAP_FOR_BUFFERS
4851 if (dumped_with_unexec_p ())
4852 {
4853 Lisp_Object tail, buffer;
4854
4855 #ifndef WINDOWSNT
4856
4857
4858
4859
4860
4861
4862 mmap_regions = NULL;
4863 mmap_fd = -1;
4864 #endif
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879 FOR_EACH_LIVE_BUFFER (tail, buffer)
4880 {
4881 struct buffer *b = XBUFFER (buffer);
4882 b->text->beg = NULL;
4883 enlarge_buffer_text (b, 0);
4884 }
4885
4886 XBUFFER (Vprin1_to_string_buffer)->text->beg = NULL;
4887 enlarge_buffer_text (XBUFFER (Vprin1_to_string_buffer), 0);
4888 }
4889 #endif
4890
4891 AUTO_STRING (scratch, "*scratch*");
4892 Fset_buffer (Fget_buffer_create (scratch, Qnil));
4893 if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters)))
4894 Fset_buffer_multibyte (Qnil);
4895
4896 char const *pwd = emacs_wd;
4897
4898 if (!pwd)
4899 {
4900 fprintf (stderr, "Error getting directory: %s\n",
4901 emacs_strerror (errno));
4902 bset_directory (current_buffer, Qnil);
4903 }
4904 else
4905 {
4906
4907
4908 ptrdiff_t len = strlen (pwd);
4909 bool add_slash = ! IS_DIRECTORY_SEP (pwd[len - 1]);
4910
4911
4912
4913
4914 Lisp_Object dirname = make_unibyte_string (pwd, len + add_slash);
4915 if (add_slash)
4916 SSET (dirname, len, DIRECTORY_SEP);
4917 bset_directory (current_buffer, dirname);
4918
4919
4920
4921 temp = Ffind_file_name_handler (BVAR (current_buffer, directory), Qt);
4922 if (! NILP (temp)
4923
4924
4925
4926
4927 && strcmp ("/", SSDATA (BVAR (current_buffer, directory))))
4928 {
4929 AUTO_STRING (slash_colon, "/:");
4930 bset_directory (current_buffer,
4931 concat2 (slash_colon,
4932 BVAR (current_buffer, directory)));
4933 }
4934 }
4935
4936 temp = get_minibuffer (0);
4937 bset_directory (XBUFFER (temp), BVAR (current_buffer, directory));
4938 }
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948 #define DEFVAR_PER_BUFFER(lname, vname, predicate, doc) \
4949 do { \
4950 static struct Lisp_Buffer_Objfwd bo_fwd; \
4951 defvar_per_buffer (&bo_fwd, lname, vname, predicate); \
4952 } while (0)
4953
4954 static void
4955 defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
4956 Lisp_Object *address, Lisp_Object predicate)
4957 {
4958 struct Lisp_Symbol *sym;
4959 int offset;
4960
4961 sym = XSYMBOL (intern (namestring));
4962 offset = (char *)address - (char *)current_buffer;
4963
4964 bo_fwd->type = Lisp_Fwd_Buffer_Obj;
4965 bo_fwd->offset = offset;
4966 bo_fwd->predicate = predicate;
4967 sym->u.s.declared_special = true;
4968 sym->u.s.redirect = SYMBOL_FORWARDED;
4969 SET_SYMBOL_FWD (sym, bo_fwd);
4970 XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym);
4971
4972 if (PER_BUFFER_IDX (offset) == 0)
4973
4974
4975 emacs_abort ();
4976 }
4977
4978 #ifdef ITREE_DEBUG
4979 static Lisp_Object
4980 make_lispy_itree_node (const struct itree_node *node)
4981 {
4982 return listn (12,
4983 intern (":begin"),
4984 make_fixnum (node->begin),
4985 intern (":end"),
4986 make_fixnum (node->end),
4987 intern (":limit"),
4988 make_fixnum (node->limit),
4989 intern (":offset"),
4990 make_fixnum (node->offset),
4991 intern (":rear-advance"),
4992 node->rear_advance ? Qt : Qnil,
4993 intern (":front-advance"),
4994 node->front_advance ? Qt : Qnil);
4995 }
4996
4997 static Lisp_Object
4998 overlay_tree (const struct itree_tree *tree,
4999 const struct itree_node *node)
5000 {
5001 if (node == ITREE_NULL)
5002 return Qnil;
5003 return list3 (make_lispy_itree_node (node),
5004 overlay_tree (tree, node->left),
5005 overlay_tree (tree, node->right));
5006 }
5007
5008 DEFUN ("overlay-tree", Foverlay_tree, Soverlay_tree, 0, 1, 0,
5009 doc: )
5010 (Lisp_Object buffer)
5011 {
5012 struct buffer *b = decode_buffer (buffer);
5013 if (! b->overlays)
5014 return Qnil;
5015 return overlay_tree (b->overlays, b->overlays->root);
5016 }
5017 #endif
5018
5019
5020
5021
5022 void
5023 syms_of_buffer (void)
5024 {
5025 staticpro (&last_overlay_modification_hooks);
5026 last_overlay_modification_hooks = make_nil_vector (10);
5027
5028 staticpro (&QSFundamental);
5029 staticpro (&Vbuffer_alist);
5030
5031 DEFSYM (Qchoice, "choice");
5032 DEFSYM (Qleft, "left");
5033 DEFSYM (Qright, "right");
5034 DEFSYM (Qrange, "range");
5035
5036 DEFSYM (Qpermanent_local_hook, "permanent-local-hook");
5037 DEFSYM (Qoverlayp, "overlayp");
5038 DEFSYM (Qevaporate, "evaporate");
5039 DEFSYM (Qmodification_hooks, "modification-hooks");
5040 DEFSYM (Qinsert_in_front_hooks, "insert-in-front-hooks");
5041 DEFSYM (Qinsert_behind_hooks, "insert-behind-hooks");
5042 DEFSYM (Qget_file_buffer, "get-file-buffer");
5043 DEFSYM (Qpriority, "priority");
5044 DEFSYM (Qbefore_string, "before-string");
5045 DEFSYM (Qafter_string, "after-string");
5046 DEFSYM (Qfirst_change_hook, "first-change-hook");
5047 DEFSYM (Qbefore_change_functions, "before-change-functions");
5048 DEFSYM (Qafter_change_functions, "after-change-functions");
5049 DEFSYM (Qkill_buffer_query_functions, "kill-buffer-query-functions");
5050 DEFSYM (Qget_scratch_buffer_create, "get-scratch-buffer-create");
5051
5052 DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar");
5053 Fput (Qvertical_scroll_bar, Qchoice, list4 (Qnil, Qt, Qleft, Qright));
5054 DEFSYM (Qhorizontal_scroll_bar, "horizontal-scroll-bar");
5055
5056 DEFSYM (Qfraction, "fraction");
5057 Fput (Qfraction, Qrange, Fcons (make_float (0.0), make_float (1.0)));
5058
5059 DEFSYM (Qoverwrite_mode, "overwrite-mode");
5060 Fput (Qoverwrite_mode, Qchoice,
5061 list3 (Qnil, intern ("overwrite-mode-textual"),
5062 Qoverwrite_mode_binary));
5063
5064 Fput (Qprotected_field, Qerror_conditions,
5065 pure_list (Qprotected_field, Qerror));
5066 Fput (Qprotected_field, Qerror_message,
5067 build_pure_c_string ("Attempt to modify a protected field"));
5068
5069 DEFSYM (Qclone_indirect_buffer_hook, "clone-indirect-buffer-hook");
5070
5071 DEFVAR_PER_BUFFER ("tab-line-format",
5072 &BVAR (current_buffer, tab_line_format),
5073 Qnil,
5074 doc:
5075
5076 );
5077
5078 DEFVAR_PER_BUFFER ("header-line-format",
5079 &BVAR (current_buffer, header_line_format),
5080 Qnil,
5081 doc:
5082
5083
5084
5085
5086 );
5087
5088 DEFVAR_PER_BUFFER ("mode-line-format", &BVAR (current_buffer, mode_line_format),
5089 Qnil,
5090 doc:
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157 );
5158
5159 DEFVAR_PER_BUFFER ("major-mode", &BVAR (current_buffer, major_mode),
5160 Qsymbolp,
5161 doc:
5162
5163
5164 );
5165
5166 DEFVAR_PER_BUFFER ("local-minor-modes",
5167 &BVAR (current_buffer, local_minor_modes),
5168 Qnil,
5169 doc:
5170 );
5171
5172 DEFVAR_PER_BUFFER ("mode-name", &BVAR (current_buffer, mode_name),
5173 Qnil,
5174 doc:
5175
5176
5177 );
5178
5179 DEFVAR_PER_BUFFER ("local-abbrev-table", &BVAR (current_buffer, abbrev_table), Qnil,
5180 doc: );
5181
5182 DEFVAR_PER_BUFFER ("abbrev-mode", &BVAR (current_buffer, abbrev_mode), Qnil,
5183 doc:
5184 );
5185
5186 DEFVAR_PER_BUFFER ("case-fold-search", &BVAR (current_buffer, case_fold_search),
5187 Qnil,
5188 doc: );
5189
5190 DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column),
5191 Qintegerp,
5192 doc:
5193
5194
5195
5196 );
5197
5198 DEFVAR_PER_BUFFER ("left-margin", &BVAR (current_buffer, left_margin),
5199 Qintegerp,
5200 doc:
5201 );
5202
5203 DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width),
5204 Qintegerp,
5205 doc:
5206
5207
5208
5209
5210
5211 );
5212
5213 DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil,
5214 doc:
5215
5216
5217 );
5218
5219 DEFVAR_PER_BUFFER ("enable-multibyte-characters",
5220 &BVAR (current_buffer, enable_multibyte_characters),
5221 Qnil,
5222 doc:
5223
5224
5225
5226
5227
5228
5229
5230 );
5231 make_symbol_constant (intern_c_string ("enable-multibyte-characters"));
5232
5233 DEFVAR_PER_BUFFER ("buffer-file-coding-system",
5234 &BVAR (current_buffer, buffer_file_coding_system), Qnil,
5235 doc:
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249 );
5250
5251 DEFVAR_PER_BUFFER ("bidi-display-reordering",
5252 &BVAR (current_buffer, bidi_display_reordering), Qnil,
5253 doc:
5254
5255
5256
5257 );
5258
5259 DEFVAR_PER_BUFFER ("bidi-paragraph-start-re",
5260 &BVAR (current_buffer, bidi_paragraph_start_re), Qnil,
5261 doc:
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279 );
5280
5281 DEFVAR_PER_BUFFER ("bidi-paragraph-separate-re",
5282 &BVAR (current_buffer, bidi_paragraph_separate_re), Qnil,
5283 doc:
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300 );
5301
5302 DEFVAR_PER_BUFFER ("bidi-paragraph-direction",
5303 &BVAR (current_buffer, bidi_paragraph_direction), Qnil,
5304 doc:
5305
5306
5307
5308
5309
5310
5311
5312 );
5313
5314 DEFVAR_PER_BUFFER ("truncate-lines", &BVAR (current_buffer, truncate_lines), Qnil,
5315 doc:
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325 );
5326
5327 DEFVAR_PER_BUFFER ("word-wrap", &BVAR (current_buffer, word_wrap), Qnil,
5328 doc:
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343 );
5344
5345 DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory),
5346 Qstringp,
5347 doc:
5348
5349
5350 );
5351
5352 DEFVAR_PER_BUFFER ("auto-fill-function", &BVAR (current_buffer, auto_fill_function),
5353 Qnil,
5354 doc:
5355
5356
5357
5358 );
5359
5360 DEFVAR_PER_BUFFER ("buffer-file-name", &BVAR (current_buffer, filename),
5361 Qstringp,
5362 doc:
5363 );
5364
5365 DEFVAR_PER_BUFFER ("buffer-file-truename", &BVAR (current_buffer, file_truename),
5366 Qstringp,
5367 doc:
5368
5369 );
5370
5371 DEFVAR_PER_BUFFER ("buffer-auto-save-file-name",
5372 &BVAR (current_buffer, auto_save_file_name),
5373 Qstringp,
5374 doc:
5375 );
5376
5377 DEFVAR_PER_BUFFER ("buffer-read-only", &BVAR (current_buffer, read_only), Qnil,
5378 doc: );
5379
5380 DEFVAR_PER_BUFFER ("buffer-backed-up", &BVAR (current_buffer, backed_up), Qnil,
5381 doc:
5382 );
5383
5384 DEFVAR_PER_BUFFER ("buffer-saved-size", &BVAR (current_buffer, save_length),
5385 Qintegerp,
5386 doc:
5387
5388
5389
5390
5391
5392 );
5393
5394 DEFVAR_PER_BUFFER ("selective-display", &BVAR (current_buffer, selective_display),
5395 Qnil,
5396 doc:
5397
5398
5399
5400
5401
5402
5403
5404 );
5405
5406 DEFVAR_PER_BUFFER ("selective-display-ellipses",
5407 &BVAR (current_buffer, selective_display_ellipses),
5408 Qnil,
5409 doc: );
5410
5411 DEFVAR_PER_BUFFER ("overwrite-mode", &BVAR (current_buffer, overwrite_mode),
5412 Qoverwrite_mode,
5413 doc:
5414
5415
5416
5417
5418
5419 );
5420
5421 DEFVAR_PER_BUFFER ("buffer-display-table", &BVAR (current_buffer, display_table),
5422 Qnil,
5423 doc:
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456 );
5457
5458 DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols),
5459 Qintegerp,
5460 doc:
5461
5462
5463
5464 );
5465
5466 DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols),
5467 Qintegerp,
5468 doc:
5469
5470
5471
5472 );
5473
5474 DEFVAR_PER_BUFFER ("left-fringe-width", &BVAR (current_buffer, left_fringe_width),
5475 Qintegerp,
5476 doc:
5477
5478
5479
5480
5481 );
5482
5483 DEFVAR_PER_BUFFER ("right-fringe-width", &BVAR (current_buffer, right_fringe_width),
5484 Qintegerp,
5485 doc:
5486
5487
5488
5489
5490 );
5491
5492 DEFVAR_PER_BUFFER ("fringes-outside-margins", &BVAR (current_buffer, fringes_outside_margins),
5493 Qnil,
5494 doc:
5495
5496
5497
5498 );
5499
5500 DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width),
5501 Qintegerp,
5502 doc:
5503 );
5504
5505 DEFVAR_PER_BUFFER ("scroll-bar-height", &BVAR (current_buffer, scroll_bar_height),
5506 Qintegerp,
5507 doc:
5508 );
5509
5510 DEFVAR_PER_BUFFER ("vertical-scroll-bar", &BVAR (current_buffer, vertical_scroll_bar_type),
5511 Qvertical_scroll_bar,
5512 doc:
5513
5514
5515
5516
5517
5518 );
5519
5520 DEFVAR_PER_BUFFER ("horizontal-scroll-bar", &BVAR (current_buffer, horizontal_scroll_bar_type),
5521 Qnil,
5522 doc:
5523
5524
5525
5526
5527
5528
5529 );
5530
5531 DEFVAR_PER_BUFFER ("indicate-empty-lines",
5532 &BVAR (current_buffer, indicate_empty_lines), Qnil,
5533 doc:
5534
5535
5536 );
5537
5538 DEFVAR_PER_BUFFER ("indicate-buffer-boundaries",
5539 &BVAR (current_buffer, indicate_buffer_boundaries), Qnil,
5540 doc:
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561 );
5562
5563 DEFVAR_PER_BUFFER ("fringe-indicator-alist",
5564 &BVAR (current_buffer, fringe_indicator_alist), Qnil,
5565 doc:
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580 );
5581
5582 DEFVAR_PER_BUFFER ("fringe-cursor-alist",
5583 &BVAR (current_buffer, fringe_cursor_alist), Qnil,
5584 doc:
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595 );
5596
5597 DEFVAR_PER_BUFFER ("scroll-up-aggressively",
5598 &BVAR (current_buffer, scroll_up_aggressively), Qfraction,
5599 doc:
5600
5601
5602
5603
5604
5605
5606
5607
5608 );
5609
5610 DEFVAR_PER_BUFFER ("scroll-down-aggressively",
5611 &BVAR (current_buffer, scroll_down_aggressively), Qfraction,
5612 doc:
5613
5614
5615
5616
5617
5618
5619
5620
5621 );
5622
5623 DEFVAR_LISP ("before-change-functions", Vbefore_change_functions,
5624 doc:
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636 );
5637 Vbefore_change_functions = Qnil;
5638
5639 DEFVAR_LISP ("after-change-functions", Vafter_change_functions,
5640 doc:
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654 );
5655 Vafter_change_functions = Qnil;
5656
5657 DEFVAR_LISP ("first-change-hook", Vfirst_change_hook,
5658 doc:
5659 );
5660 Vfirst_change_hook = Qnil;
5661
5662 DEFVAR_PER_BUFFER ("buffer-undo-list", &BVAR (current_buffer, undo_list), Qnil,
5663 doc:
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706 );
5707
5708 DEFVAR_PER_BUFFER ("mark-active", &BVAR (current_buffer, mark_active), Qnil,
5709 doc: );
5710
5711 DEFVAR_PER_BUFFER ("cache-long-scans", &BVAR (current_buffer, cache_long_scans), Qnil,
5712 doc:
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745 );
5746
5747 DEFVAR_PER_BUFFER ("point-before-scroll", &BVAR (current_buffer, point_before_scroll), Qnil,
5748 doc: );
5749
5750 DEFVAR_PER_BUFFER ("buffer-file-format", &BVAR (current_buffer, file_format), Qnil,
5751 doc:
5752
5753 );
5754
5755 DEFVAR_PER_BUFFER ("buffer-auto-save-file-format",
5756 &BVAR (current_buffer, auto_save_file_format), Qnil,
5757 doc:
5758
5759
5760 );
5761
5762 DEFVAR_PER_BUFFER ("buffer-invisibility-spec",
5763 &BVAR (current_buffer, invisibility_spec), Qnil,
5764 doc:
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774 );
5775
5776 DEFVAR_PER_BUFFER ("buffer-display-count",
5777 &BVAR (current_buffer, display_count), Qintegerp,
5778 doc:
5779 );
5780
5781 DEFVAR_PER_BUFFER ("buffer-display-time",
5782 &BVAR (current_buffer, display_time), Qnil,
5783 doc:
5784
5785
5786 );
5787
5788 DEFVAR_LISP ("transient-mark-mode", Vtransient_mark_mode,
5789 doc:
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807 );
5808 Vtransient_mark_mode = Qnil;
5809
5810 DEFVAR_LISP ("inhibit-read-only", Vinhibit_read_only,
5811 doc:
5812
5813
5814
5815 );
5816 Vinhibit_read_only = Qnil;
5817
5818 DEFVAR_PER_BUFFER ("cursor-type", &BVAR (current_buffer, cursor_type), Qnil,
5819 doc:
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839 );
5840
5841 DEFVAR_PER_BUFFER ("line-spacing",
5842 &BVAR (current_buffer, extra_line_spacing), Qnumberp,
5843 doc:
5844
5845
5846
5847 );
5848
5849 DEFVAR_PER_BUFFER ("cursor-in-non-selected-windows",
5850 &BVAR (current_buffer, cursor_in_non_selected_windows), Qnil,
5851 doc:
5852
5853
5854
5855
5856 );
5857
5858 DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions,
5859 doc:
5860
5861
5862
5863
5864
5865
5866
5867
5868 );
5869 Vkill_buffer_query_functions = Qnil;
5870
5871 DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook,
5872 doc:
5873 );
5874 Vchange_major_mode_hook = Qnil;
5875 DEFSYM (Qchange_major_mode_hook, "change-major-mode-hook");
5876
5877 DEFVAR_LISP ("buffer-list-update-hook", Vbuffer_list_update_hook,
5878 doc:
5879
5880
5881
5882
5883
5884
5885
5886 );
5887 Vbuffer_list_update_hook = Qnil;
5888 DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");
5889
5890 DEFVAR_BOOL ("kill-buffer-delete-auto-save-files",
5891 kill_buffer_delete_auto_save_files,
5892 doc:
5893
5894 );
5895 kill_buffer_delete_auto_save_files = 0;
5896
5897 DEFVAR_BOOL ("delete-auto-save-files", delete_auto_save_files,
5898 doc:
5899 );
5900 delete_auto_save_files = 1;
5901
5902 DEFVAR_LISP ("clone-indirect-buffer-hook", Vclone_indirect_buffer_hook,
5903 doc:
5904
5905
5906 );
5907 Vclone_indirect_buffer_hook = Qnil;
5908
5909 DEFVAR_LISP ("long-line-threshold", Vlong_line_threshold,
5910 doc:
5911
5912
5913
5914
5915
5916
5917
5918
5919 );
5920 XSETFASTINT (Vlong_line_threshold, 50000);
5921
5922 DEFVAR_INT ("long-line-optimizations-region-size",
5923 long_line_optimizations_region_size,
5924 doc:
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937 );
5938 long_line_optimizations_region_size = 500000;
5939
5940 DEFVAR_INT ("long-line-optimizations-bol-search-limit",
5941 long_line_optimizations_bol_search_limit,
5942 doc:
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955 );
5956 long_line_optimizations_bol_search_limit = 128;
5957
5958 DEFVAR_INT ("large-hscroll-threshold", large_hscroll_threshold,
5959 doc:
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973 );
5974 large_hscroll_threshold = 10000;
5975
5976 defsubr (&Sbuffer_live_p);
5977 defsubr (&Sbuffer_list);
5978 defsubr (&Sget_buffer);
5979 defsubr (&Sget_file_buffer);
5980 defsubr (&Sget_buffer_create);
5981 defsubr (&Smake_indirect_buffer);
5982 defsubr (&Sgenerate_new_buffer_name);
5983 defsubr (&Sbuffer_name);
5984 defsubr (&Sbuffer_file_name);
5985 defsubr (&Sbuffer_base_buffer);
5986 defsubr (&Sbuffer_local_value);
5987 defsubr (&Sbuffer_local_variables);
5988 defsubr (&Sbuffer_modified_p);
5989 defsubr (&Sforce_mode_line_update);
5990 defsubr (&Sset_buffer_modified_p);
5991 defsubr (&Sbuffer_modified_tick);
5992 defsubr (&Sinternal__set_buffer_modified_tick);
5993 defsubr (&Sbuffer_chars_modified_tick);
5994 defsubr (&Srename_buffer);
5995 defsubr (&Sother_buffer);
5996 defsubr (&Sbuffer_enable_undo);
5997 defsubr (&Skill_buffer);
5998 defsubr (&Sbury_buffer_internal);
5999 defsubr (&Sset_buffer_major_mode);
6000 defsubr (&Scurrent_buffer);
6001 defsubr (&Sset_buffer);
6002 defsubr (&Sbarf_if_buffer_read_only);
6003 defsubr (&Serase_buffer);
6004 defsubr (&Sbuffer_swap_text);
6005 defsubr (&Sset_buffer_multibyte);
6006 defsubr (&Skill_all_local_variables);
6007
6008 defsubr (&Soverlayp);
6009 defsubr (&Smake_overlay);
6010 defsubr (&Sdelete_overlay);
6011 defsubr (&Sdelete_all_overlays);
6012 defsubr (&Smove_overlay);
6013 defsubr (&Soverlay_start);
6014 defsubr (&Soverlay_end);
6015 defsubr (&Soverlay_buffer);
6016 defsubr (&Soverlay_properties);
6017 defsubr (&Soverlays_at);
6018 defsubr (&Soverlays_in);
6019 defsubr (&Snext_overlay_change);
6020 defsubr (&Sprevious_overlay_change);
6021 defsubr (&Soverlay_recenter);
6022 defsubr (&Soverlay_lists);
6023 defsubr (&Soverlay_get);
6024 defsubr (&Soverlay_put);
6025 defsubr (&Srestore_buffer_modified_p);
6026
6027 DEFSYM (Qautosaved, "autosaved");
6028
6029 #ifdef ITREE_DEBUG
6030 defsubr (&Soverlay_tree);
6031 #endif
6032
6033 DEFSYM (Qkill_buffer__possibly_save, "kill-buffer--possibly-save");
6034
6035 DEFSYM (Qbuffer_stale_function, "buffer-stale-function");
6036
6037 Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt);
6038 }