aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer.c
diff options
context:
space:
mode:
authorStefan Monnier2022-09-25 16:15:16 -0400
committerStefan Monnier2022-09-25 16:15:16 -0400
commit650c20f1ca4e07591a727e1cfcc74b3363d15985 (patch)
tree85d11f6437cde22f410c25e0e5f71a3131ebd07d /src/buffer.c
parent8869332684c2302b5ba1ead4568bbc7ba1c0183e (diff)
parent4b85ae6a24380fb67a3315eaec9233f17a872473 (diff)
downloademacs-650c20f1ca4e07591a727e1cfcc74b3363d15985.tar.gz
emacs-650c20f1ca4e07591a727e1cfcc74b3363d15985.zip
Merge 'master' into noverlay
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c1178
1 files changed, 701 insertions, 477 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 9ddc9c7e056..1bb2af98e75 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1,7 +1,6 @@
1/* Buffer manipulation primitives for GNU Emacs. 1/* Buffer manipulation primitives for GNU Emacs.
2 2
3Copyright (C) 1985-1989, 1993-1995, 1997-2017 Free Software Foundation, 3Copyright (C) 1985-2022 Free Software Foundation, Inc.
4Inc.
5 4
6This file is part of GNU Emacs. 5This file is part of GNU Emacs.
7 6
@@ -45,16 +44,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
45#include "frame.h" 44#include "frame.h"
46#include "xwidget.h" 45#include "xwidget.h"
47#include "itree.h" 46#include "itree.h"
47#include "pdumper.h"
48 48
49#ifdef WINDOWSNT 49#ifdef WINDOWSNT
50#include "w32heap.h" /* for mmap_* */ 50#include "w32heap.h" /* for mmap_* */
51#endif 51#endif
52 52
53/* First buffer in chain of all buffers (in reverse order of creation).
54 Threaded through ->header.next.buffer. */
55
56struct buffer *all_buffers;
57
58/* This structure holds the default values of the buffer-local variables 53/* This structure holds the default values of the buffer-local variables
59 defined with DEFVAR_PER_BUFFER, that have special slots in each buffer. 54 defined with DEFVAR_PER_BUFFER, that have special slots in each buffer.
60 The default value occupies the same slot in this structure 55 The default value occupies the same slot in this structure
@@ -62,12 +57,13 @@ struct buffer *all_buffers;
62 Setting the default value also goes through the alist of buffers 57 Setting the default value also goes through the alist of buffers
63 and stores into each buffer that does not say it has a local value. */ 58 and stores into each buffer that does not say it has a local value. */
64 59
65struct buffer alignas (GCALIGNMENT) buffer_defaults; 60struct buffer buffer_defaults;
66 61
67/* This structure marks which slots in a buffer have corresponding 62/* This structure marks which slots in a buffer have corresponding
68 default values in buffer_defaults. 63 default values in buffer_defaults.
69 Each such slot has a nonzero value in this structure. 64 Each such slot has a value in this structure.
70 The value has only one nonzero bit. 65 The value is a positive Lisp integer that must be smaller than
66 MAX_PER_BUFFER_VARS.
71 67
72 When a buffer has its own local value for a slot, 68 When a buffer has its own local value for a slot,
73 the entry for that slot (found in the same slot in this structure) 69 the entry for that slot (found in the same slot in this structure)
@@ -85,7 +81,7 @@ struct buffer buffer_local_flags;
85/* This structure holds the names of symbols whose values may be 81/* This structure holds the names of symbols whose values may be
86 buffer-local. It is indexed and accessed in the same way as the above. */ 82 buffer-local. It is indexed and accessed in the same way as the above. */
87 83
88struct buffer alignas (GCALIGNMENT) buffer_local_symbols; 84struct buffer buffer_local_symbols;
89 85
90/* Return the symbol of the per-buffer variable at offset OFFSET in 86/* Return the symbol of the per-buffer variable at offset OFFSET in
91 the buffer structure. */ 87 the buffer structure. */
@@ -104,12 +100,11 @@ static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
104 100
105/* Number of per-buffer variables used. */ 101/* Number of per-buffer variables used. */
106 102
107int last_per_buffer_idx; 103static int last_per_buffer_idx;
108 104
109static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, 105static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay,
110 bool after, Lisp_Object arg1, 106 bool after, Lisp_Object arg1,
111 Lisp_Object arg2, Lisp_Object arg3); 107 Lisp_Object arg2, Lisp_Object arg3);
112static void swap_out_buffer_local_variables (struct buffer *b);
113static void reset_buffer_local_variables (struct buffer *, bool); 108static void reset_buffer_local_variables (struct buffer *, bool);
114 109
115/* Alist of all buffer names vs the buffers. This used to be 110/* Alist of all buffer names vs the buffers. This used to be
@@ -124,6 +119,7 @@ static void free_buffer_text (struct buffer *b);
124static void copy_overlays (struct buffer *, struct buffer *); 119static void copy_overlays (struct buffer *, struct buffer *);
125static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t); 120static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t);
126static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool); 121static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool);
122static Lisp_Object buffer_local_variables_1 (struct buffer *buf, int offset, Lisp_Object sym);
127 123
128static void 124static void
129CHECK_OVERLAY (Lisp_Object x) 125CHECK_OVERLAY (Lisp_Object x)
@@ -131,6 +127,23 @@ CHECK_OVERLAY (Lisp_Object x)
131 CHECK_TYPE (OVERLAYP (x), Qoverlayp, x); 127 CHECK_TYPE (OVERLAYP (x), Qoverlayp, x);
132} 128}
133 129
130/* Convert the position POS to an EMACS_INT that fits in a fixnum.
131 Yield POS's value if POS is already a fixnum, POS's marker position
132 if POS is a marker, and MOST_NEGATIVE_FIXNUM or
133 MOST_POSITIVE_FIXNUM if POS is a negative or positive bignum.
134 Signal an error if POS is not of the proper form. */
135
136EMACS_INT
137fix_position (Lisp_Object pos)
138{
139 if (FIXNUMP (pos))
140 return XFIXNUM (pos);
141 if (MARKERP (pos))
142 return marker_position (pos);
143 CHECK_TYPE (BIGNUMP (pos), Qinteger_or_marker_p, pos);
144 return !NILP (Fnatnump (pos)) ? MOST_POSITIVE_FIXNUM : MOST_NEGATIVE_FIXNUM;
145}
146
134/* These setters are used only in this file, so they can be private. 147/* These setters are used only in this file, so they can be private.
135 The public setters are inline functions defined in buffer.h. */ 148 The public setters are inline functions defined in buffer.h. */
136static void 149static void
@@ -249,6 +262,11 @@ bset_header_line_format (struct buffer *b, Lisp_Object val)
249 b->header_line_format_ = val; 262 b->header_line_format_ = val;
250} 263}
251static void 264static void
265bset_tab_line_format (struct buffer *b, Lisp_Object val)
266{
267 b->tab_line_format_ = val;
268}
269static void
252bset_indicate_buffer_boundaries (struct buffer *b, Lisp_Object val) 270bset_indicate_buffer_boundaries (struct buffer *b, Lisp_Object val)
253{ 271{
254 b->indicate_buffer_boundaries_ = val; 272 b->indicate_buffer_boundaries_ = val;
@@ -274,14 +292,14 @@ bset_major_mode (struct buffer *b, Lisp_Object val)
274 b->major_mode_ = val; 292 b->major_mode_ = val;
275} 293}
276static void 294static void
277bset_mark (struct buffer *b, Lisp_Object val) 295bset_local_minor_modes (struct buffer *b, Lisp_Object val)
278{ 296{
279 b->mark_ = val; 297 b->local_minor_modes_ = val;
280} 298}
281static void 299static void
282bset_minor_modes (struct buffer *b, Lisp_Object val) 300bset_mark (struct buffer *b, Lisp_Object val)
283{ 301{
284 b->minor_modes_ = val; 302 b->mark_ = val;
285} 303}
286static void 304static void
287bset_mode_line_format (struct buffer *b, Lisp_Object val) 305bset_mode_line_format (struct buffer *b, Lisp_Object val)
@@ -378,7 +396,7 @@ nsberror (Lisp_Object spec)
378} 396}
379 397
380DEFUN ("buffer-live-p", Fbuffer_live_p, Sbuffer_live_p, 1, 1, 0, 398DEFUN ("buffer-live-p", Fbuffer_live_p, Sbuffer_live_p, 1, 1, 0,
381 doc: /* Return non-nil if OBJECT is a buffer which has not been killed. 399 doc: /* Return t if OBJECT is a buffer which has not been killed.
382Value is nil if OBJECT is not a buffer or if it has been killed. */) 400Value is nil if OBJECT is not a buffer or if it has been killed. */)
383 (Lisp_Object object) 401 (Lisp_Object object)
384{ 402{
@@ -387,9 +405,9 @@ Value is nil if OBJECT is not a buffer or if it has been killed. */)
387} 405}
388 406
389DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0, 407DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0,
390 doc: /* Return a list of all existing live buffers. 408 doc: /* Return a list of all live buffers.
391If the optional arg FRAME is a frame, we return the buffer list in the 409If the optional arg FRAME is a frame, return the buffer list in the
392proper order for that frame: the buffers show in FRAME come first, 410proper order for that frame: the buffers shown in FRAME come first,
393followed by the rest of the buffers. */) 411followed by the rest of the buffers. */)
394 (Lisp_Object frame) 412 (Lisp_Object frame)
395{ 413{
@@ -468,7 +486,7 @@ See also `find-buffer-visiting'. */)
468 filename = Fexpand_file_name (filename, Qnil); 486 filename = Fexpand_file_name (filename, Qnil);
469 487
470 /* If the file name has special constructs in it, 488 /* If the file name has special constructs in it,
471 call the corresponding file handler. */ 489 call the corresponding file name handler. */
472 handler = Ffind_file_name_handler (filename, Qget_file_buffer); 490 handler = Ffind_file_name_handler (filename, Qget_file_buffer);
473 if (!NILP (handler)) 491 if (!NILP (handler))
474 { 492 {
@@ -500,16 +518,33 @@ get_truename_buffer (register Lisp_Object filename)
500 return Qnil; 518 return Qnil;
501} 519}
502 520
503DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 1, 0, 521/* Run buffer-list-update-hook if Vrun_hooks is non-nil, and BUF is NULL
522 or does not have buffer hooks inhibited. BUF is NULL when called by
523 make-indirect-buffer, since it does not inhibit buffer hooks. */
524
525static void
526run_buffer_list_update_hook (struct buffer *buf)
527{
528 if (! (NILP (Vrun_hooks) || (buf && buf->inhibit_buffer_hooks)))
529 call1 (Vrun_hooks, Qbuffer_list_update_hook);
530}
531
532DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 2, 0,
504 doc: /* Return the buffer specified by BUFFER-OR-NAME, creating a new one if needed. 533 doc: /* Return the buffer specified by BUFFER-OR-NAME, creating a new one if needed.
505If BUFFER-OR-NAME is a string and a live buffer with that name exists, 534If BUFFER-OR-NAME is a string and a live buffer with that name exists,
506return that buffer. If no such buffer exists, create a new buffer with 535return that buffer. If no such buffer exists, create a new buffer with
507that name and return it. If BUFFER-OR-NAME starts with a space, the new 536that name and return it.
508buffer does not keep undo information. 537
538If BUFFER-OR-NAME starts with a space, the new buffer does not keep undo
539information. If optional argument INHIBIT-BUFFER-HOOKS is non-nil, the
540new buffer does not run the hooks `kill-buffer-hook',
541`kill-buffer-query-functions', and `buffer-list-update-hook'. This
542avoids slowing down internal or temporary buffers that are never
543presented to users or passed on to other applications.
509 544
510If BUFFER-OR-NAME is a buffer instead of a string, return it as given, 545If BUFFER-OR-NAME is a buffer instead of a string, return it as given,
511even if it is dead. The return value is never nil. */) 546even if it is dead. The return value is never nil. */)
512 (register Lisp_Object buffer_or_name) 547 (register Lisp_Object buffer_or_name, Lisp_Object inhibit_buffer_hooks)
513{ 548{
514 register Lisp_Object buffer, name; 549 register Lisp_Object buffer, name;
515 register struct buffer *b; 550 register struct buffer *b;
@@ -531,6 +566,8 @@ even if it is dead. The return value is never nil. */)
531 /* No one shows us now. */ 566 /* No one shows us now. */
532 b->window_count = 0; 567 b->window_count = 0;
533 568
569 memset (&b->local_flags, 0, sizeof (b->local_flags));
570
534 BUF_GAP_SIZE (b) = 20; 571 BUF_GAP_SIZE (b) = 20;
535 block_input (); 572 block_input ();
536 /* We allocate extra 1-byte at the tail and keep it always '\0' for 573 /* We allocate extra 1-byte at the tail and keep it always '\0' for
@@ -560,6 +597,7 @@ even if it is dead. The return value is never nil. */)
560 set_buffer_intervals (b, NULL); 597 set_buffer_intervals (b, NULL);
561 BUF_UNCHANGED_MODIFIED (b) = 1; 598 BUF_UNCHANGED_MODIFIED (b) = 1;
562 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1; 599 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1;
600 BUF_CHARS_UNCHANGED_MODIFIED (b) = 1;
563 BUF_END_UNCHANGED (b) = 0; 601 BUF_END_UNCHANGED (b) = 0;
564 BUF_BEG_UNCHANGED (b) = 0; 602 BUF_BEG_UNCHANGED (b) = 0;
565 *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */ 603 *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */
@@ -582,6 +620,7 @@ even if it is dead. The return value is never nil. */)
582 set_string_intervals (name, NULL); 620 set_string_intervals (name, NULL);
583 bset_name (b, name); 621 bset_name (b, name);
584 622
623 b->inhibit_buffer_hooks = !NILP (inhibit_buffer_hooks);
585 bset_undo_list (b, SREF (name, 0) != ' ' ? Qnil : Qt); 624 bset_undo_list (b, SREF (name, 0) != ' ' ? Qnil : Qt);
586 625
587 reset_buffer (b); 626 reset_buffer (b);
@@ -593,9 +632,8 @@ even if it is dead. The return value is never nil. */)
593 /* Put this in the alist of all live buffers. */ 632 /* Put this in the alist of all live buffers. */
594 XSETBUFFER (buffer, b); 633 XSETBUFFER (buffer, b);
595 Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buffer))); 634 Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buffer)));
596 /* And run buffer-list-update-hook. */ 635
597 if (!NILP (Vrun_hooks)) 636 run_buffer_list_update_hook (b);
598 call1 (Vrun_hooks, Qbuffer_list_update_hook);
599 637
600 return buffer; 638 return buffer;
601} 639}
@@ -622,6 +660,12 @@ copy_overlays (struct buffer *from, struct buffer *to)
622 buffer_overlay_iter_finish (from); 660 buffer_overlay_iter_finish (from);
623} 661}
624 662
663bool
664valid_per_buffer_idx (int idx)
665{
666 return 0 <= idx && idx < last_per_buffer_idx;
667}
668
625/* Clone per-buffer values of buffer FROM. 669/* Clone per-buffer values of buffer FROM.
626 670
627 Buffer TO gets the same per-buffer values as FROM, with the 671 Buffer TO gets the same per-buffer values as FROM, with the
@@ -711,15 +755,22 @@ fetch_buffer_markers (struct buffer *b)
711 755
712 756
713DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, Smake_indirect_buffer, 757DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, Smake_indirect_buffer,
714 2, 3, 758 2, 4,
715 "bMake indirect buffer (to buffer): \nBName of indirect buffer: ", 759 "bMake indirect buffer (to buffer): \nBName of indirect buffer: ",
716 doc: /* Create and return an indirect buffer for buffer BASE-BUFFER, named NAME. 760 doc: /* Create and return an indirect buffer for buffer BASE-BUFFER, named NAME.
717BASE-BUFFER should be a live buffer, or the name of an existing buffer. 761BASE-BUFFER should be a live buffer, or the name of an existing buffer.
762
718NAME should be a string which is not the name of an existing buffer. 763NAME should be a string which is not the name of an existing buffer.
719Optional argument CLONE non-nil means preserve BASE-BUFFER's state, 764Optional argument CLONE non-nil means preserve BASE-BUFFER's state,
720such as major and minor modes, in the indirect buffer. 765such as major and minor modes, in the indirect buffer.
721CLONE nil means the indirect buffer's state is reset to default values. */) 766
722 (Lisp_Object base_buffer, Lisp_Object name, Lisp_Object clone) 767CLONE nil means the indirect buffer's state is reset to default values.
768
769If optional argument INHIBIT-BUFFER-HOOKS is non-nil, the new buffer
770does not run the hooks `kill-buffer-hook',
771`kill-buffer-query-functions', and `buffer-list-update-hook'. */)
772 (Lisp_Object base_buffer, Lisp_Object name, Lisp_Object clone,
773 Lisp_Object inhibit_buffer_hooks)
723{ 774{
724 Lisp_Object buf, tem; 775 Lisp_Object buf, tem;
725 struct buffer *b; 776 struct buffer *b;
@@ -756,12 +807,15 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
756 /* Always -1 for an indirect buffer. */ 807 /* Always -1 for an indirect buffer. */
757 b->window_count = -1; 808 b->window_count = -1;
758 809
810 memset (&b->local_flags, 0, sizeof (b->local_flags));
811
759 b->pt = b->base_buffer->pt; 812 b->pt = b->base_buffer->pt;
760 b->begv = b->base_buffer->begv; 813 b->begv = b->base_buffer->begv;
761 b->zv = b->base_buffer->zv; 814 b->zv = b->base_buffer->zv;
762 b->pt_byte = b->base_buffer->pt_byte; 815 b->pt_byte = b->base_buffer->pt_byte;
763 b->begv_byte = b->base_buffer->begv_byte; 816 b->begv_byte = b->base_buffer->begv_byte;
764 b->zv_byte = b->base_buffer->zv_byte; 817 b->zv_byte = b->base_buffer->zv_byte;
818 b->inhibit_buffer_hooks = !NILP (inhibit_buffer_hooks);
765 819
766 b->newline_cache = 0; 820 b->newline_cache = 0;
767 b->width_run_cache = 0; 821 b->width_run_cache = 0;
@@ -824,19 +878,23 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
824 clone_per_buffer_values (b->base_buffer, b); 878 clone_per_buffer_values (b->base_buffer, b);
825 bset_filename (b, Qnil); 879 bset_filename (b, Qnil);
826 bset_file_truename (b, Qnil); 880 bset_file_truename (b, Qnil);
827 bset_display_count (b, make_number (0)); 881 bset_display_count (b, make_fixnum (0));
828 bset_backed_up (b, Qnil); 882 bset_backed_up (b, Qnil);
883 bset_local_minor_modes (b, Qnil);
829 bset_auto_save_file_name (b, Qnil); 884 bset_auto_save_file_name (b, Qnil);
830 set_buffer_internal_1 (b); 885 set_buffer_internal_1 (b);
831 Fset (intern ("buffer-save-without-query"), Qnil); 886 Fset (intern ("buffer-save-without-query"), Qnil);
832 Fset (intern ("buffer-file-number"), Qnil); 887 Fset (intern ("buffer-file-number"), Qnil);
833 Fset (intern ("buffer-stale-function"), Qnil); 888 if (!NILP (Flocal_variable_p (Qbuffer_stale_function, base_buffer)))
889 Fkill_local_variable (Qbuffer_stale_function);
890 /* Cloned buffers need extra setup, to do things such as deep
891 variable copies for list variables that might be mangled due
892 to destructive operations in the indirect buffer. */
893 run_hook (Qclone_indirect_buffer_hook);
834 set_buffer_internal_1 (old_b); 894 set_buffer_internal_1 (old_b);
835 } 895 }
836 896
837 /* Run buffer-list-update-hook. */ 897 run_buffer_list_update_hook (NULL);
838 if (!NILP (Vrun_hooks))
839 call1 (Vrun_hooks, Qbuffer_list_update_hook);
840 898
841 return buf; 899 return buf;
842} 900}
@@ -944,7 +1002,9 @@ reset_buffer (register struct buffer *b)
944 /* It is more conservative to start out "changed" than "unchanged". */ 1002 /* It is more conservative to start out "changed" than "unchanged". */
945 b->clip_changed = 0; 1003 b->clip_changed = 0;
946 b->prevent_redisplay_optimizations_p = 1; 1004 b->prevent_redisplay_optimizations_p = 1;
1005 b->long_line_optimizations_p = 0;
947 bset_backed_up (b, Qnil); 1006 bset_backed_up (b, Qnil);
1007 bset_local_minor_modes (b, Qnil);
948 BUF_AUTOSAVE_MODIFF (b) = 0; 1008 BUF_AUTOSAVE_MODIFF (b) = 0;
949 b->auto_save_failure_time = 0; 1009 b->auto_save_failure_time = 0;
950 bset_auto_save_file_name (b, Qnil); 1010 bset_auto_save_file_name (b, Qnil);
@@ -955,7 +1015,7 @@ reset_buffer (register struct buffer *b)
955 bset_file_format (b, Qnil); 1015 bset_file_format (b, Qnil);
956 bset_auto_save_file_format (b, Qt); 1016 bset_auto_save_file_format (b, Qt);
957 bset_last_selected_window (b, Qnil); 1017 bset_last_selected_window (b, Qnil);
958 bset_display_count (b, make_number (0)); 1018 bset_display_count (b, make_fixnum (0));
959 bset_display_time (b, Qnil); 1019 bset_display_time (b, Qnil);
960 bset_enable_multibyte_characters 1020 bset_enable_multibyte_characters
961 (b, BVAR (&buffer_defaults, enable_multibyte_characters)); 1021 (b, BVAR (&buffer_defaults, enable_multibyte_characters));
@@ -985,7 +1045,6 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too)
985 bset_major_mode (b, Qfundamental_mode); 1045 bset_major_mode (b, Qfundamental_mode);
986 bset_keymap (b, Qnil); 1046 bset_keymap (b, Qnil);
987 bset_mode_name (b, QSFundamental); 1047 bset_mode_name (b, QSFundamental);
988 bset_minor_modes (b, Qnil);
989 1048
990 /* If the standard case table has been altered and invalidated, 1049 /* If the standard case table has been altered and invalidated,
991 fix up its insides first. */ 1050 fix up its insides first. */
@@ -1006,10 +1065,29 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too)
1006 else 1065 else
1007 { 1066 {
1008 Lisp_Object tmp, last = Qnil; 1067 Lisp_Object tmp, last = Qnil;
1068 Lisp_Object buffer;
1069 XSETBUFFER (buffer, b);
1070
1009 for (tmp = BVAR (b, local_var_alist); CONSP (tmp); tmp = XCDR (tmp)) 1071 for (tmp = BVAR (b, local_var_alist); CONSP (tmp); tmp = XCDR (tmp))
1010 { 1072 {
1011 Lisp_Object local_var = XCAR (XCAR (tmp)); 1073 Lisp_Object local_var = XCAR (XCAR (tmp));
1012 Lisp_Object prop = Fget (local_var, Qpermanent_local); 1074 Lisp_Object prop = Fget (local_var, Qpermanent_local);
1075 Lisp_Object sym = local_var;
1076
1077 /* Watchers are run *before* modifying the var. */
1078 if (XSYMBOL (local_var)->u.s.trapped_write == SYMBOL_TRAPPED_WRITE)
1079 notify_variable_watchers (local_var, Qnil,
1080 Qmakunbound, Fcurrent_buffer ());
1081
1082 eassert (XSYMBOL (sym)->u.s.redirect == SYMBOL_LOCALIZED);
1083 /* Need not do anything if some other buffer's binding is
1084 now cached. */
1085 if (BASE_EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
1086 {
1087 /* Symbol is set up for this buffer's old local value:
1088 swap it out! */
1089 swap_in_global_binding (XSYMBOL (sym));
1090 }
1013 1091
1014 if (!NILP (prop)) 1092 if (!NILP (prop))
1015 { 1093 {
@@ -1027,16 +1105,17 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too)
1027 for (newlist = Qnil; CONSP (list); list = XCDR (list)) 1105 for (newlist = Qnil; CONSP (list); list = XCDR (list))
1028 { 1106 {
1029 Lisp_Object elt = XCAR (list); 1107 Lisp_Object elt = XCAR (list);
1030 /* Preserve element ELT if it's t, 1108 /* Preserve element ELT if it's t, or if it is a
1031 if it is a function with a `permanent-local-hook' property, 1109 function with a `permanent-local-hook'
1032 or if it's not a symbol. */ 1110 property. */
1033 if (! SYMBOLP (elt) 1111 if (EQ (elt, Qt)
1034 || EQ (elt, Qt) 1112 || (SYMBOLP (elt)
1035 || !NILP (Fget (elt, Qpermanent_local_hook))) 1113 && !NILP (Fget (elt, Qpermanent_local_hook))))
1036 newlist = Fcons (elt, newlist); 1114 newlist = Fcons (elt, newlist);
1037 } 1115 }
1038 newlist = Fnreverse (newlist); 1116 newlist = Fnreverse (newlist);
1039 if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE) 1117 if (XSYMBOL (local_var)->u.s.trapped_write
1118 == SYMBOL_TRAPPED_WRITE)
1040 notify_variable_watchers (local_var, newlist, 1119 notify_variable_watchers (local_var, newlist,
1041 Qmakunbound, Fcurrent_buffer ()); 1120 Qmakunbound, Fcurrent_buffer ());
1042 XSETCDR (XCAR (tmp), newlist); 1121 XSETCDR (XCAR (tmp), newlist);
@@ -1048,10 +1127,6 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too)
1048 bset_local_var_alist (b, XCDR (tmp)); 1127 bset_local_var_alist (b, XCDR (tmp));
1049 else 1128 else
1050 XSETCDR (last, XCDR (tmp)); 1129 XSETCDR (last, XCDR (tmp));
1051
1052 if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE)
1053 notify_variable_watchers (local_var, Qnil,
1054 Qmakunbound, Fcurrent_buffer ());
1055 } 1130 }
1056 } 1131 }
1057 1132
@@ -1100,8 +1175,11 @@ is first appended to NAME, to speed up finding a non-existent buffer. */)
1100 genbase = name; 1175 genbase = name;
1101 else 1176 else
1102 { 1177 {
1103 char number[sizeof "-999999"]; 1178 enum { bug_52711 = true }; /* https://bugs.gnu.org/57211 */
1104 int i = XFASTINT (Frandom (make_number (999999))); 1179 char number[bug_52711 ? INT_BUFSIZE_BOUND (int) + 1 : sizeof "-999999"];
1180 EMACS_INT r = get_random ();
1181 eassume (0 <= r);
1182 int i = r % 1000000;
1105 AUTO_STRING_WITH_LEN (lnumber, number, sprintf (number, "-%d", i)); 1183 AUTO_STRING_WITH_LEN (lnumber, number, sprintf (number, "-%d", i));
1106 genbase = concat2 (name, lnumber); 1184 genbase = concat2 (name, lnumber);
1107 if (NILP (Fget_buffer (genbase))) 1185 if (NILP (Fget_buffer (genbase)))
@@ -1158,7 +1236,7 @@ is the default binding of the variable. */)
1158{ 1236{
1159 register Lisp_Object result = buffer_local_value (variable, buffer); 1237 register Lisp_Object result = buffer_local_value (variable, buffer);
1160 1238
1161 if (EQ (result, Qunbound)) 1239 if (BASE_EQ (result, Qunbound))
1162 xsignal1 (Qvoid_variable, variable); 1240 xsignal1 (Qvoid_variable, variable);
1163 1241
1164 return result; 1242 return result;
@@ -1181,7 +1259,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer)
1181 sym = XSYMBOL (variable); 1259 sym = XSYMBOL (variable);
1182 1260
1183 start: 1261 start:
1184 switch (sym->redirect) 1262 switch (sym->u.s.redirect)
1185 { 1263 {
1186 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1264 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1187 case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break; 1265 case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break;
@@ -1189,10 +1267,10 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer)
1189 { /* Look in local_var_alist. */ 1267 { /* Look in local_var_alist. */
1190 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); 1268 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1191 XSETSYMBOL (variable, sym); /* Update In case of aliasing. */ 1269 XSETSYMBOL (variable, sym); /* Update In case of aliasing. */
1192 result = Fassoc (variable, BVAR (buf, local_var_alist), Qnil); 1270 result = assq_no_quit (variable, BVAR (buf, local_var_alist));
1193 if (!NILP (result)) 1271 if (!NILP (result))
1194 { 1272 {
1195 if (blv->fwd) 1273 if (blv->fwd.fwdptr)
1196 { /* What binding is loaded right now? */ 1274 { /* What binding is loaded right now? */
1197 Lisp_Object current_alist_element = blv->valcell; 1275 Lisp_Object current_alist_element = blv->valcell;
1198 1276
@@ -1213,7 +1291,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer)
1213 } 1291 }
1214 case SYMBOL_FORWARDED: 1292 case SYMBOL_FORWARDED:
1215 { 1293 {
1216 union Lisp_Fwd *fwd = SYMBOL_FWD (sym); 1294 lispfwd fwd = SYMBOL_FWD (sym);
1217 if (BUFFER_OBJFWDP (fwd)) 1295 if (BUFFER_OBJFWDP (fwd))
1218 result = per_buffer_value (buf, XBUFFER_OBJFWD (fwd)->offset); 1296 result = per_buffer_value (buf, XBUFFER_OBJFWD (fwd)->offset);
1219 else 1297 else
@@ -1253,7 +1331,7 @@ buffer_lisp_local_variables (struct buffer *buf, bool clone)
1253 if (buf != current_buffer) 1331 if (buf != current_buffer)
1254 val = XCDR (elt); 1332 val = XCDR (elt);
1255 1333
1256 result = Fcons (!clone && EQ (val, Qunbound) 1334 result = Fcons (!clone && BASE_EQ (val, Qunbound)
1257 ? XCAR (elt) 1335 ? XCAR (elt)
1258 : Fcons (XCAR (elt), val), 1336 : Fcons (XCAR (elt), val),
1259 result); 1337 result);
@@ -1262,6 +1340,25 @@ buffer_lisp_local_variables (struct buffer *buf, bool clone)
1262 return result; 1340 return result;
1263} 1341}
1264 1342
1343
1344/* If the variable at position index OFFSET in buffer BUF has a
1345 buffer-local value, return (name . value). If SYM is non-nil,
1346 it replaces name. */
1347
1348static Lisp_Object
1349buffer_local_variables_1 (struct buffer *buf, int offset, Lisp_Object sym)
1350{
1351 int idx = PER_BUFFER_IDX (offset);
1352 if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
1353 && SYMBOLP (PER_BUFFER_SYMBOL (offset)))
1354 {
1355 sym = NILP (sym) ? PER_BUFFER_SYMBOL (offset) : sym;
1356 Lisp_Object val = per_buffer_value (buf, offset);
1357 return BASE_EQ (val, Qunbound) ? sym : Fcons (sym, val);
1358 }
1359 return Qnil;
1360}
1361
1265DEFUN ("buffer-local-variables", Fbuffer_local_variables, 1362DEFUN ("buffer-local-variables", Fbuffer_local_variables,
1266 Sbuffer_local_variables, 0, 1, 0, 1363 Sbuffer_local_variables, 0, 1, 0,
1267 doc: /* Return an alist of variables that are buffer-local in BUFFER. 1364 doc: /* Return an alist of variables that are buffer-local in BUFFER.
@@ -1273,42 +1370,53 @@ No argument or nil as argument means use current buffer as BUFFER. */)
1273{ 1370{
1274 struct buffer *buf = decode_buffer (buffer); 1371 struct buffer *buf = decode_buffer (buffer);
1275 Lisp_Object result = buffer_lisp_local_variables (buf, 0); 1372 Lisp_Object result = buffer_lisp_local_variables (buf, 0);
1373 Lisp_Object tem;
1276 1374
1277 /* Add on all the variables stored in special slots. */ 1375 /* Add on all the variables stored in special slots. */
1278 { 1376 {
1279 int offset, idx; 1377 int offset;
1280 1378
1281 FOR_EACH_PER_BUFFER_OBJECT_AT (offset) 1379 FOR_EACH_PER_BUFFER_OBJECT_AT (offset)
1282 { 1380 {
1283 idx = PER_BUFFER_IDX (offset); 1381 tem = buffer_local_variables_1 (buf, offset, Qnil);
1284 if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx)) 1382 if (!NILP (tem))
1285 && SYMBOLP (PER_BUFFER_SYMBOL (offset))) 1383 result = Fcons (tem, result);
1286 {
1287 Lisp_Object sym = PER_BUFFER_SYMBOL (offset);
1288 Lisp_Object val = per_buffer_value (buf, offset);
1289 result = Fcons (EQ (val, Qunbound) ? sym : Fcons (sym, val),
1290 result);
1291 }
1292 } 1384 }
1293 } 1385 }
1294 1386
1387 tem = buffer_local_variables_1 (buf, PER_BUFFER_VAR_OFFSET (undo_list),
1388 intern ("buffer-undo-list"));
1389 if (!NILP (tem))
1390 result = Fcons (tem, result);
1391
1295 return result; 1392 return result;
1296} 1393}
1297 1394
1298DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p, 1395DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p,
1299 0, 1, 0, 1396 0, 1, 0,
1300 doc: /* Return t if BUFFER was modified since its file was last read or saved. 1397 doc: /* Return non-nil if BUFFER was modified since its file was last read or saved.
1301No argument or nil as argument means use current buffer as BUFFER. */) 1398No argument or nil as argument means use current buffer as BUFFER.
1399
1400If BUFFER was autosaved since it was last modified, this function
1401returns the symbol `autosaved'. */)
1302 (Lisp_Object buffer) 1402 (Lisp_Object buffer)
1303{ 1403{
1304 struct buffer *buf = decode_buffer (buffer); 1404 struct buffer *buf = decode_buffer (buffer);
1305 return BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf) ? Qt : Qnil; 1405 if (BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf))
1406 {
1407 if (BUF_AUTOSAVE_MODIFF (buf) == BUF_MODIFF (buf))
1408 return Qautosaved;
1409 else
1410 return Qt;
1411 }
1412 else
1413 return Qnil;
1306} 1414}
1307 1415
1308DEFUN ("force-mode-line-update", Fforce_mode_line_update, 1416DEFUN ("force-mode-line-update", Fforce_mode_line_update,
1309 Sforce_mode_line_update, 0, 1, 0, 1417 Sforce_mode_line_update, 0, 1, 0,
1310 doc: /* Force redisplay of the current buffer's mode line and header line. 1418 doc: /* Force redisplay of the current buffer's mode line and header line.
1311With optional non-nil ALL, force redisplay of all mode lines and 1419With optional non-nil ALL, force redisplay of all mode lines, tab lines and
1312header lines. This function also forces recomputation of the 1420header lines. This function also forces recomputation of the
1313menu bar menus and the frame title. */) 1421menu bar menus and the frame title. */)
1314 (Lisp_Object all) 1422 (Lisp_Object all)
@@ -1330,7 +1438,12 @@ menu bar menus and the frame title. */)
1330DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p, 1438DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p,
1331 1, 1, 0, 1439 1, 1, 0,
1332 doc: /* Mark current buffer as modified or unmodified according to FLAG. 1440 doc: /* Mark current buffer as modified or unmodified according to FLAG.
1333A non-nil FLAG means mark the buffer modified. */) 1441A non-nil FLAG means mark the buffer modified.
1442In addition, this function unconditionally forces redisplay of the
1443mode lines of the windows that display the current buffer, and also
1444locks or unlocks the file visited by the buffer, depending on whether
1445the function's argument is non-nil, but only if both `buffer-file-name'
1446and `buffer-file-truename' are non-nil. */)
1334 (Lisp_Object flag) 1447 (Lisp_Object flag)
1335{ 1448{
1336 Frestore_buffer_modified_p (flag); 1449 Frestore_buffer_modified_p (flag);
@@ -1351,12 +1464,19 @@ A non-nil FLAG means mark the buffer modified. */)
1351 1464
1352DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p, 1465DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p,
1353 Srestore_buffer_modified_p, 1, 1, 0, 1466 Srestore_buffer_modified_p, 1, 1, 0,
1354 doc: /* Like `set-buffer-modified-p', with a difference concerning redisplay. 1467 doc: /* Like `set-buffer-modified-p', but doesn't redisplay buffer's mode line.
1468A nil FLAG means to mark the buffer as unmodified. A non-nil FLAG
1469means mark the buffer as modified. A special value of `autosaved'
1470will mark the buffer as modified and also as autosaved since it was
1471last modified.
1472
1473This function also locks or unlocks the file visited by the buffer,
1474if both `buffer-file-truename' and `buffer-file-name' are non-nil.
1475
1355It is not ensured that mode lines will be updated to show the modified 1476It is not ensured that mode lines will be updated to show the modified
1356state of the current buffer. Use with care. */) 1477state of the current buffer. Use with care. */)
1357 (Lisp_Object flag) 1478 (Lisp_Object flag)
1358{ 1479{
1359 Lisp_Object fn;
1360 1480
1361 /* If buffer becoming modified, lock the file. 1481 /* If buffer becoming modified, lock the file.
1362 If buffer becoming unmodified, unlock the file. */ 1482 If buffer becoming unmodified, unlock the file. */
@@ -1365,15 +1485,18 @@ state of the current buffer. Use with care. */)
1365 ? current_buffer->base_buffer 1485 ? current_buffer->base_buffer
1366 : current_buffer; 1486 : current_buffer;
1367 1487
1368 fn = BVAR (b, file_truename); 1488 if (!inhibit_modification_hooks)
1369 /* Test buffer-file-name so that binding it to nil is effective. */
1370 if (!NILP (fn) && ! NILP (BVAR (b, filename)))
1371 { 1489 {
1372 bool already = SAVE_MODIFF < MODIFF; 1490 Lisp_Object fn = BVAR (b, file_truename);
1373 if (!already && !NILP (flag)) 1491 /* Test buffer-file-name so that binding it to nil is effective. */
1374 lock_file (fn); 1492 if (!NILP (fn) && ! NILP (BVAR (b, filename)))
1375 else if (already && NILP (flag)) 1493 {
1376 unlock_file (fn); 1494 bool already = SAVE_MODIFF < MODIFF;
1495 if (!already && !NILP (flag))
1496 Flock_file (fn);
1497 else if (already && NILP (flag))
1498 Funlock_file (fn);
1499 }
1377 } 1500 }
1378 1501
1379 /* Here we have a problem. SAVE_MODIFF is used here to encode 1502 /* Here we have a problem. SAVE_MODIFF is used here to encode
@@ -1386,16 +1509,19 @@ state of the current buffer. Use with care. */)
1386 recent-auto-save-p from t to nil. 1509 recent-auto-save-p from t to nil.
1387 Vice versa, if FLAG is non-nil and SAVE_MODIFF>=auto_save_modified 1510 Vice versa, if FLAG is non-nil and SAVE_MODIFF>=auto_save_modified
1388 we risk changing recent-auto-save-p from nil to t. */ 1511 we risk changing recent-auto-save-p from nil to t. */
1389 SAVE_MODIFF = (NILP (flag) 1512 if (NILP (flag))
1390 /* FIXME: This unavoidably sets recent-auto-save-p to nil. */ 1513 /* This unavoidably sets recent-auto-save-p to nil. */
1391 ? MODIFF 1514 SAVE_MODIFF = MODIFF;
1392 /* Let's try to preserve recent-auto-save-p. */ 1515 else
1393 : SAVE_MODIFF < MODIFF ? SAVE_MODIFF 1516 {
1394 /* If SAVE_MODIFF == auto_save_modified == MODIFF, 1517 /* If SAVE_MODIFF == auto_save_modified == MODIFF, we can either
1395 we can either decrease SAVE_MODIFF and auto_save_modified 1518 decrease SAVE_MODIFF and auto_save_modified or increase
1396 or increase MODIFF. */ 1519 MODIFF. */
1397 : MODIFF++); 1520 if (SAVE_MODIFF >= MODIFF)
1398 1521 SAVE_MODIFF = modiff_incr (&MODIFF, 1);
1522 if (EQ (flag, Qautosaved))
1523 BUF_AUTOSAVE_MODIFF (b) = MODIFF;
1524 }
1399 return flag; 1525 return flag;
1400} 1526}
1401 1527
@@ -1403,11 +1529,23 @@ DEFUN ("buffer-modified-tick", Fbuffer_modified_tick, Sbuffer_modified_tick,
1403 0, 1, 0, 1529 0, 1, 0,
1404 doc: /* Return BUFFER's tick counter, incremented for each change in text. 1530 doc: /* Return BUFFER's tick counter, incremented for each change in text.
1405Each buffer has a tick counter which is incremented each time the 1531Each buffer has a tick counter which is incremented each time the
1406text in that buffer is changed. It wraps around occasionally. 1532text in that buffer is changed. No argument or nil as argument means
1533use current buffer as BUFFER. */)
1534 (Lisp_Object buffer)
1535{
1536 return modiff_to_integer (BUF_MODIFF (decode_buffer (buffer)));
1537}
1538
1539DEFUN ("internal--set-buffer-modified-tick",
1540 Finternal__set_buffer_modified_tick, Sinternal__set_buffer_modified_tick,
1541 1, 2, 0,
1542 doc: /* Set BUFFER's tick counter to TICK.
1407No argument or nil as argument means use current buffer as BUFFER. */) 1543No argument or nil as argument means use current buffer as BUFFER. */)
1408 (register Lisp_Object buffer) 1544 (Lisp_Object tick, Lisp_Object buffer)
1409{ 1545{
1410 return make_number (BUF_MODIFF (decode_buffer (buffer))); 1546 CHECK_FIXNUM (tick);
1547 BUF_MODIFF (decode_buffer (buffer)) = XFIXNUM (tick);
1548 return Qnil;
1411} 1549}
1412 1550
1413DEFUN ("buffer-chars-modified-tick", Fbuffer_chars_modified_tick, 1551DEFUN ("buffer-chars-modified-tick", Fbuffer_chars_modified_tick,
@@ -1420,9 +1558,9 @@ values returned by two individual calls of `buffer-chars-modified-tick',
1420you can tell whether a character change occurred in that buffer in 1558you can tell whether a character change occurred in that buffer in
1421between these calls. No argument or nil as argument means use current 1559between these calls. No argument or nil as argument means use current
1422buffer as BUFFER. */) 1560buffer as BUFFER. */)
1423 (register Lisp_Object buffer) 1561 (Lisp_Object buffer)
1424{ 1562{
1425 return make_number (BUF_CHARS_MODIFF (decode_buffer (buffer))); 1563 return modiff_to_integer (BUF_CHARS_MODIFF (decode_buffer (buffer)));
1426} 1564}
1427 1565
1428DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2, 1566DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2,
@@ -1440,6 +1578,7 @@ This does not change the name of the visited file (if any). */)
1440 (register Lisp_Object newname, Lisp_Object unique) 1578 (register Lisp_Object newname, Lisp_Object unique)
1441{ 1579{
1442 register Lisp_Object tem, buf; 1580 register Lisp_Object tem, buf;
1581 Lisp_Object requestedname = newname;
1443 1582
1444 CHECK_STRING (newname); 1583 CHECK_STRING (newname);
1445 1584
@@ -1456,7 +1595,8 @@ This does not change the name of the visited file (if any). */)
1456 if (NILP (unique) && XBUFFER (tem) == current_buffer) 1595 if (NILP (unique) && XBUFFER (tem) == current_buffer)
1457 return BVAR (current_buffer, name); 1596 return BVAR (current_buffer, name);
1458 if (!NILP (unique)) 1597 if (!NILP (unique))
1459 newname = Fgenerate_new_buffer_name (newname, BVAR (current_buffer, name)); 1598 newname = Fgenerate_new_buffer_name (newname,
1599 BVAR (current_buffer, name));
1460 else 1600 else
1461 error ("Buffer name `%s' is in use", SDATA (newname)); 1601 error ("Buffer name `%s' is in use", SDATA (newname));
1462 } 1602 }
@@ -1465,7 +1605,7 @@ This does not change the name of the visited file (if any). */)
1465 1605
1466 /* Catch redisplay's attention. Unless we do this, the mode lines for 1606 /* Catch redisplay's attention. Unless we do this, the mode lines for
1467 any windows displaying current_buffer will stay unchanged. */ 1607 any windows displaying current_buffer will stay unchanged. */
1468 update_mode_lines = 11; 1608 bset_update_mode_line (current_buffer);
1469 1609
1470 XSETBUFFER (buf, current_buffer); 1610 XSETBUFFER (buf, current_buffer);
1471 Fsetcar (Frassq (buf, Vbuffer_alist), newname); 1611 Fsetcar (Frassq (buf, Vbuffer_alist), newname);
@@ -1473,9 +1613,10 @@ This does not change the name of the visited file (if any). */)
1473 && !NILP (BVAR (current_buffer, auto_save_file_name))) 1613 && !NILP (BVAR (current_buffer, auto_save_file_name)))
1474 call0 (intern ("rename-auto-save-file")); 1614 call0 (intern ("rename-auto-save-file"));
1475 1615
1476 /* Run buffer-list-update-hook. */ 1616 run_buffer_list_update_hook (current_buffer);
1477 if (!NILP (Vrun_hooks)) 1617
1478 call1 (Vrun_hooks, Qbuffer_list_update_hook); 1618 call2 (intern ("uniquify--rename-buffer-advice"),
1619 requestedname, unique);
1479 1620
1480 /* Refetch since that last call may have done GC. */ 1621 /* Refetch since that last call may have done GC. */
1481 return BVAR (current_buffer, name); 1622 return BVAR (current_buffer, name);
@@ -1486,7 +1627,7 @@ This does not change the name of the visited file (if any). */)
1486static bool 1627static bool
1487candidate_buffer (Lisp_Object b, Lisp_Object buffer) 1628candidate_buffer (Lisp_Object b, Lisp_Object buffer)
1488{ 1629{
1489 return (BUFFERP (b) && !EQ (b, buffer) 1630 return (BUFFERP (b) && !BASE_EQ (b, buffer)
1490 && BUFFER_LIVE_P (XBUFFER (b)) 1631 && BUFFER_LIVE_P (XBUFFER (b))
1491 && !BUFFER_HIDDEN_P (XBUFFER (b))); 1632 && !BUFFER_HIDDEN_P (XBUFFER (b)));
1492} 1633}
@@ -1544,16 +1685,7 @@ exists, return the buffer `*scratch*' (creating it if necessary). */)
1544 if (!NILP (notsogood)) 1685 if (!NILP (notsogood))
1545 return notsogood; 1686 return notsogood;
1546 else 1687 else
1547 { 1688 return safe_call (1, Qget_scratch_buffer_create);
1548 AUTO_STRING (scratch, "*scratch*");
1549 buf = Fget_buffer (scratch);
1550 if (NILP (buf))
1551 {
1552 buf = Fget_buffer_create (scratch);
1553 Fset_buffer_major_mode (buf);
1554 }
1555 return buf;
1556 }
1557} 1689}
1558 1690
1559/* The following function is a safe variant of Fother_buffer: It doesn't 1691/* The following function is a safe variant of Fother_buffer: It doesn't
@@ -1569,15 +1701,7 @@ other_buffer_safely (Lisp_Object buffer)
1569 if (candidate_buffer (buf, buffer)) 1701 if (candidate_buffer (buf, buffer))
1570 return buf; 1702 return buf;
1571 1703
1572 AUTO_STRING (scratch, "*scratch*"); 1704 return safe_call (1, Qget_scratch_buffer_create);
1573 buf = Fget_buffer (scratch);
1574 if (NILP (buf))
1575 {
1576 buf = Fget_buffer_create (scratch);
1577 Fset_buffer_major_mode (buf);
1578 }
1579
1580 return buf;
1581} 1705}
1582 1706
1583DEFUN ("buffer-enable-undo", Fbuffer_enable_undo, Sbuffer_enable_undo, 1707DEFUN ("buffer-enable-undo", Fbuffer_enable_undo, Sbuffer_enable_undo,
@@ -1650,7 +1774,9 @@ buffer to be killed as the current buffer. If any of them returns nil,
1650the buffer is not killed. The hook `kill-buffer-hook' is run before the 1774the buffer is not killed. The hook `kill-buffer-hook' is run before the
1651buffer is actually killed. The buffer being killed will be current 1775buffer is actually killed. The buffer being killed will be current
1652while the hook is running. Functions called by any of these hooks are 1776while the hook is running. Functions called by any of these hooks are
1653supposed to not change the current buffer. 1777supposed to not change the current buffer. Neither hook is run for
1778internal or temporary buffers created by `get-buffer-create' or
1779`generate-new-buffer' with argument INHIBIT-BUFFER-HOOKS non-nil.
1654 1780
1655Any processes that have this buffer as the `process-buffer' are killed 1781Any processes that have this buffer as the `process-buffer' are killed
1656with SIGHUP. This function calls `replace-buffer-in-windows' for 1782with SIGHUP. This function calls `replace-buffer-in-windows' for
@@ -1678,28 +1804,54 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1678 if (thread_check_current_buffer (b)) 1804 if (thread_check_current_buffer (b))
1679 return Qnil; 1805 return Qnil;
1680 1806
1681 /* Run hooks with the buffer to be killed the current buffer. */ 1807 /* Run hooks with the buffer to be killed as the current buffer. */
1682 { 1808 {
1683 ptrdiff_t count = SPECPDL_INDEX (); 1809 specpdl_ref count = SPECPDL_INDEX ();
1810 bool modified;
1684 1811
1685 record_unwind_protect (save_excursion_restore, save_excursion_save ()); 1812 record_unwind_protect_excursion ();
1686 set_buffer_internal (b); 1813 set_buffer_internal (b);
1687 1814
1688 /* First run the query functions; if any query is answered no, 1815 /* First run the query functions; if any query is answered no,
1689 don't kill the buffer. */ 1816 don't kill the buffer. */
1690 tem = CALLN (Frun_hook_with_args_until_failure, 1817 if (!b->inhibit_buffer_hooks)
1691 Qkill_buffer_query_functions); 1818 {
1692 if (NILP (tem)) 1819 tem = CALLN (Frun_hook_with_args_until_failure,
1693 return unbind_to (count, Qnil); 1820 Qkill_buffer_query_functions);
1821 if (NILP (tem))
1822 return unbind_to (count, Qnil);
1823 }
1824
1825 /* Is this a modified buffer that's visiting a file? */
1826 modified = !NILP (BVAR (b, filename))
1827 && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
1694 1828
1695 /* Query if the buffer is still modified. */ 1829 /* Query if the buffer is still modified. */
1696 if (INTERACTIVE && !NILP (BVAR (b, filename)) 1830 if (INTERACTIVE && modified)
1697 && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
1698 { 1831 {
1699 AUTO_STRING (format, "Buffer %s modified; kill anyway? "); 1832 /* Ask whether to kill the buffer, and exit if the user says
1700 tem = do_yes_or_no_p (CALLN (Fformat, format, BVAR (b, name))); 1833 "no". */
1701 if (NILP (tem)) 1834 if (NILP (call1 (Qkill_buffer__possibly_save, buffer)))
1702 return unbind_to (count, Qnil); 1835 return unbind_to (count, Qnil);
1836 /* Recheck modified. */
1837 modified = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
1838 }
1839
1840 /* Delete the autosave file, if requested. */
1841 if (modified
1842 && kill_buffer_delete_auto_save_files
1843 && delete_auto_save_files
1844 && !NILP (Frecent_auto_save_p ())
1845 && STRINGP (BVAR (b, auto_save_file_name))
1846 && !NILP (Ffile_exists_p (BVAR (b, auto_save_file_name)))
1847 /* If `auto-save-visited-mode' is on, then we're auto-saving
1848 to the visited file -- don't delete it.. */
1849 && NILP (Fstring_equal (BVAR (b, auto_save_file_name),
1850 BVAR (b, filename))))
1851 {
1852 tem = do_yes_or_no_p (build_string ("Delete auto-save file? "));
1853 if (!NILP (tem))
1854 call0 (intern ("delete-auto-save-file-if-necessary"));
1703 } 1855 }
1704 1856
1705 /* If the hooks have killed the buffer, exit now. */ 1857 /* If the hooks have killed the buffer, exit now. */
@@ -1707,7 +1859,8 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1707 return unbind_to (count, Qt); 1859 return unbind_to (count, Qt);
1708 1860
1709 /* Then run the hooks. */ 1861 /* Then run the hooks. */
1710 run_hook (Qkill_buffer_hook); 1862 if (!b->inhibit_buffer_hooks)
1863 run_hook (Qkill_buffer_hook);
1711 unbind_to (count, Qnil); 1864 unbind_to (count, Qnil);
1712 } 1865 }
1713 1866
@@ -1720,7 +1873,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1720 since anything can happen within do_yes_or_no_p. */ 1873 since anything can happen within do_yes_or_no_p. */
1721 1874
1722 /* Don't kill the minibuffer now current. */ 1875 /* Don't kill the minibuffer now current. */
1723 if (EQ (buffer, XWINDOW (minibuf_window)->contents)) 1876 if (BASE_EQ (buffer, XWINDOW (minibuf_window)->contents))
1724 return Qnil; 1877 return Qnil;
1725 1878
1726 /* When we kill an ordinary buffer which shares its buffer text 1879 /* When we kill an ordinary buffer which shares its buffer text
@@ -1729,15 +1882,11 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1729 ask questions or their hooks get errors. */ 1882 ask questions or their hooks get errors. */
1730 if (!b->base_buffer && b->indirections > 0) 1883 if (!b->base_buffer && b->indirections > 0)
1731 { 1884 {
1732 struct buffer *other; 1885 Lisp_Object tail, other;
1733 1886
1734 FOR_EACH_BUFFER (other) 1887 FOR_EACH_LIVE_BUFFER (tail, other)
1735 if (other->base_buffer == b) 1888 if (XBUFFER (other)->base_buffer == b)
1736 { 1889 Fkill_buffer (other);
1737 Lisp_Object buf;
1738 XSETBUFFER (buf, other);
1739 Fkill_buffer (buf);
1740 }
1741 1890
1742 /* Exit if we now have killed the base buffer (Bug#11665). */ 1891 /* Exit if we now have killed the base buffer (Bug#11665). */
1743 if (!BUFFER_LIVE_P (b)) 1892 if (!BUFFER_LIVE_P (b))
@@ -1768,7 +1917,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1768 is the sole other buffer give up. */ 1917 is the sole other buffer give up. */
1769 XSETBUFFER (tem, current_buffer); 1918 XSETBUFFER (tem, current_buffer);
1770 if (EQ (tem, XWINDOW (minibuf_window)->contents) 1919 if (EQ (tem, XWINDOW (minibuf_window)->contents)
1771 && EQ (buffer, Fother_buffer (buffer, Qnil, Qnil))) 1920 && BASE_EQ (buffer, Fother_buffer (buffer, Qnil, Qnil)))
1772 return Qnil; 1921 return Qnil;
1773 1922
1774 /* Now there is no question: we can kill the buffer. */ 1923 /* Now there is no question: we can kill the buffer. */
@@ -1792,30 +1941,15 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1792 1941
1793 tem = Vinhibit_quit; 1942 tem = Vinhibit_quit;
1794 Vinhibit_quit = Qt; 1943 Vinhibit_quit = Qt;
1944 /* Once the buffer is removed from Vbuffer_alist, its undo_list field is
1945 not traced by the GC in the same way. So set it to nil early. */
1946 bset_undo_list (b, Qnil);
1795 /* Remove the buffer from the list of all buffers. */ 1947 /* Remove the buffer from the list of all buffers. */
1796 Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist); 1948 Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
1797 /* If replace_buffer_in_windows didn't do its job fix that now. */ 1949 /* If replace_buffer_in_windows didn't do its job fix that now. */
1798 replace_buffer_in_windows_safely (buffer); 1950 replace_buffer_in_windows_safely (buffer);
1799 Vinhibit_quit = tem; 1951 Vinhibit_quit = tem;
1800 1952
1801 /* Delete any auto-save file, if we saved it in this session.
1802 But not if the buffer is modified. */
1803 if (STRINGP (BVAR (b, auto_save_file_name))
1804 && BUF_AUTOSAVE_MODIFF (b) != 0
1805 && BUF_SAVE_MODIFF (b) < BUF_AUTOSAVE_MODIFF (b)
1806 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
1807 && NILP (Fsymbol_value (intern ("auto-save-visited-file-name"))))
1808 {
1809 Lisp_Object delete;
1810 delete = Fsymbol_value (intern ("delete-auto-save-files"));
1811 if (! NILP (delete))
1812 internal_delete_file (BVAR (b, auto_save_file_name));
1813 }
1814
1815 /* Deleting an auto-save file could have killed our buffer. */
1816 if (!BUFFER_LIVE_P (b))
1817 return Qt;
1818
1819 if (b->base_buffer) 1953 if (b->base_buffer)
1820 { 1954 {
1821 INTERVAL i; 1955 INTERVAL i;
@@ -1865,7 +1999,6 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1865 won't be protected from GC. They would be protected 1999 won't be protected from GC. They would be protected
1866 if they happened to remain cached in their symbols. 2000 if they happened to remain cached in their symbols.
1867 This gets rid of them for certain. */ 2001 This gets rid of them for certain. */
1868 swap_out_buffer_local_variables (b);
1869 reset_buffer_local_variables (b, 1); 2002 reset_buffer_local_variables (b, 1);
1870 2003
1871 bset_name (b, Qnil); 2004 bset_name (b, Qnil);
@@ -1905,11 +2038,8 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1905 } 2038 }
1906 bset_width_table (b, Qnil); 2039 bset_width_table (b, Qnil);
1907 unblock_input (); 2040 unblock_input ();
1908 bset_undo_list (b, Qnil);
1909 2041
1910 /* Run buffer-list-update-hook. */ 2042 run_buffer_list_update_hook (b);
1911 if (!NILP (Vrun_hooks))
1912 call1 (Vrun_hooks, Qbuffer_list_update_hook);
1913 2043
1914 return Qt; 2044 return Qt;
1915} 2045}
@@ -1949,9 +2079,7 @@ record_buffer (Lisp_Object buffer)
1949 fset_buffer_list (f, Fcons (buffer, Fdelq (buffer, f->buffer_list))); 2079 fset_buffer_list (f, Fcons (buffer, Fdelq (buffer, f->buffer_list)));
1950 fset_buried_buffer_list (f, Fdelq (buffer, f->buried_buffer_list)); 2080 fset_buried_buffer_list (f, Fdelq (buffer, f->buried_buffer_list));
1951 2081
1952 /* Run buffer-list-update-hook. */ 2082 run_buffer_list_update_hook (XBUFFER (buffer));
1953 if (!NILP (Vrun_hooks))
1954 call1 (Vrun_hooks, Qbuffer_list_update_hook);
1955} 2083}
1956 2084
1957 2085
@@ -1988,9 +2116,7 @@ DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal,
1988 fset_buried_buffer_list 2116 fset_buried_buffer_list
1989 (f, Fcons (buffer, Fdelq (buffer, f->buried_buffer_list))); 2117 (f, Fcons (buffer, Fdelq (buffer, f->buried_buffer_list)));
1990 2118
1991 /* Run buffer-list-update-hook. */ 2119 run_buffer_list_update_hook (XBUFFER (buffer));
1992 if (!NILP (Vrun_hooks))
1993 call1 (Vrun_hooks, Qbuffer_list_update_hook);
1994 2120
1995 return Qnil; 2121 return Qnil;
1996} 2122}
@@ -2003,7 +2129,6 @@ Use this function before selecting the buffer, since it may need to inspect
2003the current buffer's major mode. */) 2129the current buffer's major mode. */)
2004 (Lisp_Object buffer) 2130 (Lisp_Object buffer)
2005{ 2131{
2006 ptrdiff_t count;
2007 Lisp_Object function; 2132 Lisp_Object function;
2008 2133
2009 CHECK_BUFFER (buffer); 2134 CHECK_BUFFER (buffer);
@@ -2026,7 +2151,7 @@ the current buffer's major mode. */)
2026 `hack-local-variables' get run. */ 2151 `hack-local-variables' get run. */
2027 return Qnil; 2152 return Qnil;
2028 2153
2029 count = SPECPDL_INDEX (); 2154 specpdl_ref count = SPECPDL_INDEX ();
2030 2155
2031 /* To select a nonfundamental mode, 2156 /* To select a nonfundamental mode,
2032 select the buffer temporarily and then call the mode function. */ 2157 select the buffer temporarily and then call the mode function. */
@@ -2109,8 +2234,8 @@ void set_buffer_internal_2 (register struct buffer *b)
2109 { 2234 {
2110 Lisp_Object var = XCAR (XCAR (tail)); 2235 Lisp_Object var = XCAR (XCAR (tail));
2111 struct Lisp_Symbol *sym = XSYMBOL (var); 2236 struct Lisp_Symbol *sym = XSYMBOL (var);
2112 if (sym->redirect == SYMBOL_LOCALIZED /* Just to be sure. */ 2237 if (sym->u.s.redirect == SYMBOL_LOCALIZED /* Just to be sure. */
2113 && SYMBOL_BLV (sym)->fwd) 2238 && SYMBOL_BLV (sym)->fwd.fwdptr)
2114 /* Just reference the variable 2239 /* Just reference the variable
2115 to cause it to become set for this buffer. */ 2240 to cause it to become set for this buffer. */
2116 Fsymbol_value (var); 2241 Fsymbol_value (var);
@@ -2188,7 +2313,7 @@ If the text under POSITION (which defaults to point) has the
2188 if (NILP (position)) 2313 if (NILP (position))
2189 XSETFASTINT (position, PT); 2314 XSETFASTINT (position, PT);
2190 else 2315 else
2191 CHECK_NUMBER (position); 2316 CHECK_FIXNUM (position);
2192 2317
2193 if (!NILP (BVAR (current_buffer, read_only)) 2318 if (!NILP (BVAR (current_buffer, read_only))
2194 && NILP (Vinhibit_read_only) 2319 && NILP (Vinhibit_read_only)
@@ -2216,25 +2341,26 @@ so the buffer is truly empty after this. */)
2216} 2341}
2217 2342
2218void 2343void
2219validate_region (register Lisp_Object *b, register Lisp_Object *e) 2344validate_region (Lisp_Object *b, Lisp_Object *e)
2220{ 2345{
2221 CHECK_NUMBER_COERCE_MARKER (*b); 2346 EMACS_INT beg = fix_position (*b), end = fix_position (*e);
2222 CHECK_NUMBER_COERCE_MARKER (*e);
2223 2347
2224 if (XINT (*b) > XINT (*e)) 2348 if (end < beg)
2225 { 2349 {
2226 Lisp_Object tem; 2350 EMACS_INT tem = beg; beg = end; end = tem;
2227 tem = *b; *b = *e; *e = tem;
2228 } 2351 }
2229 2352
2230 if (! (BEGV <= XINT (*b) && XINT (*e) <= ZV)) 2353 if (! (BEGV <= beg && end <= ZV))
2231 args_out_of_range_3 (Fcurrent_buffer (), *b, *e); 2354 args_out_of_range_3 (Fcurrent_buffer (), *b, *e);
2355
2356 *b = make_fixnum (beg);
2357 *e = make_fixnum (end);
2232} 2358}
2233 2359
2234/* Advance BYTE_POS up to a character boundary 2360/* Advance BYTE_POS up to a character boundary
2235 and return the adjusted position. */ 2361 and return the adjusted position. */
2236 2362
2237static ptrdiff_t 2363ptrdiff_t
2238advance_to_char_boundary (ptrdiff_t byte_pos) 2364advance_to_char_boundary (ptrdiff_t byte_pos)
2239{ 2365{
2240 int c; 2366 int c;
@@ -2256,7 +2382,7 @@ advance_to_char_boundary (ptrdiff_t byte_pos)
2256 c = FETCH_BYTE (byte_pos); 2382 c = FETCH_BYTE (byte_pos);
2257 } 2383 }
2258 while (! CHAR_HEAD_P (c) && byte_pos > BEG); 2384 while (! CHAR_HEAD_P (c) && byte_pos > BEG);
2259 INC_POS (byte_pos); 2385 byte_pos += next_char_len (byte_pos);
2260 if (byte_pos < orig_byte_pos) 2386 if (byte_pos < orig_byte_pos)
2261 byte_pos = orig_byte_pos; 2387 byte_pos = orig_byte_pos;
2262 /* If C is a constituent of a multibyte sequence, BYTE_POS was 2388 /* If C is a constituent of a multibyte sequence, BYTE_POS was
@@ -2313,10 +2439,10 @@ results, see Info node `(elisp)Swapping Text'. */)
2313 error ("Cannot swap indirect buffers's text"); 2439 error ("Cannot swap indirect buffers's text");
2314 2440
2315 { /* This is probably harder to make work. */ 2441 { /* This is probably harder to make work. */
2316 struct buffer *other; 2442 Lisp_Object tail, other;
2317 FOR_EACH_BUFFER (other) 2443 FOR_EACH_LIVE_BUFFER (tail, other)
2318 if (other->base_buffer == other_buffer 2444 if (XBUFFER (other)->base_buffer == other_buffer
2319 || other->base_buffer == current_buffer) 2445 || XBUFFER (other)->base_buffer == current_buffer)
2320 error ("One of the buffers to swap has indirect buffers"); 2446 error ("One of the buffers to swap has indirect buffers");
2321 } 2447 }
2322 2448
@@ -2358,8 +2484,10 @@ results, see Info node `(elisp)Swapping Text'. */)
2358 swapfield (bidi_paragraph_cache, struct region_cache *); 2484 swapfield (bidi_paragraph_cache, struct region_cache *);
2359 current_buffer->prevent_redisplay_optimizations_p = 1; 2485 current_buffer->prevent_redisplay_optimizations_p = 1;
2360 other_buffer->prevent_redisplay_optimizations_p = 1; 2486 other_buffer->prevent_redisplay_optimizations_p = 1;
2487 swapfield (long_line_optimizations_p, bool_bf);
2361 swapfield_ (undo_list, Lisp_Object); 2488 swapfield_ (undo_list, Lisp_Object);
2362 swapfield_ (mark, Lisp_Object); 2489 swapfield_ (mark, Lisp_Object);
2490 swapfield_ (mark_active, Lisp_Object); /* Belongs with the `mark'. */
2363 swapfield_ (enable_multibyte_characters, Lisp_Object); 2491 swapfield_ (enable_multibyte_characters, Lisp_Object);
2364 swapfield_ (bidi_display_reordering, Lisp_Object); 2492 swapfield_ (bidi_display_reordering, Lisp_Object);
2365 swapfield_ (bidi_paragraph_direction, Lisp_Object); 2493 swapfield_ (bidi_paragraph_direction, Lisp_Object);
@@ -2373,9 +2501,12 @@ results, see Info node `(elisp)Swapping Text'. */)
2373 bset_point_before_scroll (current_buffer, Qnil); 2501 bset_point_before_scroll (current_buffer, Qnil);
2374 bset_point_before_scroll (other_buffer, Qnil); 2502 bset_point_before_scroll (other_buffer, Qnil);
2375 2503
2376 current_buffer->text->modiff++; other_buffer->text->modiff++; 2504 modiff_incr (&current_buffer->text->modiff, 1);
2377 current_buffer->text->chars_modiff++; other_buffer->text->chars_modiff++; 2505 modiff_incr (&other_buffer->text->modiff, 1);
2378 current_buffer->text->overlay_modiff++; other_buffer->text->overlay_modiff++; 2506 modiff_incr (&current_buffer->text->chars_modiff, 1);
2507 modiff_incr (&other_buffer->text->chars_modiff, 1);
2508 modiff_incr (&current_buffer->text->overlay_modiff, 1);
2509 modiff_incr (&other_buffer->text->overlay_modiff, 1);
2379 current_buffer->text->beg_unchanged = current_buffer->text->gpt; 2510 current_buffer->text->beg_unchanged = current_buffer->text->gpt;
2380 current_buffer->text->end_unchanged = current_buffer->text->gpt; 2511 current_buffer->text->end_unchanged = current_buffer->text->gpt;
2381 other_buffer->text->beg_unchanged = other_buffer->text->gpt; 2512 other_buffer->text->beg_unchanged = other_buffer->text->gpt;
@@ -2410,25 +2541,25 @@ results, see Info node `(elisp)Swapping Text'. */)
2410 { 2541 {
2411 ws = Fcons (w, ws); 2542 ws = Fcons (w, ws);
2412 if (MARKERP (XWINDOW (w)->pointm) 2543 if (MARKERP (XWINDOW (w)->pointm)
2413 && (EQ (XWINDOW (w)->contents, buf1) 2544 && (BASE_EQ (XWINDOW (w)->contents, buf1)
2414 || EQ (XWINDOW (w)->contents, buf2))) 2545 || BASE_EQ (XWINDOW (w)->contents, buf2)))
2415 Fset_marker (XWINDOW (w)->pointm, 2546 Fset_marker (XWINDOW (w)->pointm,
2416 make_number 2547 make_fixnum
2417 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))), 2548 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))),
2418 XWINDOW (w)->contents); 2549 XWINDOW (w)->contents);
2419 /* Blindly copied from pointm part. */ 2550 /* Blindly copied from pointm part. */
2420 if (MARKERP (XWINDOW (w)->old_pointm) 2551 if (MARKERP (XWINDOW (w)->old_pointm)
2421 && (EQ (XWINDOW (w)->contents, buf1) 2552 && (BASE_EQ (XWINDOW (w)->contents, buf1)
2422 || EQ (XWINDOW (w)->contents, buf2))) 2553 || BASE_EQ (XWINDOW (w)->contents, buf2)))
2423 Fset_marker (XWINDOW (w)->old_pointm, 2554 Fset_marker (XWINDOW (w)->old_pointm,
2424 make_number 2555 make_fixnum
2425 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))), 2556 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))),
2426 XWINDOW (w)->contents); 2557 XWINDOW (w)->contents);
2427 if (MARKERP (XWINDOW (w)->start) 2558 if (MARKERP (XWINDOW (w)->start)
2428 && (EQ (XWINDOW (w)->contents, buf1) 2559 && (BASE_EQ (XWINDOW (w)->contents, buf1)
2429 || EQ (XWINDOW (w)->contents, buf2))) 2560 || BASE_EQ (XWINDOW (w)->contents, buf2)))
2430 Fset_marker (XWINDOW (w)->start, 2561 Fset_marker (XWINDOW (w)->start,
2431 make_number 2562 make_fixnum
2432 (XBUFFER (XWINDOW (w)->contents)->last_window_start), 2563 (XBUFFER (XWINDOW (w)->contents)->last_window_start),
2433 XWINDOW (w)->contents); 2564 XWINDOW (w)->contents);
2434 w = Fnext_window (w, Qt, Qt); 2565 w = Fnext_window (w, Qt, Qt);
@@ -2436,10 +2567,11 @@ results, see Info node `(elisp)Swapping Text'. */)
2436 } 2567 }
2437 2568
2438 if (current_buffer->text->intervals) 2569 if (current_buffer->text->intervals)
2439 (eassert (EQ (current_buffer->text->intervals->up.obj, buffer)), 2570 (eassert (BASE_EQ (current_buffer->text->intervals->up.obj, buffer)),
2440 XSETBUFFER (current_buffer->text->intervals->up.obj, current_buffer)); 2571 XSETBUFFER (current_buffer->text->intervals->up.obj, current_buffer));
2441 if (other_buffer->text->intervals) 2572 if (other_buffer->text->intervals)
2442 (eassert (EQ (other_buffer->text->intervals->up.obj, Fcurrent_buffer ())), 2573 (eassert (BASE_EQ (other_buffer->text->intervals->up.obj,
2574 Fcurrent_buffer ())),
2443 XSETBUFFER (other_buffer->text->intervals->up.obj, other_buffer)); 2575 XSETBUFFER (other_buffer->text->intervals->up.obj, other_buffer));
2444 2576
2445 return Qnil; 2577 return Qnil;
@@ -2459,7 +2591,7 @@ current buffer is cleared. */)
2459 (Lisp_Object flag) 2591 (Lisp_Object flag)
2460{ 2592{
2461 struct Lisp_Marker *tail, *markers; 2593 struct Lisp_Marker *tail, *markers;
2462 struct buffer *other; 2594 Lisp_Object btail, other;
2463 ptrdiff_t begv, zv; 2595 ptrdiff_t begv, zv;
2464 bool narrowed = (BEG != BEGV || Z != ZV); 2596 bool narrowed = (BEG != BEGV || Z != ZV);
2465 bool modified_p = !NILP (Fbuffer_modified_p (Qnil)); 2597 bool modified_p = !NILP (Fbuffer_modified_p (Qnil));
@@ -2517,8 +2649,6 @@ current buffer is cleared. */)
2517 p = BEG_ADDR; 2649 p = BEG_ADDR;
2518 while (1) 2650 while (1)
2519 { 2651 {
2520 int c, bytes;
2521
2522 if (pos == stop) 2652 if (pos == stop)
2523 { 2653 {
2524 if (pos == Z) 2654 if (pos == Z)
@@ -2530,7 +2660,7 @@ current buffer is cleared. */)
2530 p++, pos++; 2660 p++, pos++;
2531 else if (CHAR_BYTE8_HEAD_P (*p)) 2661 else if (CHAR_BYTE8_HEAD_P (*p))
2532 { 2662 {
2533 c = STRING_CHAR_AND_LENGTH (p, bytes); 2663 int bytes, c = string_char_and_length (p, &bytes);
2534 /* Delete all bytes for this 8-bit character but the 2664 /* Delete all bytes for this 8-bit character but the
2535 last one, and change the last one to the character 2665 last one, and change the last one to the character
2536 code. */ 2666 code. */
@@ -2547,12 +2677,10 @@ current buffer is cleared. */)
2547 } 2677 }
2548 else 2678 else
2549 { 2679 {
2550 bytes = BYTES_BY_CHAR_HEAD (*p); 2680 int bytes = BYTES_BY_CHAR_HEAD (*p);
2551 p += bytes, pos += bytes; 2681 p += bytes, pos += bytes;
2552 } 2682 }
2553 } 2683 }
2554 if (narrowed)
2555 Fnarrow_to_region (make_number (begv), make_number (zv));
2556 } 2684 }
2557 else 2685 else
2558 { 2686 {
@@ -2601,8 +2729,7 @@ current buffer is cleared. */)
2601 if (ASCII_CHAR_P (*p)) 2729 if (ASCII_CHAR_P (*p))
2602 p++, pos++; 2730 p++, pos++;
2603 else if (EQ (flag, Qt) 2731 else if (EQ (flag, Qt)
2604 && ! CHAR_BYTE8_HEAD_P (*p) 2732 && 0 < (bytes = multibyte_length (p, pend, true, false)))
2605 && (bytes = MULTIBYTE_LENGTH (p, pend)) > 0)
2606 p += bytes, pos += bytes; 2733 p += bytes, pos += bytes;
2607 else 2734 else
2608 { 2735 {
@@ -2632,9 +2759,6 @@ current buffer is cleared. */)
2632 if (pt != PT) 2759 if (pt != PT)
2633 TEMP_SET_PT (pt); 2760 TEMP_SET_PT (pt);
2634 2761
2635 if (narrowed)
2636 Fnarrow_to_region (make_number (begv), make_number (zv));
2637
2638 /* Do this first, so that chars_in_text asks the right question. 2762 /* Do this first, so that chars_in_text asks the right question.
2639 set_intervals_multibyte needs it too. */ 2763 set_intervals_multibyte needs it too. */
2640 bset_enable_multibyte_characters (current_buffer, Qt); 2764 bset_enable_multibyte_characters (current_buffer, Qt);
@@ -2689,6 +2813,9 @@ current buffer is cleared. */)
2689 2813
2690 /* Do this last, so it can calculate the new correspondences 2814 /* Do this last, so it can calculate the new correspondences
2691 between chars and bytes. */ 2815 between chars and bytes. */
2816 /* FIXME: Is it worth the trouble, really? Couldn't we just throw
2817 away all the text-properties instead of trying to guess how
2818 to adjust them? AFAICT the result is not reliable anyway. */
2692 set_intervals_multibyte (1); 2819 set_intervals_multibyte (1);
2693 set_overlays_multibyte (1); 2820 set_overlays_multibyte (1);
2694 } 2821 }
@@ -2711,13 +2838,16 @@ current buffer is cleared. */)
2711 2838
2712 /* Copy this buffer's new multibyte status 2839 /* Copy this buffer's new multibyte status
2713 into all of its indirect buffers. */ 2840 into all of its indirect buffers. */
2714 FOR_EACH_BUFFER (other) 2841 FOR_EACH_LIVE_BUFFER (btail, other)
2715 if (other->base_buffer == current_buffer && BUFFER_LIVE_P (other)) 2842 {
2716 { 2843 struct buffer *o = XBUFFER (other);
2717 BVAR (other, enable_multibyte_characters) 2844 if (o->base_buffer == current_buffer && BUFFER_LIVE_P (o))
2718 = BVAR (current_buffer, enable_multibyte_characters); 2845 {
2719 other->prevent_redisplay_optimizations_p = 1; 2846 BVAR (o, enable_multibyte_characters)
2720 } 2847 = BVAR (current_buffer, enable_multibyte_characters);
2848 o->prevent_redisplay_optimizations_p = true;
2849 }
2850 }
2721 2851
2722 /* Restore the modifiedness of the buffer. */ 2852 /* Restore the modifiedness of the buffer. */
2723 if (!modified_p && !NILP (Fbuffer_modified_p (Qnil))) 2853 if (!modified_p && !NILP (Fbuffer_modified_p (Qnil)))
@@ -2736,7 +2866,7 @@ current buffer is cleared. */)
2736} 2866}
2737 2867
2738DEFUN ("kill-all-local-variables", Fkill_all_local_variables, 2868DEFUN ("kill-all-local-variables", Fkill_all_local_variables,
2739 Skill_all_local_variables, 0, 0, 0, 2869 Skill_all_local_variables, 0, 1, 0,
2740 doc: /* Switch to Fundamental mode by killing current buffer's local variables. 2870 doc: /* Switch to Fundamental mode by killing current buffer's local variables.
2741Most local variable bindings are eliminated so that the default values 2871Most local variable bindings are eliminated so that the default values
2742become effective once more. Also, the syntax table is set from 2872become effective once more. Also, the syntax table is set from
@@ -2747,57 +2877,28 @@ This function also forces redisplay of the mode line.
2747Every function to select a new major mode starts by 2877Every function to select a new major mode starts by
2748calling this function. 2878calling this function.
2749 2879
2750As a special exception, local variables whose names have 2880As a special exception, local variables whose names have a non-nil
2751a non-nil `permanent-local' property are not eliminated by this function. 2881`permanent-local' property are not eliminated by this function. If
2882the optional KILL-PERMANENT argument is non-nil, clear out these local
2883variables, too.
2752 2884
2753The first thing this function does is run 2885The first thing this function does is run
2754the normal hook `change-major-mode-hook'. */) 2886the normal hook `change-major-mode-hook'. */)
2755 (void) 2887 (Lisp_Object kill_permanent)
2756{ 2888{
2757 run_hook (Qchange_major_mode_hook); 2889 run_hook (Qchange_major_mode_hook);
2758 2890
2759 /* Make sure none of the bindings in local_var_alist
2760 remain swapped in, in their symbols. */
2761
2762 swap_out_buffer_local_variables (current_buffer);
2763
2764 /* Actually eliminate all local bindings of this buffer. */ 2891 /* Actually eliminate all local bindings of this buffer. */
2765 2892
2766 reset_buffer_local_variables (current_buffer, 0); 2893 reset_buffer_local_variables (current_buffer, !NILP (kill_permanent));
2767 2894
2768 /* Force mode-line redisplay. Useful here because all major mode 2895 /* Force mode-line redisplay. Useful here because all major mode
2769 commands call this function. */ 2896 commands call this function. */
2770 update_mode_lines = 12; 2897 bset_update_mode_line (current_buffer);
2771 2898
2772 return Qnil; 2899 return Qnil;
2773} 2900}
2774 2901
2775/* Make sure no local variables remain set up with buffer B
2776 for their current values. */
2777
2778static void
2779swap_out_buffer_local_variables (struct buffer *b)
2780{
2781 Lisp_Object oalist, alist, buffer;
2782
2783 XSETBUFFER (buffer, b);
2784 oalist = BVAR (b, local_var_alist);
2785
2786 for (alist = oalist; CONSP (alist); alist = XCDR (alist))
2787 {
2788 Lisp_Object sym = XCAR (XCAR (alist));
2789 eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED);
2790 /* Need not do anything if some other buffer's binding is
2791 now cached. */
2792 if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
2793 {
2794 /* Symbol is set up for this buffer's old local value:
2795 swap it out! */
2796 swap_in_global_binding (XSYMBOL (sym));
2797 }
2798 }
2799}
2800
2801 2902
2802/* Find all the overlays in the current buffer that overlap the range 2903/* Find all the overlays in the current buffer that overlap the range
2803 [BEG, END). 2904 [BEG, END).
@@ -3061,17 +3162,17 @@ make_sortvec_item (struct sortvec *item, Lisp_Object overlay)
3061 item->priority = 0; 3162 item->priority = 0;
3062 item->spriority = 0; 3163 item->spriority = 0;
3063 } 3164 }
3064 else if (INTEGERP (tem)) 3165 else if (FIXNUMP (tem))
3065 { 3166 {
3066 item->priority = XINT (tem); 3167 item->priority = XFIXNUM (tem);
3067 item->spriority = 0; 3168 item->spriority = 0;
3068 } 3169 }
3069 else if (CONSP (tem)) 3170 else if (CONSP (tem))
3070 { 3171 {
3071 Lisp_Object car = XCAR (tem); 3172 Lisp_Object car = XCAR (tem);
3072 Lisp_Object cdr = XCDR (tem); 3173 Lisp_Object cdr = XCDR (tem);
3073 item->priority = INTEGERP (car) ? XINT (car) : 0; 3174 item->priority = FIXNUMP (car) ? XFIXNUM (car) : 0;
3074 item->spriority = INTEGERP (cdr) ? XINT (cdr) : 0; 3175 item->spriority = FIXNUMP (cdr) ? XFIXNUM (cdr) : 0;
3075 } 3176 }
3076} 3177}
3077/* Sort an array of overlays by priority. The array is modified in place. 3178/* Sort an array of overlays by priority. The array is modified in place.
@@ -3168,7 +3269,7 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
3168 ssl->buf[ssl->used].string = str; 3269 ssl->buf[ssl->used].string = str;
3169 ssl->buf[ssl->used].string2 = str2; 3270 ssl->buf[ssl->used].string2 = str2;
3170 ssl->buf[ssl->used].size = size; 3271 ssl->buf[ssl->used].size = size;
3171 ssl->buf[ssl->used].priority = (INTEGERP (pri) ? XINT (pri) : 0); 3272 ssl->buf[ssl->used].priority = (FIXNUMP (pri) ? XFIXNUM (pri) : 0);
3172 ssl->used++; 3273 ssl->used++;
3173 3274
3174 if (NILP (BVAR (current_buffer, enable_multibyte_characters))) 3275 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
@@ -3215,8 +3316,6 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
3215ptrdiff_t 3316ptrdiff_t
3216overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) 3317overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3217{ 3318{
3218 Lisp_Object overlay, window, str;
3219 ptrdiff_t obegin, oend;
3220 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); 3319 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
3221 struct interval_node *node; 3320 struct interval_node *node;
3222 3321
@@ -3227,30 +3326,31 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3227 pos - 1, pos + 1, ITREE_DESCENDING); 3326 pos - 1, pos + 1, ITREE_DESCENDING);
3228 while ((node = buffer_overlay_iter_next (current_buffer))) 3327 while ((node = buffer_overlay_iter_next (current_buffer)))
3229 { 3328 {
3230 overlay = node->data; 3329 Lisp_Object overlay = node->data;
3231 eassert (OVERLAYP (overlay)); 3330 eassert (OVERLAYP (overlay));
3232 3331
3233 obegin = node->begin; 3332 ptrdiff_t startpos = node->begin;
3234 oend = node->end; 3333 ptrdiff_t endpos = node->end;
3235 3334
3236 if (oend != pos && obegin != pos) 3335 if (endpos != pos && startpos != pos)
3237 continue; 3336 continue;
3238 window = Foverlay_get (overlay, Qwindow); 3337 Lisp_Object window = Foverlay_get (overlay, Qwindow);
3239 if (WINDOWP (window) && XWINDOW (window) != w) 3338 if (WINDOWP (window) && XWINDOW (window) != w)
3240 continue; 3339 continue;
3241 if (obegin == pos 3340 Lisp_Object str;
3341 if (startpos == pos
3242 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) 3342 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3243 record_overlay_string (&overlay_heads, str, 3343 record_overlay_string (&overlay_heads, str,
3244 (obegin == oend 3344 (startpos == endpos
3245 ? Foverlay_get (overlay, Qafter_string) 3345 ? Foverlay_get (overlay, Qafter_string)
3246 : Qnil), 3346 : Qnil),
3247 Foverlay_get (overlay, Qpriority), 3347 Foverlay_get (overlay, Qpriority),
3248 oend - obegin); 3348 endpos - startpos);
3249 else if (oend == pos 3349 else if (endpos == pos
3250 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))) 3350 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
3251 record_overlay_string (&overlay_tails, str, Qnil, 3351 record_overlay_string (&overlay_tails, str, Qnil,
3252 Foverlay_get (overlay, Qpriority), 3352 Foverlay_get (overlay, Qpriority),
3253 oend - obegin); 3353 endpos - startpos);
3254 } 3354 }
3255 buffer_overlay_iter_finish (current_buffer); 3355 buffer_overlay_iter_finish (current_buffer);
3256 3356
@@ -3346,11 +3446,10 @@ for the front of the overlay advance when text is inserted there
3346The fifth arg REAR-ADVANCE, if non-nil, makes the marker 3446The fifth arg REAR-ADVANCE, if non-nil, makes the marker
3347for the rear of the overlay advance when text is inserted there 3447for the rear of the overlay advance when text is inserted there
3348\(which means the text *is* included in the overlay). */) 3448\(which means the text *is* included in the overlay). */)
3349 (Lisp_Object begin, Lisp_Object end, Lisp_Object buffer, 3449 (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer,
3350 Lisp_Object front_advance, Lisp_Object rear_advance) 3450 Lisp_Object front_advance, Lisp_Object rear_advance)
3351{ 3451{
3352 Lisp_Object ov; 3452 Lisp_Object ov;
3353 ptrdiff_t obegin, oend;
3354 struct buffer *b; 3453 struct buffer *b;
3355 3454
3356 if (NILP (buffer)) 3455 if (NILP (buffer))
@@ -3362,23 +3461,23 @@ for the rear of the overlay advance when text is inserted there
3362 if (! BUFFER_LIVE_P (b)) 3461 if (! BUFFER_LIVE_P (b))
3363 error ("Attempt to create overlay in a dead buffer"); 3462 error ("Attempt to create overlay in a dead buffer");
3364 3463
3365 if (MARKERP (begin) && !EQ (Fmarker_buffer (begin), buffer)) 3464 if (MARKERP (beg) && !BASE_EQ (Fmarker_buffer (beg), buffer))
3366 signal_error ("Marker points into wrong buffer", begin); 3465 signal_error ("Marker points into wrong buffer", beg);
3367 if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer)) 3466 if (MARKERP (end) && !BASE_EQ (Fmarker_buffer (end), buffer))
3368 signal_error ("Marker points into wrong buffer", end); 3467 signal_error ("Marker points into wrong buffer", end);
3369 3468
3370 CHECK_NUMBER_COERCE_MARKER (begin); 3469 CHECK_FIXNUM_COERCE_MARKER (beg);
3371 CHECK_NUMBER_COERCE_MARKER (end); 3470 CHECK_FIXNUM_COERCE_MARKER (end);
3372 3471
3373 if (XINT (begin) > XINT (end)) 3472 if (XFIXNUM (beg) > XFIXNUM (end))
3374 { 3473 {
3375 Lisp_Object temp; 3474 Lisp_Object temp;
3376 temp = begin; begin = end; end = temp; 3475 temp = beg; beg = end; end = temp;
3377 } 3476 }
3378 3477
3379 obegin = clip_to_bounds (BEG, XINT (begin), b->text->z); 3478 ptrdiff_t obeg = clip_to_bounds (BEG, XFIXNUM (beg), b->text->z);
3380 oend = clip_to_bounds (obegin, XINT (end), b->text->z); 3479 ptrdiff_t oend = clip_to_bounds (obeg, XFIXNUM (end), b->text->z);
3381 ov = build_overlay (obegin, oend, 3480 ov = build_overlay (obeg, oend,
3382 ! NILP (front_advance), 3481 ! NILP (front_advance),
3383 ! NILP (rear_advance), Qnil); 3482 ! NILP (rear_advance), Qnil);
3384 add_buffer_overlay (b, XOVERLAY (ov)); 3483 add_buffer_overlay (b, XOVERLAY (ov));
@@ -3405,7 +3504,7 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
3405 3504
3406 bset_redisplay (buf); 3505 bset_redisplay (buf);
3407 3506
3408 ++BUF_OVERLAY_MODIFF (buf); 3507 modiff_incr (&BUF_OVERLAY_MODIFF (buf), 1);
3409} 3508}
3410 3509
3411DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0, 3510DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
@@ -3417,7 +3516,7 @@ buffer. */)
3417{ 3516{
3418 struct buffer *b, *ob = 0; 3517 struct buffer *b, *ob = 0;
3419 Lisp_Object obuffer; 3518 Lisp_Object obuffer;
3420 ptrdiff_t count = SPECPDL_INDEX (); 3519 specpdl_ref count = SPECPDL_INDEX ();
3421 ptrdiff_t n_beg, n_end; 3520 ptrdiff_t n_beg, n_end;
3422 ptrdiff_t o_beg UNINIT, o_end UNINIT; 3521 ptrdiff_t o_beg UNINIT, o_end UNINIT;
3423 3522
@@ -3431,15 +3530,15 @@ buffer. */)
3431 if (NILP (Fbuffer_live_p (buffer))) 3530 if (NILP (Fbuffer_live_p (buffer)))
3432 error ("Attempt to move overlay to a dead buffer"); 3531 error ("Attempt to move overlay to a dead buffer");
3433 3532
3434 if (MARKERP (beg) && !EQ (Fmarker_buffer (beg), buffer)) 3533 if (MARKERP (beg) && !BASE_EQ (Fmarker_buffer (beg), buffer))
3435 signal_error ("Marker points into wrong buffer", beg); 3534 signal_error ("Marker points into wrong buffer", beg);
3436 if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer)) 3535 if (MARKERP (end) && !BASE_EQ (Fmarker_buffer (end), buffer))
3437 signal_error ("Marker points into wrong buffer", end); 3536 signal_error ("Marker points into wrong buffer", end);
3438 3537
3439 CHECK_NUMBER_COERCE_MARKER (beg); 3538 CHECK_FIXNUM_COERCE_MARKER (beg);
3440 CHECK_NUMBER_COERCE_MARKER (end); 3539 CHECK_FIXNUM_COERCE_MARKER (end);
3441 3540
3442 if (XINT (beg) > XINT (end)) 3541 if (XFIXNUM (beg) > XFIXNUM (end))
3443 { 3542 {
3444 Lisp_Object temp; 3543 Lisp_Object temp;
3445 temp = beg; beg = end; end = temp; 3544 temp = beg; beg = end; end = temp;
@@ -3465,13 +3564,13 @@ buffer. */)
3465 add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay)); 3564 add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay));
3466 } 3565 }
3467 /* Set the overlay boundaries, which may clip them. */ 3566 /* Set the overlay boundaries, which may clip them. */
3468 set_overlay_region (XOVERLAY (overlay), XINT (beg), XINT (end)); 3567 set_overlay_region (XOVERLAY (overlay), XFIXNUM (beg), XFIXNUM (end));
3469 3568
3470 n_beg = OVERLAY_START (overlay); 3569 n_beg = OVERLAY_START (overlay);
3471 n_end = OVERLAY_END (overlay); 3570 n_end = OVERLAY_END (overlay);
3472 3571
3473 /* If the overlay has changed buffers, do a thorough redisplay. */ 3572 /* If the overlay has changed buffers, do a thorough redisplay. */
3474 if (!EQ (buffer, obuffer)) 3573 if (!BASE_EQ (buffer, obuffer))
3475 { 3574 {
3476 /* Redisplay where the overlay was. */ 3575 /* Redisplay where the overlay was. */
3477 if (ob) 3576 if (ob)
@@ -3494,7 +3593,15 @@ buffer. */)
3494 /* Delete the overlay if it is empty after clipping and has the 3593 /* Delete the overlay if it is empty after clipping and has the
3495 evaporate property. */ 3594 evaporate property. */
3496 if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate))) 3595 if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate)))
3497 return unbind_to (count, Fdelete_overlay (overlay)); 3596 { /* We used to call `Fdelete_overlay' here, but it causes problems:
3597 - At this stage, `overlay' is not included in its buffer's lists
3598 of overlays (the data-structure is in an inconsistent state),
3599 contrary to `Fdelete_overlay's assumptions.
3600 - Most of the work done by Fdelete_overlay has already been done
3601 here for other reasons. */
3602 drop_overlay (XOVERLAY (overlay));
3603 return unbind_to (count, overlay);
3604 }
3498 3605
3499 return unbind_to (count, overlay); 3606 return unbind_to (count, overlay);
3500} 3607}
@@ -3504,7 +3611,7 @@ DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
3504 (Lisp_Object overlay) 3611 (Lisp_Object overlay)
3505{ 3612{
3506 struct buffer *b; 3613 struct buffer *b;
3507 ptrdiff_t count = SPECPDL_INDEX (); 3614 specpdl_ref count = SPECPDL_INDEX ();
3508 3615
3509 CHECK_OVERLAY (overlay); 3616 CHECK_OVERLAY (overlay);
3510 3617
@@ -3548,7 +3655,7 @@ DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
3548 if (! OVERLAY_BUFFER (overlay)) 3655 if (! OVERLAY_BUFFER (overlay))
3549 return Qnil; 3656 return Qnil;
3550 3657
3551 return make_number (OVERLAY_START (overlay)); 3658 return make_fixnum (OVERLAY_START (overlay));
3552} 3659}
3553 3660
3554DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0, 3661DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
@@ -3559,7 +3666,7 @@ DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
3559 if (! OVERLAY_BUFFER (overlay)) 3666 if (! OVERLAY_BUFFER (overlay))
3560 return Qnil; 3667 return Qnil;
3561 3668
3562 return make_number (OVERLAY_END (overlay)); 3669 return make_fixnum (OVERLAY_END (overlay));
3563} 3670}
3564 3671
3565DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0, 3672DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
@@ -3593,14 +3700,18 @@ OVERLAY. */)
3593 3700
3594DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 2, 0, 3701DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 2, 0,
3595 doc: /* Return a list of the overlays that contain the character at POS. 3702 doc: /* Return a list of the overlays that contain the character at POS.
3596If SORTED is non-nil, then sort them by decreasing priority. */) 3703If SORTED is non-nil, then sort them by decreasing priority.
3704
3705Zero-length overlays that start and stop at POS are not included in
3706the return value. Instead use `overlays-in' if those overlays are of
3707interest. */)
3597 (Lisp_Object pos, Lisp_Object sorted) 3708 (Lisp_Object pos, Lisp_Object sorted)
3598{ 3709{
3599 ptrdiff_t len, noverlays; 3710 ptrdiff_t len, noverlays;
3600 Lisp_Object *overlay_vec; 3711 Lisp_Object *overlay_vec;
3601 Lisp_Object result; 3712 Lisp_Object result;
3602 3713
3603 CHECK_NUMBER_COERCE_MARKER (pos); 3714 CHECK_FIXNUM_COERCE_MARKER (pos);
3604 3715
3605 if (!buffer_has_overlays ()) 3716 if (!buffer_has_overlays ())
3606 return Qnil; 3717 return Qnil;
@@ -3611,7 +3722,7 @@ If SORTED is non-nil, then sort them by decreasing priority. */)
3611 3722
3612 /* Put all the overlays we want in a vector in overlay_vec. 3723 /* Put all the overlays we want in a vector in overlay_vec.
3613 Store the length in len. */ 3724 Store the length in len. */
3614 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, NULL); 3725 noverlays = overlays_at (XFIXNUM (pos), true, &overlay_vec, &len, NULL);
3615 3726
3616 if (!NILP (sorted)) 3727 if (!NILP (sorted))
3617 noverlays = sort_overlays (overlay_vec, noverlays, 3728 noverlays = sort_overlays (overlay_vec, noverlays,
@@ -3634,17 +3745,18 @@ DEFUN ("overlays-in", Foverlays_in, Soverlays_in, 2, 2, 0,
3634 doc: /* Return a list of the overlays that overlap the region BEG ... END. 3745 doc: /* Return a list of the overlays that overlap the region BEG ... END.
3635Overlap means that at least one character is contained within the overlay 3746Overlap means that at least one character is contained within the overlay
3636and also contained within the specified region. 3747and also contained within the specified region.
3748
3637Empty overlays are included in the result if they are located at BEG, 3749Empty overlays are included in the result if they are located at BEG,
3638between BEG and END, or at END provided END denotes the position at the 3750between BEG and END, or at END provided END denotes the position at the
3639end of the buffer. */) 3751end of the accessible part of the buffer. */)
3640 (Lisp_Object beg, Lisp_Object end) 3752 (Lisp_Object beg, Lisp_Object end)
3641{ 3753{
3642 ptrdiff_t len, noverlays; 3754 ptrdiff_t len, noverlays;
3643 Lisp_Object *overlay_vec; 3755 Lisp_Object *overlay_vec;
3644 Lisp_Object result; 3756 Lisp_Object result;
3645 3757
3646 CHECK_NUMBER_COERCE_MARKER (beg); 3758 CHECK_FIXNUM_COERCE_MARKER (beg);
3647 CHECK_NUMBER_COERCE_MARKER (end); 3759 CHECK_FIXNUM_COERCE_MARKER (end);
3648 3760
3649 if (!buffer_has_overlays ()) 3761 if (!buffer_has_overlays ())
3650 return Qnil; 3762 return Qnil;
@@ -3654,7 +3766,8 @@ end of the buffer. */)
3654 3766
3655 /* Put all the overlays we want in a vector in overlay_vec. 3767 /* Put all the overlays we want in a vector in overlay_vec.
3656 Store the length in len. */ 3768 Store the length in len. */
3657 noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len, true, NULL); 3769 noverlays = overlays_in (XFIXNUM (beg), XFIXNUM (end), 1, &overlay_vec, &len,
3770 true, NULL);
3658 3771
3659 /* Make a list of them all. */ 3772 /* Make a list of them all. */
3660 result = Flist (noverlays, overlay_vec); 3773 result = Flist (noverlays, overlay_vec);
@@ -3670,12 +3783,12 @@ If there are no overlay boundaries from POS to (point-max),
3670the value is (point-max). */) 3783the value is (point-max). */)
3671 (Lisp_Object pos) 3784 (Lisp_Object pos)
3672{ 3785{
3673 CHECK_NUMBER_COERCE_MARKER (pos); 3786 CHECK_FIXNUM_COERCE_MARKER (pos);
3674 3787
3675 if (!buffer_has_overlays ()) 3788 if (!buffer_has_overlays ())
3676 return make_number (ZV); 3789 return make_fixnum (ZV);
3677 3790
3678 return make_number (next_overlay_change (XINT (pos))); 3791 return make_fixnum (next_overlay_change (XFIXNUM (pos)));
3679} 3792}
3680 3793
3681DEFUN ("previous-overlay-change", Fprevious_overlay_change, 3794DEFUN ("previous-overlay-change", Fprevious_overlay_change,
@@ -3686,12 +3799,12 @@ the value is (point-min). */)
3686 (Lisp_Object pos) 3799 (Lisp_Object pos)
3687{ 3800{
3688 3801
3689 CHECK_NUMBER_COERCE_MARKER (pos); 3802 CHECK_FIXNUM_COERCE_MARKER (pos);
3690 3803
3691 if (!buffer_has_overlays ()) 3804 if (!buffer_has_overlays ())
3692 return make_number (BEGV); 3805 return make_fixnum (BEGV);
3693 3806
3694 return make_number (previous_overlay_change (XINT (pos))); 3807 return make_fixnum (previous_overlay_change (XFIXNUM (pos)));
3695} 3808}
3696 3809
3697 3810
@@ -3723,7 +3836,7 @@ That makes overlay lookup faster for positions near POS (but perhaps slower
3723for positions far away from POS). */) 3836for positions far away from POS). */)
3724 (Lisp_Object pos) 3837 (Lisp_Object pos)
3725{ 3838{
3726 CHECK_NUMBER_COERCE_MARKER (pos); 3839 CHECK_FIXNUM_COERCE_MARKER (pos);
3727 /* Noop */ 3840 /* Noop */
3728 return Qnil; 3841 return Qnil;
3729} 3842}
@@ -3829,7 +3942,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
3829 Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3) 3942 Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
3830{ 3943{
3831 /* True if this change is an insertion. */ 3944 /* True if this change is an insertion. */
3832 bool insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end)); 3945 bool insertion = (after ? XFIXNAT (arg3) == 0 : EQ (start, end));
3833 3946
3834 /* We used to run the functions as soon as we found them and only register 3947 /* We used to run the functions as soon as we found them and only register
3835 them in last_overlay_modification_hooks for the purpose of the `after' 3948 them in last_overlay_modification_hooks for the purpose of the `after'
@@ -3842,8 +3955,8 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
3842 if (!after) 3955 if (!after)
3843 { 3956 {
3844 struct interval_node *node; 3957 struct interval_node *node;
3845 EMACS_INT begin_arg = XFASTINT (start); 3958 EMACS_INT begin_arg = XFIXNUM (start);
3846 EMACS_INT end_arg = XFASTINT (end); 3959 EMACS_INT end_arg = XFIXNUM (end);
3847 /* We are being called before a change. 3960 /* We are being called before a change.
3848 Scan the overlays to find the functions to call. */ 3961 Scan the overlays to find the functions to call. */
3849 last_overlay_modification_hooks_used = 0; 3962 last_overlay_modification_hooks_used = 0;
@@ -3859,19 +3972,18 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
3859 Lisp_Object overlay = node->data; 3972 Lisp_Object overlay = node->data;
3860 ptrdiff_t obegin = OVERLAY_START (overlay); 3973 ptrdiff_t obegin = OVERLAY_START (overlay);
3861 ptrdiff_t oend = OVERLAY_END (overlay); 3974 ptrdiff_t oend = OVERLAY_END (overlay);
3862 Lisp_Object prop;
3863 3975
3864 if (insertion && (begin_arg == obegin 3976 if (insertion && (begin_arg == obegin
3865 || end_arg == obegin)) 3977 || end_arg == obegin))
3866 { 3978 {
3867 prop = Foverlay_get (overlay, Qinsert_in_front_hooks); 3979 Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
3868 if (!NILP (prop)) 3980 if (!NILP (prop))
3869 add_overlay_mod_hooklist (prop, overlay); 3981 add_overlay_mod_hooklist (prop, overlay);
3870 } 3982 }
3871 if (insertion && (begin_arg == oend 3983 if (insertion && (begin_arg == oend
3872 || end_arg == oend)) 3984 || end_arg == oend))
3873 { 3985 {
3874 prop = Foverlay_get (overlay, Qinsert_behind_hooks); 3986 Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
3875 if (!NILP (prop)) 3987 if (!NILP (prop))
3876 add_overlay_mod_hooklist (prop, overlay); 3988 add_overlay_mod_hooklist (prop, overlay);
3877 } 3989 }
@@ -3879,7 +3991,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
3879 for both insertion and deletion. */ 3991 for both insertion and deletion. */
3880 if (! insertion || (end_arg > obegin && begin_arg < oend)) 3992 if (! insertion || (end_arg > obegin && begin_arg < oend))
3881 { 3993 {
3882 prop = Foverlay_get (overlay, Qmodification_hooks); 3994 Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
3883 if (!NILP (prop)) 3995 if (!NILP (prop))
3884 add_overlay_mod_hooklist (prop, overlay); 3996 add_overlay_mod_hooklist (prop, overlay);
3885 } 3997 }
@@ -3894,23 +4006,6 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
3894 Lisp_Object *copy; 4006 Lisp_Object *copy;
3895 ptrdiff_t i; 4007 ptrdiff_t i;
3896 4008
3897 if (size)
3898 {
3899 Lisp_Object ovl
3900 = XVECTOR (last_overlay_modification_hooks)->contents[1];
3901
3902 /* If the buffer of the first overlay in the array doesn't
3903 match the current buffer, then these modification hooks
3904 should not be run in this buffer. This could happen when
3905 some code calls some insdel functions, such as del_range_1,
3906 with the PREPARE argument false -- in that case this
3907 function is never called to record the overlay modification
3908 hook functions in the last_overlay_modification_hooks
3909 array, so anything we find there is not ours. */
3910 if (OVERLAY_BUFFER (ovl) != current_buffer)
3911 return;
3912 }
3913
3914 USE_SAFE_ALLOCA; 4009 USE_SAFE_ALLOCA;
3915 SAFE_ALLOCA_LISP (copy, size); 4010 SAFE_ALLOCA_LISP (copy, size);
3916 memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents, 4011 memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
@@ -3921,7 +4016,12 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
3921 Lisp_Object prop_i, overlay_i; 4016 Lisp_Object prop_i, overlay_i;
3922 prop_i = copy[i++]; 4017 prop_i = copy[i++];
3923 overlay_i = copy[i++]; 4018 overlay_i = copy[i++];
3924 call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3); 4019 /* It is possible that the recorded overlay has been deleted
4020 (which makes its markers' buffers be nil), or that (due to
4021 some bug) it belongs to a different buffer. Only run this
4022 hook if the overlay belongs to the current buffer. */
4023 if (OVERLAY_BUFFER (overlay_i) == current_buffer)
4024 call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3);
3925 } 4025 }
3926 4026
3927 SAFE_FREE (); 4027 SAFE_FREE ();
@@ -4086,7 +4186,7 @@ mmap_init (void)
4086 if (mmap_fd <= 0) 4186 if (mmap_fd <= 0)
4087 { 4187 {
4088 /* No anonymous mmap -- we need the file descriptor. */ 4188 /* No anonymous mmap -- we need the file descriptor. */
4089 mmap_fd = emacs_open ("/dev/zero", O_RDONLY, 0); 4189 mmap_fd = emacs_open_noquit ("/dev/zero", O_RDONLY, 0);
4090 if (mmap_fd == -1) 4190 if (mmap_fd == -1)
4091 fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno)); 4191 fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
4092 } 4192 }
@@ -4358,24 +4458,38 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
4358void 4458void
4359enlarge_buffer_text (struct buffer *b, ptrdiff_t delta) 4459enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
4360{ 4460{
4361 void *p;
4362 ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
4363 + delta);
4364 block_input (); 4461 block_input ();
4462 void *p;
4463 unsigned char *old_beg = b->text->beg;
4464 ptrdiff_t old_nbytes =
4465 BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1;
4466 ptrdiff_t new_nbytes = old_nbytes + delta;
4467
4468 if (pdumper_object_p (old_beg))
4469 b->text->beg = NULL;
4470 else
4471 old_beg = NULL;
4472
4365#if defined USE_MMAP_FOR_BUFFERS 4473#if defined USE_MMAP_FOR_BUFFERS
4366 p = mmap_realloc ((void **) &b->text->beg, nbytes); 4474 p = mmap_realloc ((void **) &b->text->beg, new_nbytes);
4367#elif defined REL_ALLOC 4475#elif defined REL_ALLOC
4368 p = r_re_alloc ((void **) &b->text->beg, nbytes); 4476 p = r_re_alloc ((void **) &b->text->beg, new_nbytes);
4369#else 4477#else
4370 p = xrealloc (b->text->beg, nbytes); 4478 p = xrealloc (b->text->beg, new_nbytes);
4371#endif 4479#endif
4480 __lsan_ignore_object (p);
4372 4481
4373 if (p == NULL) 4482 if (p == NULL)
4374 { 4483 {
4484 if (old_beg)
4485 b->text->beg = old_beg;
4375 unblock_input (); 4486 unblock_input ();
4376 memory_full (nbytes); 4487 memory_full (new_nbytes);
4377 } 4488 }
4378 4489
4490 if (old_beg)
4491 memcpy (p, old_beg, min (old_nbytes, new_nbytes));
4492
4379 BUF_BEG_ADDR (b) = p; 4493 BUF_BEG_ADDR (b) = p;
4380 unblock_input (); 4494 unblock_input ();
4381} 4495}
@@ -4388,13 +4502,16 @@ free_buffer_text (struct buffer *b)
4388{ 4502{
4389 block_input (); 4503 block_input ();
4390 4504
4505 if (!pdumper_object_p (b->text->beg))
4506 {
4391#if defined USE_MMAP_FOR_BUFFERS 4507#if defined USE_MMAP_FOR_BUFFERS
4392 mmap_free ((void **) &b->text->beg); 4508 mmap_free ((void **) &b->text->beg);
4393#elif defined REL_ALLOC 4509#elif defined REL_ALLOC
4394 r_alloc_free ((void **) &b->text->beg); 4510 r_alloc_free ((void **) &b->text->beg);
4395#else 4511#else
4396 xfree (b->text->beg); 4512 xfree (b->text->beg);
4397#endif 4513#endif
4514 }
4398 4515
4399 BUF_BEG_ADDR (b) = NULL; 4516 BUF_BEG_ADDR (b) = NULL;
4400 unblock_input (); 4517 unblock_input ();
@@ -4405,51 +4522,64 @@ free_buffer_text (struct buffer *b)
4405/*********************************************************************** 4522/***********************************************************************
4406 Initialization 4523 Initialization
4407 ***********************************************************************/ 4524 ***********************************************************************/
4408
4409void 4525void
4410init_buffer_once (void) 4526init_buffer_once (void)
4411{ 4527{
4528 /* TODO: clean up the buffer-local machinery. Right now,
4529 we have:
4530
4531 buffer_defaults: default values of buffer-locals
4532 buffer_local_flags: metadata
4533 buffer_permanent_local_flags: metadata
4534 buffer_local_symbols: metadata
4535
4536 There must be a simpler way to store the metadata.
4537 */
4538
4412 int idx; 4539 int idx;
4413 4540
4541 /* Items flagged permanent get an explicit permanent-local property
4542 added in bindings.el, for clarity. */
4543 PDUMPER_REMEMBER_SCALAR (buffer_permanent_local_flags);
4414 memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags); 4544 memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags);
4415 4545
4416 /* 0 means not a lisp var, -1 means always local, else mask. */ 4546 /* 0 means not a lisp var, -1 means always local, else mask. */
4417 memset (&buffer_local_flags, 0, sizeof buffer_local_flags); 4547 memset (&buffer_local_flags, 0, sizeof buffer_local_flags);
4418 bset_filename (&buffer_local_flags, make_number (-1)); 4548 bset_filename (&buffer_local_flags, make_fixnum (-1));
4419 bset_directory (&buffer_local_flags, make_number (-1)); 4549 bset_directory (&buffer_local_flags, make_fixnum (-1));
4420 bset_backed_up (&buffer_local_flags, make_number (-1)); 4550 bset_backed_up (&buffer_local_flags, make_fixnum (-1));
4421 bset_save_length (&buffer_local_flags, make_number (-1)); 4551 bset_save_length (&buffer_local_flags, make_fixnum (-1));
4422 bset_auto_save_file_name (&buffer_local_flags, make_number (-1)); 4552 bset_auto_save_file_name (&buffer_local_flags, make_fixnum (-1));
4423 bset_read_only (&buffer_local_flags, make_number (-1)); 4553 bset_read_only (&buffer_local_flags, make_fixnum (-1));
4424 bset_major_mode (&buffer_local_flags, make_number (-1)); 4554 bset_major_mode (&buffer_local_flags, make_fixnum (-1));
4425 bset_mode_name (&buffer_local_flags, make_number (-1)); 4555 bset_local_minor_modes (&buffer_local_flags, make_fixnum (-1));
4426 bset_undo_list (&buffer_local_flags, make_number (-1)); 4556 bset_mode_name (&buffer_local_flags, make_fixnum (-1));
4427 bset_mark_active (&buffer_local_flags, make_number (-1)); 4557 bset_undo_list (&buffer_local_flags, make_fixnum (-1));
4428 bset_point_before_scroll (&buffer_local_flags, make_number (-1)); 4558 bset_mark_active (&buffer_local_flags, make_fixnum (-1));
4429 bset_file_truename (&buffer_local_flags, make_number (-1)); 4559 bset_point_before_scroll (&buffer_local_flags, make_fixnum (-1));
4430 bset_invisibility_spec (&buffer_local_flags, make_number (-1)); 4560 bset_file_truename (&buffer_local_flags, make_fixnum (-1));
4431 bset_file_format (&buffer_local_flags, make_number (-1)); 4561 bset_invisibility_spec (&buffer_local_flags, make_fixnum (-1));
4432 bset_auto_save_file_format (&buffer_local_flags, make_number (-1)); 4562 bset_file_format (&buffer_local_flags, make_fixnum (-1));
4433 bset_display_count (&buffer_local_flags, make_number (-1)); 4563 bset_auto_save_file_format (&buffer_local_flags, make_fixnum (-1));
4434 bset_display_time (&buffer_local_flags, make_number (-1)); 4564 bset_display_count (&buffer_local_flags, make_fixnum (-1));
4435 bset_enable_multibyte_characters (&buffer_local_flags, make_number (-1)); 4565 bset_display_time (&buffer_local_flags, make_fixnum (-1));
4566 bset_enable_multibyte_characters (&buffer_local_flags, make_fixnum (-1));
4436 4567
4437 /* These used to be stuck at 0 by default, but now that the all-zero value 4568 /* These used to be stuck at 0 by default, but now that the all-zero value
4438 means Qnil, we have to initialize them explicitly. */ 4569 means Qnil, we have to initialize them explicitly. */
4439 bset_name (&buffer_local_flags, make_number (0)); 4570 bset_name (&buffer_local_flags, make_fixnum (0));
4440 bset_mark (&buffer_local_flags, make_number (0)); 4571 bset_mark (&buffer_local_flags, make_fixnum (0));
4441 bset_local_var_alist (&buffer_local_flags, make_number (0)); 4572 bset_local_var_alist (&buffer_local_flags, make_fixnum (0));
4442 bset_keymap (&buffer_local_flags, make_number (0)); 4573 bset_keymap (&buffer_local_flags, make_fixnum (0));
4443 bset_downcase_table (&buffer_local_flags, make_number (0)); 4574 bset_downcase_table (&buffer_local_flags, make_fixnum (0));
4444 bset_upcase_table (&buffer_local_flags, make_number (0)); 4575 bset_upcase_table (&buffer_local_flags, make_fixnum (0));
4445 bset_case_canon_table (&buffer_local_flags, make_number (0)); 4576 bset_case_canon_table (&buffer_local_flags, make_fixnum (0));
4446 bset_case_eqv_table (&buffer_local_flags, make_number (0)); 4577 bset_case_eqv_table (&buffer_local_flags, make_fixnum (0));
4447 bset_minor_modes (&buffer_local_flags, make_number (0)); 4578 bset_width_table (&buffer_local_flags, make_fixnum (0));
4448 bset_width_table (&buffer_local_flags, make_number (0)); 4579 bset_pt_marker (&buffer_local_flags, make_fixnum (0));
4449 bset_pt_marker (&buffer_local_flags, make_number (0)); 4580 bset_begv_marker (&buffer_local_flags, make_fixnum (0));
4450 bset_begv_marker (&buffer_local_flags, make_number (0)); 4581 bset_zv_marker (&buffer_local_flags, make_fixnum (0));
4451 bset_zv_marker (&buffer_local_flags, make_number (0)); 4582 bset_last_selected_window (&buffer_local_flags, make_fixnum (0));
4452 bset_last_selected_window (&buffer_local_flags, make_number (0));
4453 4583
4454 idx = 1; 4584 idx = 1;
4455 XSETFASTINT (BVAR (&buffer_local_flags, mode_line_format), idx); ++idx; 4585 XSETFASTINT (BVAR (&buffer_local_flags, mode_line_format), idx); ++idx;
@@ -4460,7 +4590,9 @@ init_buffer_once (void)
4460 XSETFASTINT (BVAR (&buffer_local_flags, selective_display), idx); ++idx; 4590 XSETFASTINT (BVAR (&buffer_local_flags, selective_display), idx); ++idx;
4461 XSETFASTINT (BVAR (&buffer_local_flags, selective_display_ellipses), idx); ++idx; 4591 XSETFASTINT (BVAR (&buffer_local_flags, selective_display_ellipses), idx); ++idx;
4462 XSETFASTINT (BVAR (&buffer_local_flags, tab_width), idx); ++idx; 4592 XSETFASTINT (BVAR (&buffer_local_flags, tab_width), idx); ++idx;
4463 XSETFASTINT (BVAR (&buffer_local_flags, truncate_lines), idx); ++idx; 4593 XSETFASTINT (BVAR (&buffer_local_flags, truncate_lines), idx);
4594 /* Make this one a permanent local. */
4595 buffer_permanent_local_flags[idx++] = 1;
4464 XSETFASTINT (BVAR (&buffer_local_flags, word_wrap), idx); ++idx; 4596 XSETFASTINT (BVAR (&buffer_local_flags, word_wrap), idx); ++idx;
4465 XSETFASTINT (BVAR (&buffer_local_flags, ctl_arrow), idx); ++idx; 4597 XSETFASTINT (BVAR (&buffer_local_flags, ctl_arrow), idx); ++idx;
4466 XSETFASTINT (BVAR (&buffer_local_flags, fill_column), idx); ++idx; 4598 XSETFASTINT (BVAR (&buffer_local_flags, fill_column), idx); ++idx;
@@ -4493,14 +4625,20 @@ init_buffer_once (void)
4493 XSETFASTINT (BVAR (&buffer_local_flags, scroll_up_aggressively), idx); ++idx; 4625 XSETFASTINT (BVAR (&buffer_local_flags, scroll_up_aggressively), idx); ++idx;
4494 XSETFASTINT (BVAR (&buffer_local_flags, scroll_down_aggressively), idx); ++idx; 4626 XSETFASTINT (BVAR (&buffer_local_flags, scroll_down_aggressively), idx); ++idx;
4495 XSETFASTINT (BVAR (&buffer_local_flags, header_line_format), idx); ++idx; 4627 XSETFASTINT (BVAR (&buffer_local_flags, header_line_format), idx); ++idx;
4628 XSETFASTINT (BVAR (&buffer_local_flags, tab_line_format), idx); ++idx;
4496 XSETFASTINT (BVAR (&buffer_local_flags, cursor_type), idx); ++idx; 4629 XSETFASTINT (BVAR (&buffer_local_flags, cursor_type), idx); ++idx;
4497 XSETFASTINT (BVAR (&buffer_local_flags, extra_line_spacing), idx); ++idx; 4630 XSETFASTINT (BVAR (&buffer_local_flags, extra_line_spacing), idx); ++idx;
4498 XSETFASTINT (BVAR (&buffer_local_flags, cursor_in_non_selected_windows), idx); ++idx; 4631 XSETFASTINT (BVAR (&buffer_local_flags, cursor_in_non_selected_windows), idx); ++idx;
4499 4632
4633 /* buffer_local_flags contains no pointers, so it's safe to treat it
4634 as a blob for pdumper. */
4635 PDUMPER_REMEMBER_SCALAR (buffer_local_flags);
4636
4500 /* Need more room? */ 4637 /* Need more room? */
4501 if (idx >= MAX_PER_BUFFER_VARS) 4638 if (idx >= MAX_PER_BUFFER_VARS)
4502 emacs_abort (); 4639 emacs_abort ();
4503 last_per_buffer_idx = idx; 4640 last_per_buffer_idx = idx;
4641 PDUMPER_REMEMBER_SCALAR (last_per_buffer_idx);
4504 4642
4505 /* Make sure all markable slots in buffer_defaults 4643 /* Make sure all markable slots in buffer_defaults
4506 are initialized reasonably, so mark_buffer won't choke. */ 4644 are initialized reasonably, so mark_buffer won't choke. */
@@ -4533,6 +4671,7 @@ init_buffer_once (void)
4533 /* real setup is done in bindings.el */ 4671 /* real setup is done in bindings.el */
4534 bset_mode_line_format (&buffer_defaults, build_pure_c_string ("%-")); 4672 bset_mode_line_format (&buffer_defaults, build_pure_c_string ("%-"));
4535 bset_header_line_format (&buffer_defaults, Qnil); 4673 bset_header_line_format (&buffer_defaults, Qnil);
4674 bset_tab_line_format (&buffer_defaults, Qnil);
4536 bset_abbrev_mode (&buffer_defaults, Qnil); 4675 bset_abbrev_mode (&buffer_defaults, Qnil);
4537 bset_overwrite_mode (&buffer_defaults, Qnil); 4676 bset_overwrite_mode (&buffer_defaults, Qnil);
4538 bset_case_fold_search (&buffer_defaults, Qt); 4677 bset_case_fold_search (&buffer_defaults, Qt);
@@ -4593,7 +4732,7 @@ init_buffer_once (void)
4593 4732
4594 Vbuffer_alist = Qnil; 4733 Vbuffer_alist = Qnil;
4595 current_buffer = 0; 4734 current_buffer = 0;
4596 all_buffers = 0; 4735 pdumper_remember_lv_ptr_raw (&current_buffer, Lisp_Vectorlike);
4597 4736
4598 QSFundamental = build_pure_c_string ("Fundamental"); 4737 QSFundamental = build_pure_c_string ("Fundamental");
4599 4738
@@ -4608,25 +4747,24 @@ init_buffer_once (void)
4608 Fput (Qkill_buffer_hook, Qpermanent_local, Qt); 4747 Fput (Qkill_buffer_hook, Qpermanent_local, Qt);
4609 4748
4610 /* Super-magic invisible buffer. */ 4749 /* Super-magic invisible buffer. */
4611 Vprin1_to_string_buffer = Fget_buffer_create (build_pure_c_string (" prin1")); 4750 Vprin1_to_string_buffer =
4751 Fget_buffer_create (build_pure_c_string (" prin1"), Qt);
4612 Vbuffer_alist = Qnil; 4752 Vbuffer_alist = Qnil;
4613 4753
4614 Fset_buffer (Fget_buffer_create (build_pure_c_string ("*scratch*"))); 4754 Fset_buffer (Fget_buffer_create (build_pure_c_string ("*scratch*"), Qnil));
4615 4755
4616 inhibit_modification_hooks = 0; 4756 inhibit_modification_hooks = 0;
4617} 4757}
4618 4758
4619void 4759void
4620init_buffer (int initialized) 4760init_buffer (void)
4621{ 4761{
4622 char *pwd;
4623 Lisp_Object temp; 4762 Lisp_Object temp;
4624 ptrdiff_t len;
4625 4763
4626#ifdef USE_MMAP_FOR_BUFFERS 4764#ifdef USE_MMAP_FOR_BUFFERS
4627 if (initialized) 4765 if (dumped_with_unexec_p ())
4628 { 4766 {
4629 struct buffer *b; 4767 Lisp_Object tail, buffer;
4630 4768
4631#ifndef WINDOWSNT 4769#ifndef WINDOWSNT
4632 /* These must be reset in the dumped Emacs, to avoid stale 4770 /* These must be reset in the dumped Emacs, to avoid stale
@@ -4643,39 +4781,33 @@ init_buffer (int initialized)
4643 recorded by temacs, that cannot be used by the dumped Emacs. 4781 recorded by temacs, that cannot be used by the dumped Emacs.
4644 We map new memory for their text here. 4782 We map new memory for their text here.
4645 4783
4646 Implementation note: the buffers we carry from temacs are: 4784 Implementation notes: the buffers we carry from temacs are:
4647 " prin1", "*scratch*", " *Minibuf-0*", "*Messages*", and 4785 " prin1", "*scratch*", " *Minibuf-0*", "*Messages*", and
4648 " *code-conversion-work*". They are created by 4786 " *code-conversion-work*". They are created by
4649 init_buffer_once and init_window_once (which are not called 4787 init_buffer_once and init_window_once (which are not called
4650 in the dumped Emacs), and by the first call to coding.c routines. */ 4788 in the dumped Emacs), and by the first call to coding.c
4651 FOR_EACH_BUFFER (b) 4789 routines. Since FOR_EACH_LIVE_BUFFER only walks the buffers
4790 in Vbuffer_alist, any buffer we carry from temacs that is
4791 not in the alist (a.k.a. "magic invisible buffers") should
4792 be handled here explicitly. */
4793 FOR_EACH_LIVE_BUFFER (tail, buffer)
4652 { 4794 {
4795 struct buffer *b = XBUFFER (buffer);
4653 b->text->beg = NULL; 4796 b->text->beg = NULL;
4654 enlarge_buffer_text (b, 0); 4797 enlarge_buffer_text (b, 0);
4655 } 4798 }
4799 /* The " prin1" buffer is not in Vbuffer_alist. */
4800 XBUFFER (Vprin1_to_string_buffer)->text->beg = NULL;
4801 enlarge_buffer_text (XBUFFER (Vprin1_to_string_buffer), 0);
4656 } 4802 }
4657 else
4658 {
4659 struct buffer *b;
4660
4661 /* Only buffers with allocated buffer text should be present at
4662 this point in temacs. */
4663 FOR_EACH_BUFFER (b)
4664 {
4665 eassert (b->text->beg != NULL);
4666 }
4667 }
4668#else /* not USE_MMAP_FOR_BUFFERS */
4669 /* Avoid compiler warnings. */
4670 (void) initialized;
4671#endif /* USE_MMAP_FOR_BUFFERS */ 4803#endif /* USE_MMAP_FOR_BUFFERS */
4672 4804
4673 AUTO_STRING (scratch, "*scratch*"); 4805 AUTO_STRING (scratch, "*scratch*");
4674 Fset_buffer (Fget_buffer_create (scratch)); 4806 Fset_buffer (Fget_buffer_create (scratch, Qnil));
4675 if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters))) 4807 if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters)))
4676 Fset_buffer_multibyte (Qnil); 4808 Fset_buffer_multibyte (Qnil);
4677 4809
4678 pwd = emacs_get_current_dir_name (); 4810 char const *pwd = emacs_wd;
4679 4811
4680 if (!pwd) 4812 if (!pwd)
4681 { 4813 {
@@ -4687,22 +4819,16 @@ init_buffer (int initialized)
4687 { 4819 {
4688 /* Maybe this should really use some standard subroutine 4820 /* Maybe this should really use some standard subroutine
4689 whose definition is filename syntax dependent. */ 4821 whose definition is filename syntax dependent. */
4690 len = strlen (pwd); 4822 ptrdiff_t len = strlen (pwd);
4691 if (!(IS_DIRECTORY_SEP (pwd[len - 1]))) 4823 bool add_slash = ! IS_DIRECTORY_SEP (pwd[len - 1]);
4692 {
4693 /* Grow buffer to add directory separator and '\0'. */
4694 pwd = realloc (pwd, len + 2);
4695 if (!pwd)
4696 fatal ("get_current_dir_name: %s\n", strerror (errno));
4697 pwd[len] = DIRECTORY_SEP;
4698 pwd[len + 1] = '\0';
4699 len++;
4700 }
4701 4824
4702 /* At this moment, we still don't know how to decode the directory 4825 /* At this moment, we still don't know how to decode the directory
4703 name. So, we keep the bytes in unibyte form so that file I/O 4826 name. So, we keep the bytes in unibyte form so that file I/O
4704 routines correctly get the original bytes. */ 4827 routines correctly get the original bytes. */
4705 bset_directory (current_buffer, make_unibyte_string (pwd, len)); 4828 Lisp_Object dirname = make_unibyte_string (pwd, len + add_slash);
4829 if (add_slash)
4830 SSET (dirname, len, DIRECTORY_SEP);
4831 bset_directory (current_buffer, dirname);
4706 4832
4707 /* Add /: to the front of the name 4833 /* Add /: to the front of the name
4708 if it would otherwise be treated as magic. */ 4834 if it would otherwise be treated as magic. */
@@ -4723,8 +4849,6 @@ init_buffer (int initialized)
4723 4849
4724 temp = get_minibuffer (0); 4850 temp = get_minibuffer (0);
4725 bset_directory (XBUFFER (temp), BVAR (current_buffer, directory)); 4851 bset_directory (XBUFFER (temp), BVAR (current_buffer, directory));
4726
4727 free (pwd);
4728} 4852}
4729 4853
4730/* Similar to defvar_lisp but define a variable whose value is the 4854/* Similar to defvar_lisp but define a variable whose value is the
@@ -4754,9 +4878,9 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
4754 bo_fwd->type = Lisp_Fwd_Buffer_Obj; 4878 bo_fwd->type = Lisp_Fwd_Buffer_Obj;
4755 bo_fwd->offset = offset; 4879 bo_fwd->offset = offset;
4756 bo_fwd->predicate = predicate; 4880 bo_fwd->predicate = predicate;
4757 sym->declared_special = 1; 4881 sym->u.s.declared_special = true;
4758 sym->redirect = SYMBOL_FORWARDED; 4882 sym->u.s.redirect = SYMBOL_FORWARDED;
4759 SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd); 4883 SET_SYMBOL_FWD (sym, bo_fwd);
4760 XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); 4884 XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym);
4761 4885
4762 if (PER_BUFFER_IDX (offset) == 0) 4886 if (PER_BUFFER_IDX (offset) == 0)
@@ -4813,8 +4937,7 @@ void
4813syms_of_buffer (void) 4937syms_of_buffer (void)
4814{ 4938{
4815 staticpro (&last_overlay_modification_hooks); 4939 staticpro (&last_overlay_modification_hooks);
4816 last_overlay_modification_hooks 4940 last_overlay_modification_hooks = make_nil_vector (10);
4817 = Fmake_vector (make_number (10), Qnil);
4818 4941
4819 staticpro (&QSFundamental); 4942 staticpro (&QSFundamental);
4820 staticpro (&Vbuffer_alist); 4943 staticpro (&Vbuffer_alist);
@@ -4838,6 +4961,7 @@ syms_of_buffer (void)
4838 DEFSYM (Qbefore_change_functions, "before-change-functions"); 4961 DEFSYM (Qbefore_change_functions, "before-change-functions");
4839 DEFSYM (Qafter_change_functions, "after-change-functions"); 4962 DEFSYM (Qafter_change_functions, "after-change-functions");
4840 DEFSYM (Qkill_buffer_query_functions, "kill-buffer-query-functions"); 4963 DEFSYM (Qkill_buffer_query_functions, "kill-buffer-query-functions");
4964 DEFSYM (Qget_scratch_buffer_create, "get-scratch-buffer-create");
4841 4965
4842 DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar"); 4966 DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar");
4843 Fput (Qvertical_scroll_bar, Qchoice, list4 (Qnil, Qt, Qleft, Qright)); 4967 Fput (Qvertical_scroll_bar, Qchoice, list4 (Qnil, Qt, Qleft, Qright));
@@ -4852,20 +4976,32 @@ syms_of_buffer (void)
4852 Qoverwrite_mode_binary)); 4976 Qoverwrite_mode_binary));
4853 4977
4854 Fput (Qprotected_field, Qerror_conditions, 4978 Fput (Qprotected_field, Qerror_conditions,
4855 listn (CONSTYPE_PURE, 2, Qprotected_field, Qerror)); 4979 pure_list (Qprotected_field, Qerror));
4856 Fput (Qprotected_field, Qerror_message, 4980 Fput (Qprotected_field, Qerror_message,
4857 build_pure_c_string ("Attempt to modify a protected field")); 4981 build_pure_c_string ("Attempt to modify a protected field"));
4858 4982
4983 DEFSYM (Qclone_indirect_buffer_hook, "clone-indirect-buffer-hook");
4984
4985 DEFVAR_PER_BUFFER ("tab-line-format",
4986 &BVAR (current_buffer, tab_line_format),
4987 Qnil,
4988 doc: /* Analogous to `mode-line-format', but controls the tab line.
4989The tab line appears, optionally, at the top of a window;
4990the mode line appears at the bottom. */);
4991
4859 DEFVAR_PER_BUFFER ("header-line-format", 4992 DEFVAR_PER_BUFFER ("header-line-format",
4860 &BVAR (current_buffer, header_line_format), 4993 &BVAR (current_buffer, header_line_format),
4861 Qnil, 4994 Qnil,
4862 doc: /* Analogous to `mode-line-format', but controls the header line. 4995 doc: /* Analogous to `mode-line-format', but controls the header line.
4863The header line appears, optionally, at the top of a window; 4996The header line appears, optionally, at the top of a window; the mode
4864the mode line appears at the bottom. */); 4997line appears at the bottom.
4998
4999Also see `header-line-indent-mode' if `display-line-number-mode' is
5000used. */);
4865 5001
4866 DEFVAR_PER_BUFFER ("mode-line-format", &BVAR (current_buffer, mode_line_format), 5002 DEFVAR_PER_BUFFER ("mode-line-format", &BVAR (current_buffer, mode_line_format),
4867 Qnil, 5003 Qnil,
4868 doc: /* Template for displaying mode line for current buffer. 5004 doc: /* Template for displaying mode line for a window's buffer.
4869 5005
4870The value may be nil, a string, a symbol or a list. 5006The value may be nil, a string, a symbol or a list.
4871 5007
@@ -4878,6 +5014,9 @@ For any symbol other than t or nil, the symbol's value is processed as
4878 `risky-local-variable' property, all properties in any strings, as 5014 `risky-local-variable' property, all properties in any strings, as
4879 well as all :eval and :propertize forms in the value, are ignored. 5015 well as all :eval and :propertize forms in the value, are ignored.
4880 5016
5017When the value is processed, the window's buffer is temporarily the
5018current buffer.
5019
4881A list whose car is a string or list is processed by processing each 5020A list whose car is a string or list is processed by processing each
4882 of the list elements recursively, as separate mode line constructs, 5021 of the list elements recursively, as separate mode line constructs,
4883 and concatenating the results. 5022 and concatenating the results.
@@ -4936,6 +5075,12 @@ The default value (normally `fundamental-mode') affects new buffers.
4936A value of nil means to use the current buffer's major mode, provided 5075A value of nil means to use the current buffer's major mode, provided
4937it is not marked as "special". */); 5076it is not marked as "special". */);
4938 5077
5078 DEFVAR_PER_BUFFER ("local-minor-modes",
5079 &BVAR (current_buffer, local_minor_modes),
5080 Qnil,
5081 doc: /* Minor modes currently active in the current buffer.
5082This is a list of symbols, or nil if there are no minor modes active. */);
5083
4939 DEFVAR_PER_BUFFER ("mode-name", &BVAR (current_buffer, mode_name), 5084 DEFVAR_PER_BUFFER ("mode-name", &BVAR (current_buffer, mode_name),
4940 Qnil, 5085 Qnil,
4941 doc: /* Pretty name of current buffer's major mode. 5086 doc: /* Pretty name of current buffer's major mode.
@@ -4957,6 +5102,9 @@ Use the command `abbrev-mode' to change this variable. */);
4957 DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column), 5102 DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column),
4958 Qintegerp, 5103 Qintegerp,
4959 doc: /* Column beyond which automatic line-wrapping should happen. 5104 doc: /* Column beyond which automatic line-wrapping should happen.
5105It is used by filling commands, such as `fill-region' and `fill-paragraph',
5106and by `auto-fill-mode', which see.
5107See also `current-fill-column'.
4960Interactively, you can set the buffer local value using \\[set-fill-column]. */); 5108Interactively, you can set the buffer local value using \\[set-fill-column]. */);
4961 5109
4962 DEFVAR_PER_BUFFER ("left-margin", &BVAR (current_buffer, left_margin), 5110 DEFVAR_PER_BUFFER ("left-margin", &BVAR (current_buffer, left_margin),
@@ -4967,15 +5115,18 @@ Linefeed indents to this column in Fundamental mode. */);
4967 DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width), 5115 DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width),
4968 Qintegerp, 5116 Qintegerp,
4969 doc: /* Distance between tab stops (for display of tab characters), in columns. 5117 doc: /* Distance between tab stops (for display of tab characters), in columns.
4970NOTE: This controls the display width of a TAB character, and not 5118This controls the width of a TAB character on display.
4971the size of an indentation step. 5119The value should be a positive integer.
4972This should be an integer greater than zero. */); 5120Note that this variable doesn't necessarily affect the size of the
5121indentation step. However, if the major mode's indentation facility
5122inserts one or more TAB characters, this variable will affect the
5123indentation step as well, even if `indent-tabs-mode' is non-nil. */);
4973 5124
4974 DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil, 5125 DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil,
4975 doc: /* Non-nil means display control chars with uparrow. 5126 doc: /* Non-nil means display control chars with uparrow `^'.
4976A value of nil means use backslash and octal digits. 5127A value of nil means use backslash `\\' and octal digits.
4977This variable does not apply to characters whose display is specified 5128This variable does not apply to characters whose display is specified in
4978in the current display table (if there is one). */); 5129the current display table (if there is one; see `standard-display-table'). */);
4979 5130
4980 DEFVAR_PER_BUFFER ("enable-multibyte-characters", 5131 DEFVAR_PER_BUFFER ("enable-multibyte-characters",
4981 &BVAR (current_buffer, enable_multibyte_characters), 5132 &BVAR (current_buffer, enable_multibyte_characters),
@@ -4986,6 +5137,8 @@ file I/O and the behavior of various editing commands.
4986 5137
4987This variable is buffer-local but you cannot set it directly; 5138This variable is buffer-local but you cannot set it directly;
4988use the function `set-buffer-multibyte' to change a buffer's representation. 5139use the function `set-buffer-multibyte' to change a buffer's representation.
5140To prevent any attempts to set it or make it buffer-local, Emacs will
5141signal an error in those cases.
4989See also Info node `(elisp)Text Representations'. */); 5142See also Info node `(elisp)Text Representations'. */);
4990 make_symbol_constant (intern_c_string ("enable-multibyte-characters")); 5143 make_symbol_constant (intern_c_string ("enable-multibyte-characters"));
4991 5144
@@ -5009,7 +5162,11 @@ This variable is never applied to a way of decoding a file while reading it. */
5009 5162
5010 DEFVAR_PER_BUFFER ("bidi-display-reordering", 5163 DEFVAR_PER_BUFFER ("bidi-display-reordering",
5011 &BVAR (current_buffer, bidi_display_reordering), Qnil, 5164 &BVAR (current_buffer, bidi_display_reordering), Qnil,
5012 doc: /* Non-nil means reorder bidirectional text for display in the visual order. */); 5165 doc: /* Non-nil means reorder bidirectional text for display in the visual order.
5166Setting this to nil is intended for use in debugging the display code.
5167Don't set to nil in normal sessions, as that is not supported.
5168See also `bidi-paragraph-direction'; setting that non-nil might
5169speed up redisplay. */);
5013 5170
5014 DEFVAR_PER_BUFFER ("bidi-paragraph-start-re", 5171 DEFVAR_PER_BUFFER ("bidi-paragraph-start-re",
5015 &BVAR (current_buffer, bidi_paragraph_start_re), Qnil, 5172 &BVAR (current_buffer, bidi_paragraph_start_re), Qnil,
@@ -5074,7 +5231,10 @@ Note that this is overridden by the variable
5074`truncate-partial-width-windows' if that variable is non-nil 5231`truncate-partial-width-windows' if that variable is non-nil
5075and this buffer is not full-frame width. 5232and this buffer is not full-frame width.
5076 5233
5077Minibuffers set this variable to nil. */); 5234Minibuffers set this variable to nil.
5235
5236Don't set this to a non-nil value when `visual-line-mode' is
5237turned on, as it could produce confusing results. */);
5078 5238
5079 DEFVAR_PER_BUFFER ("word-wrap", &BVAR (current_buffer, word_wrap), Qnil, 5239 DEFVAR_PER_BUFFER ("word-wrap", &BVAR (current_buffer, word_wrap), Qnil,
5080 doc: /* Non-nil means to use word-wrapping for continuation lines. 5240 doc: /* Non-nil means to use word-wrapping for continuation lines.
@@ -5089,7 +5249,7 @@ word-wrapping, you might want to reduce the value of
5089in narrower windows. 5249in narrower windows.
5090 5250
5091Instead of setting this variable directly, most users should use 5251Instead of setting this variable directly, most users should use
5092Visual Line mode . Visual Line mode, when enabled, sets `word-wrap' 5252Visual Line mode. Visual Line mode, when enabled, sets `word-wrap'
5093to t, and additionally redefines simple editing commands to act on 5253to t, and additionally redefines simple editing commands to act on
5094visual lines rather than logical lines. See the documentation of 5254visual lines rather than logical lines. See the documentation of
5095`visual-line-mode'. */); 5255`visual-line-mode'. */);
@@ -5097,8 +5257,8 @@ visual lines rather than logical lines. See the documentation of
5097 DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory), 5257 DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory),
5098 Qstringp, 5258 Qstringp,
5099 doc: /* Name of default directory of current buffer. 5259 doc: /* Name of default directory of current buffer.
5100It should be a directory name (as opposed to a directory file-name). 5260It should be an absolute directory name; on GNU and Unix systems,
5101On GNU and Unix systems, directory names end in a slash `/'. 5261these names start with `/' or `~' and end with `/'.
5102To interactively change the default directory, use command `cd'. */); 5262To interactively change the default directory, use command `cd'. */);
5103 5263
5104 DEFVAR_PER_BUFFER ("auto-fill-function", &BVAR (current_buffer, auto_fill_function), 5264 DEFVAR_PER_BUFFER ("auto-fill-function", &BVAR (current_buffer, auto_fill_function),
@@ -5282,15 +5442,16 @@ specifies. */);
5282 5442
5283 DEFVAR_PER_BUFFER ("indicate-empty-lines", 5443 DEFVAR_PER_BUFFER ("indicate-empty-lines",
5284 &BVAR (current_buffer, indicate_empty_lines), Qnil, 5444 &BVAR (current_buffer, indicate_empty_lines), Qnil,
5285 doc: /* Visually indicate empty lines after the buffer end. 5445 doc: /* Visually indicate unused ("empty") screen lines after the buffer end.
5286If non-nil, a bitmap is displayed in the left fringe of a window on 5446If non-nil, a bitmap is displayed in the left fringe of a window
5287window-systems. */); 5447on graphical displays for each screen line that doesn't correspond
5448to any buffer text. */);
5288 5449
5289 DEFVAR_PER_BUFFER ("indicate-buffer-boundaries", 5450 DEFVAR_PER_BUFFER ("indicate-buffer-boundaries",
5290 &BVAR (current_buffer, indicate_buffer_boundaries), Qnil, 5451 &BVAR (current_buffer, indicate_buffer_boundaries), Qnil,
5291 doc: /* Visually indicate buffer boundaries and scrolling. 5452 doc: /* Visually indicate buffer boundaries and scrolling.
5292If non-nil, the first and last line of the buffer are marked in the fringe 5453If non-nil, the first and last line of the buffer are marked in the fringe
5293of a window on window-systems with angle bitmaps, or if the window can be 5454of a window on graphical displays with angle bitmaps, or if the window can be
5294scrolled, the top and bottom line of the window are marked with up and down 5455scrolled, the top and bottom line of the window are marked with up and down
5295arrow bitmaps. 5456arrow bitmaps.
5296 5457
@@ -5421,13 +5582,13 @@ An entry (TEXT . POSITION) represents the deletion of the string TEXT
5421from (abs POSITION). If POSITION is positive, point was at the front 5582from (abs POSITION). If POSITION is positive, point was at the front
5422of the text being deleted; if negative, point was at the end. 5583of the text being deleted; if negative, point was at the end.
5423 5584
5424An entry (t HIGH LOW USEC PSEC) indicates that the buffer was previously 5585An entry (t . TIMESTAMP), where TIMESTAMP is in the style of
5425unmodified; (HIGH LOW USEC PSEC) is in the same style as (current-time) 5586`current-time', indicates that the buffer was previously unmodified;
5426and is the visited file's modification time, as of that time. If the 5587TIMESTAMP is the visited file's modification time, as of that time.
5427modification time of the most recent save is different, this entry is 5588If the modification time of the most recent save is different, this
5428obsolete. 5589entry is obsolete.
5429 5590
5430An entry (t . 0) means means the buffer was previously unmodified but 5591An entry (t . 0) means the buffer was previously unmodified but
5431its time stamp was unknown because it was not associated with a file. 5592its time stamp was unknown because it was not associated with a file.
5432An entry (t . -1) is similar, except that it means the buffer's visited 5593An entry (t . -1) is similar, except that it means the buffer's visited
5433file did not exist. 5594file did not exist.
@@ -5560,10 +5721,10 @@ Lisp programs may give this variable certain special values:
5560 5721
5561 DEFVAR_LISP ("inhibit-read-only", Vinhibit_read_only, 5722 DEFVAR_LISP ("inhibit-read-only", Vinhibit_read_only,
5562 doc: /* Non-nil means disregard read-only status of buffers or characters. 5723 doc: /* Non-nil means disregard read-only status of buffers or characters.
5563If the value is t, disregard `buffer-read-only' and all `read-only' 5724A non-nil value that is a list means disregard `buffer-read-only' status,
5564text properties. If the value is a list, disregard `buffer-read-only' 5725and disregard a `read-only' text property if the property value is a
5565and disregard a `read-only' text property if the property value 5726member of the list. Any other non-nil value means disregard `buffer-read-only'
5566is a member of the list. */); 5727and all `read-only' text properties. */);
5567 Vinhibit_read_only = Qnil; 5728 Vinhibit_read_only = Qnil;
5568 5729
5569 DEFVAR_PER_BUFFER ("cursor-type", &BVAR (current_buffer, cursor_type), Qnil, 5730 DEFVAR_PER_BUFFER ("cursor-type", &BVAR (current_buffer, cursor_type), Qnil,
@@ -5573,6 +5734,9 @@ Values are interpreted as follows:
5573 t use the cursor specified for the frame 5734 t use the cursor specified for the frame
5574 nil don't display a cursor 5735 nil don't display a cursor
5575 box display a filled box cursor 5736 box display a filled box cursor
5737 (box . SIZE) display a filled box cursor, but make it
5738 hollow if cursor is under masked image larger than
5739 SIZE pixels in either dimension.
5576 hollow display a hollow box cursor 5740 hollow display a hollow box cursor
5577 bar display a vertical bar cursor with default width 5741 bar display a vertical bar cursor with default width
5578 (bar . WIDTH) display a vertical bar cursor with width WIDTH 5742 (bar . WIDTH) display a vertical bar cursor with width WIDTH
@@ -5606,9 +5770,14 @@ Use Custom to set this variable and update the display. */);
5606 DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions, 5770 DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions,
5607 doc: /* List of functions called with no args to query before killing a buffer. 5771 doc: /* List of functions called with no args to query before killing a buffer.
5608The buffer being killed will be current while the functions are running. 5772The buffer being killed will be current while the functions are running.
5773See `kill-buffer'.
5609 5774
5610If any of them returns nil, the buffer is not killed. Functions run by 5775If any of them returns nil, the buffer is not killed. Functions run by
5611this hook are supposed to not change the current buffer. */); 5776this hook are supposed to not change the current buffer.
5777
5778This hook is not run for internal or temporary buffers created by
5779`get-buffer-create' or `generate-new-buffer' with argument
5780INHIBIT-BUFFER-HOOKS non-nil. */);
5612 Vkill_buffer_query_functions = Qnil; 5781 Vkill_buffer_query_functions = Qnil;
5613 5782
5614 DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook, 5783 DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook,
@@ -5619,12 +5788,67 @@ The function `kill-all-local-variables' runs this before doing anything else. *
5619 5788
5620 DEFVAR_LISP ("buffer-list-update-hook", Vbuffer_list_update_hook, 5789 DEFVAR_LISP ("buffer-list-update-hook", Vbuffer_list_update_hook,
5621 doc: /* Hook run when the buffer list changes. 5790 doc: /* Hook run when the buffer list changes.
5622Functions running this hook are, `get-buffer-create', 5791Functions (implicitly) running this hook are `get-buffer-create',
5623`make-indirect-buffer', `rename-buffer', `kill-buffer', 5792`make-indirect-buffer', `rename-buffer', `kill-buffer', `bury-buffer'
5624`bury-buffer-internal' and `select-window'. */); 5793and `select-window'. This hook is not run for internal or temporary
5794buffers created by `get-buffer-create' or `generate-new-buffer' with
5795argument INHIBIT-BUFFER-HOOKS non-nil.
5796
5797Functions run by this hook should avoid calling `select-window' with a
5798nil NORECORD argument since it may lead to infinite recursion. */);
5625 Vbuffer_list_update_hook = Qnil; 5799 Vbuffer_list_update_hook = Qnil;
5626 DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook"); 5800 DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");
5627 5801
5802 DEFVAR_BOOL ("kill-buffer-delete-auto-save-files",
5803 kill_buffer_delete_auto_save_files,
5804 doc: /* If non-nil, offer to delete any autosave file when killing a buffer.
5805
5806If `delete-auto-save-files' is nil, any autosave deletion is inhibited. */);
5807 kill_buffer_delete_auto_save_files = 0;
5808
5809 DEFVAR_BOOL ("delete-auto-save-files", delete_auto_save_files,
5810 doc: /* Non-nil means delete auto-save file when a buffer is saved.
5811This is the default. If nil, auto-save file deletion is inhibited. */);
5812 delete_auto_save_files = 1;
5813
5814 DEFVAR_LISP ("clone-indirect-buffer-hook", Vclone_indirect_buffer_hook,
5815 doc: /* Normal hook to run in the new buffer at the end of `make-indirect-buffer'.
5816
5817Since `clone-indirect-buffer' calls `make-indirect-buffer', this hook
5818will run for `clone-indirect-buffer' calls as well. */);
5819 Vclone_indirect_buffer_hook = Qnil;
5820
5821 DEFVAR_LISP ("long-line-threshold", Vlong_line_threshold,
5822 doc: /* Line length above which to use redisplay shortcuts.
5823
5824The value should be a positive integer or nil.
5825If the value is an integer, shortcuts in the display code intended
5826to speed up redisplay for long lines will automatically be enabled
5827in buffers which contain one or more lines whose length is above
5828this threshold.
5829If nil, these display shortcuts will always remain disabled.
5830
5831There is no reason to change that value except for debugging purposes. */);
5832 XSETFASTINT (Vlong_line_threshold, 10000);
5833
5834 DEFVAR_INT ("large-hscroll-threshold", large_hscroll_threshold,
5835 doc: /* Horizontal scroll of truncated lines above which to use redisplay shortcuts.
5836
5837The value should be a positive integer.
5838
5839Shortcuts in the display code intended to speed up redisplay for long
5840and truncated lines will automatically be enabled when a line's
5841horizontal scroll amount is or about to become larger than the value
5842of this variable.
5843
5844This variable has effect only in buffers which contain one or more
5845lines whose length is above `long-line-threshold', which see.
5846To disable redisplay shortcuts for long truncated line, set this
5847variable to `most-positive-fixnum'.
5848
5849There is no reason to change that value except for debugging purposes. */);
5850 large_hscroll_threshold = 10000;
5851
5628 defsubr (&Sbuffer_live_p); 5852 defsubr (&Sbuffer_live_p);
5629 defsubr (&Sbuffer_list); 5853 defsubr (&Sbuffer_list);
5630 defsubr (&Sget_buffer); 5854 defsubr (&Sget_buffer);
@@ -5641,6 +5865,7 @@ Functions running this hook are, `get-buffer-create',
5641 defsubr (&Sforce_mode_line_update); 5865 defsubr (&Sforce_mode_line_update);
5642 defsubr (&Sset_buffer_modified_p); 5866 defsubr (&Sset_buffer_modified_p);
5643 defsubr (&Sbuffer_modified_tick); 5867 defsubr (&Sbuffer_modified_tick);
5868 defsubr (&Sinternal__set_buffer_modified_tick);
5644 defsubr (&Sbuffer_chars_modified_tick); 5869 defsubr (&Sbuffer_chars_modified_tick);
5645 defsubr (&Srename_buffer); 5870 defsubr (&Srename_buffer);
5646 defsubr (&Sother_buffer); 5871 defsubr (&Sother_buffer);
@@ -5675,16 +5900,15 @@ Functions running this hook are, `get-buffer-create',
5675 defsubr (&Soverlay_put); 5900 defsubr (&Soverlay_put);
5676 defsubr (&Srestore_buffer_modified_p); 5901 defsubr (&Srestore_buffer_modified_p);
5677 5902
5678 Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt); 5903 DEFSYM (Qautosaved, "autosaved");
5679 5904
5680#ifdef ITREE_DEBUG 5905#ifdef ITREE_DEBUG
5681 defsubr (&Soverlay_tree); 5906 defsubr (&Soverlay_tree);
5682#endif 5907#endif
5683}
5684 5908
5685void 5909 DEFSYM (Qkill_buffer__possibly_save, "kill-buffer--possibly-save");
5686keys_of_buffer (void) 5910
5687{ 5911 DEFSYM (Qbuffer_stale_function, "buffer-stale-function");
5688 initial_define_key (control_x_map, 'b', "switch-to-buffer"); 5912
5689 initial_define_key (control_x_map, 'k', "kill-buffer"); 5913 Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt);
5690} 5914}