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