* buffer.h (BSET): Remove.
[bpt/emacs.git] / src / buffer.c
CommitLineData
1ab256cb 1/* Buffer manipulation primitives for GNU Emacs.
66c6abf0 2
96a72ee9 3Copyright (C) 1985-1989, 1993-1995, 1997-2012 Free Software Foundation, Inc.
1ab256cb
RM
4
5This file is part of GNU Emacs.
6
9ec0b715 7GNU Emacs is free software: you can redistribute it and/or modify
1ab256cb 8it under the terms of the GNU General Public License as published by
9ec0b715
GM
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
1ab256cb
RM
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
9ec0b715 18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
1ab256cb 19
68c45bf0 20#include <config.h>
1ab256cb 21
f162bcc3
PE
22#define BUFFER_INLINE EXTERN_INLINE
23
2381d133
JB
24#include <sys/types.h>
25#include <sys/stat.h>
1ab256cb 26#include <sys/param.h>
9dde47f5 27#include <errno.h>
15e7873a 28#include <stdio.h>
d7306fe6 29#include <setjmp.h>
dfcf069d 30#include <unistd.h>
7ee72033 31
d6202519
PE
32#include <verify.h>
33
1ab256cb 34#include "lisp.h"
21cf4cf8 35#include "intervals.h"
1ab256cb
RM
36#include "window.h"
37#include "commands.h"
8f348ed5 38#include "character.h"
e5560ff7 39#include "buffer.h"
28e969dd 40#include "region-cache.h"
1ab256cb 41#include "indent.h"
d014bf88 42#include "blockinput.h"
2538fae4 43#include "keyboard.h"
e35f6ff7 44#include "keymap.h"
08460cd4 45#include "frame.h"
1ab256cb
RM
46
47struct buffer *current_buffer; /* the current buffer */
48
49/* First buffer in chain of all buffers (in reverse order of creation).
179dade4 50 Threaded through ->header.next.buffer. */
1ab256cb
RM
51
52struct buffer *all_buffers;
53
54/* This structure holds the default values of the buffer-local variables
55 defined with DEFVAR_PER_BUFFER, that have special slots in each buffer.
56 The default value occupies the same slot in this structure
57 as an individual buffer's value occupies in that buffer.
58 Setting the default value also goes through the alist of buffers
59 and stores into each buffer that does not say it has a local value. */
60
e32a5799 61struct buffer alignas (GCALIGNMENT) buffer_defaults;
1ab256cb
RM
62
63/* A Lisp_Object pointer to the above, used for staticpro */
64
65static Lisp_Object Vbuffer_defaults;
66
67/* This structure marks which slots in a buffer have corresponding
68 default values in buffer_defaults.
69 Each such slot has a nonzero value in this structure.
70 The value has only one nonzero bit.
71
72 When a buffer has its own local value for a slot,
7c02e886
GM
73 the entry for that slot (found in the same slot in this structure)
74 is turned on in the buffer's local_flags array.
1ab256cb
RM
75
76 If a slot in this structure is -1, then even though there may
77 be a DEFVAR_PER_BUFFER for the slot, there is no default value for it;
78 and the corresponding slot in buffer_defaults is not used.
79
1ab256cb
RM
80 If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is
81 zero, that is a bug */
82
83struct buffer buffer_local_flags;
84
85/* 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. */
87
e32a5799 88struct buffer alignas (GCALIGNMENT) buffer_local_symbols;
6b61353c 89
1ab256cb
RM
90/* A Lisp_Object pointer to the above, used for staticpro */
91static Lisp_Object Vbuffer_local_symbols;
92
ce5b453a
SM
93/* Return the symbol of the per-buffer variable at offset OFFSET in
94 the buffer structure. */
95
96#define PER_BUFFER_SYMBOL(OFFSET) \
97 (*(Lisp_Object *)((OFFSET) + (char *) &buffer_local_symbols))
98
21514da7
PE
99/* Maximum length of an overlay vector. */
100#define OVERLAY_COUNT_MAX \
101 ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, \
663e2b3f 102 min (PTRDIFF_MAX, SIZE_MAX) / word_size))
21514da7 103
13de9290
RS
104/* Flags indicating which built-in buffer-local variables
105 are permanent locals. */
7313acd0 106static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
7c02e886
GM
107
108/* Number of per-buffer variables used. */
109
7313acd0 110int last_per_buffer_idx;
13de9290 111
f57e2426
J
112static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay,
113 int after, Lisp_Object arg1,
114 Lisp_Object arg2, Lisp_Object arg3);
115static void swap_out_buffer_local_variables (struct buffer *b);
116static void reset_buffer_local_variables (struct buffer *b, int permanent_too);
1ab256cb
RM
117
118/* Alist of all buffer names vs the buffers. */
119/* This used to be a variable, but is no longer,
120 to prevent lossage due to user rplac'ing this alist or its elements. */
121Lisp_Object Vbuffer_alist;
122
955cbe7b 123static Lisp_Object Qkill_buffer_query_functions;
dcdffbf6 124
43ed3b8d 125/* Hook run before changing a major mode. */
955cbe7b 126static Lisp_Object Qchange_major_mode_hook;
22378665 127
dbc4e1c1 128Lisp_Object Qfirst_change_hook;
22378665
RS
129Lisp_Object Qbefore_change_functions;
130Lisp_Object Qafter_change_functions;
1ab256cb 131
955cbe7b
PE
132static Lisp_Object Qfundamental_mode, Qmode_class, Qpermanent_local;
133static Lisp_Object Qpermanent_local_hook;
1ab256cb 134
955cbe7b 135static Lisp_Object Qprotected_field;
1ab256cb 136
955cbe7b 137static Lisp_Object QSFundamental; /* A string "Fundamental" */
1ab256cb 138
955cbe7b 139static Lisp_Object Qkill_buffer_hook;
9397e56f 140static Lisp_Object Qbuffer_list_update_hook;
1ab256cb 141
955cbe7b 142static Lisp_Object Qget_file_buffer;
5fe0b67e 143
955cbe7b 144static Lisp_Object Qoverlayp;
52f8ec73 145
955cbe7b 146Lisp_Object Qpriority, Qbefore_string, Qafter_string;
9397e56f 147
28545e04 148static Lisp_Object Qevaporate;
5985d248 149
294d215f
RS
150Lisp_Object Qmodification_hooks;
151Lisp_Object Qinsert_in_front_hooks;
152Lisp_Object Qinsert_behind_hooks;
153
fd05c7e9 154static void alloc_buffer_text (struct buffer *, ptrdiff_t);
f57e2426
J
155static void free_buffer_text (struct buffer *b);
156static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *);
d311d28c 157static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t);
8a05d57a 158static Lisp_Object buffer_lisp_local_variables (struct buffer *, int);
b86af064 159
39eb03f1
PE
160/* These setters are used only in this file, so they can be private. */
161static inline void
162bset_abbrev_mode (struct buffer *b, Lisp_Object val)
163{
164 b->INTERNAL_FIELD (abbrev_mode) = val;
165}
166static inline void
167bset_abbrev_table (struct buffer *b, Lisp_Object val)
168{
169 b->INTERNAL_FIELD (abbrev_table) = val;
170}
171static inline void
172bset_auto_fill_function (struct buffer *b, Lisp_Object val)
173{
174 b->INTERNAL_FIELD (auto_fill_function) = val;
175}
176static inline void
177bset_auto_save_file_format (struct buffer *b, Lisp_Object val)
178{
179 b->INTERNAL_FIELD (auto_save_file_format) = val;
180}
181static inline void
182bset_auto_save_file_name (struct buffer *b, Lisp_Object val)
183{
184 b->INTERNAL_FIELD (auto_save_file_name) = val;
185}
186static inline void
187bset_backed_up (struct buffer *b, Lisp_Object val)
188{
189 b->INTERNAL_FIELD (backed_up) = val;
190}
191static inline void
192bset_begv_marker (struct buffer *b, Lisp_Object val)
193{
194 b->INTERNAL_FIELD (begv_marker) = val;
195}
196static inline void
197bset_bidi_display_reordering (struct buffer *b, Lisp_Object val)
198{
199 b->INTERNAL_FIELD (bidi_display_reordering) = val;
200}
201static inline void
202bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val)
203{
204 b->INTERNAL_FIELD (buffer_file_coding_system) = val;
205}
206static inline void
207bset_cache_long_line_scans (struct buffer *b, Lisp_Object val)
208{
209 b->INTERNAL_FIELD (cache_long_line_scans) = val;
210}
211static inline void
212bset_case_fold_search (struct buffer *b, Lisp_Object val)
213{
214 b->INTERNAL_FIELD (case_fold_search) = val;
215}
216static inline void
217bset_ctl_arrow (struct buffer *b, Lisp_Object val)
218{
219 b->INTERNAL_FIELD (ctl_arrow) = val;
220}
221static inline void
222bset_cursor_in_non_selected_windows (struct buffer *b, Lisp_Object val)
223{
224 b->INTERNAL_FIELD (cursor_in_non_selected_windows) = val;
225}
226static inline void
227bset_cursor_type (struct buffer *b, Lisp_Object val)
228{
229 b->INTERNAL_FIELD (cursor_type) = val;
230}
231static inline void
232bset_display_table (struct buffer *b, Lisp_Object val)
233{
234 b->INTERNAL_FIELD (display_table) = val;
235}
236static inline void
237bset_extra_line_spacing (struct buffer *b, Lisp_Object val)
238{
239 b->INTERNAL_FIELD (extra_line_spacing) = val;
240}
241static inline void
242bset_file_format (struct buffer *b, Lisp_Object val)
243{
244 b->INTERNAL_FIELD (file_format) = val;
245}
246static inline void
247bset_file_truename (struct buffer *b, Lisp_Object val)
248{
249 b->INTERNAL_FIELD (file_truename) = val;
250}
251static inline void
252bset_fringe_cursor_alist (struct buffer *b, Lisp_Object val)
253{
254 b->INTERNAL_FIELD (fringe_cursor_alist) = val;
255}
256static inline void
257bset_fringe_indicator_alist (struct buffer *b, Lisp_Object val)
258{
259 b->INTERNAL_FIELD (fringe_indicator_alist) = val;
260}
261static inline void
262bset_fringes_outside_margins (struct buffer *b, Lisp_Object val)
263{
264 b->INTERNAL_FIELD (fringes_outside_margins) = val;
265}
266static inline void
267bset_header_line_format (struct buffer *b, Lisp_Object val)
268{
269 b->INTERNAL_FIELD (header_line_format) = val;
270}
271static inline void
272bset_indicate_buffer_boundaries (struct buffer *b, Lisp_Object val)
273{
274 b->INTERNAL_FIELD (indicate_buffer_boundaries) = val;
275}
276static inline void
277bset_indicate_empty_lines (struct buffer *b, Lisp_Object val)
278{
279 b->INTERNAL_FIELD (indicate_empty_lines) = val;
280}
281static inline void
282bset_invisibility_spec (struct buffer *b, Lisp_Object val)
283{
284 b->INTERNAL_FIELD (invisibility_spec) = val;
285}
286static inline void
287bset_left_fringe_width (struct buffer *b, Lisp_Object val)
288{
289 b->INTERNAL_FIELD (left_fringe_width) = val;
290}
291static inline void
292bset_major_mode (struct buffer *b, Lisp_Object val)
293{
294 b->INTERNAL_FIELD (major_mode) = val;
295}
296static inline void
297bset_mark (struct buffer *b, Lisp_Object val)
298{
299 b->INTERNAL_FIELD (mark) = val;
300}
301static inline void
302bset_minor_modes (struct buffer *b, Lisp_Object val)
303{
304 b->INTERNAL_FIELD (minor_modes) = val;
305}
306static inline void
307bset_mode_line_format (struct buffer *b, Lisp_Object val)
308{
309 b->INTERNAL_FIELD (mode_line_format) = val;
310}
311static inline void
312bset_mode_name (struct buffer *b, Lisp_Object val)
313{
314 b->INTERNAL_FIELD (mode_name) = val;
315}
316static inline void
317bset_name (struct buffer *b, Lisp_Object val)
318{
319 b->INTERNAL_FIELD (name) = val;
320}
321static inline void
322bset_overwrite_mode (struct buffer *b, Lisp_Object val)
323{
324 b->INTERNAL_FIELD (overwrite_mode) = val;
325}
326static inline void
327bset_pt_marker (struct buffer *b, Lisp_Object val)
328{
329 b->INTERNAL_FIELD (pt_marker) = val;
330}
331static inline void
332bset_right_fringe_width (struct buffer *b, Lisp_Object val)
333{
334 b->INTERNAL_FIELD (right_fringe_width) = val;
335}
336static inline void
337bset_save_length (struct buffer *b, Lisp_Object val)
338{
339 b->INTERNAL_FIELD (save_length) = val;
340}
341static inline void
342bset_scroll_bar_width (struct buffer *b, Lisp_Object val)
343{
344 b->INTERNAL_FIELD (scroll_bar_width) = val;
345}
346static inline void
347bset_scroll_down_aggressively (struct buffer *b, Lisp_Object val)
348{
349 b->INTERNAL_FIELD (scroll_down_aggressively) = val;
350}
351static inline void
352bset_scroll_up_aggressively (struct buffer *b, Lisp_Object val)
353{
354 b->INTERNAL_FIELD (scroll_up_aggressively) = val;
355}
356static inline void
357bset_selective_display (struct buffer *b, Lisp_Object val)
358{
359 b->INTERNAL_FIELD (selective_display) = val;
360}
361static inline void
362bset_selective_display_ellipses (struct buffer *b, Lisp_Object val)
363{
364 b->INTERNAL_FIELD (selective_display_ellipses) = val;
365}
366static inline void
367bset_vertical_scroll_bar_type (struct buffer *b, Lisp_Object val)
368{
369 b->INTERNAL_FIELD (vertical_scroll_bar_type) = val;
370}
371static inline void
372bset_word_wrap (struct buffer *b, Lisp_Object val)
373{
374 b->INTERNAL_FIELD (word_wrap) = val;
375}
376static inline void
377bset_zv_marker (struct buffer *b, Lisp_Object val)
378{
379 b->INTERNAL_FIELD (zv_marker) = val;
380}
381
1ab256cb
RM
382/* For debugging; temporary. See set_buffer_internal. */
383/* Lisp_Object Qlisp_mode, Vcheck_symbol; */
384
01136e9b 385void
d3da34e0 386nsberror (Lisp_Object spec)
1ab256cb 387{
a7a60ce9 388 if (STRINGP (spec))
d5db4077 389 error ("No buffer named %s", SDATA (spec));
1ab256cb
RM
390 error ("Invalid buffer argument");
391}
392\f
a7ca3326 393DEFUN ("buffer-live-p", Fbuffer_live_p, Sbuffer_live_p, 1, 1, 0,
7ee72033
MB
394 doc: /* Return non-nil if OBJECT is a buffer which has not been killed.
395Value is nil if OBJECT is not a buffer or if it has been killed. */)
5842a27b 396 (Lisp_Object object)
0dc88e60 397{
4b4deea2 398 return ((BUFFERP (object) && ! NILP (BVAR (XBUFFER (object), name)))
0dc88e60
RS
399 ? Qt : Qnil);
400}
401
08460cd4 402DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0,
7ee72033 403 doc: /* Return a list of all existing live buffers.
9397e56f
MR
404If the optional arg FRAME is a frame, we return the buffer list in the
405proper order for that frame: the buffers show in FRAME come first,
406followed by the rest of the buffers. */)
5842a27b 407 (Lisp_Object frame)
1ab256cb 408{
a18b8cb5 409 Lisp_Object general;
08460cd4
RS
410 general = Fmapcar (Qcdr, Vbuffer_alist);
411
412 if (FRAMEP (frame))
413 {
a18b8cb5
KL
414 Lisp_Object framelist, prevlist, tail;
415 Lisp_Object args[3];
08460cd4 416
b7826503 417 CHECK_FRAME (frame);
e69b0960 418 framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
9397e56f 419 prevlist = Fnreverse (Fcopy_sequence
e69b0960 420 (XFRAME (frame)->buried_buffer_list));
08460cd4 421
a18b8cb5
KL
422 /* Remove from GENERAL any buffer that duplicates one in
423 FRAMELIST or PREVLIST. */
08460cd4 424 tail = framelist;
a18b8cb5 425 while (CONSP (tail))
08460cd4 426 {
7539e11f
KR
427 general = Fdelq (XCAR (tail), general);
428 tail = XCDR (tail);
08460cd4 429 }
a18b8cb5
KL
430 tail = prevlist;
431 while (CONSP (tail))
432 {
433 general = Fdelq (XCAR (tail), general);
434 tail = XCDR (tail);
435 }
436
437 args[0] = framelist;
438 args[1] = general;
439 args[2] = prevlist;
440 return Fnconc (3, args);
08460cd4 441 }
9397e56f
MR
442 else
443 return general;
1ab256cb
RM
444}
445
04ae1b48
RS
446/* Like Fassoc, but use Fstring_equal to compare
447 (which ignores text properties),
448 and don't ever QUIT. */
449
450static Lisp_Object
d3da34e0 451assoc_ignore_text_properties (register Lisp_Object key, Lisp_Object list)
04ae1b48
RS
452{
453 register Lisp_Object tail;
6d70a280 454 for (tail = list; CONSP (tail); tail = XCDR (tail))
04ae1b48
RS
455 {
456 register Lisp_Object elt, tem;
6d70a280 457 elt = XCAR (tail);
04ae1b48
RS
458 tem = Fstring_equal (Fcar (elt), key);
459 if (!NILP (tem))
460 return elt;
461 }
462 return Qnil;
463}
464
a7ca3326 465DEFUN ("get-buffer", Fget_buffer, Sget_buffer, 1, 1, 0,
c8804c4f
MR
466 doc: /* Return the buffer named BUFFER-OR-NAME.
467BUFFER-OR-NAME must be either a string or a buffer. If BUFFER-OR-NAME
468is a string and there is no buffer with that name, return nil. If
469BUFFER-OR-NAME is a buffer, return it as given. */)
5842a27b 470 (register Lisp_Object buffer_or_name)
1ab256cb 471{
c8804c4f
MR
472 if (BUFFERP (buffer_or_name))
473 return buffer_or_name;
474 CHECK_STRING (buffer_or_name);
1ab256cb 475
c8804c4f 476 return Fcdr (assoc_ignore_text_properties (buffer_or_name, Vbuffer_alist));
1ab256cb
RM
477}
478
479DEFUN ("get-file-buffer", Fget_file_buffer, Sget_file_buffer, 1, 1, 0,
7ee72033 480 doc: /* Return the buffer visiting file FILENAME (a string).
018ba359
PJ
481The buffer's `buffer-file-name' must match exactly the expansion of FILENAME.
482If there is no such live buffer, return nil.
7ee72033 483See also `find-buffer-visiting'. */)
5842a27b 484 (register Lisp_Object filename)
1ab256cb
RM
485{
486 register Lisp_Object tail, buf, tem;
5fe0b67e
RS
487 Lisp_Object handler;
488
b7826503 489 CHECK_STRING (filename);
1ab256cb
RM
490 filename = Fexpand_file_name (filename, Qnil);
491
5fe0b67e
RS
492 /* If the file name has special constructs in it,
493 call the corresponding file handler. */
a617e913 494 handler = Ffind_file_name_handler (filename, Qget_file_buffer);
5fe0b67e 495 if (!NILP (handler))
a59225b1
CY
496 {
497 Lisp_Object handled_buf = call2 (handler, Qget_file_buffer,
498 filename);
499 return BUFFERP (handled_buf) ? handled_buf : Qnil;
500 }
5fe0b67e 501
7539e11f 502 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
1ab256cb 503 {
7539e11f 504 buf = Fcdr (XCAR (tail));
a7a60ce9 505 if (!BUFFERP (buf)) continue;
4b4deea2
TT
506 if (!STRINGP (BVAR (XBUFFER (buf), filename))) continue;
507 tem = Fstring_equal (BVAR (XBUFFER (buf), filename), filename);
265a9e55 508 if (!NILP (tem))
1ab256cb
RM
509 return buf;
510 }
511 return Qnil;
512}
513
52e01189 514Lisp_Object
d3da34e0 515get_truename_buffer (register Lisp_Object filename)
52e01189
RS
516{
517 register Lisp_Object tail, buf, tem;
518
7539e11f 519 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
52e01189 520 {
7539e11f 521 buf = Fcdr (XCAR (tail));
52e01189 522 if (!BUFFERP (buf)) continue;
4b4deea2
TT
523 if (!STRINGP (BVAR (XBUFFER (buf), file_truename))) continue;
524 tem = Fstring_equal (BVAR (XBUFFER (buf), file_truename), filename);
52e01189
RS
525 if (!NILP (tem))
526 return buf;
527 }
528 return Qnil;
529}
530
a7ca3326 531DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 1, 0,
cd265ca6
MR
532 doc: /* Return the buffer specified by BUFFER-OR-NAME, creating a new one if needed.
533If BUFFER-OR-NAME is a string and a live buffer with that name exists,
534return that buffer. If no such buffer exists, create a new buffer with
535that name and return it. If BUFFER-OR-NAME starts with a space, the new
536buffer does not keep undo information.
537
538If BUFFER-OR-NAME is a buffer instead of a string, return it as given,
539even if it is dead. The return value is never nil. */)
5842a27b 540 (register Lisp_Object buffer_or_name)
1ab256cb 541{
cd265ca6 542 register Lisp_Object buffer, name;
1ab256cb
RM
543 register struct buffer *b;
544
cd265ca6
MR
545 buffer = Fget_buffer (buffer_or_name);
546 if (!NILP (buffer))
547 return buffer;
1ab256cb 548
cd265ca6 549 if (SCHARS (buffer_or_name) == 0)
31cd83e9
KH
550 error ("Empty string for buffer name is not allowed");
551
cc648cef 552 b = allocate_buffer ();
1ab256cb 553
336cd056
RS
554 /* An ordinary buffer uses its own struct buffer_text. */
555 b->text = &b->own_text;
9928463d
DA
556 b->base_buffer = NULL;
557 /* No one shares the text with us now. */
558 b->indirections = 0;
336cd056 559
1ab256cb 560 BUF_GAP_SIZE (b) = 20;
9ac0d9e0 561 BLOCK_INPUT;
3b06f880
KH
562 /* We allocate extra 1-byte at the tail and keep it always '\0' for
563 anchoring a search. */
b86af064 564 alloc_buffer_text (b, BUF_GAP_SIZE (b) + 1);
9ac0d9e0 565 UNBLOCK_INPUT;
1ab256cb 566 if (! BUF_BEG_ADDR (b))
531b0165 567 buffer_memory_full (BUF_GAP_SIZE (b) + 1);
1ab256cb 568
cffc6f3b
CY
569 b->pt = BEG;
570 b->begv = BEG;
571 b->zv = BEG;
572 b->pt_byte = BEG_BYTE;
573 b->begv_byte = BEG_BYTE;
574 b->zv_byte = BEG_BYTE;
575
6d70a280 576 BUF_GPT (b) = BEG;
6d70a280 577 BUF_GPT_BYTE (b) = BEG_BYTE;
cffc6f3b
CY
578
579 BUF_Z (b) = BEG;
6d70a280 580 BUF_Z_BYTE (b) = BEG_BYTE;
1ab256cb 581 BUF_MODIFF (b) = 1;
3e145152 582 BUF_CHARS_MODIFF (b) = 1;
2509d356 583 BUF_OVERLAY_MODIFF (b) = 1;
336cd056 584 BUF_SAVE_MODIFF (b) = 1;
0c94c8d6 585 set_buffer_intervals (b, NULL);
b5a225b4
GM
586 BUF_UNCHANGED_MODIFIED (b) = 1;
587 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1;
588 BUF_END_UNCHANGED (b) = 0;
589 BUF_BEG_UNCHANGED (b) = 0;
3b06f880 590 *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */
2941c447 591 b->text->inhibit_shrinking = 0;
1ab256cb 592
28e969dd
JB
593 b->newline_cache = 0;
594 b->width_run_cache = 0;
39eb03f1 595 bset_width_table (b, Qnil);
b5a225b4 596 b->prevent_redisplay_optimizations_p = 1;
28e969dd 597
1ab256cb 598 /* Put this on the chain of all buffers including killed ones. */
eab3844f 599 b->header.next.buffer = all_buffers;
1ab256cb
RM
600 all_buffers = b;
601
336cd056
RS
602 /* An ordinary buffer normally doesn't need markers
603 to handle BEGV and ZV. */
39eb03f1
PE
604 bset_pt_marker (b, Qnil);
605 bset_begv_marker (b, Qnil);
606 bset_zv_marker (b, Qnil);
04ae1b48 607
cd265ca6 608 name = Fcopy_sequence (buffer_or_name);
0c94c8d6 609 set_string_intervals (name, NULL);
39eb03f1 610 bset_name (b, name);
04ae1b48 611
39eb03f1 612 bset_undo_list (b, SREF (name, 0) != ' ' ? Qnil : Qt);
1ab256cb
RM
613
614 reset_buffer (b);
13de9290 615 reset_buffer_local_variables (b, 1);
1ab256cb 616
39eb03f1 617 bset_mark (b, Fmake_marker ());
65745fad 618 BUF_MARKERS (b) = NULL;
1f57cb74 619
1ab256cb 620 /* Put this in the alist of all live buffers. */
cd265ca6
MR
621 XSETBUFFER (buffer, b);
622 Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buffer), Qnil));
9397e56f
MR
623 /* And run buffer-list-update-hook. */
624 if (!NILP (Vrun_hooks))
625 call1 (Vrun_hooks, Qbuffer_list_update_hook);
1ab256cb 626
cd265ca6 627 return buffer;
336cd056
RS
628}
629
7e9d5818 630
04e4cb3a
GM
631/* Return a list of overlays which is a copy of the overlay list
632 LIST, but for buffer B. */
633
2410d73a 634static struct Lisp_Overlay *
d3da34e0 635copy_overlays (struct buffer *b, struct Lisp_Overlay *list)
04e4cb3a 636{
2410d73a 637 struct Lisp_Overlay *result = NULL, *tail = NULL;
04e4cb3a 638
2410d73a 639 for (; list; list = list->next)
04e4cb3a 640 {
fa691a83
DA
641 Lisp_Object overlay, start, end;
642 struct Lisp_Marker *m;
04e4cb3a 643
c644523b
DA
644 eassert (MARKERP (list->start));
645 m = XMARKER (list->start);
fa691a83
DA
646 start = build_marker (b, m->charpos, m->bytepos);
647 XMARKER (start)->insertion_type = m->insertion_type;
04e4cb3a 648
c644523b
DA
649 eassert (MARKERP (list->end));
650 m = XMARKER (list->end);
fa691a83
DA
651 end = build_marker (b, m->charpos, m->bytepos);
652 XMARKER (end)->insertion_type = m->insertion_type;
177c0ea7 653
c644523b 654 overlay = build_overlay (start, end, Fcopy_sequence (list->plist));
2410d73a
SM
655 if (tail)
656 tail = tail->next = XOVERLAY (overlay);
657 else
658 result = tail = XOVERLAY (overlay);
04e4cb3a
GM
659 }
660
2410d73a 661 return result;
04e4cb3a 662}
177c0ea7 663
0c94c8d6
PE
664/* Set an appropriate overlay of B. */
665
666static inline void
667set_buffer_overlays_before (struct buffer *b, struct Lisp_Overlay *o)
668{
669 b->overlays_before = o;
670}
671
672static inline void
673set_buffer_overlays_after (struct buffer *b, struct Lisp_Overlay *o)
674{
675 b->overlays_after = o;
676}
04e4cb3a 677
7e9d5818
GM
678/* Clone per-buffer values of buffer FROM.
679
680 Buffer TO gets the same per-buffer values as FROM, with the
681 following exceptions: (1) TO's name is left untouched, (2) markers
682 are copied and made to refer to TO, and (3) overlay lists are
683 copied. */
684
685static void
d3da34e0 686clone_per_buffer_values (struct buffer *from, struct buffer *to)
7e9d5818 687{
7e9d5818
GM
688 int offset;
689
52b852c7 690 FOR_EACH_PER_BUFFER_OBJECT_AT (offset)
7e9d5818
GM
691 {
692 Lisp_Object obj;
693
4b7cdc0e
SM
694 /* Don't touch the `name' which should be unique for every buffer. */
695 if (offset == PER_BUFFER_VAR_OFFSET (name))
696 continue;
697
7e9d5818 698 obj = PER_BUFFER_VALUE (from, offset);
ce5b453a 699 if (MARKERP (obj) && XMARKER (obj)->buffer == from)
7e9d5818
GM
700 {
701 struct Lisp_Marker *m = XMARKER (obj);
657924ff
DA
702
703 obj = build_marker (to, m->charpos, m->bytepos);
7e9d5818 704 XMARKER (obj)->insertion_type = m->insertion_type;
7e9d5818
GM
705 }
706
707 PER_BUFFER_VALUE (to, offset) = obj;
708 }
709
72af86bd 710 memcpy (to->local_flags, from->local_flags, sizeof to->local_flags);
177c0ea7 711
0c94c8d6
PE
712 set_buffer_overlays_before (to, copy_overlays (to, from->overlays_before));
713 set_buffer_overlays_after (to, copy_overlays (to, from->overlays_after));
02f28bbd 714
e1688f54
RS
715 /* Get (a copy of) the alist of Lisp-level local variables of FROM
716 and install that in TO. */
39eb03f1 717 bset_local_var_alist (to, buffer_lisp_local_variables (from, 1));
7e9d5818
GM
718}
719
cffc6f3b
CY
720
721/* If buffer B has markers to record PT, BEGV and ZV when it is not
722 current, update these markers. */
723
724static void
725record_buffer_markers (struct buffer *b)
726{
727 if (! NILP (BVAR (b, pt_marker)))
728 {
729 Lisp_Object buffer;
730
731 eassert (!NILP (BVAR (b, begv_marker)));
732 eassert (!NILP (BVAR (b, zv_marker)));
733
734 XSETBUFFER (buffer, b);
735 set_marker_both (BVAR (b, pt_marker), buffer, b->pt, b->pt_byte);
736 set_marker_both (BVAR (b, begv_marker), buffer, b->begv, b->begv_byte);
737 set_marker_both (BVAR (b, zv_marker), buffer, b->zv, b->zv_byte);
738 }
739}
740
741
742/* If buffer B has markers to record PT, BEGV and ZV when it is not
743 current, fetch these values into B->begv etc. */
744
745static void
746fetch_buffer_markers (struct buffer *b)
747{
748 if (! NILP (BVAR (b, pt_marker)))
749 {
750 Lisp_Object m;
751
752 eassert (!NILP (BVAR (b, begv_marker)));
753 eassert (!NILP (BVAR (b, zv_marker)));
754
755 m = BVAR (b, pt_marker);
756 SET_BUF_PT_BOTH (b, marker_position (m), marker_byte_position (m));
757
758 m = BVAR (b, begv_marker);
759 SET_BUF_BEGV_BOTH (b, marker_position (m), marker_byte_position (m));
760
761 m = BVAR (b, zv_marker);
762 SET_BUF_ZV_BOTH (b, marker_position (m), marker_byte_position (m));
763 }
764}
765
766
7e9d5818
GM
767DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, Smake_indirect_buffer,
768 2, 3,
193c3837 769 "bMake indirect buffer (to buffer): \nBName of indirect buffer: ",
7ee72033 770 doc: /* Create and return an indirect buffer for buffer BASE-BUFFER, named NAME.
6b61353c 771BASE-BUFFER should be a live buffer, or the name of an existing buffer.
018ba359
PJ
772NAME should be a string which is not the name of an existing buffer.
773Optional argument CLONE non-nil means preserve BASE-BUFFER's state,
774such as major and minor modes, in the indirect buffer.
7ee72033 775CLONE nil means the indirect buffer's state is reset to default values. */)
5842a27b 776 (Lisp_Object base_buffer, Lisp_Object name, Lisp_Object clone)
336cd056 777{
6b61353c 778 Lisp_Object buf, tem;
7e9d5818 779 struct buffer *b;
336cd056 780
6b61353c 781 CHECK_STRING (name);
336cd056
RS
782 buf = Fget_buffer (name);
783 if (!NILP (buf))
d5db4077 784 error ("Buffer name `%s' is in use", SDATA (name));
336cd056 785
6b61353c 786 tem = base_buffer;
336cd056
RS
787 base_buffer = Fget_buffer (base_buffer);
788 if (NILP (base_buffer))
6b61353c 789 error ("No such buffer: `%s'", SDATA (tem));
4b4deea2 790 if (NILP (BVAR (XBUFFER (base_buffer), name)))
6b61353c 791 error ("Base buffer has been killed");
336cd056 792
d5db4077 793 if (SCHARS (name) == 0)
336cd056
RS
794 error ("Empty string for buffer name is not allowed");
795
cc648cef 796 b = allocate_buffer ();
336cd056 797
9928463d
DA
798 /* No double indirection - if base buffer is indirect,
799 new buffer becomes an indirect to base's base. */
67ee9f6e
SM
800 b->base_buffer = (XBUFFER (base_buffer)->base_buffer
801 ? XBUFFER (base_buffer)->base_buffer
802 : XBUFFER (base_buffer));
336cd056
RS
803
804 /* Use the base buffer's text object. */
805 b->text = b->base_buffer->text;
9928463d
DA
806 /* We have no own text. */
807 b->indirections = -1;
808 /* Notify base buffer that we share the text now. */
809 b->base_buffer->indirections++;
336cd056 810
cffc6f3b
CY
811 b->pt = b->base_buffer->pt;
812 b->begv = b->base_buffer->begv;
813 b->zv = b->base_buffer->zv;
814 b->pt_byte = b->base_buffer->pt_byte;
815 b->begv_byte = b->base_buffer->begv_byte;
816 b->zv_byte = b->base_buffer->zv_byte;
336cd056
RS
817
818 b->newline_cache = 0;
819 b->width_run_cache = 0;
39eb03f1 820 bset_width_table (b, Qnil);
336cd056
RS
821
822 /* Put this on the chain of all buffers including killed ones. */
eab3844f 823 b->header.next.buffer = all_buffers;
336cd056
RS
824 all_buffers = b;
825
826 name = Fcopy_sequence (name);
0c94c8d6 827 set_string_intervals (name, NULL);
39eb03f1 828 bset_name (b, name);
336cd056
RS
829
830 reset_buffer (b);
13de9290 831 reset_buffer_local_variables (b, 1);
336cd056
RS
832
833 /* Put this in the alist of all live buffers. */
834 XSETBUFFER (buf, b);
835 Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil));
836
39eb03f1 837 bset_mark (b, Fmake_marker ());
336cd056 838
abc9d959 839 /* The multibyte status belongs to the base buffer. */
39eb03f1
PE
840 bset_enable_multibyte_characters
841 (b, BVAR (b->base_buffer, enable_multibyte_characters));
abc9d959 842
336cd056 843 /* Make sure the base buffer has markers for its narrowing. */
4b4deea2 844 if (NILP (BVAR (b->base_buffer, pt_marker)))
336cd056 845 {
2aa46d6c
CY
846 eassert (NILP (BVAR (b->base_buffer, begv_marker)));
847 eassert (NILP (BVAR (b->base_buffer, zv_marker)));
cffc6f3b 848
39eb03f1
PE
849 bset_pt_marker (b->base_buffer,
850 build_marker (b->base_buffer, b->base_buffer->pt,
851 b->base_buffer->pt_byte));
657924ff 852
39eb03f1
PE
853 bset_begv_marker (b->base_buffer,
854 build_marker (b->base_buffer, b->base_buffer->begv,
855 b->base_buffer->begv_byte));
cffc6f3b 856
39eb03f1
PE
857 bset_zv_marker (b->base_buffer,
858 build_marker (b->base_buffer, b->base_buffer->zv,
859 b->base_buffer->zv_byte));
cffc6f3b 860
4b4deea2 861 XMARKER (BVAR (b->base_buffer, zv_marker))->insertion_type = 1;
336cd056
RS
862 }
863
7e9d5818
GM
864 if (NILP (clone))
865 {
866 /* Give the indirect buffer markers for its narrowing. */
39eb03f1
PE
867 bset_pt_marker (b, build_marker (b, b->pt, b->pt_byte));
868 bset_begv_marker (b, build_marker (b, b->begv, b->begv_byte));
869 bset_zv_marker (b, build_marker (b, b->zv, b->zv_byte));
4b4deea2 870 XMARKER (BVAR (b, zv_marker))->insertion_type = 1;
7e9d5818
GM
871 }
872 else
7fa57e45
RS
873 {
874 struct buffer *old_b = current_buffer;
875
876 clone_per_buffer_values (b->base_buffer, b);
39eb03f1
PE
877 bset_filename (b, Qnil);
878 bset_file_truename (b, Qnil);
879 bset_display_count (b, make_number (0));
880 bset_backed_up (b, Qnil);
881 bset_auto_save_file_name (b, Qnil);
7fa57e45
RS
882 set_buffer_internal_1 (b);
883 Fset (intern ("buffer-save-without-query"), Qnil);
884 Fset (intern ("buffer-file-number"), Qnil);
885 Fset (intern ("buffer-stale-function"), Qnil);
886 set_buffer_internal_1 (old_b);
887 }
336cd056 888
9397e56f
MR
889 /* Run buffer-list-update-hook. */
890 if (!NILP (Vrun_hooks))
891 call1 (Vrun_hooks, Qbuffer_list_update_hook);
892
a9ee7a59 893 return buf;
1ab256cb
RM
894}
895
041a49a6
DA
896/* Mark OV as no longer associated with B. */
897
898static void
899drop_overlay (struct buffer *b, struct Lisp_Overlay *ov)
900{
c644523b
DA
901 eassert (b == XBUFFER (Fmarker_buffer (ov->start)));
902 modify_overlay (b, marker_position (ov->start),
903 marker_position (ov->end));
904 Fset_marker (ov->start, Qnil, Qnil);
905 Fset_marker (ov->end, Qnil, Qnil);
041a49a6
DA
906
907}
908
909/* Delete all overlays of B and reset it's overlay lists. */
910
d4f5719a 911void
d3da34e0 912delete_all_overlays (struct buffer *b)
d4f5719a 913{
041a49a6 914 struct Lisp_Overlay *ov, *next;
d4f5719a 915
fd318b54 916 for (ov = b->overlays_before; ov; ov = next)
d4f5719a 917 {
041a49a6
DA
918 drop_overlay (b, ov);
919 next = ov->next;
920 ov->next = NULL;
d4f5719a 921 }
041a49a6 922
fd318b54 923 for (ov = b->overlays_after; ov; ov = next)
d4f5719a 924 {
041a49a6
DA
925 drop_overlay (b, ov);
926 next = ov->next;
927 ov->next = NULL;
d4f5719a 928 }
041a49a6 929
0c94c8d6
PE
930 set_buffer_overlays_before (b, NULL);
931 set_buffer_overlays_after (b, NULL);
d4f5719a
SM
932}
933
bcd40520 934/* Reinitialize everything about a buffer except its name and contents
6b61353c 935 and local variables.
d4f5719a
SM
936 If called on an already-initialized buffer, the list of overlays
937 should be deleted before calling this function, otherwise we end up
938 with overlays that claim to belong to the buffer but the buffer
939 claims it doesn't belong to it. */
1ab256cb
RM
940
941void
d3da34e0 942reset_buffer (register struct buffer *b)
1ab256cb 943{
39eb03f1
PE
944 bset_filename (b, Qnil);
945 bset_file_truename (b, Qnil);
946 bset_directory (b, current_buffer ? BVAR (current_buffer, directory) : Qnil);
e9a9ae03 947 b->modtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS);
58b963f7 948 b->modtime_size = -1;
4b4deea2 949 XSETFASTINT (BVAR (b, save_length), 0);
1ab256cb 950 b->last_window_start = 1;
8b264726 951 /* It is more conservative to start out "changed" than "unchanged". */
b5a225b4
GM
952 b->clip_changed = 0;
953 b->prevent_redisplay_optimizations_p = 1;
39eb03f1 954 bset_backed_up (b, Qnil);
0b5397c2 955 BUF_AUTOSAVE_MODIFF (b) = 0;
d311d28c 956 b->auto_save_failure_time = 0;
39eb03f1
PE
957 bset_auto_save_file_name (b, Qnil);
958 bset_read_only (b, Qnil);
0c94c8d6
PE
959 set_buffer_overlays_before (b, NULL);
960 set_buffer_overlays_after (b, NULL);
c2d5b10f 961 b->overlay_center = BEG;
39eb03f1
PE
962 bset_mark_active (b, Qnil);
963 bset_point_before_scroll (b, Qnil);
964 bset_file_format (b, Qnil);
965 bset_auto_save_file_format (b, Qt);
966 bset_last_selected_window (b, Qnil);
967 bset_display_count (b, make_number (0));
968 bset_display_time (b, Qnil);
969 bset_enable_multibyte_characters
970 (b, BVAR (&buffer_defaults, enable_multibyte_characters));
971 bset_cursor_type (b, BVAR (&buffer_defaults, cursor_type));
972 bset_extra_line_spacing (b, BVAR (&buffer_defaults, extra_line_spacing));
0522997d
RS
973
974 b->display_error_modiff = 0;
1ab256cb
RM
975}
976
bcd40520
RS
977/* Reset buffer B's local variables info.
978 Don't use this on a buffer that has already been in use;
979 it does not treat permanent locals consistently.
13de9290
RS
980 Instead, use Fkill_all_local_variables.
981
3709505e 982 If PERMANENT_TOO is 1, then we reset permanent
13de9290
RS
983 buffer-local variables. If PERMANENT_TOO is 0,
984 we preserve those. */
bcd40520 985
13de9290 986static void
d3da34e0 987reset_buffer_local_variables (register struct buffer *b, int permanent_too)
1ab256cb
RM
988{
989 register int offset;
7c02e886 990 int i;
1ab256cb
RM
991
992 /* Reset the major mode to Fundamental, together with all the
993 things that depend on the major mode.
994 default-major-mode is handled at a higher level.
995 We ignore it here. */
39eb03f1
PE
996 bset_major_mode (b, Qfundamental_mode);
997 bset_keymap (b, Qnil);
998 bset_mode_name (b, QSFundamental);
999 bset_minor_modes (b, Qnil);
3446af9c
RS
1000
1001 /* If the standard case table has been altered and invalidated,
1002 fix up its insides first. */
1003 if (! (CHAR_TABLE_P (XCHAR_TABLE (Vascii_downcase_table)->extras[0])
1004 && CHAR_TABLE_P (XCHAR_TABLE (Vascii_downcase_table)->extras[1])
1005 && CHAR_TABLE_P (XCHAR_TABLE (Vascii_downcase_table)->extras[2])))
1006 Fset_standard_case_table (Vascii_downcase_table);
1007
39eb03f1
PE
1008 bset_downcase_table (b, Vascii_downcase_table);
1009 bset_upcase_table (b, XCHAR_TABLE (Vascii_downcase_table)->extras[0]);
1010 bset_case_canon_table (b, XCHAR_TABLE (Vascii_downcase_table)->extras[1]);
1011 bset_case_eqv_table (b, XCHAR_TABLE (Vascii_downcase_table)->extras[2]);
1012 bset_invisibility_spec (b, Qt);
3cb719bd 1013
13de9290 1014 /* Reset all (or most) per-buffer variables to their defaults. */
3709505e 1015 if (permanent_too)
39eb03f1 1016 bset_local_var_alist (b, Qnil);
3709505e
SM
1017 else
1018 {
2f7a359d 1019 Lisp_Object tmp, prop, last = Qnil;
4b4deea2 1020 for (tmp = BVAR (b, local_var_alist); CONSP (tmp); tmp = XCDR (tmp))
ce5b453a 1021 if (!NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local)))
2f7a359d
RS
1022 {
1023 /* If permanent-local, keep it. */
1024 last = tmp;
1025 if (EQ (prop, Qpermanent_local_hook))
1026 {
1027 /* This is a partially permanent hook variable.
1028 Preserve only the elements that want to be preserved. */
1029 Lisp_Object list, newlist;
1030 list = XCDR (XCAR (tmp));
1031 if (!CONSP (list))
1032 newlist = list;
1033 else
1034 for (newlist = Qnil; CONSP (list); list = XCDR (list))
1035 {
1036 Lisp_Object elt = XCAR (list);
1037 /* Preserve element ELT if it's t,
1038 if it is a function with a `permanent-local-hook' property,
1039 or if it's not a symbol. */
1040 if (! SYMBOLP (elt)
1041 || EQ (elt, Qt)
1042 || !NILP (Fget (elt, Qpermanent_local_hook)))
1043 newlist = Fcons (elt, newlist);
1044 }
1045 XSETCDR (XCAR (tmp), Fnreverse (newlist));
1046 }
1047 }
1048 /* Delete this local variable. */
3709505e 1049 else if (NILP (last))
39eb03f1 1050 bset_local_var_alist (b, XCDR (tmp));
3709505e
SM
1051 else
1052 XSETCDR (last, XCDR (tmp));
1053 }
1054
7313acd0 1055 for (i = 0; i < last_per_buffer_idx; ++i)
7c02e886 1056 if (permanent_too || buffer_permanent_local_flags[i] == 0)
7313acd0 1057 SET_PER_BUFFER_VALUE_P (b, i, 0);
1ab256cb 1058
36429c89 1059 /* For each slot that has a default value, copy that into the slot. */
52b852c7 1060 FOR_EACH_PER_BUFFER_OBJECT_AT (offset)
aab80822 1061 {
7313acd0 1062 int idx = PER_BUFFER_IDX (offset);
7c02e886
GM
1063 if ((idx > 0
1064 && (permanent_too
ce5b453a 1065 || buffer_permanent_local_flags[idx] == 0)))
7313acd0 1066 PER_BUFFER_VALUE (b, offset) = PER_BUFFER_DEFAULT (offset);
aab80822 1067 }
1ab256cb
RM
1068}
1069
01050cb5
RM
1070/* We split this away from generate-new-buffer, because rename-buffer
1071 and set-visited-file-name ought to be able to use this to really
1072 rename the buffer properly. */
1073
a7ca3326 1074DEFUN ("generate-new-buffer-name", Fgenerate_new_buffer_name,
16a97296 1075 Sgenerate_new_buffer_name, 1, 2, 0,
7ee72033 1076 doc: /* Return a string that is the name of no existing buffer based on NAME.
018ba359
PJ
1077If there is no live buffer named NAME, then return NAME.
1078Otherwise modify name by appending `<NUMBER>', incrementing NUMBER
6b61353c 1079\(starting at 2) until an unused name is found, and then return that name.
2f064abf 1080Optional second argument IGNORE specifies a name that is okay to use (if
8e4fd1e1
GM
1081it is in the sequence to be tried) even if a buffer with that name exists.
1082
1083If NAME begins with a space (i.e., a buffer that is not normally
1084visible to users), then if buffer NAME already exists a random number
1085is first appended to NAME, to speed up finding a non-existent buffer. */)
5842a27b 1086 (register Lisp_Object name, Lisp_Object ignore)
1ab256cb 1087{
8e4fd1e1 1088 register Lisp_Object gentemp, tem, tem2;
d311d28c
PE
1089 ptrdiff_t count;
1090 char number[INT_BUFSIZE_BOUND (ptrdiff_t) + sizeof "<>"];
1ab256cb 1091
b7826503 1092 CHECK_STRING (name);
1ab256cb 1093
6b61353c
KH
1094 tem = Fstring_equal (name, ignore);
1095 if (!NILP (tem))
1096 return name;
1ab256cb 1097 tem = Fget_buffer (name);
265a9e55 1098 if (NILP (tem))
01050cb5 1099 return name;
1ab256cb 1100
8e4fd1e1
GM
1101 if (!strncmp (SSDATA (name), " ", 1)) /* see bug#1229 */
1102 {
1103 /* Note fileio.c:make_temp_name does random differently. */
a8290ec3 1104 tem2 = concat2 (name, make_formatted_string
52b852c7 1105 (number, "-%"pI"d",
a8290ec3 1106 XFASTINT (Frandom (make_number (999999)))));
8e4fd1e1
GM
1107 tem = Fget_buffer (tem2);
1108 if (NILP (tem))
1109 return tem2;
1110 }
1111 else
1112 tem2 = name;
1113
1ab256cb
RM
1114 count = 1;
1115 while (1)
1116 {
a8290ec3
DA
1117 gentemp = concat2 (tem2, make_formatted_string
1118 (number, "<%"pD"d>", ++count));
638e4fc3 1119 tem = Fstring_equal (gentemp, ignore);
c273e647
RS
1120 if (!NILP (tem))
1121 return gentemp;
1ab256cb 1122 tem = Fget_buffer (gentemp);
265a9e55 1123 if (NILP (tem))
01050cb5 1124 return gentemp;
1ab256cb
RM
1125 }
1126}
1127
1128\f
a7ca3326 1129DEFUN ("buffer-name", Fbuffer_name, Sbuffer_name, 0, 1, 0,
7ee72033 1130 doc: /* Return the name of BUFFER, as a string.
35f5c1d2
JB
1131BUFFER defaults to the current buffer.
1132Return nil if BUFFER has been killed. */)
5842a27b 1133 (register Lisp_Object buffer)
1ab256cb 1134{
265a9e55 1135 if (NILP (buffer))
4b4deea2 1136 return BVAR (current_buffer, name);
b7826503 1137 CHECK_BUFFER (buffer);
4b4deea2 1138 return BVAR (XBUFFER (buffer), name);
1ab256cb
RM
1139}
1140
a7ca3326 1141DEFUN ("buffer-file-name", Fbuffer_file_name, Sbuffer_file_name, 0, 1, 0,
7ee72033
MB
1142 doc: /* Return name of file BUFFER is visiting, or nil if none.
1143No argument or nil as argument means use the current buffer. */)
5842a27b 1144 (register Lisp_Object buffer)
1ab256cb 1145{
265a9e55 1146 if (NILP (buffer))
4b4deea2 1147 return BVAR (current_buffer, filename);
b7826503 1148 CHECK_BUFFER (buffer);
4b4deea2 1149 return BVAR (XBUFFER (buffer), filename);
1ab256cb
RM
1150}
1151
336cd056
RS
1152DEFUN ("buffer-base-buffer", Fbuffer_base_buffer, Sbuffer_base_buffer,
1153 0, 1, 0,
7ee72033 1154 doc: /* Return the base buffer of indirect buffer BUFFER.
5a72efd4
LT
1155If BUFFER is not indirect, return nil.
1156BUFFER defaults to the current buffer. */)
5842a27b 1157 (register Lisp_Object buffer)
336cd056
RS
1158{
1159 struct buffer *base;
1160 Lisp_Object base_buffer;
1161
1162 if (NILP (buffer))
1163 base = current_buffer->base_buffer;
1164 else
1165 {
b7826503 1166 CHECK_BUFFER (buffer);
336cd056
RS
1167 base = XBUFFER (buffer)->base_buffer;
1168 }
1169
1170 if (! base)
1171 return Qnil;
1172 XSETBUFFER (base_buffer, base);
1173 return base_buffer;
1174}
1175
a7ca3326 1176DEFUN ("buffer-local-value", Fbuffer_local_value,
177c0ea7 1177 Sbuffer_local_value, 2, 2, 0,
79aa712d
RS
1178 doc: /* Return the value of VARIABLE in BUFFER.
1179If VARIABLE does not have a buffer-local binding in BUFFER, the value
5e2ad10b 1180is the default binding of the variable. */)
5842a27b 1181 (register Lisp_Object variable, register Lisp_Object buffer)
5f2c76c6
CY
1182{
1183 register Lisp_Object result = buffer_local_value_1 (variable, buffer);
1184
1185 if (EQ (result, Qunbound))
1186 xsignal1 (Qvoid_variable, variable);
1187
1188 return result;
1189}
1190
1191
1192/* Like Fbuffer_local_value, but return Qunbound if the variable is
1193 locally unbound. */
1194
1195Lisp_Object
1196buffer_local_value_1 (Lisp_Object variable, Lisp_Object buffer)
79aa712d
RS
1197{
1198 register struct buffer *buf;
1199 register Lisp_Object result;
ad97b375 1200 struct Lisp_Symbol *sym;
79aa712d 1201
5e2ad10b 1202 CHECK_SYMBOL (variable);
ae69175b 1203 CHECK_BUFFER (buffer);
79aa712d 1204 buf = XBUFFER (buffer);
ce5b453a 1205 sym = XSYMBOL (variable);
79aa712d 1206
ce5b453a
SM
1207 start:
1208 switch (sym->redirect)
f0bac7de 1209 {
ce5b453a
SM
1210 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1211 case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break;
1212 case SYMBOL_LOCALIZED:
1213 { /* Look in local_var_alist. */
1214 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1215 XSETSYMBOL (variable, sym); /* Update In case of aliasing. */
4b4deea2 1216 result = Fassoc (variable, BVAR (buf, local_var_alist));
ce5b453a
SM
1217 if (!NILP (result))
1218 {
1219 if (blv->fwd)
1220 { /* What binding is loaded right now? */
1221 Lisp_Object current_alist_element = blv->valcell;
f0bac7de 1222
ce5b453a
SM
1223 /* The value of the currently loaded binding is not
1224 stored in it, but rather in the realvalue slot.
1225 Store that value into the binding it belongs to
1226 in case that is the one we are about to use. */
f0bac7de 1227
ce5b453a
SM
1228 XSETCDR (current_alist_element,
1229 do_symval_forwarding (blv->fwd));
1230 }
1231 /* Now get the (perhaps updated) value out of the binding. */
1232 result = XCDR (result);
1233 }
1234 else
1235 result = Fdefault_value (variable);
1236 break;
1237 }
1238 case SYMBOL_FORWARDED:
1239 {
1240 union Lisp_Fwd *fwd = SYMBOL_FWD (sym);
1241 if (BUFFER_OBJFWDP (fwd))
1242 result = PER_BUFFER_VALUE (buf, XBUFFER_OBJFWD (fwd)->offset);
1243 else
1244 result = Fdefault_value (variable);
1245 break;
1246 }
1247 default: abort ();
f0bac7de 1248 }
79aa712d 1249
5f2c76c6 1250 return result;
79aa712d
RS
1251}
1252
e1688f54 1253/* Return an alist of the Lisp-level buffer-local bindings of
7fa57e45 1254 buffer BUF. That is, don't include the variables maintained
8a05d57a
AS
1255 in special slots in the buffer object.
1256 If CLONE is zero elements of the form (VAR . unbound) are replaced
1257 by VAR. */
e1688f54
RS
1258
1259static Lisp_Object
8a05d57a 1260buffer_lisp_local_variables (struct buffer *buf, int clone)
e1688f54
RS
1261{
1262 Lisp_Object result = Qnil;
1263 register Lisp_Object tail;
4b4deea2 1264 for (tail = BVAR (buf, local_var_alist); CONSP (tail); tail = XCDR (tail))
e1688f54
RS
1265 {
1266 Lisp_Object val, elt;
1267
1268 elt = XCAR (tail);
1269
1270 /* Reference each variable in the alist in buf.
1271 If inquiring about the current buffer, this gets the current values,
1272 so store them into the alist so the alist is up to date.
1273 If inquiring about some other buffer, this swaps out any values
1274 for that buffer, making the alist up to date automatically. */
1275 val = find_symbol_value (XCAR (elt));
1276 /* Use the current buffer value only if buf is the current buffer. */
1277 if (buf != current_buffer)
1278 val = XCDR (elt);
1279
8a05d57a 1280 result = Fcons (!clone && EQ (val, Qunbound)
0992bd9c
CY
1281 ? XCAR (elt)
1282 : Fcons (XCAR (elt), val),
1283 result);
e1688f54
RS
1284 }
1285
1286 return result;
1287}
1288
1ab256cb 1289DEFUN ("buffer-local-variables", Fbuffer_local_variables,
efc7e75f 1290 Sbuffer_local_variables, 0, 1, 0,
7ee72033 1291 doc: /* Return an alist of variables that are buffer-local in BUFFER.
018ba359
PJ
1292Most elements look like (SYMBOL . VALUE), describing one variable.
1293For a symbol that is locally unbound, just the symbol appears in the value.
1294Note that storing new VALUEs in these elements doesn't change the variables.
7ee72033 1295No argument or nil as argument means use current buffer as BUFFER. */)
5842a27b 1296 (register Lisp_Object buffer)
1ab256cb
RM
1297{
1298 register struct buffer *buf;
553defa4 1299 register Lisp_Object result;
1ab256cb 1300
265a9e55 1301 if (NILP (buffer))
1ab256cb
RM
1302 buf = current_buffer;
1303 else
1304 {
b7826503 1305 CHECK_BUFFER (buffer);
1ab256cb
RM
1306 buf = XBUFFER (buffer);
1307 }
1308
8a05d57a 1309 result = buffer_lisp_local_variables (buf, 0);
1ab256cb 1310
1ab256cb
RM
1311 /* Add on all the variables stored in special slots. */
1312 {
7c02e886 1313 int offset, idx;
1ab256cb 1314
52b852c7 1315 FOR_EACH_PER_BUFFER_OBJECT_AT (offset)
1ab256cb 1316 {
7313acd0
GM
1317 idx = PER_BUFFER_IDX (offset);
1318 if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
1319 && SYMBOLP (PER_BUFFER_SYMBOL (offset)))
0992bd9c
CY
1320 {
1321 Lisp_Object sym = PER_BUFFER_SYMBOL (offset);
1322 Lisp_Object val = PER_BUFFER_VALUE (buf, offset);
1323 result = Fcons (EQ (val, Qunbound) ? sym : Fcons (sym, val),
1324 result);
1325 }
1ab256cb
RM
1326 }
1327 }
553defa4
RS
1328
1329 return result;
1ab256cb 1330}
1ab256cb 1331\f
a7ca3326 1332DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p,
efc7e75f 1333 0, 1, 0,
7ee72033
MB
1334 doc: /* Return t if BUFFER was modified since its file was last read or saved.
1335No argument or nil as argument means use current buffer as BUFFER. */)
5842a27b 1336 (register Lisp_Object buffer)
1ab256cb
RM
1337{
1338 register struct buffer *buf;
265a9e55 1339 if (NILP (buffer))
1ab256cb
RM
1340 buf = current_buffer;
1341 else
1342 {
b7826503 1343 CHECK_BUFFER (buffer);
1ab256cb
RM
1344 buf = XBUFFER (buffer);
1345 }
1346
336cd056 1347 return BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf) ? Qt : Qnil;
1ab256cb
RM
1348}
1349
a7ca3326 1350DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p,
efc7e75f 1351 1, 1, 0,
7ee72033
MB
1352 doc: /* Mark current buffer as modified or unmodified according to FLAG.
1353A non-nil FLAG means mark the buffer modified. */)
5842a27b 1354 (register Lisp_Object flag)
1ab256cb
RM
1355{
1356 register int already;
1357 register Lisp_Object fn;
8ec01c70 1358 Lisp_Object buffer, window;
1ab256cb
RM
1359
1360#ifdef CLASH_DETECTION
1361 /* If buffer becoming modified, lock the file.
1362 If buffer becoming unmodified, unlock the file. */
1363
4b4deea2 1364 fn = BVAR (current_buffer, file_truename);
90d456d2 1365 /* Test buffer-file-name so that binding it to nil is effective. */
4b4deea2 1366 if (!NILP (fn) && ! NILP (BVAR (current_buffer, filename)))
1ab256cb 1367 {
336cd056 1368 already = SAVE_MODIFF < MODIFF;
265a9e55 1369 if (!already && !NILP (flag))
1ab256cb 1370 lock_file (fn);
265a9e55 1371 else if (already && NILP (flag))
1ab256cb
RM
1372 unlock_file (fn);
1373 }
1374#endif /* CLASH_DETECTION */
1375
0b5397c2
SM
1376 /* Here we have a problem. SAVE_MODIFF is used here to encode
1377 buffer-modified-p (as SAVE_MODIFF<MODIFF) as well as
1378 recent-auto-save-p (as SAVE_MODIFF<auto_save_modified). So if we
1379 modify SAVE_MODIFF to affect one, we may affect the other
1380 as well.
1381 E.g. if FLAG is nil we need to set SAVE_MODIFF to MODIFF, but
1382 if SAVE_MODIFF<auto_save_modified that means we risk changing
1383 recent-auto-save-p from t to nil.
1384 Vice versa, if FLAG is non-nil and SAVE_MODIFF>=auto_save_modified
1385 we risk changing recent-auto-save-p from nil to t. */
1386 SAVE_MODIFF = (NILP (flag)
1387 /* FIXME: This unavoidably sets recent-auto-save-p to nil. */
1388 ? MODIFF
1389 /* Let's try to preserve recent-auto-save-p. */
1390 : SAVE_MODIFF < MODIFF ? SAVE_MODIFF
1391 /* If SAVE_MODIFF == auto_save_modified == MODIFF,
1392 we can either decrease SAVE_MODIFF and auto_save_modified
1393 or increase MODIFF. */
1394 : MODIFF++);
177c0ea7 1395
8ec01c70
GM
1396 /* Set update_mode_lines only if buffer is displayed in some window.
1397 Packages like jit-lock or lazy-lock preserve a buffer's modified
1398 state by recording/restoring the state around blocks of code.
1399 Setting update_mode_lines makes redisplay consider all windows
1400 (on all frames). Stealth fontification of buffers not displayed
1401 would incur additional redisplay costs if we'd set
1402 update_modes_lines unconditionally.
1403
1404 Ideally, I think there should be another mechanism for fontifying
1405 buffers without "modifying" buffers, or redisplay should be
1406 smarter about updating the `*' in mode lines. --gerd */
1407 XSETBUFFER (buffer, current_buffer);
1408 window = Fget_buffer_window (buffer, Qt);
1409 if (WINDOWP (window))
d57b83b3
GM
1410 {
1411 ++update_mode_lines;
1412 current_buffer->prevent_redisplay_optimizations_p = 1;
1413 }
177c0ea7 1414
1ab256cb
RM
1415 return flag;
1416}
1417
a8c21b48
GM
1418DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p,
1419 Srestore_buffer_modified_p, 1, 1, 0,
42f47086 1420 doc: /* Like `set-buffer-modified-p', with a difference concerning redisplay.
018ba359 1421It is not ensured that mode lines will be updated to show the modified
7ee72033 1422state of the current buffer. Use with care. */)
5842a27b 1423 (Lisp_Object flag)
a8c21b48
GM
1424{
1425#ifdef CLASH_DETECTION
1426 Lisp_Object fn;
177c0ea7 1427
a8c21b48
GM
1428 /* If buffer becoming modified, lock the file.
1429 If buffer becoming unmodified, unlock the file. */
1430
4b4deea2 1431 fn = BVAR (current_buffer, file_truename);
a8c21b48 1432 /* Test buffer-file-name so that binding it to nil is effective. */
4b4deea2 1433 if (!NILP (fn) && ! NILP (BVAR (current_buffer, filename)))
a8c21b48
GM
1434 {
1435 int already = SAVE_MODIFF < MODIFF;
1436 if (!already && !NILP (flag))
1437 lock_file (fn);
1438 else if (already && NILP (flag))
1439 unlock_file (fn);
1440 }
1441#endif /* CLASH_DETECTION */
177c0ea7 1442
a8c21b48
GM
1443 SAVE_MODIFF = NILP (flag) ? MODIFF : 0;
1444 return flag;
1445}
1446
1ab256cb 1447DEFUN ("buffer-modified-tick", Fbuffer_modified_tick, Sbuffer_modified_tick,
efc7e75f 1448 0, 1, 0,
7ee72033 1449 doc: /* Return BUFFER's tick counter, incremented for each change in text.
2f064abf
JB
1450Each buffer has a tick counter which is incremented each time the
1451text in that buffer is changed. It wraps around occasionally.
7ee72033 1452No argument or nil as argument means use current buffer as BUFFER. */)
5842a27b 1453 (register Lisp_Object buffer)
1ab256cb
RM
1454{
1455 register struct buffer *buf;
265a9e55 1456 if (NILP (buffer))
1ab256cb
RM
1457 buf = current_buffer;
1458 else
1459 {
b7826503 1460 CHECK_BUFFER (buffer);
1ab256cb
RM
1461 buf = XBUFFER (buffer);
1462 }
1463
1464 return make_number (BUF_MODIFF (buf));
1465}
3e145152
CY
1466
1467DEFUN ("buffer-chars-modified-tick", Fbuffer_chars_modified_tick,
1468 Sbuffer_chars_modified_tick, 0, 1, 0,
1469 doc: /* Return BUFFER's character-change tick counter.
1470Each buffer has a character-change tick counter, which is set to the
1471value of the buffer's tick counter \(see `buffer-modified-tick'), each
1472time text in that buffer is inserted or deleted. By comparing the
12bd42be 1473values returned by two individual calls of `buffer-chars-modified-tick',
3e145152
CY
1474you can tell whether a character change occurred in that buffer in
1475between these calls. No argument or nil as argument means use current
1476buffer as BUFFER. */)
5842a27b 1477 (register Lisp_Object buffer)
3e145152
CY
1478{
1479 register struct buffer *buf;
1480 if (NILP (buffer))
1481 buf = current_buffer;
1482 else
1483 {
1484 CHECK_BUFFER (buffer);
1485 buf = XBUFFER (buffer);
1486 }
1487
1488 return make_number (BUF_CHARS_MODIFF (buf));
1489}
1ab256cb 1490\f
01050cb5 1491DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2,
c7d97628
JL
1492 "(list (read-string \"Rename buffer (to new name): \" \
1493 nil 'buffer-name-history (buffer-name (current-buffer))) \
1494 current-prefix-arg)",
7ee72033 1495 doc: /* Change current buffer's name to NEWNAME (a string).
018ba359
PJ
1496If second arg UNIQUE is nil or omitted, it is an error if a
1497buffer named NEWNAME already exists.
1498If UNIQUE is non-nil, come up with a new name using
1499`generate-new-buffer-name'.
1500Interactively, you can set UNIQUE with a prefix argument.
1501We return the name we actually gave the buffer.
7ee72033 1502This does not change the name of the visited file (if any). */)
5842a27b 1503 (register Lisp_Object newname, Lisp_Object unique)
1ab256cb
RM
1504{
1505 register Lisp_Object tem, buf;
1506
b7826503 1507 CHECK_STRING (newname);
d59698c4 1508
d5db4077 1509 if (SCHARS (newname) == 0)
d59698c4
RS
1510 error ("Empty string is invalid as a buffer name");
1511
489c043a 1512 tem = Fget_buffer (newname);
265a9e55 1513 if (!NILP (tem))
01050cb5 1514 {
8801a864
KR
1515 /* Don't short-circuit if UNIQUE is t. That is a useful way to
1516 rename the buffer automatically so you can create another
1517 with the original name. It makes UNIQUE equivalent to
1518 (rename-buffer (generate-new-buffer-name NEWNAME)). */
1519 if (NILP (unique) && XBUFFER (tem) == current_buffer)
4b4deea2 1520 return BVAR (current_buffer, name);
3bd779aa 1521 if (!NILP (unique))
4b4deea2 1522 newname = Fgenerate_new_buffer_name (newname, BVAR (current_buffer, name));
01050cb5 1523 else
d5db4077 1524 error ("Buffer name `%s' is in use", SDATA (newname));
01050cb5 1525 }
1ab256cb 1526
39eb03f1 1527 bset_name (current_buffer, newname);
76f590d7
JB
1528
1529 /* Catch redisplay's attention. Unless we do this, the mode lines for
1530 any windows displaying current_buffer will stay unchanged. */
1531 update_mode_lines++;
1532
67180c6a 1533 XSETBUFFER (buf, current_buffer);
489c043a 1534 Fsetcar (Frassq (buf, Vbuffer_alist), newname);
4b4deea2
TT
1535 if (NILP (BVAR (current_buffer, filename))
1536 && !NILP (BVAR (current_buffer, auto_save_file_name)))
1ab256cb 1537 call0 (intern ("rename-auto-save-file"));
9397e56f
MR
1538
1539 /* Run buffer-list-update-hook. */
1540 if (!NILP (Vrun_hooks))
1541 call1 (Vrun_hooks, Qbuffer_list_update_hook);
1542
fb5eba9c 1543 /* Refetch since that last call may have done GC. */
4b4deea2 1544 return BVAR (current_buffer, name);
1ab256cb
RM
1545}
1546
a7ca3326 1547DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0,
7ee72033 1548 doc: /* Return most recently selected buffer other than BUFFER.
9397e56f
MR
1549Buffers not visible in windows are preferred to visible buffers, unless
1550optional second argument VISIBLE-OK is non-nil. Ignore the argument
1551BUFFER unless it denotes a live buffer. If the optional third argument
1552FRAME is non-nil, use that frame's buffer list instead of the selected
1553frame's buffer list.
1554
1555The buffer is found by scanning the selected or specified frame's buffer
1556list first, followed by the list of all buffers. If no other buffer
1557exists, return the buffer `*scratch*' (creating it if necessary). */)
5842a27b 1558 (register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
1ab256cb 1559{
9397e56f
MR
1560 Lisp_Object Fset_buffer_major_mode (Lisp_Object buffer);
1561 Lisp_Object tail, buf, pred;
1562 Lisp_Object notsogood = Qnil;
1ab256cb 1563
773fbdb9 1564 if (NILP (frame))
9ba9623d 1565 frame = selected_frame;
773fbdb9 1566
d234d13e
JL
1567 CHECK_FRAME (frame);
1568
773fbdb9 1569 pred = frame_buffer_predicate (frame);
9397e56f 1570 /* Consider buffers that have been seen in the frame first. */
e69b0960 1571 tail = XFRAME (frame)->buffer_list;
9397e56f 1572 for (; CONSP (tail); tail = XCDR (tail))
7962a441 1573 {
9397e56f
MR
1574 buf = XCAR (tail);
1575 if (BUFFERP (buf) && !EQ (buf, buffer)
1576 && !NILP (BVAR (XBUFFER (buf), name))
1577 && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
1578 /* If the frame has a buffer_predicate, disregard buffers that
1579 don't fit the predicate. */
1580 && (NILP (pred) || !NILP (call1 (pred, buf))))
1581 {
1582 if (!NILP (visible_ok)
1583 || NILP (Fget_buffer_window (buf, Qvisible)))
1584 return buf;
1585 else if (NILP (notsogood))
1586 notsogood = buf;
1587 }
7962a441 1588 }
7962a441 1589
9397e56f
MR
1590 /* Consider alist of all buffers next. */
1591 tail = Vbuffer_alist;
6d70a280 1592 for (; CONSP (tail); tail = XCDR (tail))
1ab256cb 1593 {
6d70a280 1594 buf = Fcdr (XCAR (tail));
9397e56f
MR
1595 if (BUFFERP (buf) && !EQ (buf, buffer)
1596 && !NILP (BVAR (XBUFFER (buf), name))
1597 && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
1598 /* If the frame has a buffer_predicate, disregard buffers that
1599 don't fit the predicate. */
1600 && (NILP (pred) || !NILP (call1 (pred, buf))))
1601 {
1602 if (!NILP (visible_ok)
1603 || NILP (Fget_buffer_window (buf, Qvisible)))
1604 return buf;
1605 else if (NILP (notsogood))
1606 notsogood = buf;
1607 }
1608 }
1609
1610 if (!NILP (notsogood))
1611 return notsogood;
1612 else
1613 {
1614 buf = Fget_buffer (build_string ("*scratch*"));
6b61353c 1615 if (NILP (buf))
04ae1b48 1616 {
9397e56f
MR
1617 buf = Fget_buffer_create (build_string ("*scratch*"));
1618 Fset_buffer_major_mode (buf);
04ae1b48 1619 }
9397e56f
MR
1620 return buf;
1621 }
1622}
04ae1b48 1623
9397e56f
MR
1624/* The following function is a safe variant of Fother_buffer: It doesn't
1625 pay attention to any frame-local buffer lists, doesn't care about
1626 visibility of buffers, and doesn't evaluate any frame predicates. */
1627
1628Lisp_Object
1629other_buffer_safely (Lisp_Object buffer)
1630{
1631 Lisp_Object Fset_buffer_major_mode (Lisp_Object buffer);
1632 Lisp_Object tail, buf;
1633
1634 tail = Vbuffer_alist;
1635 for (; CONSP (tail); tail = XCDR (tail))
1636 {
1637 buf = Fcdr (XCAR (tail));
1638 if (BUFFERP (buf) && !EQ (buf, buffer)
1639 && !NILP (BVAR (XBUFFER (buf), name))
1640 && (SREF (BVAR (XBUFFER (buf), name), 0) != ' '))
1ab256cb 1641 return buf;
1ab256cb 1642 }
9397e56f 1643
dba1a30a
GM
1644 buf = Fget_buffer (build_string ("*scratch*"));
1645 if (NILP (buf))
1646 {
1647 buf = Fget_buffer_create (build_string ("*scratch*"));
1648 Fset_buffer_major_mode (buf);
1649 }
9397e56f 1650
89132f25 1651 return buf;
1ab256cb
RM
1652}
1653\f
a7ca3326 1654DEFUN ("buffer-enable-undo", Fbuffer_enable_undo, Sbuffer_enable_undo,
1ab256cb 1655 0, 1, "",
7ee72033
MB
1656 doc: /* Start keeping undo information for buffer BUFFER.
1657No argument or nil as argument means do this for the current buffer. */)
5842a27b 1658 (register Lisp_Object buffer)
1ab256cb 1659{
ffd56f97 1660 Lisp_Object real_buffer;
1ab256cb 1661
ffd56f97 1662 if (NILP (buffer))
67180c6a 1663 XSETBUFFER (real_buffer, current_buffer);
1ab256cb
RM
1664 else
1665 {
ffd56f97
JB
1666 real_buffer = Fget_buffer (buffer);
1667 if (NILP (real_buffer))
1668 nsberror (buffer);
1ab256cb
RM
1669 }
1670
4b4deea2 1671 if (EQ (BVAR (XBUFFER (real_buffer), undo_list), Qt))
39eb03f1 1672 bset_undo_list (XBUFFER (real_buffer), Qnil);
1ab256cb
RM
1673
1674 return Qnil;
1675}
1676
9cd47b72
DA
1677/* Truncate undo list and shrink the gap of BUFFER. */
1678
1679int
1680compact_buffer (struct buffer *buffer)
1681{
9928463d
DA
1682 /* Verify indirection counters. */
1683 if (buffer->base_buffer)
1684 {
1685 eassert (buffer->indirections == -1);
1686 eassert (buffer->base_buffer->indirections > 0);
1687 }
1688 else
1689 eassert (buffer->indirections >= 0);
1690
9cd47b72
DA
1691 /* Skip dead buffers, indirect buffers and buffers
1692 which aren't changed since last compaction. */
e34f7f79 1693 if (!NILP (buffer->INTERNAL_FIELD (name))
9cd47b72
DA
1694 && (buffer->base_buffer == NULL)
1695 && (buffer->text->compact != buffer->text->modiff))
1696 {
1697 /* If a buffer's undo list is Qt, that means that undo is
1698 turned off in that buffer. Calling truncate_undo_list on
1699 Qt tends to return NULL, which effectively turns undo back on.
1700 So don't call truncate_undo_list if undo_list is Qt. */
e34f7f79 1701 if (!EQ (buffer->INTERNAL_FIELD (undo_list), Qt))
9cd47b72
DA
1702 truncate_undo_list (buffer);
1703
1704 /* Shrink buffer gaps. */
1705 if (!buffer->text->inhibit_shrinking)
1706 {
1707 /* If a buffer's gap size is more than 10% of the buffer
1708 size, or larger than 2000 bytes, then shrink it
1709 accordingly. Keep a minimum size of 20 bytes. */
1710 int size = min (2000, max (20, (buffer->text->z_byte / 10)));
1711
1712 if (buffer->text->gap_size > size)
1713 {
1714 struct buffer *save_current = current_buffer;
1715 current_buffer = buffer;
1716 make_gap (-(buffer->text->gap_size - size));
1717 current_buffer = save_current;
1718 }
1719 }
1720 buffer->text->compact = buffer->text->modiff;
1721 return 1;
1722 }
1723 return 0;
1724}
1725
a7ca3326 1726DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ",
b7e8d081 1727 doc: /* Kill the buffer specified by BUFFER-OR-NAME.
c8804c4f
MR
1728The argument may be a buffer or the name of an existing buffer.
1729Argument nil or omitted means kill the current buffer. Return t if the
1730buffer is actually killed, nil otherwise.
1731
b7e8d081
MR
1732The functions in `kill-buffer-query-functions' are called with the
1733buffer to be killed as the current buffer. If any of them returns nil,
1734the buffer is not killed. The hook `kill-buffer-hook' is run before the
1735buffer is actually killed. The buffer being killed will be current
1736while the hook is running. Functions called by any of these hooks are
1737supposed to not change the current buffer.
018ba359
PJ
1738
1739Any processes that have this buffer as the `process-buffer' are killed
b7e8d081
MR
1740with SIGHUP. This function calls `replace-buffer-in-windows' for
1741cleaning up all windows currently displaying the buffer to be killed. */)
5842a27b 1742 (Lisp_Object buffer_or_name)
1ab256cb 1743{
c8804c4f 1744 Lisp_Object buffer;
1ab256cb
RM
1745 register struct buffer *b;
1746 register Lisp_Object tem;
1747 register struct Lisp_Marker *m;
6af718a4 1748 struct gcpro gcpro1;
1ab256cb 1749
c8804c4f
MR
1750 if (NILP (buffer_or_name))
1751 buffer = Fcurrent_buffer ();
1ab256cb 1752 else
c8804c4f
MR
1753 buffer = Fget_buffer (buffer_or_name);
1754 if (NILP (buffer))
1755 nsberror (buffer_or_name);
1ab256cb 1756
c8804c4f 1757 b = XBUFFER (buffer);
1ab256cb 1758
4a4a9db5 1759 /* Avoid trouble for buffer already dead. */
4b4deea2 1760 if (NILP (BVAR (b, name)))
4a4a9db5
KH
1761 return Qnil;
1762
1ab256cb 1763 /* Query if the buffer is still modified. */
4b4deea2 1764 if (INTERACTIVE && !NILP (BVAR (b, filename))
336cd056 1765 && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
1ab256cb 1766 {
c8804c4f 1767 GCPRO1 (buffer);
5c4930b0 1768 tem = do_yes_or_no_p (format2 ("Buffer %s modified; kill anyway? ",
4b4deea2 1769 BVAR (b, name), make_number (0)));
1ab256cb 1770 UNGCPRO;
265a9e55 1771 if (NILP (tem))
1ab256cb
RM
1772 return Qnil;
1773 }
1774
dcdffbf6 1775 /* Run hooks with the buffer to be killed the current buffer. */
1ab256cb 1776 {
d311d28c 1777 ptrdiff_t count = SPECPDL_INDEX ();
5b20caf0 1778 Lisp_Object arglist[1];
1ab256cb
RM
1779
1780 record_unwind_protect (save_excursion_restore, save_excursion_save ());
1781 set_buffer_internal (b);
dcdffbf6
RS
1782
1783 /* First run the query functions; if any query is answered no,
1784 don't kill the buffer. */
5b20caf0 1785 arglist[0] = Qkill_buffer_query_functions;
09706e1f
KR
1786 tem = Frun_hook_with_args_until_failure (1, arglist);
1787 if (NILP (tem))
5b20caf0 1788 return unbind_to (count, Qnil);
dcdffbf6
RS
1789
1790 /* Then run the hooks. */
f1597a3a 1791 Frun_hooks (1, &Qkill_buffer_hook);
1ab256cb
RM
1792 unbind_to (count, Qnil);
1793 }
1794
b7e8d081
MR
1795 /* If the hooks have killed the buffer, exit now. */
1796 if (NILP (BVAR (b, name)))
1797 return Qt;
1798
1ab256cb
RM
1799 /* We have no more questions to ask. Verify that it is valid
1800 to kill the buffer. This must be done after the questions
1801 since anything can happen within do_yes_or_no_p. */
1802
1803 /* Don't kill the minibuffer now current. */
d3d50620 1804 if (EQ (buffer, XWINDOW (minibuf_window)->buffer))
1ab256cb
RM
1805 return Qnil;
1806
9928463d
DA
1807 /* When we kill an ordinary buffer which shares it's buffer text
1808 with indirect buffer(s), we must kill indirect buffer(s) too.
336cd056
RS
1809 We do it at this stage so nothing terrible happens if they
1810 ask questions or their hooks get errors. */
9928463d 1811 if (!b->base_buffer && b->indirections > 0)
336cd056
RS
1812 {
1813 struct buffer *other;
1814
c8804c4f 1815 GCPRO1 (buffer);
336cd056 1816
52b852c7 1817 FOR_EACH_BUFFER (other)
d17337e5 1818 if (other->base_buffer == b)
336cd056 1819 {
8f54f30a
PE
1820 Lisp_Object buf;
1821 XSETBUFFER (buf, other);
1822 Fkill_buffer (buf);
336cd056
RS
1823 }
1824
1825 UNGCPRO;
b7e8d081
MR
1826
1827 /* Exit if we now have killed the base buffer (Bug#11665). */
1828 if (NILP (BVAR (b, name)))
1829 return Qt;
336cd056 1830 }
177c0ea7 1831
56e2e794
MR
1832 /* Run replace_buffer_in_windows before making another buffer current
1833 since set-window-buffer-start-and-point will refuse to make another
1834 buffer current if the selected window does not show the current
1835 buffer. (Bug#10114) */
1836 replace_buffer_in_windows (buffer);
1837
b7e8d081
MR
1838 /* Exit if replacing the buffer in windows has killed our buffer. */
1839 if (NILP (BVAR (b, name)))
1840 return Qt;
1841
1842 /* Make this buffer not be current. Exit if it is the sole visible
1843 buffer. */
1ab256cb
RM
1844 if (b == current_buffer)
1845 {
c8804c4f 1846 tem = Fother_buffer (buffer, Qnil, Qnil);
1ab256cb
RM
1847 Fset_buffer (tem);
1848 if (b == current_buffer)
1849 return Qnil;
1850 }
1851
b7e8d081
MR
1852 /* If the buffer now current is shown in the minibuffer and our buffer
1853 is the sole other buffer give up. */
77270fac 1854 XSETBUFFER (tem, current_buffer);
d3d50620 1855 if (EQ (tem, XWINDOW (minibuf_window)->buffer)
b7e8d081
MR
1856 && EQ (buffer, Fother_buffer (buffer, Qnil, Qnil)))
1857 return Qnil;
77270fac 1858
1ab256cb
RM
1859 /* Now there is no question: we can kill the buffer. */
1860
1861#ifdef CLASH_DETECTION
1862 /* Unlock this buffer's file, if it is locked. */
1863 unlock_buffer (b);
1864#endif /* CLASH_DETECTION */
1865
c8804c4f
MR
1866 GCPRO1 (buffer);
1867 kill_buffer_processes (buffer);
49da74e6
KS
1868 UNGCPRO;
1869
b7e8d081
MR
1870 /* Killing buffer processes may run sentinels which may have killed
1871 our buffer. */
4b4deea2 1872 if (NILP (BVAR (b, name)))
b7e8d081 1873 return Qt;
49da74e6 1874
9397e56f
MR
1875 /* These may run Lisp code and into infinite loops (if someone
1876 insisted on circular lists) so allow quitting here. */
9397e56f
MR
1877 frames_discard_buffer (buffer);
1878
b93fb365 1879 clear_charpos_cache (b);
1ab256cb
RM
1880
1881 tem = Vinhibit_quit;
1882 Vinhibit_quit = Qt;
9397e56f 1883 /* Remove the buffer from the list of all buffers. */
c8804c4f 1884 Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
b7e8d081 1885 /* If replace_buffer_in_windows didn't do its job fix that now. */
9397e56f 1886 replace_buffer_in_windows_safely (buffer);
1ab256cb
RM
1887 Vinhibit_quit = tem;
1888
9cf712eb
RS
1889 /* Delete any auto-save file, if we saved it in this session.
1890 But not if the buffer is modified. */
4b4deea2 1891 if (STRINGP (BVAR (b, auto_save_file_name))
0b5397c2
SM
1892 && BUF_AUTOSAVE_MODIFF (b) != 0
1893 && BUF_SAVE_MODIFF (b) < BUF_AUTOSAVE_MODIFF (b)
6b61353c
KH
1894 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
1895 && NILP (Fsymbol_value (intern ("auto-save-visited-file-name"))))
1ab256cb 1896 {
8f54f30a
PE
1897 Lisp_Object delete;
1898 delete = Fsymbol_value (intern ("delete-auto-save-files"));
1899 if (! NILP (delete))
4b4deea2 1900 internal_delete_file (BVAR (b, auto_save_file_name));
1ab256cb
RM
1901 }
1902
b7e8d081
MR
1903 /* Deleting an auto-save file could have killed our buffer. */
1904 if (NILP (BVAR (b, name)))
1905 return Qt;
1906
4a4a9db5
KH
1907 if (b->base_buffer)
1908 {
1909 /* Unchain all markers that belong to this indirect buffer.
1910 Don't unchain the markers that belong to the base buffer
1911 or its other indirect buffers. */
65745fad 1912 for (m = BUF_MARKERS (b); m; )
4a4a9db5 1913 {
65745fad 1914 struct Lisp_Marker *next = m->next;
4a4a9db5 1915 if (m->buffer == b)
65745fad
SM
1916 unchain_marker (m);
1917 m = next;
4a4a9db5
KH
1918 }
1919 }
1920 else
1ab256cb 1921 {
4a4a9db5 1922 /* Unchain all markers of this buffer and its indirect buffers.
336cd056 1923 and leave them pointing nowhere. */
65745fad 1924 for (m = BUF_MARKERS (b); m; )
336cd056 1925 {
65745fad 1926 struct Lisp_Marker *next = m->next;
336cd056 1927 m->buffer = 0;
65745fad
SM
1928 m->next = NULL;
1929 m = next;
336cd056 1930 }
65745fad 1931 BUF_MARKERS (b) = NULL;
0c94c8d6 1932 set_buffer_intervals (b, NULL);
336cd056
RS
1933
1934 /* Perhaps we should explicitly free the interval tree here... */
1935 }
33f7013e 1936
2f3f993b
RS
1937 /* Reset the local variables, so that this buffer's local values
1938 won't be protected from GC. They would be protected
e4769531 1939 if they happened to remain cached in their symbols.
2f3f993b
RS
1940 This gets rid of them for certain. */
1941 swap_out_buffer_local_variables (b);
13de9290 1942 reset_buffer_local_variables (b, 1);
2f3f993b 1943
39eb03f1 1944 bset_name (b, Qnil);
336cd056 1945
9ac0d9e0 1946 BLOCK_INPUT;
04e9897c
DA
1947 if (b->base_buffer)
1948 {
1949 /* Notify our base buffer that we don't share the text anymore. */
1950 eassert (b->indirections == -1);
1951 b->base_buffer->indirections--;
1952 eassert (b->base_buffer->indirections >= 0);
1953 }
1954 else
1955 /* No one shares our buffer text, can free it. */
b86af064 1956 free_buffer_text (b);
336cd056 1957
28e969dd
JB
1958 if (b->newline_cache)
1959 {
1960 free_region_cache (b->newline_cache);
1961 b->newline_cache = 0;
1962 }
1963 if (b->width_run_cache)
1964 {
1965 free_region_cache (b->width_run_cache);
1966 b->width_run_cache = 0;
1967 }
39eb03f1 1968 bset_width_table (b, Qnil);
9ac0d9e0 1969 UNBLOCK_INPUT;
39eb03f1 1970 bset_undo_list (b, Qnil);
1ab256cb 1971
9397e56f
MR
1972 /* Run buffer-list-update-hook. */
1973 if (!NILP (Vrun_hooks))
1974 call1 (Vrun_hooks, Qbuffer_list_update_hook);
1975
1ab256cb
RM
1976 return Qt;
1977}
1978\f
9397e56f
MR
1979/* Move association for BUFFER to the front of buffer (a)lists. Since
1980 we do this each time BUFFER is selected visibly, the more recently
1981 selected buffers are always closer to the front of those lists. This
1982 means that other_buffer is more likely to choose a relevant buffer.
1983
1984 Note that this moves BUFFER to the front of the buffer lists of the
1985 selected frame even if BUFFER is not shown there. If BUFFER is not
1986 shown in the selected frame, consider the present behavior a feature.
1987 `select-window' gets this right since it shows BUFFER in the selected
1988 window when calling us. */
1ab256cb 1989
01136e9b 1990void
9397e56f 1991record_buffer (Lisp_Object buffer)
1ab256cb 1992{
4475bec4 1993 Lisp_Object aelt, aelt_cons, tem;
9397e56f 1994 register struct frame *f = XFRAME (selected_frame);
1ab256cb 1995
9397e56f 1996 CHECK_BUFFER (buffer);
1ab256cb 1997
9397e56f
MR
1998 /* Update Vbuffer_alist (we know that it has an entry for BUFFER).
1999 Don't allow quitting since this might leave the buffer list in an
2000 inconsistent state. */
2001 tem = Vinhibit_quit;
2002 Vinhibit_quit = Qt;
2003 aelt = Frassq (buffer, Vbuffer_alist);
4475bec4 2004 aelt_cons = Fmemq (aelt, Vbuffer_alist);
9397e56f 2005 Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
4475bec4
PE
2006 XSETCDR (aelt_cons, Vbuffer_alist);
2007 Vbuffer_alist = aelt_cons;
9397e56f 2008 Vinhibit_quit = tem;
1ab256cb 2009
9397e56f 2010 /* Update buffer list of selected frame. */
f00af5b1
PE
2011 fset_buffer_list (f, Fcons (buffer, Fdelq (buffer, f->buffer_list)));
2012 fset_buried_buffer_list (f, Fdelq (buffer, f->buried_buffer_list));
177c0ea7 2013
9397e56f
MR
2014 /* Run buffer-list-update-hook. */
2015 if (!NILP (Vrun_hooks))
2016 call1 (Vrun_hooks, Qbuffer_list_update_hook);
2017}
7962a441 2018
7962a441 2019
e4ed06f1
CY
2020/* Move BUFFER to the end of the buffer (a)lists. Do nothing if the
2021 buffer is killed. For the selected frame's buffer list this moves
2022 BUFFER to its end even if it was never shown in that frame. If
96a72ee9 2023 this happens we have a feature, hence `bury-buffer-internal' should be
e4ed06f1 2024 called only when BUFFER was shown in the selected frame. */
7962a441 2025
e4ed06f1
CY
2026DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal,
2027 1, 1, 0,
2028 doc: /* Move BUFFER to the end of the buffer list. */)
9397e56f
MR
2029 (Lisp_Object buffer)
2030{
4475bec4 2031 Lisp_Object aelt, aelt_cons, tem;
9397e56f 2032 register struct frame *f = XFRAME (selected_frame);
7962a441 2033
9397e56f 2034 CHECK_BUFFER (buffer);
177c0ea7 2035
9397e56f
MR
2036 /* Update Vbuffer_alist (we know that it has an entry for BUFFER).
2037 Don't allow quitting since this might leave the buffer list in an
2038 inconsistent state. */
2039 tem = Vinhibit_quit;
2040 Vinhibit_quit = Qt;
2041 aelt = Frassq (buffer, Vbuffer_alist);
4475bec4 2042 aelt_cons = Fmemq (aelt, Vbuffer_alist);
9397e56f 2043 Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
4475bec4
PE
2044 XSETCDR (aelt_cons, Qnil);
2045 Vbuffer_alist = nconc2 (Vbuffer_alist, aelt_cons);
9397e56f
MR
2046 Vinhibit_quit = tem;
2047
2048 /* Update buffer lists of selected frame. */
f00af5b1
PE
2049 fset_buffer_list (f, Fdelq (buffer, f->buffer_list));
2050 fset_buried_buffer_list
2051 (f, Fcons (buffer, Fdelq (buffer, f->buried_buffer_list)));
9397e56f
MR
2052
2053 /* Run buffer-list-update-hook. */
2054 if (!NILP (Vrun_hooks))
2055 call1 (Vrun_hooks, Qbuffer_list_update_hook);
2056
e4ed06f1 2057 return Qnil;
1ab256cb
RM
2058}
2059
a9ee7a59 2060DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0,
7ee72033 2061 doc: /* Set an appropriate major mode for BUFFER.
864b90c9 2062For the *scratch* buffer, use `initial-major-mode', otherwise choose a mode
71a0f2c6 2063according to `default-major-mode'.
018ba359 2064Use this function before selecting the buffer, since it may need to inspect
7ee72033 2065the current buffer's major mode. */)
5842a27b 2066 (Lisp_Object buffer)
a9ee7a59 2067{
d311d28c 2068 ptrdiff_t count;
a9ee7a59
KH
2069 Lisp_Object function;
2070
ea4fddd8
JB
2071 CHECK_BUFFER (buffer);
2072
4b4deea2
TT
2073 if (STRINGP (BVAR (XBUFFER (buffer), name))
2074 && strcmp (SSDATA (BVAR (XBUFFER (buffer), name)), "*scratch*") == 0)
71a0f2c6
GM
2075 function = find_symbol_value (intern ("initial-major-mode"));
2076 else
2077 {
4b4deea2 2078 function = BVAR (&buffer_defaults, major_mode);
71a0f2c6 2079 if (NILP (function)
4b4deea2
TT
2080 && NILP (Fget (BVAR (current_buffer, major_mode), Qmode_class)))
2081 function = BVAR (current_buffer, major_mode);
71a0f2c6 2082 }
177c0ea7 2083
48265e61
DL
2084 if (NILP (function) || EQ (function, Qfundamental_mode))
2085 return Qnil;
2086
aed13378 2087 count = SPECPDL_INDEX ();
a9ee7a59 2088
48265e61
DL
2089 /* To select a nonfundamental mode,
2090 select the buffer temporarily and then call the mode function. */
a9ee7a59
KH
2091
2092 record_unwind_protect (save_excursion_restore, save_excursion_save ());
2093
a2428fa2 2094 Fset_buffer (buffer);
48265e61 2095 call0 (function);
a9ee7a59
KH
2096
2097 return unbind_to (count, Qnil);
2098}
2099
a7ca3326 2100DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
7ee72033 2101 doc: /* Return the current buffer as a Lisp object. */)
5842a27b 2102 (void)
1ab256cb
RM
2103{
2104 register Lisp_Object buf;
67180c6a 2105 XSETBUFFER (buf, current_buffer);
1ab256cb
RM
2106 return buf;
2107}
2108\f
7ec44ec6
GM
2109/* Set the current buffer to B.
2110
2111 We previously set windows_or_buffers_changed here to invalidate
2112 global unchanged information in beg_unchanged and end_unchanged.
2113 This is no longer necessary because we now compute unchanged
2114 information on a buffer-basis. Every action affecting other
2115 windows than the selected one requires a select_window at some
2116 time, and that increments windows_or_buffers_changed. */
1ab256cb
RM
2117
2118void
d3da34e0 2119set_buffer_internal (register struct buffer *b)
1ab256cb 2120{
b5a225b4 2121 if (current_buffer != b)
7ec44ec6 2122 set_buffer_internal_1 (b);
c7aa5005
KH
2123}
2124
2125/* Set the current buffer to B, and do not set windows_or_buffers_changed.
2126 This is used by redisplay. */
2127
2128void
d3da34e0 2129set_buffer_internal_1 (register struct buffer *b)
c7aa5005
KH
2130{
2131 register struct buffer *old_buf;
ce5b453a 2132 register Lisp_Object tail;
c7aa5005 2133
b86af064 2134#ifdef USE_MMAP_FOR_BUFFERS
684b01ee 2135 if (b->text->beg == NULL)
b86af064
GM
2136 enlarge_buffer_text (b, 0);
2137#endif /* USE_MMAP_FOR_BUFFERS */
177c0ea7 2138
c7aa5005
KH
2139 if (current_buffer == b)
2140 return;
2141
1ab256cb
RM
2142 old_buf = current_buffer;
2143 current_buffer = b;
2144 last_known_column_point = -1; /* invalidate indentation cache */
2145
336cd056
RS
2146 if (old_buf)
2147 {
2148 /* Put the undo list back in the base buffer, so that it appears
2149 that an indirect buffer shares the undo list of its base. */
2150 if (old_buf->base_buffer)
39eb03f1 2151 bset_undo_list (old_buf->base_buffer, BVAR (old_buf, undo_list));
336cd056
RS
2152
2153 /* If the old current buffer has markers to record PT, BEGV and ZV
2154 when it is not current, update them now. */
cffc6f3b 2155 record_buffer_markers (old_buf);
336cd056
RS
2156 }
2157
2158 /* Get the undo list from the base buffer, so that it appears
2159 that an indirect buffer shares the undo list of its base. */
2160 if (b->base_buffer)
39eb03f1 2161 bset_undo_list (b, BVAR (b->base_buffer, undo_list));
336cd056
RS
2162
2163 /* If the new current buffer has markers to record PT, BEGV and ZV
2164 when it is not current, fetch them now. */
cffc6f3b 2165 fetch_buffer_markers (b);
336cd056 2166
1ab256cb
RM
2167 /* Look down buffer's list of local Lisp variables
2168 to find and update any that forward into C variables. */
2169
ce5b453a 2170 do
1ab256cb 2171 {
4b4deea2 2172 for (tail = BVAR (b, local_var_alist); CONSP (tail); tail = XCDR (tail))
ce5b453a
SM
2173 {
2174 Lisp_Object var = XCAR (XCAR (tail));
2175 struct Lisp_Symbol *sym = XSYMBOL (var);
2176 if (sym->redirect == SYMBOL_LOCALIZED /* Just to be sure. */
2177 && SYMBOL_BLV (sym)->fwd)
2178 /* Just reference the variable
2179 to cause it to become set for this buffer. */
2180 Fsymbol_value (var);
2181 }
1ab256cb 2182 }
1ab256cb 2183 /* Do the same with any others that were local to the previous buffer */
ce5b453a 2184 while (b != old_buf && (b = old_buf, b));
1ab256cb
RM
2185}
2186
336cd056 2187/* Switch to buffer B temporarily for redisplay purposes.
bbbe9545 2188 This avoids certain things that don't need to be done within redisplay. */
336cd056
RS
2189
2190void
d3da34e0 2191set_buffer_temp (struct buffer *b)
336cd056
RS
2192{
2193 register struct buffer *old_buf;
2194
2195 if (current_buffer == b)
2196 return;
2197
2198 old_buf = current_buffer;
2199 current_buffer = b;
2200
cffc6f3b
CY
2201 /* If the old current buffer has markers to record PT, BEGV and ZV
2202 when it is not current, update them now. */
2203 record_buffer_markers (old_buf);
336cd056
RS
2204
2205 /* If the new current buffer has markers to record PT, BEGV and ZV
2206 when it is not current, fetch them now. */
cffc6f3b 2207 fetch_buffer_markers (b);
336cd056
RS
2208}
2209
a7ca3326 2210DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0,
c8804c4f
MR
2211 doc: /* Make buffer BUFFER-OR-NAME current for editing operations.
2212BUFFER-OR-NAME may be a buffer or the name of an existing buffer. See
2213also `save-excursion' when you want to make a buffer current
2214temporarily. This function does not display the buffer, so its effect
2215ends when the current command terminates. Use `switch-to-buffer' or
2216`pop-to-buffer' to switch buffers permanently. */)
5842a27b 2217 (register Lisp_Object buffer_or_name)
1ab256cb 2218{
c8804c4f
MR
2219 register Lisp_Object buffer;
2220 buffer = Fget_buffer (buffer_or_name);
2221 if (NILP (buffer))
2222 nsberror (buffer_or_name);
4b4deea2 2223 if (NILP (BVAR (XBUFFER (buffer), name)))
1ab256cb 2224 error ("Selecting deleted buffer");
c8804c4f
MR
2225 set_buffer_internal (XBUFFER (buffer));
2226 return buffer;
1ab256cb 2227}
d0628b06
RS
2228
2229/* Set the current buffer to BUFFER provided it is alive. */
2230
2231Lisp_Object
d3da34e0 2232set_buffer_if_live (Lisp_Object buffer)
d0628b06 2233{
4b4deea2 2234 if (! NILP (BVAR (XBUFFER (buffer), name)))
d0628b06
RS
2235 Fset_buffer (buffer);
2236 return Qnil;
2237}
1ab256cb 2238\f
a7ca3326 2239DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
1ab256cb 2240 Sbarf_if_buffer_read_only, 0, 0, 0,
7ee72033 2241 doc: /* Signal a `buffer-read-only' error if the current buffer is read-only. */)
5842a27b 2242 (void)
1ab256cb 2243{
4b4deea2 2244 if (!NILP (BVAR (current_buffer, read_only))
a96b68f1 2245 && NILP (Vinhibit_read_only))
4c4dc0b0 2246 xsignal1 (Qbuffer_read_only, Fcurrent_buffer ());
1ab256cb
RM
2247 return Qnil;
2248}
1ab256cb 2249\f
a7ca3326 2250DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*",
7ee72033 2251 doc: /* Delete the entire contents of the current buffer.
018ba359 2252Any narrowing restriction in effect (see `narrow-to-region') is removed,
7ee72033 2253so the buffer is truly empty after this. */)
5842a27b 2254 (void)
1ab256cb
RM
2255{
2256 Fwiden ();
c0d9a0c3
GM
2257
2258 del_range (BEG, Z);
c280bc6a 2259
1ab256cb
RM
2260 current_buffer->last_window_start = 1;
2261 /* Prevent warnings, or suspension of auto saving, that would happen
2262 if future size is less than past size. Use of erase-buffer
2263 implies that the future text is not really related to the past text. */
4b4deea2 2264 XSETFASTINT (BVAR (current_buffer, save_length), 0);
1ab256cb
RM
2265 return Qnil;
2266}
2267
01136e9b 2268void
d3da34e0 2269validate_region (register Lisp_Object *b, register Lisp_Object *e)
1ab256cb 2270{
b7826503
PJ
2271 CHECK_NUMBER_COERCE_MARKER (*b);
2272 CHECK_NUMBER_COERCE_MARKER (*e);
1ab256cb
RM
2273
2274 if (XINT (*b) > XINT (*e))
2275 {
03192067
KH
2276 Lisp_Object tem;
2277 tem = *b; *b = *e; *e = tem;
1ab256cb
RM
2278 }
2279
d311d28c 2280 if (! (BEGV <= XINT (*b) && XINT (*e) <= ZV))
1ab256cb
RM
2281 args_out_of_range (*b, *e);
2282}
2283\f
b05525fa
RS
2284/* Advance BYTE_POS up to a character boundary
2285 and return the adjusted position. */
2286
d311d28c
PE
2287static ptrdiff_t
2288advance_to_char_boundary (ptrdiff_t byte_pos)
b05525fa 2289{
f8449323 2290 int c;
b05525fa 2291
f8449323
RS
2292 if (byte_pos == BEG)
2293 /* Beginning of buffer is always a character boundary. */
6d70a280 2294 return BEG;
f8449323
RS
2295
2296 c = FETCH_BYTE (byte_pos);
2297 if (! CHAR_HEAD_P (c))
b05525fa 2298 {
1be6387d 2299 /* We should advance BYTE_POS only when C is a constituent of a
f8449323 2300 multibyte sequence. */
d311d28c 2301 ptrdiff_t orig_byte_pos = byte_pos;
a9bcded1
KH
2302
2303 do
2304 {
2305 byte_pos--;
2306 c = FETCH_BYTE (byte_pos);
2307 }
2308 while (! CHAR_HEAD_P (c) && byte_pos > BEG);
f8449323 2309 INC_POS (byte_pos);
a9bcded1
KH
2310 if (byte_pos < orig_byte_pos)
2311 byte_pos = orig_byte_pos;
f8449323
RS
2312 /* If C is a constituent of a multibyte sequence, BYTE_POS was
2313 surely advance to the correct character boundary. If C is
2314 not, BYTE_POS was unchanged. */
b05525fa
RS
2315 }
2316
20773569 2317 return byte_pos;
b05525fa
RS
2318}
2319
13cda5f9
SM
2320DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
2321 1, 1, 0,
2322 doc: /* Swap the text between current buffer and BUFFER. */)
5842a27b 2323 (Lisp_Object buffer)
13cda5f9
SM
2324{
2325 struct buffer *other_buffer;
2326 CHECK_BUFFER (buffer);
2327 other_buffer = XBUFFER (buffer);
2328
4b4deea2 2329 if (NILP (BVAR (other_buffer, name)))
409f2919 2330 error ("Cannot swap a dead buffer's text");
dc9cc574 2331
13cda5f9
SM
2332 /* Actually, it probably works just fine.
2333 * if (other_buffer == current_buffer)
2334 * error ("Cannot swap a buffer's text with itself"); */
2335
2336 /* Actually, this may be workable as well, tho probably only if they're
2337 *both* indirect. */
2338 if (other_buffer->base_buffer
2339 || current_buffer->base_buffer)
2340 error ("Cannot swap indirect buffers's text");
2341
2342 { /* This is probably harder to make work. */
2343 struct buffer *other;
52b852c7 2344 FOR_EACH_BUFFER (other)
13cda5f9
SM
2345 if (other->base_buffer == other_buffer
2346 || other->base_buffer == current_buffer)
2347 error ("One of the buffers to swap has indirect buffers");
2348 }
2349
2350#define swapfield(field, type) \
2351 do { \
2352 type tmp##field = other_buffer->field; \
2353 other_buffer->field = current_buffer->field; \
2354 current_buffer->field = tmp##field; \
2355 } while (0)
5d8ea120
TT
2356#define swapfield_(field, type) \
2357 do { \
4b4deea2 2358 type tmp##field = BVAR (other_buffer, field); \
39eb03f1
PE
2359 bset_##field (other_buffer, BVAR (current_buffer, field)); \
2360 bset_##field (current_buffer, tmp##field); \
5d8ea120 2361 } while (0)
13cda5f9
SM
2362
2363 swapfield (own_text, struct buffer_text);
2364 eassert (current_buffer->text == &current_buffer->own_text);
2365 eassert (other_buffer->text == &other_buffer->own_text);
baae5c2d 2366#ifdef REL_ALLOC
261cb4bb
PE
2367 r_alloc_reset_variable ((void **) &current_buffer->own_text.beg,
2368 (void **) &other_buffer->own_text.beg);
2369 r_alloc_reset_variable ((void **) &other_buffer->own_text.beg,
2370 (void **) &current_buffer->own_text.beg);
baae5c2d
JR
2371#endif /* REL_ALLOC */
2372
d311d28c
PE
2373 swapfield (pt, ptrdiff_t);
2374 swapfield (pt_byte, ptrdiff_t);
2375 swapfield (begv, ptrdiff_t);
2376 swapfield (begv_byte, ptrdiff_t);
2377 swapfield (zv, ptrdiff_t);
2378 swapfield (zv_byte, ptrdiff_t);
13cda5f9
SM
2379 eassert (!current_buffer->base_buffer);
2380 eassert (!other_buffer->base_buffer);
372f8ffc 2381 swapfield (indirections, ptrdiff_t);
13cda5f9
SM
2382 current_buffer->clip_changed = 1; other_buffer->clip_changed = 1;
2383 swapfield (newline_cache, struct region_cache *);
2384 swapfield (width_run_cache, struct region_cache *);
2385 current_buffer->prevent_redisplay_optimizations_p = 1;
2386 other_buffer->prevent_redisplay_optimizations_p = 1;
2387 swapfield (overlays_before, struct Lisp_Overlay *);
2388 swapfield (overlays_after, struct Lisp_Overlay *);
d311d28c 2389 swapfield (overlay_center, ptrdiff_t);
5d8ea120
TT
2390 swapfield_ (undo_list, Lisp_Object);
2391 swapfield_ (mark, Lisp_Object);
2392 swapfield_ (enable_multibyte_characters, Lisp_Object);
2393 swapfield_ (bidi_display_reordering, Lisp_Object);
2394 swapfield_ (bidi_paragraph_direction, Lisp_Object);
13cda5f9
SM
2395 /* FIXME: Not sure what we should do with these *_marker fields.
2396 Hopefully they're just nil anyway. */
5d8ea120
TT
2397 swapfield_ (pt_marker, Lisp_Object);
2398 swapfield_ (begv_marker, Lisp_Object);
2399 swapfield_ (zv_marker, Lisp_Object);
39eb03f1
PE
2400 bset_point_before_scroll (current_buffer, Qnil);
2401 bset_point_before_scroll (other_buffer, Qnil);
13cda5f9
SM
2402
2403 current_buffer->text->modiff++; other_buffer->text->modiff++;
2404 current_buffer->text->chars_modiff++; other_buffer->text->chars_modiff++;
2405 current_buffer->text->overlay_modiff++; other_buffer->text->overlay_modiff++;
2406 current_buffer->text->beg_unchanged = current_buffer->text->gpt;
2407 current_buffer->text->end_unchanged = current_buffer->text->gpt;
b8ff72fa
SM
2408 other_buffer->text->beg_unchanged = other_buffer->text->gpt;
2409 other_buffer->text->end_unchanged = other_buffer->text->gpt;
13cda5f9
SM
2410 {
2411 struct Lisp_Marker *m;
2412 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
2413 if (m->buffer == other_buffer)
2414 m->buffer = current_buffer;
b8ff72fa
SM
2415 else
2416 /* Since there's no indirect buffer in sight, markers on
2417 BUF_MARKERS(buf) should either be for `buf' or dead. */
2418 eassert (!m->buffer);
13cda5f9
SM
2419 for (m = BUF_MARKERS (other_buffer); m; m = m->next)
2420 if (m->buffer == current_buffer)
2421 m->buffer = other_buffer;
b8ff72fa
SM
2422 else
2423 /* Since there's no indirect buffer in sight, markers on
2424 BUF_MARKERS(buf) should either be for `buf' or dead. */
2425 eassert (!m->buffer);
13cda5f9 2426 }
126f1fc1
SM
2427 { /* Some of the C code expects that w->buffer == w->pointm->buffer.
2428 So since we just swapped the markers between the two buffers, we need
2429 to undo the effect of this swap for window markers. */
2430 Lisp_Object w = Fselected_window (), ws = Qnil;
2431 Lisp_Object buf1, buf2;
2432 XSETBUFFER (buf1, current_buffer); XSETBUFFER (buf2, other_buffer);
2433
2434 while (NILP (Fmemq (w, ws)))
2435 {
2436 ws = Fcons (w, ws);
d3d50620
DA
2437 if (MARKERP (XWINDOW (w)->pointm)
2438 && (EQ (XWINDOW (w)->buffer, buf1)
2439 || EQ (XWINDOW (w)->buffer, buf2)))
2440 Fset_marker (XWINDOW (w)->pointm,
3a45383a 2441 make_number
d3d50620
DA
2442 (BUF_BEGV (XBUFFER (XWINDOW (w)->buffer))),
2443 XWINDOW (w)->buffer);
126f1fc1
SM
2444 w = Fnext_window (w, Qt, Qt);
2445 }
2446 }
2447
13cda5f9
SM
2448 if (current_buffer->text->intervals)
2449 (eassert (EQ (current_buffer->text->intervals->up.obj, buffer)),
2450 XSETBUFFER (current_buffer->text->intervals->up.obj, current_buffer));
2451 if (other_buffer->text->intervals)
2452 (eassert (EQ (other_buffer->text->intervals->up.obj, Fcurrent_buffer ())),
2453 XSETBUFFER (other_buffer->text->intervals->up.obj, other_buffer));
2454
2455 return Qnil;
2456}
2457
a7ca3326 2458DEFUN ("set-buffer-multibyte", Fset_buffer_multibyte, Sset_buffer_multibyte,
3ac81adb 2459 1, 1, 0,
7ee72033 2460 doc: /* Set the multibyte flag of the current buffer to FLAG.
018ba359
PJ
2461If FLAG is t, this makes the buffer a multibyte buffer.
2462If FLAG is nil, this makes the buffer a single-byte buffer.
8f924df7
KH
2463In these cases, the buffer contents remain unchanged as a sequence of
2464bytes but the contents viewed as characters do change.
2465If FLAG is `to', this makes the buffer a multibyte buffer by changing
6b61353c
KH
2466all eight-bit bytes to eight-bit characters.
2467If the multibyte flag was really changed, undo information of the
2468current buffer is cleared. */)
5842a27b 2469 (Lisp_Object flag)
3ac81adb 2470{
65745fad 2471 struct Lisp_Marker *tail, *markers;
abc9d959 2472 struct buffer *other;
d311d28c 2473 ptrdiff_t begv, zv;
8d1203ea 2474 int narrowed = (BEG != BEGV || Z != ZV);
ed00559d 2475 int modified_p = !NILP (Fbuffer_modified_p (Qnil));
4b4deea2 2476 Lisp_Object old_undo = BVAR (current_buffer, undo_list);
38babc07 2477 struct gcpro gcpro1;
3ac81adb 2478
6e553d5e
RS
2479 if (current_buffer->base_buffer)
2480 error ("Cannot do `set-buffer-multibyte' on an indirect buffer");
2481
70e77119 2482 /* Do nothing if nothing actually changes. */
4b4deea2 2483 if (NILP (flag) == NILP (BVAR (current_buffer, enable_multibyte_characters)))
70e77119
AS
2484 return flag;
2485
38babc07
KS
2486 GCPRO1 (old_undo);
2487
2488 /* Don't record these buffer changes. We will put a special undo entry
2489 instead. */
39eb03f1 2490 bset_undo_list (current_buffer, Qt);
b05525fa 2491
3ac81adb
RS
2492 /* If the cached position is for this buffer, clear it out. */
2493 clear_charpos_cache (current_buffer);
2494
458c8af4
KH
2495 if (NILP (flag))
2496 begv = BEGV_BYTE, zv = ZV_BYTE;
2497 else
2498 begv = BEGV, zv = ZV;
2499
a9bcded1
KH
2500 if (narrowed)
2501 Fwiden ();
2502
3ac81adb
RS
2503 if (NILP (flag))
2504 {
d311d28c 2505 ptrdiff_t pos, stop;
a9bcded1
KH
2506 unsigned char *p;
2507
3ac81adb
RS
2508 /* Do this first, so it can use CHAR_TO_BYTE
2509 to calculate the old correspondences. */
2510 set_intervals_multibyte (0);
2511
39eb03f1 2512 bset_enable_multibyte_characters (current_buffer, Qnil);
3ac81adb
RS
2513
2514 Z = Z_BYTE;
2515 BEGV = BEGV_BYTE;
2516 ZV = ZV_BYTE;
2517 GPT = GPT_BYTE;
2518 TEMP_SET_PT_BOTH (PT_BYTE, PT_BYTE);
2519
60ebfdf3 2520
65745fad
SM
2521 for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
2522 tail->charpos = tail->bytepos;
a9bcded1
KH
2523
2524 /* Convert multibyte form of 8-bit characters to unibyte. */
2525 pos = BEG;
2526 stop = GPT;
2527 p = BEG_ADDR;
2528 while (1)
2529 {
2530 int c, bytes;
2531
2532 if (pos == stop)
2533 {
2534 if (pos == Z)
2535 break;
2536 p = GAP_END_ADDR;
2537 stop = Z;
2538 }
8f348ed5
KH
2539 if (ASCII_BYTE_P (*p))
2540 p++, pos++;
2541 else if (CHAR_BYTE8_HEAD_P (*p))
a9bcded1 2542 {
62a6e103 2543 c = STRING_CHAR_AND_LENGTH (p, bytes);
a9bcded1 2544 /* Delete all bytes for this 8-bit character but the
3b59c351 2545 last one, and change the last one to the character
a9bcded1
KH
2546 code. */
2547 bytes--;
2548 del_range_2 (pos, pos, pos + bytes, pos + bytes, 0);
2549 p = GAP_END_ADDR;
2550 *p++ = c;
2551 pos++;
2552 if (begv > pos)
2553 begv -= bytes;
2554 if (zv > pos)
2555 zv -= bytes;
2556 stop = Z;
2557 }
8f924df7 2558 else
8f348ed5
KH
2559 {
2560 bytes = BYTES_BY_CHAR_HEAD (*p);
2561 p += bytes, pos += bytes;
2562 }
a9bcded1
KH
2563 }
2564 if (narrowed)
2565 Fnarrow_to_region (make_number (begv), make_number (zv));
3ac81adb
RS
2566 }
2567 else
2568 {
d311d28c
PE
2569 ptrdiff_t pt = PT;
2570 ptrdiff_t pos, stop;
8f348ed5 2571 unsigned char *p, *pend;
a9bcded1 2572
673c57d2 2573 /* Be sure not to have a multibyte sequence striding over the GAP.
8f348ed5
KH
2574 Ex: We change this: "...abc\302 _GAP_ \241def..."
2575 to: "...abc _GAP_ \302\241def..." */
673c57d2 2576
8f924df7 2577 if (EQ (flag, Qt)
a3a303df 2578 && GPT_BYTE > 1 && GPT_BYTE < Z_BYTE
673c57d2
KH
2579 && ! CHAR_HEAD_P (*(GAP_END_ADDR)))
2580 {
8f54f30a 2581 unsigned char *q = GPT_ADDR - 1;
673c57d2 2582
8f54f30a
PE
2583 while (! CHAR_HEAD_P (*q) && q > BEG_ADDR) q--;
2584 if (LEADING_CODE_P (*q))
673c57d2 2585 {
d311d28c 2586 ptrdiff_t new_gpt = GPT_BYTE - (GPT_ADDR - q);
673c57d2
KH
2587
2588 move_gap_both (new_gpt, new_gpt);
2589 }
2590 }
2591
a9bcded1
KH
2592 /* Make the buffer contents valid as multibyte by converting
2593 8-bit characters to multibyte form. */
2594 pos = BEG;
2595 stop = GPT;
2596 p = BEG_ADDR;
8f348ed5 2597 pend = GPT_ADDR;
a9bcded1
KH
2598 while (1)
2599 {
2600 int bytes;
2601
2602 if (pos == stop)
2603 {
2604 if (pos == Z)
2605 break;
2606 p = GAP_END_ADDR;
8f348ed5 2607 pend = Z_ADDR;
a9bcded1
KH
2608 stop = Z;
2609 }
177c0ea7 2610
a3a303df
KH
2611 if (ASCII_BYTE_P (*p))
2612 p++, pos++;
dcfb9bc4
KH
2613 else if (EQ (flag, Qt)
2614 && ! CHAR_BYTE8_HEAD_P (*p)
2615 && (bytes = MULTIBYTE_LENGTH (p, pend)) > 0)
a9bcded1
KH
2616 p += bytes, pos += bytes;
2617 else
2618 {
2619 unsigned char tmp[MAX_MULTIBYTE_LENGTH];
a3a303df 2620 int c;
a9bcded1 2621
8f924df7 2622 c = BYTE8_TO_CHAR (*p);
8c2fc311 2623 bytes = CHAR_STRING (c, tmp);
a9bcded1
KH
2624 *p = tmp[0];
2625 TEMP_SET_PT_BOTH (pos + 1, pos + 1);
2626 bytes--;
b68864e5 2627 insert_1_both ((char *) tmp + 1, bytes, bytes, 1, 0, 0);
a9bcded1
KH
2628 /* Now the gap is after the just inserted data. */
2629 pos = GPT;
2630 p = GAP_END_ADDR;
2631 if (pos <= begv)
2632 begv += bytes;
2633 if (pos <= zv)
2634 zv += bytes;
2635 if (pos <= pt)
2636 pt += bytes;
31285a8f 2637 pend = Z_ADDR;
a9bcded1
KH
2638 stop = Z;
2639 }
2640 }
2641
2642 if (pt != PT)
2643 TEMP_SET_PT (pt);
2644
2645 if (narrowed)
2646 Fnarrow_to_region (make_number (begv), make_number (zv));
2647
3ac81adb
RS
2648 /* Do this first, so that chars_in_text asks the right question.
2649 set_intervals_multibyte needs it too. */
39eb03f1 2650 bset_enable_multibyte_characters (current_buffer, Qt);
3ac81adb 2651
b05525fa 2652 GPT_BYTE = advance_to_char_boundary (GPT_BYTE);
3ac81adb 2653 GPT = chars_in_text (BEG_ADDR, GPT_BYTE - BEG_BYTE) + BEG;
b05525fa 2654
673c57d2 2655 Z = chars_in_text (GAP_END_ADDR, Z_BYTE - GPT_BYTE) + GPT;
b05525fa
RS
2656
2657 BEGV_BYTE = advance_to_char_boundary (BEGV_BYTE);
3ac81adb 2658 if (BEGV_BYTE > GPT_BYTE)
673c57d2 2659 BEGV = chars_in_text (GAP_END_ADDR, BEGV_BYTE - GPT_BYTE) + GPT;
3ac81adb
RS
2660 else
2661 BEGV = chars_in_text (BEG_ADDR, BEGV_BYTE - BEG_BYTE) + BEG;
b05525fa
RS
2662
2663 ZV_BYTE = advance_to_char_boundary (ZV_BYTE);
3ac81adb 2664 if (ZV_BYTE > GPT_BYTE)
673c57d2 2665 ZV = chars_in_text (GAP_END_ADDR, ZV_BYTE - GPT_BYTE) + GPT;
3ac81adb
RS
2666 else
2667 ZV = chars_in_text (BEG_ADDR, ZV_BYTE - BEG_BYTE) + BEG;
b05525fa
RS
2668
2669 {
d311d28c
PE
2670 ptrdiff_t byte = advance_to_char_boundary (PT_BYTE);
2671 ptrdiff_t position;
b05525fa 2672
8f54f30a
PE
2673 if (byte > GPT_BYTE)
2674 position = chars_in_text (GAP_END_ADDR, byte - GPT_BYTE) + GPT;
b05525fa 2675 else
8f54f30a
PE
2676 position = chars_in_text (BEG_ADDR, byte - BEG_BYTE) + BEG;
2677 TEMP_SET_PT_BOTH (position, byte);
b05525fa 2678 }
3ac81adb
RS
2679
2680 tail = markers = BUF_MARKERS (current_buffer);
95fb069b
RS
2681
2682 /* This prevents BYTE_TO_CHAR (that is, buf_bytepos_to_charpos) from
2683 getting confused by the markers that have not yet been updated.
2684 It is also a signal that it should never create a marker. */
65745fad 2685 BUF_MARKERS (current_buffer) = NULL;
3ac81adb 2686
65745fad 2687 for (; tail; tail = tail->next)
3ac81adb 2688 {
65745fad
SM
2689 tail->bytepos = advance_to_char_boundary (tail->bytepos);
2690 tail->charpos = BYTE_TO_CHAR (tail->bytepos);
3ac81adb 2691 }
b69f9797
RS
2692
2693 /* Make sure no markers were put on the chain
2694 while the chain value was incorrect. */
65745fad 2695 if (BUF_MARKERS (current_buffer))
b69f9797
RS
2696 abort ();
2697
3ac81adb
RS
2698 BUF_MARKERS (current_buffer) = markers;
2699
2700 /* Do this last, so it can calculate the new correspondences
2701 between chars and bytes. */
2702 set_intervals_multibyte (1);
2703 }
2704
38babc07
KS
2705 if (!EQ (old_undo, Qt))
2706 {
2707 /* Represent all the above changes by a special undo entry. */
39eb03f1
PE
2708 bset_undo_list (current_buffer,
2709 Fcons (list3 (Qapply,
2710 intern ("set-buffer-multibyte"),
2711 NILP (flag) ? Qt : Qnil),
2712 old_undo));
38babc07
KS
2713 }
2714
2715 UNGCPRO;
a9bcded1 2716
724b203f
GM
2717 /* Changing the multibyteness of a buffer means that all windows
2718 showing that buffer must be updated thoroughly. */
2719 current_buffer->prevent_redisplay_optimizations_p = 1;
2720 ++windows_or_buffers_changed;
2721
abc9d959
RS
2722 /* Copy this buffer's new multibyte status
2723 into all of its indirect buffers. */
52b852c7 2724 FOR_EACH_BUFFER (other)
4b4deea2 2725 if (other->base_buffer == current_buffer && !NILP (BVAR (other, name)))
724b203f 2726 {
4b4deea2
TT
2727 BVAR (other, enable_multibyte_characters)
2728 = BVAR (current_buffer, enable_multibyte_characters);
724b203f
GM
2729 other->prevent_redisplay_optimizations_p = 1;
2730 }
abc9d959 2731
ed00559d
KH
2732 /* Restore the modifiedness of the buffer. */
2733 if (!modified_p && !NILP (Fbuffer_modified_p (Qnil)))
2734 Fset_buffer_modified_p (Qnil);
2735
172f9454
KH
2736 /* Update coding systems of this buffer's process (if any). */
2737 {
2738 Lisp_Object process;
2739
2740 process = Fget_buffer_process (Fcurrent_buffer ());
2741 if (PROCESSP (process))
2742 setup_process_coding_systems (process);
2743 }
2744
3ac81adb
RS
2745 return flag;
2746}
2747\f
a7ca3326 2748DEFUN ("kill-all-local-variables", Fkill_all_local_variables,
16a97296 2749 Skill_all_local_variables, 0, 0, 0,
7ee72033 2750 doc: /* Switch to Fundamental mode by killing current buffer's local variables.
018ba359
PJ
2751Most local variable bindings are eliminated so that the default values
2752become effective once more. Also, the syntax table is set from
2753`standard-syntax-table', the local keymap is set to nil,
2754and the abbrev table from `fundamental-mode-abbrev-table'.
2755This function also forces redisplay of the mode line.
2756
2757Every function to select a new major mode starts by
2758calling this function.
2759
2760As a special exception, local variables whose names have
2761a non-nil `permanent-local' property are not eliminated by this function.
2762
2763The first thing this function does is run
7ee72033 2764the normal hook `change-major-mode-hook'. */)
5842a27b 2765 (void)
1ab256cb 2766{
dee091a3 2767 Frun_hooks (1, &Qchange_major_mode_hook);
1ab256cb 2768
3709505e 2769 /* Make sure none of the bindings in local_var_alist
2f3f993b 2770 remain swapped in, in their symbols. */
1ab256cb 2771
2f3f993b 2772 swap_out_buffer_local_variables (current_buffer);
1ab256cb
RM
2773
2774 /* Actually eliminate all local bindings of this buffer. */
2775
13de9290 2776 reset_buffer_local_variables (current_buffer, 0);
1ab256cb 2777
1ab256cb
RM
2778 /* Force mode-line redisplay. Useful here because all major mode
2779 commands call this function. */
2780 update_mode_lines++;
2781
2782 return Qnil;
2783}
2f3f993b
RS
2784
2785/* Make sure no local variables remain set up with buffer B
2786 for their current values. */
2787
2788static void
d3da34e0 2789swap_out_buffer_local_variables (struct buffer *b)
2f3f993b 2790{
ce5b453a 2791 Lisp_Object oalist, alist, buffer;
2f3f993b
RS
2792
2793 XSETBUFFER (buffer, b);
4b4deea2 2794 oalist = BVAR (b, local_var_alist);
2f3f993b 2795
67ee9f6e 2796 for (alist = oalist; CONSP (alist); alist = XCDR (alist))
2f3f993b 2797 {
ce5b453a
SM
2798 Lisp_Object sym = XCAR (XCAR (alist));
2799 eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED);
2800 /* Need not do anything if some other buffer's binding is
e4769531 2801 now cached. */
ce5b453a 2802 if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
2f3f993b 2803 {
e7c10f83
SM
2804 /* Symbol is set up for this buffer's old local value:
2805 swap it out! */
ce5b453a 2806 swap_in_global_binding (XSYMBOL (sym));
2f3f993b
RS
2807 }
2808 }
2809}
1ab256cb 2810\f
2eec3b4e 2811/* Find all the overlays in the current buffer that contain position POS.
177c0ea7 2812 Return the number found, and store them in a vector in *VEC_PTR.
2eec3b4e 2813 Store in *LEN_PTR the size allocated for the vector.
52f8ec73 2814 Store in *NEXT_PTR the next position after POS where an overlay starts,
624d2678 2815 or ZV if there are no more overlays between POS and ZV.
bbbe9545 2816 Store in *PREV_PTR the previous position before POS where an overlay ends,
413e06a4 2817 or where an overlay starts which ends at or after POS;
624d2678 2818 or BEGV if there are no such overlays from BEGV to POS.
239c932b 2819 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
2eec3b4e
RS
2820
2821 *VEC_PTR and *LEN_PTR should contain a valid vector and size
61d54cd5
RS
2822 when this function is called.
2823
2824 If EXTEND is non-zero, we make the vector bigger if necessary.
2825 If EXTEND is zero, we never extend the vector,
2826 and we store only as many overlays as will fit.
ac869cf7
MB
2827 But we still return the total number of overlays.
2828
2829 If CHANGE_REQ is true, then any position written into *PREV_PTR or
2830 *NEXT_PTR is guaranteed to be not equal to POS, unless it is the
2831 default (BEGV or ZV). */
2eec3b4e 2832
b081724f
PE
2833ptrdiff_t
2834overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr,
2835 ptrdiff_t *len_ptr,
d311d28c 2836 ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, int change_req)
1ab256cb 2837{
2410d73a
SM
2838 Lisp_Object overlay, start, end;
2839 struct Lisp_Overlay *tail;
b081724f
PE
2840 ptrdiff_t idx = 0;
2841 ptrdiff_t len = *len_ptr;
2eec3b4e 2842 Lisp_Object *vec = *vec_ptr;
d311d28c
PE
2843 ptrdiff_t next = ZV;
2844 ptrdiff_t prev = BEGV;
61d54cd5
RS
2845 int inhibit_storing = 0;
2846
fd318b54 2847 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
2eec3b4e 2848 {
d311d28c 2849 ptrdiff_t startpos, endpos;
52f8ec73 2850
2410d73a 2851 XSETMISC (overlay, tail);
1ab256cb 2852
2eec3b4e
RS
2853 start = OVERLAY_START (overlay);
2854 end = OVERLAY_END (overlay);
239c932b
RS
2855 endpos = OVERLAY_POSITION (end);
2856 if (endpos < pos)
2857 {
2858 if (prev < endpos)
2859 prev = endpos;
2860 break;
2861 }
413e06a4
RS
2862 startpos = OVERLAY_POSITION (start);
2863 /* This one ends at or after POS
daa1c109 2864 so its start counts for PREV_PTR if it's before POS. */
413e06a4
RS
2865 if (prev < startpos && startpos < pos)
2866 prev = startpos;
239c932b
RS
2867 if (endpos == pos)
2868 continue;
2eec3b4e
RS
2869 if (startpos <= pos)
2870 {
2871 if (idx == len)
2872 {
61d54cd5
RS
2873 /* The supplied vector is full.
2874 Either make it bigger, or don't store any more in it. */
2875 if (extend)
2876 {
0065d054
PE
2877 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
2878 sizeof *vec);
61d54cd5 2879 *vec_ptr = vec;
0065d054 2880 len = *len_ptr;
61d54cd5
RS
2881 }
2882 else
2883 inhibit_storing = 1;
2eec3b4e 2884 }
61d54cd5
RS
2885
2886 if (!inhibit_storing)
2887 vec[idx] = overlay;
2888 /* Keep counting overlays even if we can't return them all. */
2889 idx++;
2eec3b4e
RS
2890 }
2891 else if (startpos < next)
2892 next = startpos;
2893 }
2894
fd318b54 2895 for (tail = current_buffer->overlays_after; tail; tail = tail->next)
1ab256cb 2896 {
d311d28c 2897 ptrdiff_t startpos, endpos;
52f8ec73 2898
2410d73a 2899 XSETMISC (overlay, tail);
2eec3b4e
RS
2900
2901 start = OVERLAY_START (overlay);
2902 end = OVERLAY_END (overlay);
2903 startpos = OVERLAY_POSITION (start);
52f8ec73 2904 if (pos < startpos)
2eec3b4e
RS
2905 {
2906 if (startpos < next)
2907 next = startpos;
2908 break;
2909 }
239c932b
RS
2910 endpos = OVERLAY_POSITION (end);
2911 if (pos < endpos)
2eec3b4e
RS
2912 {
2913 if (idx == len)
2914 {
61d54cd5
RS
2915 if (extend)
2916 {
0065d054
PE
2917 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
2918 sizeof *vec);
61d54cd5 2919 *vec_ptr = vec;
0065d054 2920 len = *len_ptr;
61d54cd5
RS
2921 }
2922 else
2923 inhibit_storing = 1;
2eec3b4e 2924 }
61d54cd5
RS
2925
2926 if (!inhibit_storing)
2927 vec[idx] = overlay;
2928 idx++;
413e06a4
RS
2929
2930 if (startpos < pos && startpos > prev)
2931 prev = startpos;
2eec3b4e 2932 }
239c932b
RS
2933 else if (endpos < pos && endpos > prev)
2934 prev = endpos;
1d5f4c1d
MB
2935 else if (endpos == pos && startpos > prev
2936 && (!change_req || startpos < pos))
413e06a4 2937 prev = startpos;
1ab256cb
RM
2938 }
2939
239c932b
RS
2940 if (next_ptr)
2941 *next_ptr = next;
2942 if (prev_ptr)
2943 *prev_ptr = prev;
2eec3b4e
RS
2944 return idx;
2945}
74514898 2946\f
7723e095
MR
2947/* Find all the overlays in the current buffer that overlap the range
2948 BEG-END, or are empty at BEG, or are empty at END provided END
2949 denotes the position at the end of the current buffer.
2a3eeee7 2950
177c0ea7 2951 Return the number found, and store them in a vector in *VEC_PTR.
74514898
RS
2952 Store in *LEN_PTR the size allocated for the vector.
2953 Store in *NEXT_PTR the next position after POS where an overlay starts,
2954 or ZV if there are no more overlays.
2955 Store in *PREV_PTR the previous position before POS where an overlay ends,
2956 or BEGV if there are no previous overlays.
2957 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
2958
2959 *VEC_PTR and *LEN_PTR should contain a valid vector and size
2960 when this function is called.
2961
2962 If EXTEND is non-zero, we make the vector bigger if necessary.
2963 If EXTEND is zero, we never extend the vector,
2964 and we store only as many overlays as will fit.
2965 But we still return the total number of overlays. */
2966
21514da7 2967static ptrdiff_t
145582a0 2968overlays_in (EMACS_INT beg, EMACS_INT end, int extend,
21514da7 2969 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
d311d28c 2970 ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr)
74514898 2971{
2410d73a
SM
2972 Lisp_Object overlay, ostart, oend;
2973 struct Lisp_Overlay *tail;
21514da7
PE
2974 ptrdiff_t idx = 0;
2975 ptrdiff_t len = *len_ptr;
74514898 2976 Lisp_Object *vec = *vec_ptr;
d311d28c
PE
2977 ptrdiff_t next = ZV;
2978 ptrdiff_t prev = BEGV;
74514898 2979 int inhibit_storing = 0;
7723e095 2980 int end_is_Z = end == Z;
74514898 2981
fd318b54 2982 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
74514898 2983 {
d311d28c 2984 ptrdiff_t startpos, endpos;
74514898 2985
2410d73a 2986 XSETMISC (overlay, tail);
74514898
RS
2987
2988 ostart = OVERLAY_START (overlay);
2989 oend = OVERLAY_END (overlay);
2990 endpos = OVERLAY_POSITION (oend);
2991 if (endpos < beg)
2992 {
2993 if (prev < endpos)
2994 prev = endpos;
2995 break;
2996 }
2997 startpos = OVERLAY_POSITION (ostart);
7723e095
MR
2998 /* Count an interval if it overlaps the range, is empty at the
2999 start of the range, or is empty at END provided END denotes the
3000 end of the buffer. */
74514898 3001 if ((beg < endpos && startpos < end)
7723e095
MR
3002 || (startpos == endpos
3003 && (beg == endpos || (end_is_Z && endpos == end))))
74514898
RS
3004 {
3005 if (idx == len)
3006 {
3007 /* The supplied vector is full.
3008 Either make it bigger, or don't store any more in it. */
3009 if (extend)
3010 {
0065d054
PE
3011 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
3012 sizeof *vec);
74514898 3013 *vec_ptr = vec;
0065d054 3014 len = *len_ptr;
74514898
RS
3015 }
3016 else
3017 inhibit_storing = 1;
3018 }
3019
3020 if (!inhibit_storing)
3021 vec[idx] = overlay;
3022 /* Keep counting overlays even if we can't return them all. */
3023 idx++;
3024 }
3025 else if (startpos < next)
3026 next = startpos;
3027 }
3028
fd318b54 3029 for (tail = current_buffer->overlays_after; tail; tail = tail->next)
74514898 3030 {
d311d28c 3031 ptrdiff_t startpos, endpos;
74514898 3032
2410d73a 3033 XSETMISC (overlay, tail);
74514898
RS
3034
3035 ostart = OVERLAY_START (overlay);
3036 oend = OVERLAY_END (overlay);
3037 startpos = OVERLAY_POSITION (ostart);
3038 if (end < startpos)
3039 {
3040 if (startpos < next)
3041 next = startpos;
3042 break;
3043 }
3044 endpos = OVERLAY_POSITION (oend);
7723e095
MR
3045 /* Count an interval if it overlaps the range, is empty at the
3046 start of the range, or is empty at END provided END denotes the
3047 end of the buffer. */
74514898 3048 if ((beg < endpos && startpos < end)
7723e095
MR
3049 || (startpos == endpos
3050 && (beg == endpos || (end_is_Z && endpos == end))))
74514898
RS
3051 {
3052 if (idx == len)
3053 {
3054 if (extend)
3055 {
0065d054
PE
3056 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
3057 sizeof *vec);
74514898 3058 *vec_ptr = vec;
0065d054 3059 len = *len_ptr;
74514898
RS
3060 }
3061 else
3062 inhibit_storing = 1;
3063 }
3064
3065 if (!inhibit_storing)
3066 vec[idx] = overlay;
3067 idx++;
3068 }
3069 else if (endpos < beg && endpos > prev)
3070 prev = endpos;
3071 }
fc04fa47 3072
74514898
RS
3073 if (next_ptr)
3074 *next_ptr = next;
3075 if (prev_ptr)
3076 *prev_ptr = prev;
3077 return idx;
3078}
09a22085
GM
3079
3080
3081/* Return non-zero if there exists an overlay with a non-nil
3082 `mouse-face' property overlapping OVERLAY. */
3083
3084int
d3da34e0 3085mouse_face_overlay_overlaps (Lisp_Object overlay)
09a22085 3086{
d311d28c
PE
3087 ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay));
3088 ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay));
21514da7 3089 ptrdiff_t n, i, size;
09a22085 3090 Lisp_Object *v, tem;
177c0ea7 3091
bfd8410f 3092 size = 10;
38182d90 3093 v = alloca (size * sizeof *v);
bfd8410f
GM
3094 n = overlays_in (start, end, 0, &v, &size, NULL, NULL);
3095 if (n > size)
09a22085 3096 {
38182d90 3097 v = alloca (n * sizeof *v);
09a22085
GM
3098 overlays_in (start, end, 0, &v, &n, NULL, NULL);
3099 }
3100
3101 for (i = 0; i < n; ++i)
3102 if (!EQ (v[i], overlay)
3103 && (tem = Foverlay_get (overlay, Qmouse_face),
3104 !NILP (tem)))
3105 break;
3106
3107 return i < n;
3108}
3109
3110
74514898 3111\f
fc04fa47
KH
3112/* Fast function to just test if we're at an overlay boundary. */
3113int
d311d28c 3114overlay_touches_p (ptrdiff_t pos)
fc04fa47 3115{
2410d73a
SM
3116 Lisp_Object overlay;
3117 struct Lisp_Overlay *tail;
fc04fa47 3118
fd318b54 3119 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
fc04fa47 3120 {
d311d28c 3121 ptrdiff_t endpos;
fc04fa47 3122
2410d73a 3123 XSETMISC (overlay ,tail);
22657b40 3124 eassert (OVERLAYP (overlay));
fc04fa47
KH
3125
3126 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3127 if (endpos < pos)
3128 break;
3129 if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos)
3130 return 1;
3131 }
3132
fd318b54 3133 for (tail = current_buffer->overlays_after; tail; tail = tail->next)
fc04fa47 3134 {
d311d28c 3135 ptrdiff_t startpos;
fc04fa47 3136
2410d73a 3137 XSETMISC (overlay, tail);
22657b40 3138 eassert (OVERLAYP (overlay));
fc04fa47
KH
3139
3140 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3141 if (pos < startpos)
3142 break;
3143 if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
3144 return 1;
3145 }
3146 return 0;
3147}
2eec3b4e 3148\f
5985d248
KH
3149struct sortvec
3150{
3151 Lisp_Object overlay;
d311d28c 3152 ptrdiff_t beg, end;
fadf4e30 3153 EMACS_INT priority;
5985d248
KH
3154};
3155
3156static int
d3da34e0 3157compare_overlays (const void *v1, const void *v2)
5985d248 3158{
dfcf069d
AS
3159 const struct sortvec *s1 = (const struct sortvec *) v1;
3160 const struct sortvec *s2 = (const struct sortvec *) v2;
5985d248 3161 if (s1->priority != s2->priority)
c20998a7 3162 return s1->priority < s2->priority ? -1 : 1;
5985d248 3163 if (s1->beg != s2->beg)
c20998a7 3164 return s1->beg < s2->beg ? -1 : 1;
5985d248 3165 if (s1->end != s2->end)
c20998a7 3166 return s2->end < s1->end ? -1 : 1;
cae07000
SM
3167 /* Avoid the non-determinism of qsort by choosing an arbitrary ordering
3168 between "equal" overlays. The result can still change between
3169 invocations of Emacs, but it won't change in the middle of
3170 `find_field' (bug#6830). */
9af5ed87
PE
3171 if (XHASH (s1->overlay) != XHASH (s2->overlay))
3172 return XHASH (s1->overlay) < XHASH (s2->overlay) ? -1 : 1;
5985d248
KH
3173 return 0;
3174}
3175
3176/* Sort an array of overlays by priority. The array is modified in place.
3177 The return value is the new size; this may be smaller than the original
3178 size if some of the overlays were invalid or were window-specific. */
b081724f
PE
3179ptrdiff_t
3180sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w)
5985d248 3181{
b081724f 3182 ptrdiff_t i, j;
38182d90 3183 struct sortvec *sortvec = alloca (noverlays * sizeof *sortvec);
5985d248
KH
3184
3185 /* Put the valid and relevant overlays into sortvec. */
3186
3187 for (i = 0, j = 0; i < noverlays; i++)
3188 {
0fa767e7 3189 Lisp_Object tem;
c99fc30f 3190 Lisp_Object overlay;
5985d248 3191
c99fc30f 3192 overlay = overlay_vec[i];
22657b40 3193 if (OVERLAYP (overlay)
5985d248
KH
3194 && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0
3195 && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0)
3196 {
0fa767e7
KH
3197 /* If we're interested in a specific window, then ignore
3198 overlays that are limited to some other window. */
3199 if (w)
5985d248 3200 {
28545e04 3201 Lisp_Object window;
0fa767e7
KH
3202
3203 window = Foverlay_get (overlay, Qwindow);
28545e04 3204 if (WINDOWP (window) && XWINDOW (window) != w)
0fa767e7 3205 continue;
5985d248 3206 }
0fa767e7
KH
3207
3208 /* This overlay is good and counts: put it into sortvec. */
3209 sortvec[j].overlay = overlay;
3210 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3211 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
3212 tem = Foverlay_get (overlay, Qpriority);
3213 if (INTEGERP (tem))
3214 sortvec[j].priority = XINT (tem);
3215 else
3216 sortvec[j].priority = 0;
3217 j++;
5985d248
KH
3218 }
3219 }
3220 noverlays = j;
3221
3222 /* Sort the overlays into the proper order: increasing priority. */
3223
3224 if (noverlays > 1)
3225 qsort (sortvec, noverlays, sizeof (struct sortvec), compare_overlays);
3226
3227 for (i = 0; i < noverlays; i++)
3228 overlay_vec[i] = sortvec[i].overlay;
3229 return (noverlays);
3230}
3231\f
bbbe9545
KH
3232struct sortstr
3233{
cb26008f 3234 Lisp_Object string, string2;
93cb6be3 3235 ptrdiff_t size;
8961a454 3236 EMACS_INT priority;
bbbe9545
KH
3237};
3238
e8185fa8
KH
3239struct sortstrlist
3240{
3241 struct sortstr *buf; /* An array that expands as needed; never freed. */
67c36fce
PE
3242 ptrdiff_t size; /* Allocated length of that array. */
3243 ptrdiff_t used; /* How much of the array is currently in use. */
0065d054 3244 ptrdiff_t bytes; /* Total length of the strings in buf. */
e8185fa8
KH
3245};
3246
3247/* Buffers for storing information about the overlays touching a given
3248 position. These could be automatic variables in overlay_strings, but
3249 it's more efficient to hold onto the memory instead of repeatedly
3250 allocating and freeing it. */
3251static struct sortstrlist overlay_heads, overlay_tails;
9492daf2 3252static unsigned char *overlay_str_buf;
e8185fa8
KH
3253
3254/* Allocated length of overlay_str_buf. */
fe5c5d37 3255static ptrdiff_t overlay_str_len;
e8185fa8 3256
bbbe9545
KH
3257/* A comparison function suitable for passing to qsort. */
3258static int
d3da34e0 3259cmp_for_strings (const void *as1, const void *as2)
bbbe9545
KH
3260{
3261 struct sortstr *s1 = (struct sortstr *)as1;
3262 struct sortstr *s2 = (struct sortstr *)as2;
3263 if (s1->size != s2->size)
c20998a7 3264 return s2->size < s1->size ? -1 : 1;
bbbe9545 3265 if (s1->priority != s2->priority)
c20998a7 3266 return s1->priority < s2->priority ? -1 : 1;
bbbe9545
KH
3267 return 0;
3268}
3269
e8185fa8 3270static void
93cb6be3
PE
3271record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
3272 Lisp_Object str2, Lisp_Object pri, ptrdiff_t size)
e8185fa8 3273{
d311d28c 3274 ptrdiff_t nbytes;
43d27a72 3275
e8185fa8 3276 if (ssl->used == ssl->size)
0065d054 3277 ssl->buf = xpalloc (ssl->buf, &ssl->size, 5, -1, sizeof *ssl->buf);
e8185fa8 3278 ssl->buf[ssl->used].string = str;
cb26008f 3279 ssl->buf[ssl->used].string2 = str2;
e8185fa8
KH
3280 ssl->buf[ssl->used].size = size;
3281 ssl->buf[ssl->used].priority = (INTEGERP (pri) ? XINT (pri) : 0);
3282 ssl->used++;
43d27a72 3283
4b4deea2 3284 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
d5db4077 3285 nbytes = SCHARS (str);
43d27a72 3286 else if (! STRING_MULTIBYTE (str))
d5db4077
KR
3287 nbytes = count_size_as_multibyte (SDATA (str),
3288 SBYTES (str));
43d27a72 3289 else
d5db4077 3290 nbytes = SBYTES (str);
43d27a72 3291
0065d054
PE
3292 if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
3293 memory_full (SIZE_MAX);
43d27a72
RS
3294 ssl->bytes += nbytes;
3295
cb26008f 3296 if (STRINGP (str2))
43d27a72 3297 {
4b4deea2 3298 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
d5db4077 3299 nbytes = SCHARS (str2);
43d27a72 3300 else if (! STRING_MULTIBYTE (str2))
d5db4077
KR
3301 nbytes = count_size_as_multibyte (SDATA (str2),
3302 SBYTES (str2));
43d27a72 3303 else
d5db4077 3304 nbytes = SBYTES (str2);
43d27a72 3305
0065d054
PE
3306 if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
3307 memory_full (SIZE_MAX);
43d27a72
RS
3308 ssl->bytes += nbytes;
3309 }
e8185fa8 3310}
bbbe9545
KH
3311
3312/* Return the concatenation of the strings associated with overlays that
3313 begin or end at POS, ignoring overlays that are specific to a window
3314 other than W. The strings are concatenated in the appropriate order:
3315 shorter overlays nest inside longer ones, and higher priority inside
cb26008f
KH
3316 lower. Normally all of the after-strings come first, but zero-sized
3317 overlays have their after-strings ride along with the before-strings
3318 because it would look strange to print them inside-out.
3319
3320 Returns the string length, and stores the contents indirectly through
3321 PSTR, if that variable is non-null. The string may be overwritten by
3322 subsequent calls. */
6b5d3b89 3323
d311d28c
PE
3324ptrdiff_t
3325overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
bbbe9545 3326{
28545e04 3327 Lisp_Object overlay, window, str;
2410d73a 3328 struct Lisp_Overlay *ov;
d311d28c 3329 ptrdiff_t startpos, endpos;
4b4deea2 3330 int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
bbbe9545 3331
e8185fa8
KH
3332 overlay_heads.used = overlay_heads.bytes = 0;
3333 overlay_tails.used = overlay_tails.bytes = 0;
fd318b54 3334 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
bbbe9545 3335 {
2410d73a 3336 XSETMISC (overlay, ov);
c2d5b10f 3337 eassert (OVERLAYP (overlay));
bbbe9545
KH
3338
3339 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3340 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3341 if (endpos < pos)
3342 break;
3343 if (endpos != pos && startpos != pos)
3344 continue;
3345 window = Foverlay_get (overlay, Qwindow);
28545e04 3346 if (WINDOWP (window) && XWINDOW (window) != w)
bbbe9545 3347 continue;
e8185fa8
KH
3348 if (startpos == pos
3349 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3350 record_overlay_string (&overlay_heads, str,
cb26008f
KH
3351 (startpos == endpos
3352 ? Foverlay_get (overlay, Qafter_string)
3353 : Qnil),
3354 Foverlay_get (overlay, Qpriority),
3355 endpos - startpos);
3356 else if (endpos == pos
3357 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
3358 record_overlay_string (&overlay_tails, str, Qnil,
e8185fa8
KH
3359 Foverlay_get (overlay, Qpriority),
3360 endpos - startpos);
bbbe9545 3361 }
fd318b54 3362 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
bbbe9545 3363 {
2410d73a
SM
3364 XSETMISC (overlay, ov);
3365 eassert (OVERLAYP (overlay));
bbbe9545
KH
3366
3367 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3368 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3369 if (startpos > pos)
3370 break;
e8185fa8
KH
3371 if (endpos != pos && startpos != pos)
3372 continue;
3373 window = Foverlay_get (overlay, Qwindow);
28545e04 3374 if (WINDOWP (window) && XWINDOW (window) != w)
e8185fa8 3375 continue;
e8185fa8
KH
3376 if (startpos == pos
3377 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3378 record_overlay_string (&overlay_heads, str,
cb26008f
KH
3379 (startpos == endpos
3380 ? Foverlay_get (overlay, Qafter_string)
3381 : Qnil),
3382 Foverlay_get (overlay, Qpriority),
3383 endpos - startpos);
3384 else if (endpos == pos
3385 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
3386 record_overlay_string (&overlay_tails, str, Qnil,
e8185fa8
KH
3387 Foverlay_get (overlay, Qpriority),
3388 endpos - startpos);
bbbe9545 3389 }
e8185fa8
KH
3390 if (overlay_tails.used > 1)
3391 qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr),
3392 cmp_for_strings);
3393 if (overlay_heads.used > 1)
3394 qsort (overlay_heads.buf, overlay_heads.used, sizeof (struct sortstr),
3395 cmp_for_strings);
3396 if (overlay_heads.bytes || overlay_tails.bytes)
bbbe9545 3397 {
e8185fa8 3398 Lisp_Object tem;
d311d28c 3399 ptrdiff_t i;
9f4d7cde 3400 unsigned char *p;
0065d054 3401 ptrdiff_t total;
bbbe9545 3402
0065d054
PE
3403 if (INT_ADD_OVERFLOW (overlay_heads.bytes, overlay_tails.bytes))
3404 memory_full (SIZE_MAX);
3405 total = overlay_heads.bytes + overlay_tails.bytes;
bbbe9545 3406 if (total > overlay_str_len)
0065d054
PE
3407 overlay_str_buf = xpalloc (overlay_str_buf, &overlay_str_len,
3408 total - overlay_str_len, -1, 1);
3409
bbbe9545 3410 p = overlay_str_buf;
e8185fa8 3411 for (i = overlay_tails.used; --i >= 0;)
bbbe9545 3412 {
d311d28c 3413 ptrdiff_t nbytes;
e8185fa8 3414 tem = overlay_tails.buf[i].string;
d5db4077
KR
3415 nbytes = copy_text (SDATA (tem), p,
3416 SBYTES (tem),
43d27a72
RS
3417 STRING_MULTIBYTE (tem), multibyte);
3418 p += nbytes;
bbbe9545 3419 }
e8185fa8 3420 for (i = 0; i < overlay_heads.used; ++i)
bbbe9545 3421 {
d311d28c 3422 ptrdiff_t nbytes;
e8185fa8 3423 tem = overlay_heads.buf[i].string;
d5db4077
KR
3424 nbytes = copy_text (SDATA (tem), p,
3425 SBYTES (tem),
43d27a72
RS
3426 STRING_MULTIBYTE (tem), multibyte);
3427 p += nbytes;
cb26008f
KH
3428 tem = overlay_heads.buf[i].string2;
3429 if (STRINGP (tem))
3430 {
d5db4077
KR
3431 nbytes = copy_text (SDATA (tem), p,
3432 SBYTES (tem),
43d27a72
RS
3433 STRING_MULTIBYTE (tem), multibyte);
3434 p += nbytes;
cb26008f 3435 }
bbbe9545 3436 }
cb26008f
KH
3437 if (p != overlay_str_buf + total)
3438 abort ();
bbbe9545
KH
3439 if (pstr)
3440 *pstr = overlay_str_buf;
e8185fa8 3441 return total;
bbbe9545 3442 }
e8185fa8 3443 return 0;
bbbe9545
KH
3444}
3445\f
5c4f68f1 3446/* Shift overlays in BUF's overlay lists, to center the lists at POS. */
1ab256cb 3447
2eec3b4e 3448void
d311d28c 3449recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
2eec3b4e 3450{
2410d73a
SM
3451 Lisp_Object overlay, beg, end;
3452 struct Lisp_Overlay *prev, *tail, *next;
2eec3b4e
RS
3453
3454 /* See if anything in overlays_before should move to overlays_after. */
3455
3456 /* We don't strictly need prev in this loop; it should always be nil.
3457 But we use it for symmetry and in case that should cease to be true
3458 with some future change. */
2410d73a 3459 prev = NULL;
fd318b54 3460 for (tail = buf->overlays_before; tail; prev = tail, tail = next)
1ab256cb 3461 {
2410d73a
SM
3462 next = tail->next;
3463 XSETMISC (overlay, tail);
22657b40 3464 eassert (OVERLAYP (overlay));
1ab256cb 3465
2eec3b4e
RS
3466 beg = OVERLAY_START (overlay);
3467 end = OVERLAY_END (overlay);
1ab256cb 3468
2eec3b4e 3469 if (OVERLAY_POSITION (end) > pos)
1ab256cb 3470 {
2eec3b4e 3471 /* OVERLAY needs to be moved. */
d311d28c 3472 ptrdiff_t where = OVERLAY_POSITION (beg);
2410d73a 3473 struct Lisp_Overlay *other, *other_prev;
2eec3b4e
RS
3474
3475 /* Splice the cons cell TAIL out of overlays_before. */
2410d73a
SM
3476 if (prev)
3477 prev->next = next;
2eec3b4e 3478 else
0c94c8d6 3479 set_buffer_overlays_before (buf, next);
2eec3b4e
RS
3480
3481 /* Search thru overlays_after for where to put it. */
2410d73a 3482 other_prev = NULL;
fd318b54 3483 for (other = buf->overlays_after; other;
2410d73a 3484 other_prev = other, other = other->next)
1ab256cb 3485 {
6af718a4 3486 Lisp_Object otherbeg, otheroverlay;
2eec3b4e 3487
2410d73a 3488 XSETMISC (otheroverlay, other);
22657b40 3489 eassert (OVERLAYP (otheroverlay));
2eec3b4e
RS
3490
3491 otherbeg = OVERLAY_START (otheroverlay);
3492 if (OVERLAY_POSITION (otherbeg) >= where)
3493 break;
1ab256cb 3494 }
2eec3b4e
RS
3495
3496 /* Add TAIL to overlays_after before OTHER. */
2410d73a
SM
3497 tail->next = other;
3498 if (other_prev)
3499 other_prev->next = tail;
1ab256cb 3500 else
0c94c8d6 3501 set_buffer_overlays_after (buf, tail);
2eec3b4e 3502 tail = prev;
1ab256cb 3503 }
2eec3b4e
RS
3504 else
3505 /* We've reached the things that should stay in overlays_before.
3506 All the rest of overlays_before must end even earlier,
3507 so stop now. */
3508 break;
3509 }
3510
3511 /* See if anything in overlays_after should be in overlays_before. */
2410d73a 3512 prev = NULL;
fd318b54 3513 for (tail = buf->overlays_after; tail; prev = tail, tail = next)
2eec3b4e 3514 {
2410d73a
SM
3515 next = tail->next;
3516 XSETMISC (overlay, tail);
22657b40 3517 eassert (OVERLAYP (overlay));
2eec3b4e
RS
3518
3519 beg = OVERLAY_START (overlay);
3520 end = OVERLAY_END (overlay);
3521
3522 /* Stop looking, when we know that nothing further
3523 can possibly end before POS. */
3524 if (OVERLAY_POSITION (beg) > pos)
3525 break;
3526
3527 if (OVERLAY_POSITION (end) <= pos)
3528 {
3529 /* OVERLAY needs to be moved. */
d311d28c 3530 ptrdiff_t where = OVERLAY_POSITION (end);
2410d73a 3531 struct Lisp_Overlay *other, *other_prev;
2eec3b4e
RS
3532
3533 /* Splice the cons cell TAIL out of overlays_after. */
2410d73a
SM
3534 if (prev)
3535 prev->next = next;
2eec3b4e 3536 else
0c94c8d6 3537 set_buffer_overlays_after (buf, next);
2eec3b4e
RS
3538
3539 /* Search thru overlays_before for where to put it. */
2410d73a 3540 other_prev = NULL;
fd318b54 3541 for (other = buf->overlays_before; other;
2410d73a 3542 other_prev = other, other = other->next)
2eec3b4e
RS
3543 {
3544 Lisp_Object otherend, otheroverlay;
2eec3b4e 3545
2410d73a 3546 XSETMISC (otheroverlay, other);
22657b40 3547 eassert (OVERLAYP (otheroverlay));
2eec3b4e
RS
3548
3549 otherend = OVERLAY_END (otheroverlay);
3550 if (OVERLAY_POSITION (otherend) <= where)
3551 break;
3552 }
3553
3554 /* Add TAIL to overlays_before before OTHER. */
2410d73a
SM
3555 tail->next = other;
3556 if (other_prev)
3557 other_prev->next = tail;
2eec3b4e 3558 else
0c94c8d6 3559 set_buffer_overlays_before (buf, tail);
2eec3b4e
RS
3560 tail = prev;
3561 }
3562 }
3563
c2d5b10f 3564 buf->overlay_center = pos;
2eec3b4e 3565}
2b1bdf65 3566
423cdb46 3567void
d311d28c 3568adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length)
423cdb46
KH
3569{
3570 /* After an insertion, the lists are still sorted properly,
3571 but we may need to update the value of the overlay center. */
c2d5b10f
SM
3572 if (current_buffer->overlay_center >= pos)
3573 current_buffer->overlay_center += length;
423cdb46
KH
3574}
3575
3576void
d311d28c 3577adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
423cdb46 3578{
c2d5b10f 3579 if (current_buffer->overlay_center < pos)
423cdb46
KH
3580 /* The deletion was to our right. No change needed; the before- and
3581 after-lists are still consistent. */
3582 ;
d311d28c 3583 else if (current_buffer->overlay_center - pos > length)
423cdb46
KH
3584 /* The deletion was to our left. We need to adjust the center value
3585 to account for the change in position, but the lists are consistent
3586 given the new value. */
c2d5b10f 3587 current_buffer->overlay_center -= length;
423cdb46
KH
3588 else
3589 /* We're right in the middle. There might be things on the after-list
3590 that now belong on the before-list. Recentering will move them,
3591 and also update the center point. */
3592 recenter_overlay_lists (current_buffer, pos);
3593}
3594
2b1bdf65
KH
3595/* Fix up overlays that were garbled as a result of permuting markers
3596 in the range START through END. Any overlay with at least one
3597 endpoint in this range will need to be unlinked from the overlay
3598 list and reinserted in its proper place.
3599 Such an overlay might even have negative size at this point.
6b61353c 3600 If so, we'll make the overlay empty. */
2b1bdf65 3601void
d311d28c 3602fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
2b1bdf65 3603{
6af718a4 3604 Lisp_Object overlay;
5df8f01b
PE
3605 struct Lisp_Overlay *before_list IF_LINT (= NULL);
3606 struct Lisp_Overlay *after_list IF_LINT (= NULL);
1138e742
KR
3607 /* These are either nil, indicating that before_list or after_list
3608 should be assigned, or the cons cell the cdr of which should be
3609 assigned. */
2410d73a 3610 struct Lisp_Overlay *beforep = NULL, *afterp = NULL;
1138e742 3611 /* 'Parent', likewise, indicates a cons cell or
fd318b54 3612 current_buffer->overlays_before or overlays_after, depending
1138e742 3613 which loop we're in. */
2410d73a 3614 struct Lisp_Overlay *tail, *parent;
d311d28c 3615 ptrdiff_t startpos, endpos;
2b1bdf65
KH
3616
3617 /* This algorithm shifts links around instead of consing and GCing.
3618 The loop invariant is that before_list (resp. after_list) is a
1138e742
KR
3619 well-formed list except that its last element, the CDR of beforep
3620 (resp. afterp) if beforep (afterp) isn't nil or before_list
3621 (after_list) if it is, is still uninitialized. So it's not a bug
3622 that before_list isn't initialized, although it may look
3623 strange. */
fd318b54 3624 for (parent = NULL, tail = current_buffer->overlays_before; tail;)
2b1bdf65 3625 {
2410d73a 3626 XSETMISC (overlay, tail);
6b61353c 3627
2b1bdf65 3628 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
6b61353c
KH
3629 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3630
3631 /* If the overlay is backwards, make it empty. */
3632 if (endpos < startpos)
3633 {
3634 startpos = endpos;
3635 Fset_marker (OVERLAY_START (overlay), make_number (startpos),
3636 Qnil);
3637 }
3638
2b1bdf65
KH
3639 if (endpos < start)
3640 break;
60ebfdf3 3641
2b1bdf65
KH
3642 if (endpos < end
3643 || (startpos >= start && startpos < end))
3644 {
2b1bdf65
KH
3645 /* Add it to the end of the wrong list. Later on,
3646 recenter_overlay_lists will move it to the right place. */
c2d5b10f 3647 if (endpos < current_buffer->overlay_center)
2b1bdf65 3648 {
2410d73a 3649 if (!afterp)
1138e742
KR
3650 after_list = tail;
3651 else
2410d73a 3652 afterp->next = tail;
1138e742 3653 afterp = tail;
2b1bdf65
KH
3654 }
3655 else
3656 {
2410d73a 3657 if (!beforep)
1138e742
KR
3658 before_list = tail;
3659 else
2410d73a 3660 beforep->next = tail;
1138e742 3661 beforep = tail;
2b1bdf65 3662 }
2410d73a 3663 if (!parent)
0c94c8d6 3664 set_buffer_overlays_before (current_buffer, tail->next);
1138e742 3665 else
2410d73a
SM
3666 parent->next = tail->next;
3667 tail = tail->next;
2b1bdf65
KH
3668 }
3669 else
2410d73a 3670 parent = tail, tail = parent->next;
2b1bdf65 3671 }
fd318b54 3672 for (parent = NULL, tail = current_buffer->overlays_after; tail;)
2b1bdf65 3673 {
2410d73a 3674 XSETMISC (overlay, tail);
6b61353c 3675
2b1bdf65 3676 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
6b61353c
KH
3677 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3678
3679 /* If the overlay is backwards, make it empty. */
3680 if (endpos < startpos)
3681 {
3682 startpos = endpos;
3683 Fset_marker (OVERLAY_START (overlay), make_number (startpos),
60ebfdf3 3684 Qnil);
6b61353c
KH
3685 }
3686
2b1bdf65
KH
3687 if (startpos >= end)
3688 break;
6b61353c 3689
2b1bdf65
KH
3690 if (startpos >= start
3691 || (endpos >= start && endpos < end))
3692 {
c2d5b10f 3693 if (endpos < current_buffer->overlay_center)
2b1bdf65 3694 {
2410d73a 3695 if (!afterp)
1138e742
KR
3696 after_list = tail;
3697 else
2410d73a 3698 afterp->next = tail;
1138e742 3699 afterp = tail;
2b1bdf65
KH
3700 }
3701 else
3702 {
2410d73a 3703 if (!beforep)
1138e742
KR
3704 before_list = tail;
3705 else
2410d73a 3706 beforep->next = tail;
1138e742 3707 beforep = tail;
2b1bdf65 3708 }
2410d73a 3709 if (!parent)
0c94c8d6 3710 set_buffer_overlays_after (current_buffer, tail->next);
1138e742 3711 else
2410d73a
SM
3712 parent->next = tail->next;
3713 tail = tail->next;
2b1bdf65
KH
3714 }
3715 else
2410d73a 3716 parent = tail, tail = parent->next;
2b1bdf65
KH
3717 }
3718
3719 /* Splice the constructed (wrong) lists into the buffer's lists,
3720 and let the recenter function make it sane again. */
2410d73a 3721 if (beforep)
1138e742 3722 {
fd318b54 3723 beforep->next = current_buffer->overlays_before;
0c94c8d6 3724 set_buffer_overlays_before (current_buffer, before_list);
1138e742 3725 }
c2d5b10f 3726 recenter_overlay_lists (current_buffer, current_buffer->overlay_center);
2b1bdf65 3727
2410d73a 3728 if (afterp)
1138e742 3729 {
fd318b54 3730 afterp->next = current_buffer->overlays_after;
0c94c8d6 3731 set_buffer_overlays_after (current_buffer, after_list);
1138e742 3732 }
c2d5b10f 3733 recenter_overlay_lists (current_buffer, current_buffer->overlay_center);
2b1bdf65 3734}
3b06f880
KH
3735
3736/* We have two types of overlay: the one whose ending marker is
3737 after-insertion-marker (this is the usual case) and the one whose
3738 ending marker is before-insertion-marker. When `overlays_before'
3739 contains overlays of the latter type and the former type in this
3740 order and both overlays end at inserting position, inserting a text
3741 increases only the ending marker of the latter type, which results
3742 in incorrect ordering of `overlays_before'.
3743
3744 This function fixes ordering of overlays in the slot
3745 `overlays_before' of the buffer *BP. Before the insertion, `point'
3746 was at PREV, and now is at POS. */
3747
01136e9b 3748void
d311d28c 3749fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos)
3b06f880 3750{
2410d73a 3751 /* If parent is nil, replace overlays_before; otherwise, parent->next. */
fd318b54 3752 struct Lisp_Overlay *tail = bp->overlays_before, *parent = NULL, *right_pair;
2410d73a 3753 Lisp_Object tem;
d311d28c 3754 ptrdiff_t end IF_LINT (= 0);
3b06f880
KH
3755
3756 /* After the insertion, the several overlays may be in incorrect
3757 order. The possibility is that, in the list `overlays_before',
3758 an overlay which ends at POS appears after an overlay which ends
3759 at PREV. Since POS is greater than PREV, we must fix the
3760 ordering of these overlays, by moving overlays ends at POS before
3761 the overlays ends at PREV. */
3762
3763 /* At first, find a place where disordered overlays should be linked
3764 in. It is where an overlay which end before POS exists. (i.e. an
3765 overlay whose ending marker is after-insertion-marker if disorder
3766 exists). */
2410d73a
SM
3767 while (tail
3768 && (XSETMISC (tem, tail),
3769 (end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos))
1138e742
KR
3770 {
3771 parent = tail;
2410d73a 3772 tail = tail->next;
1138e742 3773 }
3b06f880
KH
3774
3775 /* If we don't find such an overlay,
3776 or the found one ends before PREV,
3777 or the found one is the last one in the list,
3778 we don't have to fix anything. */
f93ad4cf 3779 if (!tail || end < prev || !tail->next)
3b06f880
KH
3780 return;
3781
1138e742
KR
3782 right_pair = parent;
3783 parent = tail;
2410d73a 3784 tail = tail->next;
3b06f880 3785
1138e742 3786 /* Now, end position of overlays in the list TAIL should be before
3b06f880 3787 or equal to PREV. In the loop, an overlay which ends at POS is
1138e742
KR
3788 moved ahead to the place indicated by the CDR of RIGHT_PAIR. If
3789 we found an overlay which ends before PREV, the remaining
3790 overlays are in correct order. */
2410d73a 3791 while (tail)
3b06f880 3792 {
2410d73a
SM
3793 XSETMISC (tem, tail);
3794 end = OVERLAY_POSITION (OVERLAY_END (tem));
3b06f880
KH
3795
3796 if (end == pos)
3797 { /* This overlay is disordered. */
2410d73a 3798 struct Lisp_Overlay *found = tail;
3b06f880
KH
3799
3800 /* Unlink the found overlay. */
2410d73a
SM
3801 tail = found->next;
3802 parent->next = tail;
1138e742
KR
3803 /* Move an overlay at RIGHT_PLACE to the next of the found one,
3804 and link it into the right place. */
2410d73a 3805 if (!right_pair)
1138e742 3806 {
fd318b54 3807 found->next = bp->overlays_before;
0c94c8d6 3808 set_buffer_overlays_before (bp, found);
1138e742
KR
3809 }
3810 else
3811 {
2410d73a
SM
3812 found->next = right_pair->next;
3813 right_pair->next = found;
1138e742 3814 }
3b06f880
KH
3815 }
3816 else if (end == prev)
1138e742
KR
3817 {
3818 parent = tail;
2410d73a 3819 tail = tail->next;
1138e742 3820 }
3b06f880
KH
3821 else /* No more disordered overlay. */
3822 break;
3823 }
3824}
2eec3b4e 3825\f
52f8ec73 3826DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
7ee72033 3827 doc: /* Return t if OBJECT is an overlay. */)
5842a27b 3828 (Lisp_Object object)
52f8ec73
JB
3829{
3830 return (OVERLAYP (object) ? Qt : Qnil);
3831}
3832
acac2700 3833DEFUN ("make-overlay", Fmake_overlay, Smake_overlay, 2, 5, 0,
7ee72033 3834 doc: /* Create a new overlay with range BEG to END in BUFFER.
018ba359
PJ
3835If omitted, BUFFER defaults to the current buffer.
3836BEG and END may be integers or markers.
a625ee20
RS
3837The fourth arg FRONT-ADVANCE, if non-nil, makes the marker
3838for the front of the overlay advance when text is inserted there
63af6055 3839\(which means the text *is not* included in the overlay).
a625ee20
RS
3840The fifth arg REAR-ADVANCE, if non-nil, makes the marker
3841for the rear of the overlay advance when text is inserted there
63af6055 3842\(which means the text *is* included in the overlay). */)
5842a27b 3843 (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer, Lisp_Object front_advance, Lisp_Object rear_advance)
2eec3b4e
RS
3844{
3845 Lisp_Object overlay;
5c4f68f1 3846 struct buffer *b;
2eec3b4e 3847
5c4f68f1 3848 if (NILP (buffer))
67180c6a 3849 XSETBUFFER (buffer, current_buffer);
883047b9 3850 else
b7826503 3851 CHECK_BUFFER (buffer);
883047b9
JB
3852 if (MARKERP (beg)
3853 && ! EQ (Fmarker_buffer (beg), buffer))
3854 error ("Marker points into wrong buffer");
3855 if (MARKERP (end)
3856 && ! EQ (Fmarker_buffer (end), buffer))
3857 error ("Marker points into wrong buffer");
2eec3b4e 3858
b7826503
PJ
3859 CHECK_NUMBER_COERCE_MARKER (beg);
3860 CHECK_NUMBER_COERCE_MARKER (end);
5c4f68f1 3861
883047b9 3862 if (XINT (beg) > XINT (end))
5c4f68f1 3863 {
c99fc30f
KH
3864 Lisp_Object temp;
3865 temp = beg; beg = end; end = temp;
5c4f68f1 3866 }
883047b9
JB
3867
3868 b = XBUFFER (buffer);
3869
3870 beg = Fset_marker (Fmake_marker (), beg, buffer);
3871 end = Fset_marker (Fmake_marker (), end, buffer);
5c4f68f1 3872
acac2700
RS
3873 if (!NILP (front_advance))
3874 XMARKER (beg)->insertion_type = 1;
3875 if (!NILP (rear_advance))
3876 XMARKER (end)->insertion_type = 1;
597dd755 3877
d7a7fda3 3878 overlay = build_overlay (beg, end, Qnil);
2eec3b4e 3879
177c0ea7 3880 /* Put the new overlay on the wrong list. */
2eec3b4e 3881 end = OVERLAY_END (overlay);
c2d5b10f 3882 if (OVERLAY_POSITION (end) < b->overlay_center)
2410d73a 3883 {
fd318b54
DA
3884 if (b->overlays_after)
3885 XOVERLAY (overlay)->next = b->overlays_after;
0c94c8d6 3886 set_buffer_overlays_after (b, XOVERLAY (overlay));
2410d73a 3887 }
2eec3b4e 3888 else
2410d73a 3889 {
fd318b54
DA
3890 if (b->overlays_before)
3891 XOVERLAY (overlay)->next = b->overlays_before;
0c94c8d6 3892 set_buffer_overlays_before (b, XOVERLAY (overlay));
2410d73a 3893 }
2eec3b4e
RS
3894
3895 /* This puts it in the right list, and in the right order. */
c2d5b10f 3896 recenter_overlay_lists (b, b->overlay_center);
2eec3b4e 3897
b61982dd
JB
3898 /* We don't need to redisplay the region covered by the overlay, because
3899 the overlay has no properties at the moment. */
3900
2eec3b4e
RS
3901 return overlay;
3902}
876aa27c
RS
3903\f
3904/* Mark a section of BUF as needing redisplay because of overlays changes. */
3905
3906static void
d311d28c 3907modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
876aa27c 3908{
876aa27c
RS
3909 if (start > end)
3910 {
d311d28c 3911 ptrdiff_t temp = start;
26f545d7
GM
3912 start = end;
3913 end = temp;
876aa27c
RS
3914 }
3915
481b5054 3916 BUF_COMPUTE_UNCHANGED (buf, start, end);
177c0ea7 3917
876aa27c
RS
3918 /* If this is a buffer not in the selected window,
3919 we must do other windows. */
d3d50620 3920 if (buf != XBUFFER (XWINDOW (selected_window)->buffer))
876aa27c 3921 windows_or_buffers_changed = 1;
876aa27c
RS
3922 /* If multiple windows show this buffer, we must do other windows. */
3923 else if (buffer_shared > 1)
3924 windows_or_buffers_changed = 1;
18700091
KS
3925 /* If we modify an overlay at the end of the buffer, we cannot
3926 be sure that window end is still valid. */
3927 else if (end >= ZV && start <= ZV)
3928 windows_or_buffers_changed = 1;
876aa27c 3929
d8b9150f 3930 ++BUF_OVERLAY_MODIFF (buf);
876aa27c 3931}
2eec3b4e 3932
7b7ae965
DA
3933/* Remove OVERLAY from LIST. */
3934
2410d73a 3935static struct Lisp_Overlay *
d3da34e0 3936unchain_overlay (struct Lisp_Overlay *list, struct Lisp_Overlay *overlay)
2410d73a 3937{
7b7ae965
DA
3938 register struct Lisp_Overlay *tail, **prev = &list;
3939
3940 for (tail = list; tail; prev = &tail->next, tail = *prev)
3941 if (tail == overlay)
2410d73a 3942 {
7b7ae965 3943 *prev = overlay->next;
2410d73a
SM
3944 overlay->next = NULL;
3945 break;
3946 }
3947 return list;
3948}
3949
4cb3e6b3
DA
3950/* Remove OVERLAY from both overlay lists of B. */
3951
3952static void
3953unchain_both (struct buffer *b, Lisp_Object overlay)
3954{
3955 struct Lisp_Overlay *ov = XOVERLAY (overlay);
3956
0c94c8d6
PE
3957 set_buffer_overlays_before (b, unchain_overlay (b->overlays_before, ov));
3958 set_buffer_overlays_after (b, unchain_overlay (b->overlays_after, ov));
fd318b54 3959 eassert (XOVERLAY (overlay)->next == NULL);
4cb3e6b3
DA
3960}
3961
5c4f68f1 3962DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
7ee72033 3963 doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER.
018ba359
PJ
3964If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.
3965If BUFFER is omitted, and OVERLAY is in no buffer, put it in the current
7ee72033 3966buffer. */)
5842a27b 3967 (Lisp_Object overlay, Lisp_Object beg, Lisp_Object end, Lisp_Object buffer)
2eec3b4e 3968{
471fe23d 3969 struct buffer *b, *ob = 0;
0a4469c9 3970 Lisp_Object obuffer;
d311d28c 3971 ptrdiff_t count = SPECPDL_INDEX ();
471fe23d 3972 ptrdiff_t n_beg, n_end, o_beg IF_LINT (= 0), o_end IF_LINT (= 0);
5c4f68f1 3973
b7826503 3974 CHECK_OVERLAY (overlay);
5c4f68f1
JB
3975 if (NILP (buffer))
3976 buffer = Fmarker_buffer (OVERLAY_START (overlay));
3ece337a 3977 if (NILP (buffer))
67180c6a 3978 XSETBUFFER (buffer, current_buffer);
b7826503 3979 CHECK_BUFFER (buffer);
883047b9 3980
471fe23d
TN
3981 if (NILP (Fbuffer_live_p (buffer)))
3982 error ("Attempt to move overlay to a dead buffer");
3983
883047b9
JB
3984 if (MARKERP (beg)
3985 && ! EQ (Fmarker_buffer (beg), buffer))
3986 error ("Marker points into wrong buffer");
3987 if (MARKERP (end)
3988 && ! EQ (Fmarker_buffer (end), buffer))
3989 error ("Marker points into wrong buffer");
3990
b7826503
PJ
3991 CHECK_NUMBER_COERCE_MARKER (beg);
3992 CHECK_NUMBER_COERCE_MARKER (end);
d311d28c 3993
471fe23d 3994 if (XINT (beg) > XINT (end))
02481186 3995 {
471fe23d
TN
3996 Lisp_Object temp;
3997 temp = beg; beg = end; end = temp;
02481186
PE
3998 }
3999
9d7608b7
KH
4000 specbind (Qinhibit_quit, Qt);
4001
0a4469c9 4002 obuffer = Fmarker_buffer (OVERLAY_START (overlay));
79cce3f2 4003 b = XBUFFER (buffer);
471fe23d
TN
4004
4005 if (!NILP (obuffer))
4006 {
4007 ob = XBUFFER (obuffer);
4008
4009 o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
4010 o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
4011
4cb3e6b3 4012 unchain_both (ob, overlay);
471fe23d
TN
4013 }
4014
4015 /* Set the overlay boundaries, which may clip them. */
4016 Fset_marker (OVERLAY_START (overlay), beg, buffer);
4017 Fset_marker (OVERLAY_END (overlay), end, buffer);
4018
4019 n_beg = marker_position (OVERLAY_START (overlay));
4020 n_end = marker_position (OVERLAY_END (overlay));
2eec3b4e 4021
c82ed728 4022 /* If the overlay has changed buffers, do a thorough redisplay. */
0a4469c9 4023 if (!EQ (buffer, obuffer))
50760c4a
RS
4024 {
4025 /* Redisplay where the overlay was. */
471fe23d
TN
4026 if (ob)
4027 modify_overlay (ob, o_beg, o_end);
50760c4a
RS
4028
4029 /* Redisplay where the overlay is going to be. */
79cce3f2 4030 modify_overlay (b, n_beg, n_end);
50760c4a 4031 }
c82ed728
JB
4032 else
4033 /* Redisplay the area the overlay has just left, or just enclosed. */
4034 {
79cce3f2
PE
4035 if (o_beg == n_beg)
4036 modify_overlay (b, o_end, n_end);
4037 else if (o_end == n_end)
4038 modify_overlay (b, o_beg, n_beg);
c82ed728 4039 else
79cce3f2 4040 modify_overlay (b, min (o_beg, n_beg), max (o_end, n_end));
c82ed728 4041 }
b61982dd 4042
471fe23d
TN
4043 /* Delete the overlay if it is empty after clipping and has the
4044 evaporate property. */
4045 if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate)))
4046 return unbind_to (count, Fdelete_overlay (overlay));
02481186 4047
471fe23d
TN
4048 /* Put the overlay into the new buffer's overlay lists, first on the
4049 wrong list. */
4050 if (n_end < b->overlay_center)
2410d73a 4051 {
fd318b54 4052 XOVERLAY (overlay)->next = b->overlays_after;
0c94c8d6 4053 set_buffer_overlays_after (b, XOVERLAY (overlay));
2410d73a 4054 }
2eec3b4e 4055 else
2410d73a 4056 {
fd318b54 4057 XOVERLAY (overlay)->next = b->overlays_before;
0c94c8d6 4058 set_buffer_overlays_before (b, XOVERLAY (overlay));
2410d73a 4059 }
2eec3b4e
RS
4060
4061 /* This puts it in the right list, and in the right order. */
c2d5b10f 4062 recenter_overlay_lists (b, b->overlay_center);
2eec3b4e 4063
0a4469c9 4064 return unbind_to (count, overlay);
2eec3b4e
RS
4065}
4066
4067DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
7ee72033 4068 doc: /* Delete the overlay OVERLAY from its buffer. */)
5842a27b 4069 (Lisp_Object overlay)
2eec3b4e 4070{
0a4469c9 4071 Lisp_Object buffer;
5c4f68f1 4072 struct buffer *b;
d311d28c 4073 ptrdiff_t count = SPECPDL_INDEX ();
5c4f68f1 4074
b7826503 4075 CHECK_OVERLAY (overlay);
52f8ec73 4076
0a4469c9
RS
4077 buffer = Fmarker_buffer (OVERLAY_START (overlay));
4078 if (NILP (buffer))
4079 return Qnil;
4080
4081 b = XBUFFER (buffer);
0a4469c9 4082 specbind (Qinhibit_quit, Qt);
177c0ea7 4083
4cb3e6b3 4084 unchain_both (b, overlay);
041a49a6 4085 drop_overlay (b, XOVERLAY (overlay));
3ece337a 4086
e58c389d 4087 /* When deleting an overlay with before or after strings, turn off
26f545d7
GM
4088 display optimizations for the affected buffer, on the basis that
4089 these strings may contain newlines. This is easier to do than to
4090 check for that situation during redisplay. */
4091 if (!windows_or_buffers_changed
4092 && (!NILP (Foverlay_get (overlay, Qbefore_string))
4093 || !NILP (Foverlay_get (overlay, Qafter_string))))
4094 b->prevent_redisplay_optimizations_p = 1;
4095
0a4469c9 4096 return unbind_to (count, Qnil);
2eec3b4e
RS
4097}
4098\f
8ebafa8d
JB
4099/* Overlay dissection functions. */
4100
a7ca3326 4101DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
7ee72033 4102 doc: /* Return the position at which OVERLAY starts. */)
5842a27b 4103 (Lisp_Object overlay)
8ebafa8d 4104{
b7826503 4105 CHECK_OVERLAY (overlay);
8ebafa8d
JB
4106
4107 return (Fmarker_position (OVERLAY_START (overlay)));
4108}
4109
a7ca3326 4110DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
7ee72033 4111 doc: /* Return the position at which OVERLAY ends. */)
5842a27b 4112 (Lisp_Object overlay)
8ebafa8d 4113{
b7826503 4114 CHECK_OVERLAY (overlay);
8ebafa8d
JB
4115
4116 return (Fmarker_position (OVERLAY_END (overlay)));
4117}
4118
4119DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
563f7128
LK
4120 doc: /* Return the buffer OVERLAY belongs to.
4121Return nil if OVERLAY has been deleted. */)
5842a27b 4122 (Lisp_Object overlay)
8ebafa8d 4123{
b7826503 4124 CHECK_OVERLAY (overlay);
8ebafa8d
JB
4125
4126 return Fmarker_buffer (OVERLAY_START (overlay));
4127}
4128
4129DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
7ee72033 4130 doc: /* Return a list of the properties on OVERLAY.
018ba359 4131This is a copy of OVERLAY's plist; modifying its conses has no effect on
7ee72033 4132OVERLAY. */)
5842a27b 4133 (Lisp_Object overlay)
8ebafa8d 4134{
b7826503 4135 CHECK_OVERLAY (overlay);
8ebafa8d 4136
c644523b 4137 return Fcopy_sequence (XOVERLAY (overlay)->plist);
8ebafa8d
JB
4138}
4139
4140\f
2eec3b4e 4141DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
aabc29c8 4142 doc: /* Return a list of the overlays that contain the character at POS. */)
5842a27b 4143 (Lisp_Object pos)
2eec3b4e 4144{
b081724f 4145 ptrdiff_t len, noverlays;
2eec3b4e 4146 Lisp_Object *overlay_vec;
2eec3b4e
RS
4147 Lisp_Object result;
4148
b7826503 4149 CHECK_NUMBER_COERCE_MARKER (pos);
2eec3b4e
RS
4150
4151 len = 10;
a9800ae8 4152 /* We can't use alloca here because overlays_at can call xrealloc. */
38182d90 4153 overlay_vec = xmalloc (len * sizeof *overlay_vec);
2eec3b4e
RS
4154
4155 /* Put all the overlays we want in a vector in overlay_vec.
4156 Store the length in len. */
2a77a7d7 4157 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
d311d28c 4158 0, 0, 0);
2eec3b4e
RS
4159
4160 /* Make a list of them all. */
4161 result = Flist (noverlays, overlay_vec);
4162
9ac0d9e0 4163 xfree (overlay_vec);
2eec3b4e
RS
4164 return result;
4165}
4166
74514898 4167DEFUN ("overlays-in", Foverlays_in, Soverlays_in, 2, 2, 0,
7ee72033 4168 doc: /* Return a list of the overlays that overlap the region BEG ... END.
018ba359
PJ
4169Overlap means that at least one character is contained within the overlay
4170and also contained within the specified region.
7723e095
MR
4171Empty overlays are included in the result if they are located at BEG,
4172between BEG and END, or at END provided END denotes the position at the
4173end of the buffer. */)
5842a27b 4174 (Lisp_Object beg, Lisp_Object end)
74514898 4175{
21514da7 4176 ptrdiff_t len, noverlays;
74514898 4177 Lisp_Object *overlay_vec;
74514898
RS
4178 Lisp_Object result;
4179
b7826503
PJ
4180 CHECK_NUMBER_COERCE_MARKER (beg);
4181 CHECK_NUMBER_COERCE_MARKER (end);
74514898
RS
4182
4183 len = 10;
38182d90 4184 overlay_vec = xmalloc (len * sizeof *overlay_vec);
74514898
RS
4185
4186 /* Put all the overlays we want in a vector in overlay_vec.
4187 Store the length in len. */
4188 noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len,
145582a0 4189 NULL, NULL);
74514898
RS
4190
4191 /* Make a list of them all. */
4192 result = Flist (noverlays, overlay_vec);
4193
4194 xfree (overlay_vec);
4195 return result;
4196}
4197
a7ca3326 4198DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change,
efc7e75f 4199 1, 1, 0,
7ee72033 4200 doc: /* Return the next position after POS where an overlay starts or ends.
624d2678
RS
4201If there are no overlay boundaries from POS to (point-max),
4202the value is (point-max). */)
5842a27b 4203 (Lisp_Object pos)
2eec3b4e 4204{
b081724f 4205 ptrdiff_t i, len, noverlays;
d311d28c 4206 ptrdiff_t endpos;
2eec3b4e 4207 Lisp_Object *overlay_vec;
2eec3b4e 4208
b7826503 4209 CHECK_NUMBER_COERCE_MARKER (pos);
2eec3b4e
RS
4210
4211 len = 10;
38182d90 4212 overlay_vec = xmalloc (len * sizeof *overlay_vec);
2eec3b4e
RS
4213
4214 /* Put all the overlays we want in a vector in overlay_vec.
4215 Store the length in len.
4216 endpos gets the position where the next overlay starts. */
2a77a7d7 4217 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
d311d28c 4218 &endpos, 0, 1);
2eec3b4e
RS
4219
4220 /* If any of these overlays ends before endpos,
4221 use its ending point instead. */
4222 for (i = 0; i < noverlays; i++)
4223 {
4224 Lisp_Object oend;
d311d28c 4225 ptrdiff_t oendpos;
2eec3b4e
RS
4226
4227 oend = OVERLAY_END (overlay_vec[i]);
4228 oendpos = OVERLAY_POSITION (oend);
4229 if (oendpos < endpos)
4230 endpos = oendpos;
1ab256cb
RM
4231 }
4232
9ac0d9e0 4233 xfree (overlay_vec);
2eec3b4e
RS
4234 return make_number (endpos);
4235}
239c932b 4236
a7ca3326 4237DEFUN ("previous-overlay-change", Fprevious_overlay_change,
239c932b 4238 Sprevious_overlay_change, 1, 1, 0,
7ee72033 4239 doc: /* Return the previous position before POS where an overlay starts or ends.
624d2678
RS
4240If there are no overlay boundaries from (point-min) to POS,
4241the value is (point-min). */)
5842a27b 4242 (Lisp_Object pos)
239c932b 4243{
d311d28c 4244 ptrdiff_t prevpos;
239c932b 4245 Lisp_Object *overlay_vec;
b081724f 4246 ptrdiff_t len;
239c932b 4247
b7826503 4248 CHECK_NUMBER_COERCE_MARKER (pos);
239c932b 4249
624bbdc4
RS
4250 /* At beginning of buffer, we know the answer;
4251 avoid bug subtracting 1 below. */
4252 if (XINT (pos) == BEGV)
4253 return pos;
4254
017f0539 4255 len = 10;
38182d90 4256 overlay_vec = xmalloc (len * sizeof *overlay_vec);
017f0539 4257
239c932b
RS
4258 /* Put all the overlays we want in a vector in overlay_vec.
4259 Store the length in len.
daa1c109 4260 prevpos gets the position of the previous change. */
328ab8e7 4261 overlays_at (XINT (pos), 1, &overlay_vec, &len,
d311d28c 4262 0, &prevpos, 1);
239c932b 4263
239c932b
RS
4264 xfree (overlay_vec);
4265 return make_number (prevpos);
4266}
2eec3b4e
RS
4267\f
4268/* These functions are for debugging overlays. */
4269
4270DEFUN ("overlay-lists", Foverlay_lists, Soverlay_lists, 0, 0, 0,
7ee72033 4271 doc: /* Return a pair of lists giving all the overlays of the current buffer.
018ba359
PJ
4272The car has all the overlays before the overlay center;
4273the cdr has all the overlays after the overlay center.
4274Recentering overlays moves overlays between these lists.
4275The lists you get are copies, so that changing them has no effect.
7ee72033 4276However, the overlays you get are the real objects that the buffer uses. */)
5842a27b 4277 (void)
2eec3b4e 4278{
2410d73a
SM
4279 struct Lisp_Overlay *ol;
4280 Lisp_Object before = Qnil, after = Qnil, tmp;
4cb3e6b3 4281
fd318b54 4282 for (ol = current_buffer->overlays_before; ol; ol = ol->next)
2410d73a
SM
4283 {
4284 XSETMISC (tmp, ol);
4285 before = Fcons (tmp, before);
4286 }
fd318b54 4287 for (ol = current_buffer->overlays_after; ol; ol = ol->next)
2410d73a
SM
4288 {
4289 XSETMISC (tmp, ol);
4290 after = Fcons (tmp, after);
4291 }
4cb3e6b3 4292
2410d73a 4293 return Fcons (Fnreverse (before), Fnreverse (after));
2eec3b4e
RS
4294}
4295
4296DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
c87426c5
RS
4297 doc: /* Recenter the overlays of the current buffer around position POS.
4298That makes overlay lookup faster for positions near POS (but perhaps slower
4299for positions far away from POS). */)
5842a27b 4300 (Lisp_Object pos)
2eec3b4e 4301{
d311d28c 4302 ptrdiff_t p;
b7826503 4303 CHECK_NUMBER_COERCE_MARKER (pos);
2eec3b4e 4304
d311d28c
PE
4305 p = clip_to_bounds (PTRDIFF_MIN, XINT (pos), PTRDIFF_MAX);
4306 recenter_overlay_lists (current_buffer, p);
2eec3b4e
RS
4307 return Qnil;
4308}
4309\f
a7ca3326 4310DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0,
7ee72033 4311 doc: /* Get the property of overlay OVERLAY with property name PROP. */)
5842a27b 4312 (Lisp_Object overlay, Lisp_Object prop)
2eec3b4e 4313{
b7826503 4314 CHECK_OVERLAY (overlay);
c644523b 4315 return lookup_char_property (XOVERLAY (overlay)->plist, prop, 0);
2eec3b4e
RS
4316}
4317
4318DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
7c301272
LMI
4319 doc: /* Set one property of overlay OVERLAY: give property PROP value VALUE.
4320VALUE will be returned.*/)
5842a27b 4321 (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value)
2eec3b4e 4322{
48e2e3ba 4323 Lisp_Object tail, buffer;
9d7608b7 4324 int changed;
2eec3b4e 4325
b7826503 4326 CHECK_OVERLAY (overlay);
b61982dd 4327
274a9425
RS
4328 buffer = Fmarker_buffer (OVERLAY_START (overlay));
4329
c644523b 4330 for (tail = XOVERLAY (overlay)->plist;
7539e11f
KR
4331 CONSP (tail) && CONSP (XCDR (tail));
4332 tail = XCDR (XCDR (tail)))
4333 if (EQ (XCAR (tail), prop))
274a9425 4334 {
7539e11f 4335 changed = !EQ (XCAR (XCDR (tail)), value);
f3fbd155 4336 XSETCAR (XCDR (tail), value);
9d7608b7 4337 goto found;
274a9425 4338 }
9d7608b7
KH
4339 /* It wasn't in the list, so add it to the front. */
4340 changed = !NILP (value);
c644523b
DA
4341 set_overlay_plist
4342 (overlay, Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist)));
9d7608b7
KH
4343 found:
4344 if (! NILP (buffer))
4345 {
4346 if (changed)
876aa27c 4347 modify_overlay (XBUFFER (buffer),
26f545d7
GM
4348 marker_position (OVERLAY_START (overlay)),
4349 marker_position (OVERLAY_END (overlay)));
9d7608b7
KH
4350 if (EQ (prop, Qevaporate) && ! NILP (value)
4351 && (OVERLAY_POSITION (OVERLAY_START (overlay))
4352 == OVERLAY_POSITION (OVERLAY_END (overlay))))
4353 Fdelete_overlay (overlay);
4354 }
7d63db98 4355
2eec3b4e 4356 return value;
1ab256cb
RM
4357}
4358\f
9115729e
KH
4359/* Subroutine of report_overlay_modification. */
4360
4361/* Lisp vector holding overlay hook functions to call.
4362 Vector elements come in pairs.
4363 Each even-index element is a list of hook functions.
4364 The following odd-index element is the overlay they came from.
4365
4366 Before the buffer change, we fill in this vector
4367 as we call overlay hook functions.
4368 After the buffer change, we get the functions to call from this vector.
4369 This way we always call the same functions before and after the change. */
4370static Lisp_Object last_overlay_modification_hooks;
4371
4372/* Number of elements actually used in last_overlay_modification_hooks. */
d311d28c 4373static ptrdiff_t last_overlay_modification_hooks_used;
9115729e
KH
4374
4375/* Add one functionlist/overlay pair
4376 to the end of last_overlay_modification_hooks. */
4377
4378static void
d3da34e0 4379add_overlay_mod_hooklist (Lisp_Object functionlist, Lisp_Object overlay)
9115729e 4380{
d311d28c 4381 ptrdiff_t oldsize = ASIZE (last_overlay_modification_hooks);
9115729e 4382
d311d28c
PE
4383 if (oldsize - 1 <= last_overlay_modification_hooks_used)
4384 last_overlay_modification_hooks =
4385 larger_vector (last_overlay_modification_hooks, 2, -1);
3ae565b3
SM
4386 ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
4387 functionlist); last_overlay_modification_hooks_used++;
4388 ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
4389 overlay); last_overlay_modification_hooks_used++;
9115729e
KH
4390}
4391\f
173f2a64
RS
4392/* Run the modification-hooks of overlays that include
4393 any part of the text in START to END.
9115729e
KH
4394 If this change is an insertion, also
4395 run the insert-before-hooks of overlay starting at END,
930a9140
RS
4396 and the insert-after-hooks of overlay ending at START.
4397
4398 This is called both before and after the modification.
4399 AFTER is nonzero when we call after the modification.
4400
9115729e
KH
4401 ARG1, ARG2, ARG3 are arguments to pass to the hook functions.
4402 When AFTER is nonzero, they are the start position,
4403 the position after the inserted new text,
4404 and the length of deleted or replaced old text. */
173f2a64
RS
4405
4406void
d3da34e0
JB
4407report_overlay_modification (Lisp_Object start, Lisp_Object end, int after,
4408 Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
173f2a64 4409{
2410d73a
SM
4410 Lisp_Object prop, overlay;
4411 struct Lisp_Overlay *tail;
9115729e
KH
4412 /* 1 if this change is an insertion. */
4413 int insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end));
a615c6dc 4414 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
55b48893
RS
4415
4416 overlay = Qnil;
2410d73a 4417 tail = NULL;
9115729e 4418
27c6b98e
SM
4419 /* We used to run the functions as soon as we found them and only register
4420 them in last_overlay_modification_hooks for the purpose of the `after'
4421 case. But running elisp code as we traverse the list of overlays is
4422 painful because the list can be modified by the elisp code so we had to
4423 copy at several places. We now simply do a read-only traversal that
4424 only collects the functions to run and we run them afterwards. It's
4425 simpler, especially since all the code was already there. -stef */
4426
a615c6dc 4427 if (!after)
173f2a64 4428 {
a615c6dc
SM
4429 /* We are being called before a change.
4430 Scan the overlays to find the functions to call. */
4431 last_overlay_modification_hooks_used = 0;
fd318b54 4432 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
173f2a64 4433 {
d311d28c 4434 ptrdiff_t startpos, endpos;
a615c6dc
SM
4435 Lisp_Object ostart, oend;
4436
2410d73a 4437 XSETMISC (overlay, tail);
a615c6dc
SM
4438
4439 ostart = OVERLAY_START (overlay);
4440 oend = OVERLAY_END (overlay);
4441 endpos = OVERLAY_POSITION (oend);
4442 if (XFASTINT (start) > endpos)
4443 break;
4444 startpos = OVERLAY_POSITION (ostart);
4445 if (insertion && (XFASTINT (start) == startpos
4446 || XFASTINT (end) == startpos))
5fb5aa33 4447 {
a615c6dc
SM
4448 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4449 if (!NILP (prop))
4450 add_overlay_mod_hooklist (prop, overlay);
5fb5aa33 4451 }
a615c6dc
SM
4452 if (insertion && (XFASTINT (start) == endpos
4453 || XFASTINT (end) == endpos))
5fb5aa33 4454 {
a615c6dc
SM
4455 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4456 if (!NILP (prop))
4457 add_overlay_mod_hooklist (prop, overlay);
5fb5aa33 4458 }
a615c6dc
SM
4459 /* Test for intersecting intervals. This does the right thing
4460 for both insertion and deletion. */
4461 if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
5fb5aa33 4462 {
a615c6dc
SM
4463 prop = Foverlay_get (overlay, Qmodification_hooks);
4464 if (!NILP (prop))
4465 add_overlay_mod_hooklist (prop, overlay);
5fb5aa33 4466 }
173f2a64 4467 }
60ebfdf3 4468
fd318b54 4469 for (tail = current_buffer->overlays_after; tail; tail = tail->next)
173f2a64 4470 {
d311d28c 4471 ptrdiff_t startpos, endpos;
a615c6dc
SM
4472 Lisp_Object ostart, oend;
4473
2410d73a 4474 XSETMISC (overlay, tail);
a615c6dc
SM
4475
4476 ostart = OVERLAY_START (overlay);
4477 oend = OVERLAY_END (overlay);
4478 startpos = OVERLAY_POSITION (ostart);
4479 endpos = OVERLAY_POSITION (oend);
4480 if (XFASTINT (end) < startpos)
4481 break;
4482 if (insertion && (XFASTINT (start) == startpos
4483 || XFASTINT (end) == startpos))
5fb5aa33 4484 {
a615c6dc
SM
4485 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4486 if (!NILP (prop))
4487 add_overlay_mod_hooklist (prop, overlay);
5fb5aa33 4488 }
a615c6dc
SM
4489 if (insertion && (XFASTINT (start) == endpos
4490 || XFASTINT (end) == endpos))
5fb5aa33 4491 {
a615c6dc
SM
4492 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4493 if (!NILP (prop))
4494 add_overlay_mod_hooklist (prop, overlay);
5fb5aa33 4495 }
a615c6dc
SM
4496 /* Test for intersecting intervals. This does the right thing
4497 for both insertion and deletion. */
4498 if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
5fb5aa33 4499 {
a615c6dc
SM
4500 prop = Foverlay_get (overlay, Qmodification_hooks);
4501 if (!NILP (prop))
4502 add_overlay_mod_hooklist (prop, overlay);
5fb5aa33 4503 }
173f2a64
RS
4504 }
4505 }
55b48893 4506
a615c6dc
SM
4507 GCPRO4 (overlay, arg1, arg2, arg3);
4508 {
4509 /* Call the functions recorded in last_overlay_modification_hooks.
4510 First copy the vector contents, in case some of these hooks
4511 do subsequent modification of the buffer. */
d311d28c 4512 ptrdiff_t size = last_overlay_modification_hooks_used;
38182d90 4513 Lisp_Object *copy = alloca (size * sizeof *copy);
d311d28c 4514 ptrdiff_t i;
a615c6dc 4515
72af86bd 4516 memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
663e2b3f 4517 size * word_size);
a615c6dc
SM
4518 gcpro1.var = copy;
4519 gcpro1.nvars = size;
4520
4521 for (i = 0; i < size;)
4522 {
8f54f30a
PE
4523 Lisp_Object prop_i, overlay_i;
4524 prop_i = copy[i++];
4525 overlay_i = copy[i++];
4526 call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3);
a615c6dc
SM
4527 }
4528 }
55b48893 4529 UNGCPRO;
173f2a64
RS
4530}
4531
4532static void
d3da34e0
JB
4533call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, int after,
4534 Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
173f2a64 4535{
930a9140 4536 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9115729e 4537
930a9140 4538 GCPRO4 (list, arg1, arg2, arg3);
9115729e 4539
6d70a280 4540 while (CONSP (list))
173f2a64 4541 {
930a9140 4542 if (NILP (arg3))
6d70a280 4543 call4 (XCAR (list), overlay, after ? Qt : Qnil, arg1, arg2);
930a9140 4544 else
6d70a280
SM
4545 call5 (XCAR (list), overlay, after ? Qt : Qnil, arg1, arg2, arg3);
4546 list = XCDR (list);
173f2a64
RS
4547 }
4548 UNGCPRO;
4549}
9d7608b7
KH
4550
4551/* Delete any zero-sized overlays at position POS, if the `evaporate'
4552 property is set. */
4553void
d311d28c 4554evaporate_overlays (ptrdiff_t pos)
9d7608b7 4555{
2410d73a
SM
4556 Lisp_Object overlay, hit_list;
4557 struct Lisp_Overlay *tail;
9d7608b7
KH
4558
4559 hit_list = Qnil;
c2d5b10f 4560 if (pos <= current_buffer->overlay_center)
fd318b54 4561 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
9d7608b7 4562 {
d311d28c 4563 ptrdiff_t endpos;
2410d73a 4564 XSETMISC (overlay, tail);
9d7608b7
KH
4565 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
4566 if (endpos < pos)
4567 break;
4568 if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos
c3935f9d 4569 && ! NILP (Foverlay_get (overlay, Qevaporate)))
9d7608b7
KH
4570 hit_list = Fcons (overlay, hit_list);
4571 }
4572 else
fd318b54 4573 for (tail = current_buffer->overlays_after; tail; tail = tail->next)
9d7608b7 4574 {
d311d28c 4575 ptrdiff_t startpos;
2410d73a 4576 XSETMISC (overlay, tail);
9d7608b7
KH
4577 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
4578 if (startpos > pos)
4579 break;
4580 if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
c3935f9d 4581 && ! NILP (Foverlay_get (overlay, Qevaporate)))
9d7608b7
KH
4582 hit_list = Fcons (overlay, hit_list);
4583 }
7539e11f
KR
4584 for (; CONSP (hit_list); hit_list = XCDR (hit_list))
4585 Fdelete_overlay (XCAR (hit_list));
9d7608b7 4586}
173f2a64 4587\f
54dfdeb0 4588/* Somebody has tried to store a value with an unacceptable type
1bf08baf
KH
4589 in the slot with offset OFFSET. */
4590
0fa3ba92 4591void
d3da34e0 4592buffer_slot_type_mismatch (Lisp_Object newval, int type)
0fa3ba92 4593{
ad97b375 4594 Lisp_Object predicate;
177c0ea7 4595
64e16c3c 4596 switch (type)
0fa3ba92 4597 {
2de9f71c 4598 case_Lisp_Int: predicate = Qintegerp; break;
ad97b375
SM
4599 case Lisp_String: predicate = Qstringp; break;
4600 case Lisp_Symbol: predicate = Qsymbolp; break;
4601 default: abort ();
0fa3ba92
JB
4602 }
4603
ad97b375 4604 wrong_type_argument (predicate, newval);
0fa3ba92 4605}
7c02e886 4606
0fa3ba92 4607\f
b86af064
GM
4608/***********************************************************************
4609 Allocation with mmap
4610 ***********************************************************************/
4611
4612#ifdef USE_MMAP_FOR_BUFFERS
4613
4614#include <sys/types.h>
4615#include <sys/mman.h>
4616
4617#ifndef MAP_ANON
4618#ifdef MAP_ANONYMOUS
4619#define MAP_ANON MAP_ANONYMOUS
4620#else
4621#define MAP_ANON 0
4622#endif
4623#endif
4624
09dfdf85
GM
4625#ifndef MAP_FAILED
4626#define MAP_FAILED ((void *) -1)
4627#endif
4628
b86af064 4629#include <stdio.h>
b86af064
GM
4630
4631#if MAP_ANON == 0
4632#include <fcntl.h>
4633#endif
4634
4635#include "coding.h"
4636
4637
4638/* Memory is allocated in regions which are mapped using mmap(2).
4639 The current implementation lets the system select mapped
4640 addresses; we're not using MAP_FIXED in general, except when
4641 trying to enlarge regions.
4642
4643 Each mapped region starts with a mmap_region structure, the user
4644 area starts after that structure, aligned to MEM_ALIGN.
4645
4646 +-----------------------+
4647 | struct mmap_info + |
4648 | padding |
4649 +-----------------------+
4650 | user data |
4651 | |
4652 | |
4653 +-----------------------+ */
4654
4655struct mmap_region
4656{
4657 /* User-specified size. */
4658 size_t nbytes_specified;
177c0ea7 4659
b86af064
GM
4660 /* Number of bytes mapped */
4661 size_t nbytes_mapped;
4662
4663 /* Pointer to the location holding the address of the memory
4664 allocated with the mmap'd block. The variable actually points
4665 after this structure. */
261cb4bb 4666 void **var;
b86af064
GM
4667
4668 /* Next and previous in list of all mmap'd regions. */
4669 struct mmap_region *next, *prev;
4670};
4671
4672/* Doubly-linked list of mmap'd regions. */
4673
4674static struct mmap_region *mmap_regions;
4675
4676/* File descriptor for mmap. If we don't have anonymous mapping,
4677 /dev/zero will be opened on it. */
4678
4679static int mmap_fd;
4680
4681/* Temporary storage for mmap_set_vars, see there. */
4682
4683static struct mmap_region *mmap_regions_1;
4684static int mmap_fd_1;
4685
4686/* Page size on this system. */
4687
4688static int mmap_page_size;
4689
cd1181db 4690/* 1 means mmap has been initialized. */
b86af064
GM
4691
4692static int mmap_initialized_p;
4693
4694/* Value is X rounded up to the next multiple of N. */
4695
4696#define ROUND(X, N) (((X) + (N) - 1) / (N) * (N))
4697
4698/* Size of mmap_region structure plus padding. */
4699
4700#define MMAP_REGION_STRUCT_SIZE \
4701 ROUND (sizeof (struct mmap_region), MEM_ALIGN)
4702
4703/* Given a pointer P to the start of the user-visible part of a mapped
4704 region, return a pointer to the start of the region. */
4705
4706#define MMAP_REGION(P) \
4707 ((struct mmap_region *) ((char *) (P) - MMAP_REGION_STRUCT_SIZE))
4708
4709/* Given a pointer P to the start of a mapped region, return a pointer
4710 to the start of the user-visible part of the region. */
4711
4712#define MMAP_USER_AREA(P) \
261cb4bb 4713 ((void *) ((char *) (P) + MMAP_REGION_STRUCT_SIZE))
b86af064
GM
4714
4715#define MEM_ALIGN sizeof (double)
4716
7273faa1
DL
4717/* Predicate returning true if part of the address range [START .. END]
4718 is currently mapped. Used to prevent overwriting an existing
08327b22
GM
4719 memory mapping.
4720
da6062e6 4721 Default is to conservatively assume the address range is occupied by
08327b22
GM
4722 something else. This can be overridden by system configuration
4723 files if system-specific means to determine this exists. */
4724
4725#ifndef MMAP_ALLOCATED_P
4726#define MMAP_ALLOCATED_P(start, end) 1
4727#endif
4728
53964682 4729/* Perform necessary initializations for the use of mmap. */
b86af064 4730
1dae0f0a
AS
4731static void
4732mmap_init (void)
4733{
4734#if MAP_ANON == 0
4735 /* The value of mmap_fd is initially 0 in temacs, and -1
4736 in a dumped Emacs. */
4737 if (mmap_fd <= 0)
4738 {
4739 /* No anonymous mmap -- we need the file descriptor. */
4740 mmap_fd = open ("/dev/zero", O_RDONLY);
4741 if (mmap_fd == -1)
4742 fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
4743 }
4744#endif /* MAP_ANON == 0 */
4745
4746 if (mmap_initialized_p)
4747 return;
4748 mmap_initialized_p = 1;
b86af064 4749
1dae0f0a
AS
4750#if MAP_ANON != 0
4751 mmap_fd = -1;
4752#endif
4753
4754 mmap_page_size = getpagesize ();
4755}
b86af064
GM
4756
4757/* Return a region overlapping address range START...END, or null if
4758 none. END is not including, i.e. the last byte in the range
4759 is at END - 1. */
4760
4761static struct mmap_region *
261cb4bb 4762mmap_find (void *start, void *end)
b86af064
GM
4763{
4764 struct mmap_region *r;
4765 char *s = (char *) start, *e = (char *) end;
177c0ea7 4766
b86af064
GM
4767 for (r = mmap_regions; r; r = r->next)
4768 {
4769 char *rstart = (char *) r;
4770 char *rend = rstart + r->nbytes_mapped;
4771
4772 if (/* First byte of range, i.e. START, in this region? */
4773 (s >= rstart && s < rend)
4774 /* Last byte of range, i.e. END - 1, in this region? */
4775 || (e > rstart && e <= rend)
4776 /* First byte of this region in the range? */
4777 || (rstart >= s && rstart < e)
4778 /* Last byte of this region in the range? */
4779 || (rend > s && rend <= e))
4780 break;
4781 }
4782
4783 return r;
4784}
4785
4786
4787/* Unmap a region. P is a pointer to the start of the user-araa of
4788 the region. Value is non-zero if successful. */
4789
4790static int
1dae0f0a 4791mmap_free_1 (struct mmap_region *r)
b86af064
GM
4792{
4793 if (r->next)
4794 r->next->prev = r->prev;
4795 if (r->prev)
4796 r->prev->next = r->next;
4797 else
4798 mmap_regions = r->next;
177c0ea7 4799
261cb4bb 4800 if (munmap (r, r->nbytes_mapped) == -1)
b86af064
GM
4801 {
4802 fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
4803 return 0;
4804 }
4805
4806 return 1;
4807}
4808
4809
4810/* Enlarge region R by NPAGES pages. NPAGES < 0 means shrink R.
4811 Value is non-zero if successful. */
4812
4813static int
1dae0f0a 4814mmap_enlarge (struct mmap_region *r, int npages)
b86af064
GM
4815{
4816 char *region_end = (char *) r + r->nbytes_mapped;
4817 size_t nbytes;
4818 int success = 0;
4819
4820 if (npages < 0)
4821 {
4822 /* Unmap pages at the end of the region. */
4823 nbytes = - npages * mmap_page_size;
4824 if (munmap (region_end - nbytes, nbytes) == -1)
4825 fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
4826 else
4827 {
4828 r->nbytes_mapped -= nbytes;
4829 success = 1;
4830 }
4831 }
4832 else if (npages > 0)
4833 {
b86af064 4834 nbytes = npages * mmap_page_size;
177c0ea7 4835
b86af064
GM
4836 /* Try to map additional pages at the end of the region. We
4837 cannot do this if the address range is already occupied by
4838 something else because mmap deletes any previous mapping.
4839 I'm not sure this is worth doing, let's see. */
08327b22 4840 if (!MMAP_ALLOCATED_P (region_end, region_end + nbytes))
b86af064 4841 {
261cb4bb 4842 void *p;
177c0ea7 4843
b86af064
GM
4844 p = mmap (region_end, nbytes, PROT_READ | PROT_WRITE,
4845 MAP_ANON | MAP_PRIVATE | MAP_FIXED, mmap_fd, 0);
4846 if (p == MAP_FAILED)
edaa9aed 4847 ; /* fprintf (stderr, "mmap: %s\n", emacs_strerror (errno)); */
261cb4bb 4848 else if (p != region_end)
b86af064
GM
4849 {
4850 /* Kernels are free to choose a different address. In
4851 that case, unmap what we've mapped above; we have
4852 no use for it. */
4853 if (munmap (p, nbytes) == -1)
4854 fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
4855 }
4856 else
4857 {
4858 r->nbytes_mapped += nbytes;
4859 success = 1;
4860 }
4861 }
4862 }
4863
4864 return success;
4865}
4866
4867
4868/* Set or reset variables holding references to mapped regions. If
4869 RESTORE_P is zero, set all variables to null. If RESTORE_P is
4870 non-zero, set all variables to the start of the user-areas
4871 of mapped regions.
4872
4873 This function is called from Fdump_emacs to ensure that the dumped
4874 Emacs doesn't contain references to memory that won't be mapped
4875 when Emacs starts. */
4876
4877void
1dae0f0a 4878mmap_set_vars (int restore_p)
b86af064
GM
4879{
4880 struct mmap_region *r;
4881
4882 if (restore_p)
4883 {
4884 mmap_regions = mmap_regions_1;
4885 mmap_fd = mmap_fd_1;
4886 for (r = mmap_regions; r; r = r->next)
4887 *r->var = MMAP_USER_AREA (r);
4888 }
4889 else
4890 {
4891 for (r = mmap_regions; r; r = r->next)
4892 *r->var = NULL;
4893 mmap_regions_1 = mmap_regions;
4894 mmap_regions = NULL;
4895 mmap_fd_1 = mmap_fd;
4896 mmap_fd = -1;
4897 }
4898}
4899
4900
4901/* Allocate a block of storage large enough to hold NBYTES bytes of
4902 data. A pointer to the data is returned in *VAR. VAR is thus the
4903 address of some variable which will use the data area.
4904
4905 The allocation of 0 bytes is valid.
4906
4907 If we can't allocate the necessary memory, set *VAR to null, and
4908 return null. */
4909
261cb4bb
PE
4910static void *
4911mmap_alloc (void **var, size_t nbytes)
b86af064
GM
4912{
4913 void *p;
4914 size_t map;
4915
4916 mmap_init ();
4917
4918 map = ROUND (nbytes + MMAP_REGION_STRUCT_SIZE, mmap_page_size);
4919 p = mmap (NULL, map, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
4920 mmap_fd, 0);
177c0ea7 4921
b86af064
GM
4922 if (p == MAP_FAILED)
4923 {
4924 if (errno != ENOMEM)
4925 fprintf (stderr, "mmap: %s\n", emacs_strerror (errno));
4926 p = NULL;
4927 }
4928 else
4929 {
4930 struct mmap_region *r = (struct mmap_region *) p;
177c0ea7 4931
b86af064
GM
4932 r->nbytes_specified = nbytes;
4933 r->nbytes_mapped = map;
4934 r->var = var;
4935 r->prev = NULL;
4936 r->next = mmap_regions;
4937 if (r->next)
4938 r->next->prev = r;
4939 mmap_regions = r;
177c0ea7 4940
b86af064
GM
4941 p = MMAP_USER_AREA (p);
4942 }
177c0ea7 4943
b86af064
GM
4944 return *var = p;
4945}
4946
4947
1dae0f0a
AS
4948/* Free a block of relocatable storage whose data is pointed to by
4949 PTR. Store 0 in *PTR to show there's no block allocated. */
4950
4951static void
261cb4bb 4952mmap_free (void **var)
1dae0f0a
AS
4953{
4954 mmap_init ();
4955
4956 if (*var)
4957 {
4958 mmap_free_1 (MMAP_REGION (*var));
4959 *var = NULL;
4960 }
4961}
4962
4963
b86af064
GM
4964/* Given a pointer at address VAR to data allocated with mmap_alloc,
4965 resize it to size NBYTES. Change *VAR to reflect the new block,
4966 and return this value. If more memory cannot be allocated, then
4967 leave *VAR unchanged, and return null. */
4968
261cb4bb
PE
4969static void *
4970mmap_realloc (void **var, size_t nbytes)
b86af064 4971{
261cb4bb 4972 void *result;
177c0ea7 4973
b86af064
GM
4974 mmap_init ();
4975
4976 if (*var == NULL)
4977 result = mmap_alloc (var, nbytes);
177c0ea7 4978 else if (nbytes == 0)
b86af064
GM
4979 {
4980 mmap_free (var);
4981 result = mmap_alloc (var, nbytes);
4982 }
4983 else
4984 {
4985 struct mmap_region *r = MMAP_REGION (*var);
4986 size_t room = r->nbytes_mapped - MMAP_REGION_STRUCT_SIZE;
177c0ea7 4987
b86af064
GM
4988 if (room < nbytes)
4989 {
4990 /* Must enlarge. */
261cb4bb 4991 void *old_ptr = *var;
b86af064
GM
4992
4993 /* Try to map additional pages at the end of the region.
4994 If that fails, allocate a new region, copy data
4995 from the old region, then free it. */
4996 if (mmap_enlarge (r, (ROUND (nbytes - room, mmap_page_size)
4997 / mmap_page_size)))
4998 {
4999 r->nbytes_specified = nbytes;
5000 *var = result = old_ptr;
5001 }
5002 else if (mmap_alloc (var, nbytes))
5003 {
72af86bd 5004 memcpy (*var, old_ptr, r->nbytes_specified);
b86af064
GM
5005 mmap_free_1 (MMAP_REGION (old_ptr));
5006 result = *var;
5007 r = MMAP_REGION (result);
5008 r->nbytes_specified = nbytes;
5009 }
5010 else
5011 {
5012 *var = old_ptr;
5013 result = NULL;
5014 }
5015 }
5016 else if (room - nbytes >= mmap_page_size)
5017 {
5018 /* Shrinking by at least a page. Let's give some
6bcdeb8c
KR
5019 memory back to the system.
5020
5021 The extra parens are to make the division happens first,
5022 on positive values, so we know it will round towards
5023 zero. */
bb63c5c9 5024 mmap_enlarge (r, - ((room - nbytes) / mmap_page_size));
b86af064
GM
5025 result = *var;
5026 r->nbytes_specified = nbytes;
5027 }
5028 else
5029 {
5030 /* Leave it alone. */
5031 result = *var;
5032 r->nbytes_specified = nbytes;
5033 }
5034 }
5035
5036 return result;
5037}
5038
5039
b86af064
GM
5040#endif /* USE_MMAP_FOR_BUFFERS */
5041
5042
5043\f
5044/***********************************************************************
5045 Buffer-text Allocation
5046 ***********************************************************************/
5047
b86af064
GM
5048/* Allocate NBYTES bytes for buffer B's text buffer. */
5049
5050static void
fd05c7e9 5051alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
b86af064 5052{
261cb4bb 5053 void *p;
177c0ea7 5054
b86af064
GM
5055 BLOCK_INPUT;
5056#if defined USE_MMAP_FOR_BUFFERS
261cb4bb 5057 p = mmap_alloc ((void **) &b->text->beg, nbytes);
b86af064 5058#elif defined REL_ALLOC
261cb4bb 5059 p = r_alloc ((void **) &b->text->beg, nbytes);
b86af064 5060#else
815add84 5061 p = xmalloc (nbytes);
b86af064 5062#endif
177c0ea7 5063
b86af064
GM
5064 if (p == NULL)
5065 {
5066 UNBLOCK_INPUT;
531b0165 5067 memory_full (nbytes);
b86af064
GM
5068 }
5069
5070 b->text->beg = (unsigned char *) p;
5071 UNBLOCK_INPUT;
5072}
5073
5074/* Enlarge buffer B's text buffer by DELTA bytes. DELTA < 0 means
5075 shrink it. */
5076
5077void
d311d28c 5078enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
b86af064 5079{
261cb4bb 5080 void *p;
fd05c7e9
PE
5081 ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
5082 + delta);
b86af064
GM
5083 BLOCK_INPUT;
5084#if defined USE_MMAP_FOR_BUFFERS
261cb4bb 5085 p = mmap_realloc ((void **) &b->text->beg, nbytes);
b86af064 5086#elif defined REL_ALLOC
261cb4bb 5087 p = r_re_alloc ((void **) &b->text->beg, nbytes);
b86af064
GM
5088#else
5089 p = xrealloc (b->text->beg, nbytes);
5090#endif
177c0ea7 5091
b86af064
GM
5092 if (p == NULL)
5093 {
5094 UNBLOCK_INPUT;
531b0165 5095 memory_full (nbytes);
b86af064
GM
5096 }
5097
5098 BUF_BEG_ADDR (b) = (unsigned char *) p;
5099 UNBLOCK_INPUT;
5100}
5101
5102
5103/* Free buffer B's text buffer. */
5104
5105static void
d3da34e0 5106free_buffer_text (struct buffer *b)
b86af064
GM
5107{
5108 BLOCK_INPUT;
5109
5110#if defined USE_MMAP_FOR_BUFFERS
261cb4bb 5111 mmap_free ((void **) &b->text->beg);
b86af064 5112#elif defined REL_ALLOC
261cb4bb 5113 r_alloc_free ((void **) &b->text->beg);
b86af064
GM
5114#else
5115 xfree (b->text->beg);
5116#endif
177c0ea7 5117
b86af064
GM
5118 BUF_BEG_ADDR (b) = NULL;
5119 UNBLOCK_INPUT;
5120}
5121
5122
5123\f
5124/***********************************************************************
5125 Initialization
5126 ***********************************************************************/
5127
dfcf069d 5128void
d3da34e0 5129init_buffer_once (void)
1ab256cb 5130{
7c02e886 5131 int idx;
3884d954
DA
5132 /* If you add, remove, or reorder Lisp_Objects in a struct buffer, make
5133 sure that this is still correct. Otherwise, mark_vectorlike may not
5134 trace all Lisp_Objects in buffer_defaults and buffer_local_symbols. */
38182d90 5135 const int pvecsize
663e2b3f 5136 = (offsetof (struct buffer, own_text) - header_size) / word_size;
7c02e886 5137
72af86bd 5138 memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags);
13de9290 5139
1ab256cb
RM
5140 /* Make sure all markable slots in buffer_defaults
5141 are initialized reasonably, so mark_buffer won't choke. */
5142 reset_buffer (&buffer_defaults);
4b4deea2 5143 eassert (EQ (BVAR (&buffer_defaults, name), make_number (0)));
13de9290 5144 reset_buffer_local_variables (&buffer_defaults, 1);
4b4deea2 5145 eassert (EQ (BVAR (&buffer_local_symbols, name), make_number (0)));
1ab256cb 5146 reset_buffer (&buffer_local_symbols);
13de9290 5147 reset_buffer_local_variables (&buffer_local_symbols, 1);
336cd056
RS
5148 /* Prevent GC from getting confused. */
5149 buffer_defaults.text = &buffer_defaults.own_text;
5150 buffer_local_symbols.text = &buffer_local_symbols.own_text;
04e9897c
DA
5151 /* No one will share the text with these buffers, but let's play it safe. */
5152 buffer_defaults.indirections = 0;
5153 buffer_local_symbols.indirections = 0;
0c94c8d6
PE
5154 set_buffer_intervals (&buffer_defaults, NULL);
5155 set_buffer_intervals (&buffer_local_symbols, NULL);
3884d954 5156 XSETPVECTYPESIZE (&buffer_defaults, PVEC_BUFFER, pvecsize);
67180c6a 5157 XSETBUFFER (Vbuffer_defaults, &buffer_defaults);
3884d954 5158 XSETPVECTYPESIZE (&buffer_local_symbols, PVEC_BUFFER, pvecsize);
67180c6a 5159 XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols);
1ab256cb
RM
5160
5161 /* Set up the default values of various buffer slots. */
5162 /* Must do these before making the first buffer! */
5163
f532dca0 5164 /* real setup is done in bindings.el */
39eb03f1
PE
5165 bset_mode_line_format (&buffer_defaults, build_pure_c_string ("%-"));
5166 bset_header_line_format (&buffer_defaults, Qnil);
5167 bset_abbrev_mode (&buffer_defaults, Qnil);
5168 bset_overwrite_mode (&buffer_defaults, Qnil);
5169 bset_case_fold_search (&buffer_defaults, Qt);
5170 bset_auto_fill_function (&buffer_defaults, Qnil);
5171 bset_selective_display (&buffer_defaults, Qnil);
5172 bset_selective_display_ellipses (&buffer_defaults, Qt);
5173 bset_abbrev_table (&buffer_defaults, Qnil);
5174 bset_display_table (&buffer_defaults, Qnil);
5175 bset_undo_list (&buffer_defaults, Qnil);
5176 bset_mark_active (&buffer_defaults, Qnil);
5177 bset_file_format (&buffer_defaults, Qnil);
5178 bset_auto_save_file_format (&buffer_defaults, Qt);
0c94c8d6
PE
5179 set_buffer_overlays_before (&buffer_defaults, NULL);
5180 set_buffer_overlays_after (&buffer_defaults, NULL);
c2d5b10f 5181 buffer_defaults.overlay_center = BEG;
1ab256cb 5182
4b4deea2 5183 XSETFASTINT (BVAR (&buffer_defaults, tab_width), 8);
39eb03f1
PE
5184 bset_truncate_lines (&buffer_defaults, Qnil);
5185 bset_word_wrap (&buffer_defaults, Qnil);
5186 bset_ctl_arrow (&buffer_defaults, Qt);
5187 bset_bidi_display_reordering (&buffer_defaults, Qt);
5188 bset_bidi_paragraph_direction (&buffer_defaults, Qnil);
5189 bset_cursor_type (&buffer_defaults, Qt);
5190 bset_extra_line_spacing (&buffer_defaults, Qnil);
5191 bset_cursor_in_non_selected_windows (&buffer_defaults, Qt);
5192
5193 bset_enable_multibyte_characters (&buffer_defaults, Qt);
5194 bset_buffer_file_coding_system (&buffer_defaults, Qnil);
4b4deea2
TT
5195 XSETFASTINT (BVAR (&buffer_defaults, fill_column), 70);
5196 XSETFASTINT (BVAR (&buffer_defaults, left_margin), 0);
39eb03f1
PE
5197 bset_cache_long_line_scans (&buffer_defaults, Qnil);
5198 bset_file_truename (&buffer_defaults, Qnil);
4b4deea2
TT
5199 XSETFASTINT (BVAR (&buffer_defaults, display_count), 0);
5200 XSETFASTINT (BVAR (&buffer_defaults, left_margin_cols), 0);
5201 XSETFASTINT (BVAR (&buffer_defaults, right_margin_cols), 0);
39eb03f1
PE
5202 bset_left_fringe_width (&buffer_defaults, Qnil);
5203 bset_right_fringe_width (&buffer_defaults, Qnil);
5204 bset_fringes_outside_margins (&buffer_defaults, Qnil);
5205 bset_scroll_bar_width (&buffer_defaults, Qnil);
5206 bset_vertical_scroll_bar_type (&buffer_defaults, Qt);
5207 bset_indicate_empty_lines (&buffer_defaults, Qnil);
5208 bset_indicate_buffer_boundaries (&buffer_defaults, Qnil);
5209 bset_fringe_indicator_alist (&buffer_defaults, Qnil);
5210 bset_fringe_cursor_alist (&buffer_defaults, Qnil);
5211 bset_scroll_up_aggressively (&buffer_defaults, Qnil);
5212 bset_scroll_down_aggressively (&buffer_defaults, Qnil);
5213 bset_display_time (&buffer_defaults, Qnil);
1ab256cb
RM
5214
5215 /* Assign the local-flags to the slots that have default values.
5216 The local flag is a bit that is used in the buffer
5217 to say that it has its own local value for the slot.
5218 The local flag bits are in the local_var_flags slot of the buffer. */
5219
5220 /* Nothing can work if this isn't true */
663e2b3f 5221 { verify (sizeof (EMACS_INT) == word_size); }
1ab256cb
RM
5222
5223 /* 0 means not a lisp var, -1 means always local, else mask */
72af86bd 5224 memset (&buffer_local_flags, 0, sizeof buffer_local_flags);
39eb03f1
PE
5225 bset_filename (&buffer_local_flags, make_number (-1));
5226 bset_directory (&buffer_local_flags, make_number (-1));
5227 bset_backed_up (&buffer_local_flags, make_number (-1));
5228 bset_save_length (&buffer_local_flags, make_number (-1));
5229 bset_auto_save_file_name (&buffer_local_flags, make_number (-1));
5230 bset_read_only (&buffer_local_flags, make_number (-1));
5231 bset_major_mode (&buffer_local_flags, make_number (-1));
5232 bset_mode_name (&buffer_local_flags, make_number (-1));
5233 bset_undo_list (&buffer_local_flags, make_number (-1));
5234 bset_mark_active (&buffer_local_flags, make_number (-1));
5235 bset_point_before_scroll (&buffer_local_flags, make_number (-1));
5236 bset_file_truename (&buffer_local_flags, make_number (-1));
5237 bset_invisibility_spec (&buffer_local_flags, make_number (-1));
5238 bset_file_format (&buffer_local_flags, make_number (-1));
5239 bset_auto_save_file_format (&buffer_local_flags, make_number (-1));
5240 bset_display_count (&buffer_local_flags, make_number (-1));
5241 bset_display_time (&buffer_local_flags, make_number (-1));
5242 bset_enable_multibyte_characters (&buffer_local_flags, make_number (-1));
8d7a4592 5243
7c02e886 5244 idx = 1;
4b4deea2
TT
5245 XSETFASTINT (BVAR (&buffer_local_flags, mode_line_format), idx); ++idx;
5246 XSETFASTINT (BVAR (&buffer_local_flags, abbrev_mode), idx); ++idx;
5247 XSETFASTINT (BVAR (&buffer_local_flags, overwrite_mode), idx); ++idx;
5248 XSETFASTINT (BVAR (&buffer_local_flags, case_fold_search), idx); ++idx;
5249 XSETFASTINT (BVAR (&buffer_local_flags, auto_fill_function), idx); ++idx;
5250 XSETFASTINT (BVAR (&buffer_local_flags, selective_display), idx); ++idx;
4b4deea2 5251 XSETFASTINT (BVAR (&buffer_local_flags, selective_display_ellipses), idx); ++idx;
4b4deea2
TT
5252 XSETFASTINT (BVAR (&buffer_local_flags, tab_width), idx); ++idx;
5253 XSETFASTINT (BVAR (&buffer_local_flags, truncate_lines), idx); ++idx;
5254 XSETFASTINT (BVAR (&buffer_local_flags, word_wrap), idx); ++idx;
5255 XSETFASTINT (BVAR (&buffer_local_flags, ctl_arrow), idx); ++idx;
5256 XSETFASTINT (BVAR (&buffer_local_flags, fill_column), idx); ++idx;
5257 XSETFASTINT (BVAR (&buffer_local_flags, left_margin), idx); ++idx;
5258 XSETFASTINT (BVAR (&buffer_local_flags, abbrev_table), idx); ++idx;
5259 XSETFASTINT (BVAR (&buffer_local_flags, display_table), idx); ++idx;
4b4deea2
TT
5260 XSETFASTINT (BVAR (&buffer_local_flags, syntax_table), idx); ++idx;
5261 XSETFASTINT (BVAR (&buffer_local_flags, cache_long_line_scans), idx); ++idx;
5262 XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx;
5263 XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); ++idx;
5264 XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); ++idx;
5265 XSETFASTINT (BVAR (&buffer_local_flags, buffer_file_coding_system), idx);
a1a17b61 5266 /* Make this one a permanent local. */
7c02e886 5267 buffer_permanent_local_flags[idx++] = 1;
4b4deea2
TT
5268 XSETFASTINT (BVAR (&buffer_local_flags, left_margin_cols), idx); ++idx;
5269 XSETFASTINT (BVAR (&buffer_local_flags, right_margin_cols), idx); ++idx;
5270 XSETFASTINT (BVAR (&buffer_local_flags, left_fringe_width), idx); ++idx;
5271 XSETFASTINT (BVAR (&buffer_local_flags, right_fringe_width), idx); ++idx;
5272 XSETFASTINT (BVAR (&buffer_local_flags, fringes_outside_margins), idx); ++idx;
5273 XSETFASTINT (BVAR (&buffer_local_flags, scroll_bar_width), idx); ++idx;
5274 XSETFASTINT (BVAR (&buffer_local_flags, vertical_scroll_bar_type), idx); ++idx;
5275 XSETFASTINT (BVAR (&buffer_local_flags, indicate_empty_lines), idx); ++idx;
5276 XSETFASTINT (BVAR (&buffer_local_flags, indicate_buffer_boundaries), idx); ++idx;
5277 XSETFASTINT (BVAR (&buffer_local_flags, fringe_indicator_alist), idx); ++idx;
5278 XSETFASTINT (BVAR (&buffer_local_flags, fringe_cursor_alist), idx); ++idx;
5279 XSETFASTINT (BVAR (&buffer_local_flags, scroll_up_aggressively), idx); ++idx;
5280 XSETFASTINT (BVAR (&buffer_local_flags, scroll_down_aggressively), idx); ++idx;
5281 XSETFASTINT (BVAR (&buffer_local_flags, header_line_format), idx); ++idx;
5282 XSETFASTINT (BVAR (&buffer_local_flags, cursor_type), idx); ++idx;
5283 XSETFASTINT (BVAR (&buffer_local_flags, extra_line_spacing), idx); ++idx;
5284 XSETFASTINT (BVAR (&buffer_local_flags, cursor_in_non_selected_windows), idx); ++idx;
7c02e886
GM
5285
5286 /* Need more room? */
7313acd0 5287 if (idx >= MAX_PER_BUFFER_VARS)
7c02e886 5288 abort ();
7313acd0 5289 last_per_buffer_idx = idx;
177c0ea7 5290
1ab256cb
RM
5291 Vbuffer_alist = Qnil;
5292 current_buffer = 0;
5293 all_buffers = 0;
5294
2a0213a6 5295 QSFundamental = build_pure_c_string ("Fundamental");
1ab256cb 5296
d67b4f80 5297 Qfundamental_mode = intern_c_string ("fundamental-mode");
39eb03f1 5298 bset_major_mode (&buffer_defaults, Qfundamental_mode);
1ab256cb 5299
d67b4f80 5300 Qmode_class = intern_c_string ("mode-class");
1ab256cb 5301
d67b4f80 5302 Qprotected_field = intern_c_string ("protected-field");
1ab256cb 5303
d67b4f80 5304 Qpermanent_local = intern_c_string ("permanent-local");
1ab256cb 5305
d67b4f80 5306 Qkill_buffer_hook = intern_c_string ("kill-buffer-hook");
fd6cfe11 5307 Fput (Qkill_buffer_hook, Qpermanent_local, Qt);
1ab256cb 5308
1ab256cb 5309 /* super-magic invisible buffer */
2a0213a6 5310 Vprin1_to_string_buffer = Fget_buffer_create (build_pure_c_string (" prin1"));
1ab256cb
RM
5311 Vbuffer_alist = Qnil;
5312
2a0213a6 5313 Fset_buffer (Fget_buffer_create (build_pure_c_string ("*scratch*")));
7775635d
KH
5314
5315 inhibit_modification_hooks = 0;
1ab256cb
RM
5316}
5317
dfcf069d 5318void
d3da34e0 5319init_buffer (void)
1ab256cb 5320{
2381d133 5321 char *pwd;
136351b7 5322 Lisp_Object temp;
965d34eb 5323 ptrdiff_t len;
1ab256cb 5324
b86af064 5325#ifdef USE_MMAP_FOR_BUFFERS
93c27ef1
GM
5326 {
5327 /* When using the ralloc implementation based on mmap(2), buffer
5328 text pointers will have been set to null in the dumped Emacs.
5329 Map new memory. */
5330 struct buffer *b;
177c0ea7 5331
52b852c7 5332 FOR_EACH_BUFFER (b)
93c27ef1 5333 if (b->text->beg == NULL)
b86af064 5334 enlarge_buffer_text (b, 0);
93c27ef1 5335 }
b86af064 5336#endif /* USE_MMAP_FOR_BUFFERS */
177c0ea7 5337
1ab256cb 5338 Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
4b4deea2 5339 if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters)))
3d871c85 5340 Fset_buffer_multibyte (Qnil);
2381d133 5341
01537133 5342 pwd = get_current_dir_name ();
a17b5ed1 5343
156bdb41 5344 if (!pwd)
a17b5ed1 5345 fatal ("`get_current_dir_name' failed: %s\n", strerror (errno));
1ab256cb 5346
1ab256cb
RM
5347 /* Maybe this should really use some standard subroutine
5348 whose definition is filename syntax dependent. */
b639c9be
RF
5349 len = strlen (pwd);
5350 if (!(IS_DIRECTORY_SEP (pwd[len - 1])))
f7975d07 5351 {
156bdb41 5352 /* Grow buffer to add directory separator and '\0'. */
38182d90 5353 pwd = realloc (pwd, len + 2);
8b146312
AS
5354 if (!pwd)
5355 fatal ("`get_current_dir_name' failed: %s\n", strerror (errno));
b639c9be
RF
5356 pwd[len] = DIRECTORY_SEP;
5357 pwd[len + 1] = '\0';
cb1caeaf 5358 len++;
f7975d07 5359 }
0995fa35 5360
39eb03f1 5361 bset_directory (current_buffer, make_unibyte_string (pwd, len));
4b4deea2 5362 if (! NILP (BVAR (&buffer_defaults, enable_multibyte_characters)))
f9962371 5363 /* At this moment, we still don't know how to decode the
156bdb41 5364 directory name. So, we keep the bytes in multibyte form so
dcd74c5f 5365 that ENCODE_FILE correctly gets the original bytes. */
39eb03f1
PE
5366 bset_directory
5367 (current_buffer, string_to_multibyte (BVAR (current_buffer, directory)));
136351b7 5368
0995fa35
RS
5369 /* Add /: to the front of the name
5370 if it would otherwise be treated as magic. */
4b4deea2 5371 temp = Ffind_file_name_handler (BVAR (current_buffer, directory), Qt);
81ab2e07
KH
5372 if (! NILP (temp)
5373 /* If the default dir is just /, TEMP is non-nil
5374 because of the ange-ftp completion handler.
5375 However, it is not necessary to turn / into /:/.
5376 So avoid doing that. */
4b4deea2 5377 && strcmp ("/", SSDATA (BVAR (current_buffer, directory))))
39eb03f1
PE
5378 bset_directory
5379 (current_buffer,
5380 concat2 (build_string ("/:"), BVAR (current_buffer, directory)));
0995fa35 5381
136351b7 5382 temp = get_minibuffer (0);
39eb03f1 5383 bset_directory (XBUFFER (temp), BVAR (current_buffer, directory));
01537133
EZ
5384
5385 free (pwd);
1ab256cb
RM
5386}
5387
d6aa1876
SM
5388/* Similar to defvar_lisp but define a variable whose value is the Lisp
5389 Object stored in the current buffer. address is the address of the slot
5390 in the buffer that is current now. */
5391
5392/* TYPE is nil for a general Lisp variable.
ce5b453a 5393 An integer specifies a type; then only Lisp values
d6aa1876 5394 with that type code are allowed (except that nil is allowed too).
ce5b453a 5395 LNAME is the Lisp-level variable name.
d6aa1876
SM
5396 VNAME is the name of the buffer slot.
5397 DOC is a dummy where you write the doc string as a comment. */
ce5b453a
SM
5398#define DEFVAR_PER_BUFFER(lname, vname, type, doc) \
5399 do { \
5400 static struct Lisp_Buffer_Objfwd bo_fwd; \
6b1f9ba4 5401 defvar_per_buffer (&bo_fwd, lname, vname, type); \
ce5b453a 5402 } while (0)
d6aa1876
SM
5403
5404static void
8ea90aa3 5405defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
6b1f9ba4 5406 Lisp_Object *address, Lisp_Object type)
d6aa1876 5407{
ce5b453a 5408 struct Lisp_Symbol *sym;
d6aa1876
SM
5409 int offset;
5410
ce5b453a 5411 sym = XSYMBOL (intern (namestring));
d6aa1876
SM
5412 offset = (char *)address - (char *)current_buffer;
5413
ce5b453a
SM
5414 bo_fwd->type = Lisp_Fwd_Buffer_Obj;
5415 bo_fwd->offset = offset;
5416 bo_fwd->slottype = type;
b9598260 5417 sym->declared_special = 1;
ce5b453a
SM
5418 sym->redirect = SYMBOL_FORWARDED;
5419 {
5420 /* I tried to do the job without a cast, but it seems impossible.
5421 union Lisp_Fwd *fwd; &(fwd->u_buffer_objfwd) = bo_fwd; */
5422 SET_SYMBOL_FWD (sym, (union Lisp_Fwd *)bo_fwd);
5423 }
5424 XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym);
d6aa1876
SM
5425
5426 if (PER_BUFFER_IDX (offset) == 0)
5427 /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
5428 slot of buffer_local_flags */
5429 abort ();
5430}
5431
5432
1ab256cb 5433/* initialize the buffer routines */
dfcf069d 5434void
d3da34e0 5435syms_of_buffer (void)
1ab256cb 5436{
9115729e
KH
5437 staticpro (&last_overlay_modification_hooks);
5438 last_overlay_modification_hooks
5439 = Fmake_vector (make_number (10), Qnil);
5440
1ab256cb
RM
5441 staticpro (&Vbuffer_defaults);
5442 staticpro (&Vbuffer_local_symbols);
5443 staticpro (&Qfundamental_mode);
5444 staticpro (&Qmode_class);
5445 staticpro (&QSFundamental);
5446 staticpro (&Vbuffer_alist);
5447 staticpro (&Qprotected_field);
5448 staticpro (&Qpermanent_local);
5449 staticpro (&Qkill_buffer_hook);
cd3520a4
JB
5450
5451 DEFSYM (Qpermanent_local_hook, "permanent-local-hook");
5452 DEFSYM (Qoverlayp, "overlayp");
5453 DEFSYM (Qevaporate, "evaporate");
5454 DEFSYM (Qmodification_hooks, "modification-hooks");
5455 DEFSYM (Qinsert_in_front_hooks, "insert-in-front-hooks");
5456 DEFSYM (Qinsert_behind_hooks, "insert-behind-hooks");
5457 DEFSYM (Qget_file_buffer, "get-file-buffer");
5458 DEFSYM (Qpriority, "priority");
5459 DEFSYM (Qbefore_string, "before-string");
5460 DEFSYM (Qafter_string, "after-string");
5461 DEFSYM (Qfirst_change_hook, "first-change-hook");
5462 DEFSYM (Qbefore_change_functions, "before-change-functions");
5463 DEFSYM (Qafter_change_functions, "after-change-functions");
5464 DEFSYM (Qkill_buffer_query_functions, "kill-buffer-query-functions");
5465
1ab256cb 5466 Fput (Qprotected_field, Qerror_conditions,
3438fe21 5467 listn (CONSTYPE_PURE, 2, Qprotected_field, Qerror));
1ab256cb 5468 Fput (Qprotected_field, Qerror_message,
2a0213a6 5469 build_pure_c_string ("Attempt to modify a protected field"));
1ab256cb 5470
422745d0
TT
5471 DEFVAR_BUFFER_DEFAULTS ("default-mode-line-format",
5472 mode_line_format,
5473 doc: /* Default value of `mode-line-format' for buffers that don't override it.
018ba359 5474This is the same as (default-value 'mode-line-format). */);
1ab256cb 5475
422745d0
TT
5476 DEFVAR_BUFFER_DEFAULTS ("default-header-line-format",
5477 header_line_format,
5478 doc: /* Default value of `header-line-format' for buffers that don't override it.
018ba359 5479This is the same as (default-value 'header-line-format). */);
0552666b 5480
422745d0
TT
5481 DEFVAR_BUFFER_DEFAULTS ("default-cursor-type", cursor_type,
5482 doc: /* Default value of `cursor-type' for buffers that don't override it.
018ba359 5483This is the same as (default-value 'cursor-type). */);
bd96bd79 5484
422745d0
TT
5485 DEFVAR_BUFFER_DEFAULTS ("default-line-spacing",
5486 extra_line_spacing,
5487 doc: /* Default value of `line-spacing' for buffers that don't override it.
018ba359 5488This is the same as (default-value 'line-spacing). */);
a3bbced0 5489
422745d0
TT
5490 DEFVAR_BUFFER_DEFAULTS ("default-cursor-in-non-selected-windows",
5491 cursor_in_non_selected_windows,
5492 doc: /* Default value of `cursor-in-non-selected-windows'.
187ccf49
KS
5493This is the same as (default-value 'cursor-in-non-selected-windows). */);
5494
422745d0
TT
5495 DEFVAR_BUFFER_DEFAULTS ("default-abbrev-mode",
5496 abbrev_mode,
5497 doc: /* Default value of `abbrev-mode' for buffers that do not override it.
018ba359 5498This is the same as (default-value 'abbrev-mode). */);
1ab256cb 5499
422745d0
TT
5500 DEFVAR_BUFFER_DEFAULTS ("default-ctl-arrow",
5501 ctl_arrow,
5502 doc: /* Default value of `ctl-arrow' for buffers that do not override it.
018ba359 5503This is the same as (default-value 'ctl-arrow). */);
1ab256cb 5504
422745d0
TT
5505 DEFVAR_BUFFER_DEFAULTS ("default-enable-multibyte-characters",
5506 enable_multibyte_characters,
fb7ada5f 5507 doc: /* Default value of `enable-multibyte-characters' for buffers not overriding it.
018ba359 5508This is the same as (default-value 'enable-multibyte-characters). */);
177c0ea7 5509
422745d0
TT
5510 DEFVAR_BUFFER_DEFAULTS ("default-buffer-file-coding-system",
5511 buffer_file_coding_system,
5512 doc: /* Default value of `buffer-file-coding-system' for buffers not overriding it.
018ba359 5513This is the same as (default-value 'buffer-file-coding-system). */);
177c0ea7 5514
422745d0
TT
5515 DEFVAR_BUFFER_DEFAULTS ("default-truncate-lines",
5516 truncate_lines,
5517 doc: /* Default value of `truncate-lines' for buffers that do not override it.
018ba359 5518This is the same as (default-value 'truncate-lines). */);
1ab256cb 5519
422745d0
TT
5520 DEFVAR_BUFFER_DEFAULTS ("default-fill-column",
5521 fill_column,
5522 doc: /* Default value of `fill-column' for buffers that do not override it.
018ba359 5523This is the same as (default-value 'fill-column). */);
1ab256cb 5524
422745d0
TT
5525 DEFVAR_BUFFER_DEFAULTS ("default-left-margin",
5526 left_margin,
5527 doc: /* Default value of `left-margin' for buffers that do not override it.
018ba359 5528This is the same as (default-value 'left-margin). */);
1ab256cb 5529
422745d0
TT
5530 DEFVAR_BUFFER_DEFAULTS ("default-tab-width",
5531 tab_width,
5532 doc: /* Default value of `tab-width' for buffers that do not override it.
018ba359 5533This is the same as (default-value 'tab-width). */);
1ab256cb 5534
422745d0
TT
5535 DEFVAR_BUFFER_DEFAULTS ("default-case-fold-search",
5536 case_fold_search,
5537 doc: /* Default value of `case-fold-search' for buffers that don't override it.
018ba359 5538This is the same as (default-value 'case-fold-search). */);
1ab256cb 5539
422745d0
TT
5540 DEFVAR_BUFFER_DEFAULTS ("default-left-margin-width",
5541 left_margin_cols,
5542 doc: /* Default value of `left-margin-width' for buffers that don't override it.
018ba359 5543This is the same as (default-value 'left-margin-width). */);
0552666b 5544
422745d0
TT
5545 DEFVAR_BUFFER_DEFAULTS ("default-right-margin-width",
5546 right_margin_cols,
5547 doc: /* Default value of `right-margin-width' for buffers that don't override it.
018ba359 5548This is the same as (default-value 'right-margin-width). */);
177c0ea7 5549
422745d0
TT
5550 DEFVAR_BUFFER_DEFAULTS ("default-left-fringe-width",
5551 left_fringe_width,
5552 doc: /* Default value of `left-fringe-width' for buffers that don't override it.
2ad8731a
KS
5553This is the same as (default-value 'left-fringe-width). */);
5554
422745d0
TT
5555 DEFVAR_BUFFER_DEFAULTS ("default-right-fringe-width",
5556 right_fringe_width,
5557 doc: /* Default value of `right-fringe-width' for buffers that don't override it.
2ad8731a
KS
5558This is the same as (default-value 'right-fringe-width). */);
5559
422745d0
TT
5560 DEFVAR_BUFFER_DEFAULTS ("default-fringes-outside-margins",
5561 fringes_outside_margins,
5562 doc: /* Default value of `fringes-outside-margins' for buffers that don't override it.
2ad8731a
KS
5563This is the same as (default-value 'fringes-outside-margins). */);
5564
422745d0
TT
5565 DEFVAR_BUFFER_DEFAULTS ("default-scroll-bar-width",
5566 scroll_bar_width,
5567 doc: /* Default value of `scroll-bar-width' for buffers that don't override it.
2ad8731a
KS
5568This is the same as (default-value 'scroll-bar-width). */);
5569
422745d0
TT
5570 DEFVAR_BUFFER_DEFAULTS ("default-vertical-scroll-bar",
5571 vertical_scroll_bar_type,
5572 doc: /* Default value of `vertical-scroll-bar' for buffers that don't override it.
2ad8731a
KS
5573This is the same as (default-value 'vertical-scroll-bar). */);
5574
422745d0
TT
5575 DEFVAR_BUFFER_DEFAULTS ("default-indicate-empty-lines",
5576 indicate_empty_lines,
5577 doc: /* Default value of `indicate-empty-lines' for buffers that don't override it.
018ba359 5578This is the same as (default-value 'indicate-empty-lines). */);
177c0ea7 5579
422745d0
TT
5580 DEFVAR_BUFFER_DEFAULTS ("default-indicate-buffer-boundaries",
5581 indicate_buffer_boundaries,
5582 doc: /* Default value of `indicate-buffer-boundaries' for buffers that don't override it.
6b61353c
KH
5583This is the same as (default-value 'indicate-buffer-boundaries). */);
5584
422745d0
TT
5585 DEFVAR_BUFFER_DEFAULTS ("default-fringe-indicator-alist",
5586 fringe_indicator_alist,
5587 doc: /* Default value of `fringe-indicator-alist' for buffers that don't override it.
c6a46372
KS
5588This is the same as (default-value 'fringe-indicator-alist'). */);
5589
422745d0
TT
5590 DEFVAR_BUFFER_DEFAULTS ("default-fringe-cursor-alist",
5591 fringe_cursor_alist,
5592 doc: /* Default value of `fringe-cursor-alist' for buffers that don't override it.
c6a46372
KS
5593This is the same as (default-value 'fringe-cursor-alist'). */);
5594
422745d0
TT
5595 DEFVAR_BUFFER_DEFAULTS ("default-scroll-up-aggressively",
5596 scroll_up_aggressively,
5597 doc: /* Default value of `scroll-up-aggressively'.
7614d762 5598This value applies in buffers that don't have their own local values.
fc961256 5599This is the same as (default-value 'scroll-up-aggressively). */);
177c0ea7 5600
422745d0
TT
5601 DEFVAR_BUFFER_DEFAULTS ("default-scroll-down-aggressively",
5602 scroll_down_aggressively,
5603 doc: /* Default value of `scroll-down-aggressively'.
7614d762 5604This value applies in buffers that don't have their own local values.
fc961256 5605This is the same as (default-value 'scroll-down-aggressively). */);
177c0ea7 5606
045dee35 5607 DEFVAR_PER_BUFFER ("header-line-format",
4b4deea2 5608 &BVAR (current_buffer, header_line_format),
7ee72033 5609 Qnil,
7614d762
RS
5610 doc: /* Analogous to `mode-line-format', but controls the header line.
5611The header line appears, optionally, at the top of a window;
5612the mode line appears at the bottom. */);
177c0ea7 5613
4b4deea2 5614 DEFVAR_PER_BUFFER ("mode-line-format", &BVAR (current_buffer, mode_line_format),
efc7e75f
PJ
5615 Qnil,
5616 doc: /* Template for displaying mode line for current buffer.
5f2c76c6
CY
5617
5618The value may be nil, a string, a symbol or a list.
5619
018ba359 5620A value of nil means don't display a mode line.
5f2c76c6
CY
5621
5622For any symbol other than t or nil, the symbol's value is processed as
5623 a mode line construct. As a special exception, if that value is a
5624 string, the string is processed verbatim, without handling any
5625 %-constructs (see below). Also, unless the symbol has a non-nil
5626 `risky-local-variable' property, all properties in any strings, as
5627 well as all :eval and :propertize forms in the value, are ignored.
5628
5629A list whose car is a string or list is processed by processing each
5630 of the list elements recursively, as separate mode line constructs,
5631 and concatenating the results.
5632
5633A list of the form `(:eval FORM)' is processed by evaluating FORM and
5634 using the result as a mode line construct. Be careful--FORM should
5635 not load any files, because that can cause an infinite recursion.
5636
5637A list of the form `(:propertize ELT PROPS...)' is processed by
5638 processing ELT as the mode line construct, and adding the text
5639 properties PROPS to the result.
5640
5641A list whose car is a symbol is processed by examining the symbol's
5642 value, and, if that value is non-nil, processing the cadr of the list
5643 recursively; and if that value is nil, processing the caddr of the
5644 list recursively.
5645
5646A list whose car is an integer is processed by processing the cadr of
5647 the list, and padding (if the number is positive) or truncating (if
5648 negative) to the width specified by that number.
5649
018ba359 5650A string is printed verbatim in the mode line except for %-constructs:
018ba359
PJ
5651 %b -- print buffer name. %f -- print visited file name.
5652 %F -- print frame name.
5653 %* -- print %, * or hyphen. %+ -- print *, % or hyphen.
5654 %& is like %*, but ignore read-only-ness.
5655 % means buffer is read-only and * means it is modified.
5656 For a modified read-only buffer, %* gives % and %+ gives *.
5657 %s -- print process status. %l -- print the current line number.
5658 %c -- print the current column number (this makes editing slower).
5659 To make the column number update correctly in all cases,
5660 `column-number-mode' must be non-nil.
6b61353c
KH
5661 %i -- print the size of the buffer.
5662 %I -- like %i, but use k, M, G, etc., to abbreviate.
018ba359
PJ
5663 %p -- print percent of buffer above top of window, or Top, Bot or All.
5664 %P -- print percent of buffer above bottom of window, perhaps plus Top,
5665 or print Bottom or All.
018ba359 5666 %n -- print Narrow if appropriate.
dafbe726 5667 %t -- visited file is text or binary (if OS supports this distinction).
47419860 5668 %z -- print mnemonics of keyboard, terminal, and buffer coding systems.
018ba359 5669 %Z -- like %z, but including the end-of-line format.
dafbe726 5670 %e -- print error message about full memory.
f7165034
NR
5671 %@ -- print @ or hyphen. @ means that default-directory is on a
5672 remote machine.
018ba359
PJ
5673 %[ -- print one [ for each recursive editing level. %] similar.
5674 %% -- print %. %- -- print infinitely many dashes.
5675Decimal digits after the % specify field width to which to pad. */);
5676
422745d0 5677 DEFVAR_BUFFER_DEFAULTS ("default-major-mode", major_mode,
fb7ada5f 5678 doc: /* Value of `major-mode' for new buffers. */);
1ab256cb 5679
4b4deea2 5680 DEFVAR_PER_BUFFER ("major-mode", &BVAR (current_buffer, major_mode),
7ee72033 5681 make_number (Lisp_Symbol),
5a021dd0
GM
5682 doc: /* Symbol for current buffer's major mode.
5683The default value (normally `fundamental-mode') affects new buffers.
5684A value of nil means to use the current buffer's major mode, provided
5685it is not marked as "special".
5686
5687When a mode is used by default, `find-file' switches to it before it
5688reads the contents into the buffer and before it finishes setting up
5689the buffer. Thus, the mode and its hooks should not expect certain
5690variables such as `buffer-read-only' and `buffer-file-coding-system'
5691to be set up. */);
1ab256cb 5692
4b4deea2 5693 DEFVAR_PER_BUFFER ("mode-name", &BVAR (current_buffer, mode_name),
c01d0677 5694 Qnil,
64a7c220 5695 doc: /* Pretty name of current buffer's major mode.
7cb70974
EZ
5696Usually a string, but can use any of the constructs for `mode-line-format',
5697which see.
5698Format with `format-mode-line' to produce a string value. */);
1ab256cb 5699
4b4deea2 5700 DEFVAR_PER_BUFFER ("local-abbrev-table", &BVAR (current_buffer, abbrev_table), Qnil,
d6aa1876
SM
5701 doc: /* Local (mode-specific) abbrev table of current buffer. */);
5702
4b4deea2 5703 DEFVAR_PER_BUFFER ("abbrev-mode", &BVAR (current_buffer, abbrev_mode), Qnil,
9d794026
GM
5704 doc: /* Non-nil if Abbrev mode is enabled.
5705Use the command `abbrev-mode' to change this variable. */);
1ab256cb 5706
4b4deea2 5707 DEFVAR_PER_BUFFER ("case-fold-search", &BVAR (current_buffer, case_fold_search),
7ee72033 5708 Qnil,
fb7ada5f 5709 doc: /* Non-nil if searches and matches should ignore case. */);
1ab256cb 5710
4b4deea2 5711 DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column),
d5040d2d 5712 make_number (Lisp_Int0),
fb7ada5f 5713 doc: /* Column beyond which automatic line-wrapping should happen.
f1ccb329 5714Interactively, you can set the buffer local value using \\[set-fill-column]. */);
1ab256cb 5715
4b4deea2 5716 DEFVAR_PER_BUFFER ("left-margin", &BVAR (current_buffer, left_margin),
d5040d2d 5717 make_number (Lisp_Int0),
fb7ada5f 5718 doc: /* Column for the default `indent-line-function' to indent to.
018ba359 5719Linefeed indents to this column in Fundamental mode. */);
1ab256cb 5720
4b4deea2 5721 DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width),
d5040d2d 5722 make_number (Lisp_Int0),
fb7ada5f 5723 doc: /* Distance between tab stops (for display of tab characters), in columns.
fde4eb86 5724This should be an integer greater than zero. */);
1ab256cb 5725
4b4deea2 5726 DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil,
fb7ada5f 5727 doc: /* Non-nil means display control chars with uparrow.
018ba359
PJ
5728A value of nil means use backslash and octal digits.
5729This variable does not apply to characters whose display is specified
5730in the current display table (if there is one). */);
1ab256cb 5731
3b06f880 5732 DEFVAR_PER_BUFFER ("enable-multibyte-characters",
4b4deea2 5733 &BVAR (current_buffer, enable_multibyte_characters),
a9b9a780 5734 Qnil,
efc7e75f 5735 doc: /* Non-nil means the buffer contents are regarded as multi-byte characters.
018ba359
PJ
5736Otherwise they are regarded as unibyte. This affects the display,
5737file I/O and the behavior of various editing commands.
5738
5739This variable is buffer-local but you cannot set it directly;
5740use the function `set-buffer-multibyte' to change a buffer's representation.
a66cfb1c 5741See also Info node `(elisp)Text Representations'. */);
d67b4f80 5742 XSYMBOL (intern_c_string ("enable-multibyte-characters"))->constant = 1;
3b06f880 5743
c71b5d9b 5744 DEFVAR_PER_BUFFER ("buffer-file-coding-system",
4b4deea2 5745 &BVAR (current_buffer, buffer_file_coding_system), Qnil,
efc7e75f 5746 doc: /* Coding system to be used for encoding the buffer contents on saving.
018ba359
PJ
5747This variable applies to saving the buffer, and also to `write-region'
5748and other functions that use `write-region'.
5749It does not apply to sending output to subprocesses, however.
5750
5751If this is nil, the buffer is saved without any code conversion
5752unless some coding system is specified in `file-coding-system-alist'
5753for the buffer file.
5754
31a6cb06
EZ
5755If the text to be saved cannot be encoded as specified by this variable,
5756an alternative encoding is selected by `select-safe-coding-system', which see.
5757
018ba359
PJ
5758The variable `coding-system-for-write', if non-nil, overrides this variable.
5759
5760This variable is never applied to a way of decoding a file while reading it. */);
c71b5d9b 5761
f44e260c 5762 DEFVAR_PER_BUFFER ("bidi-display-reordering",
4b4deea2 5763 &BVAR (current_buffer, bidi_display_reordering), Qnil,
938efb77 5764 doc: /* Non-nil means reorder bidirectional text for display in the visual order. */);
3b06f880 5765
6c0cf218 5766 DEFVAR_PER_BUFFER ("bidi-paragraph-direction",
4b4deea2 5767 &BVAR (current_buffer, bidi_paragraph_direction), Qnil,
fb7ada5f 5768 doc: /* If non-nil, forces directionality of text paragraphs in the buffer.
b4bf28b7 5769
b44d9321
EZ
5770If this is nil (the default), the direction of each paragraph is
5771determined by the first strong directional character of its text.
5772The values of `right-to-left' and `left-to-right' override that.
5773Any other value is treated as nil.
b4bf28b7 5774
b44d9321
EZ
5775This variable has no effect unless the buffer's value of
5776\`bidi-display-reordering' is non-nil. */);
5777
4b4deea2 5778 DEFVAR_PER_BUFFER ("truncate-lines", &BVAR (current_buffer, truncate_lines), Qnil,
fb7ada5f 5779 doc: /* Non-nil means do not display continuation lines.
7614d762 5780Instead, give each line of text just one screen line.
018ba359
PJ
5781
5782Note that this is overridden by the variable
5783`truncate-partial-width-windows' if that variable is non-nil
32bbb17c
GM
5784and this buffer is not full-frame width.
5785
5786Minibuffers set this variable to nil. */);
1ab256cb 5787
4b4deea2 5788 DEFVAR_PER_BUFFER ("word-wrap", &BVAR (current_buffer, word_wrap), Qnil,
fb7ada5f 5789 doc: /* Non-nil means to use word-wrapping for continuation lines.
0858cd02
CY
5790When word-wrapping is on, continuation lines are wrapped at the space
5791or tab character nearest to the right window edge.
5792If nil, continuation lines are wrapped at the right screen edge.
5793
5794This variable has no effect if long lines are truncated (see
eb577e27
GM
5795`truncate-lines' and `truncate-partial-width-windows'). If you use
5796word-wrapping, you might want to reduce the value of
5797`truncate-partial-width-windows', since wrapping can make text readable
c5cfcbe0
CY
5798in narrower windows.
5799
5800Instead of setting this variable directly, most users should use
5801Visual Line mode . Visual Line mode, when enabled, sets `word-wrap'
5802to t, and additionally redefines simple editing commands to act on
5803visual lines rather than logical lines. See the documentation of
5804`visual-line-mode'. */);
0858cd02 5805
4b4deea2 5806 DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory),
7ee72033 5807 make_number (Lisp_String),
efc7e75f 5808 doc: /* Name of default directory of current buffer. Should end with slash.
018ba359 5809To interactively change the default directory, use command `cd'. */);
1ab256cb 5810
4b4deea2 5811 DEFVAR_PER_BUFFER ("auto-fill-function", &BVAR (current_buffer, auto_fill_function),
7ee72033 5812 Qnil,
efc7e75f 5813 doc: /* Function called (if non-nil) to perform auto-fill.
018ba359
PJ
5814It is called after self-inserting any character specified in
5815the `auto-fill-chars' table.
5816NOTE: This variable is not a hook;
5817its value may not be a list of functions. */);
1ab256cb 5818
4b4deea2 5819 DEFVAR_PER_BUFFER ("buffer-file-name", &BVAR (current_buffer, filename),
7ee72033 5820 make_number (Lisp_String),
efc7e75f 5821 doc: /* Name of file visited in current buffer, or nil if not visiting a file. */);
1ab256cb 5822
4b4deea2 5823 DEFVAR_PER_BUFFER ("buffer-file-truename", &BVAR (current_buffer, file_truename),
7ee72033 5824 make_number (Lisp_String),
efc7e75f 5825 doc: /* Abbreviated truename of file visited in current buffer, or nil if none.
018ba359
PJ
5826The truename of a file is calculated by `file-truename'
5827and then abbreviated with `abbreviate-file-name'. */);
f6ed2e84 5828
1ab256cb 5829 DEFVAR_PER_BUFFER ("buffer-auto-save-file-name",
4b4deea2 5830 &BVAR (current_buffer, auto_save_file_name),
7ee72033 5831 make_number (Lisp_String),
7614d762
RS
5832 doc: /* Name of file for auto-saving current buffer.
5833If it is nil, that means don't auto-save this buffer. */);
1ab256cb 5834
4b4deea2 5835 DEFVAR_PER_BUFFER ("buffer-read-only", &BVAR (current_buffer, read_only), Qnil,
efc7e75f 5836 doc: /* Non-nil if this buffer is read-only. */);
1ab256cb 5837
4b4deea2 5838 DEFVAR_PER_BUFFER ("buffer-backed-up", &BVAR (current_buffer, backed_up), Qnil,
efc7e75f 5839 doc: /* Non-nil if this buffer's file has been backed up.
018ba359 5840Backing up is done before the first time the file is saved. */);
1ab256cb 5841
4b4deea2 5842 DEFVAR_PER_BUFFER ("buffer-saved-size", &BVAR (current_buffer, save_length),
d5040d2d 5843 make_number (Lisp_Int0),
efc7e75f 5844 doc: /* Length of current buffer when last read in, saved or auto-saved.
4be941e3
RS
58450 initially.
5846-1 means auto-saving turned off until next real save.
5847
5848If you set this to -2, that means don't turn off auto-saving in this buffer
5849if its text size shrinks. If you use `buffer-swap-text' on a buffer,
5850you probably should set this to -2 in that buffer. */);
1ab256cb 5851
4b4deea2 5852 DEFVAR_PER_BUFFER ("selective-display", &BVAR (current_buffer, selective_display),
7ee72033 5853 Qnil,
7614d762 5854 doc: /* Non-nil enables selective display.
a66f285a
JB
5855An integer N as value means display only lines
5856that start with less than N columns of space.
7614d762
RS
5857A value of t means that the character ^M makes itself and
5858all the rest of the line invisible; also, when saving the buffer
5859in a file, save the ^M as a newline. */);
1ab256cb 5860
1ab256cb 5861 DEFVAR_PER_BUFFER ("selective-display-ellipses",
4b4deea2 5862 &BVAR (current_buffer, selective_display_ellipses),
7ee72033 5863 Qnil,
3f676284 5864 doc: /* Non-nil means display ... on previous line when a line is invisible. */);
1ab256cb 5865
4b4deea2 5866 DEFVAR_PER_BUFFER ("overwrite-mode", &BVAR (current_buffer, overwrite_mode), Qnil,
efc7e75f 5867 doc: /* Non-nil if self-insertion should replace existing text.
018ba359
PJ
5868The value should be one of `overwrite-mode-textual',
5869`overwrite-mode-binary', or nil.
5870If it is `overwrite-mode-textual', self-insertion still
5871inserts at the end of a line, and inserts when point is before a tab,
5872until the tab is filled in.
5873If `overwrite-mode-binary', self-insertion replaces newlines and tabs too. */);
5874
4b4deea2 5875 DEFVAR_PER_BUFFER ("buffer-display-table", &BVAR (current_buffer, display_table),
7ee72033 5876 Qnil,
efc7e75f 5877 doc: /* Display table that controls display of the contents of current buffer.
018ba359
PJ
5878
5879If this variable is nil, the value of `standard-display-table' is used.
5880Each window can have its own, overriding display table, see
5881`set-window-display-table' and `window-display-table'.
5882
5883The display table is a char-table created with `make-display-table'.
5884A char-table is an array indexed by character codes. Normal array
5885primitives `aref' and `aset' can be used to access elements of a char-table.
5886
5887Each of the char-table elements control how to display the corresponding
5888text character: the element at index C in the table says how to display
5889the character whose code is C. Each element should be a vector of
426a9163
JB
5890characters or nil. The value nil means display the character in the
5891default fashion; otherwise, the characters from the vector are delivered
5892to the screen instead of the original character.
018ba359 5893
5fd11dc8 5894For example, (aset buffer-display-table ?X [?Y]) tells Emacs
adbb3b05 5895to display a capital Y instead of each X character.
018ba359
PJ
5896
5897In addition, a char-table has six extra slots to control the display of:
5898
5899 the end of a truncated screen line (extra-slot 0, a single character);
5900 the end of a continued line (extra-slot 1, a single character);
5901 the escape character used to display character codes in octal
5902 (extra-slot 2, a single character);
5903 the character used as an arrow for control characters (extra-slot 3,
5904 a single character);
5905 the decoration indicating the presence of invisible lines (extra-slot 4,
5906 a vector of characters);
5907 the character used to draw the border between side-by-side windows
5908 (extra-slot 5, a single character).
5909
5910See also the functions `display-table-slot' and `set-display-table-slot'. */);
1ab256cb 5911
4b4deea2 5912 DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols),
7ee72033 5913 Qnil,
fb7ada5f 5914 doc: /* Width of left marginal area for display of a buffer.
018ba359 5915A value of nil means no marginal area. */);
177c0ea7 5916
4b4deea2 5917 DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols),
7ee72033 5918 Qnil,
fb7ada5f 5919 doc: /* Width of right marginal area for display of a buffer.
018ba359 5920A value of nil means no marginal area. */);
177c0ea7 5921
4b4deea2 5922 DEFVAR_PER_BUFFER ("left-fringe-width", &BVAR (current_buffer, left_fringe_width),
2ad8731a 5923 Qnil,
fb7ada5f 5924 doc: /* Width of this buffer's left fringe (in pixels).
2ad8731a
KS
5925A value of 0 means no left fringe is shown in this buffer's window.
5926A value of nil means to use the left fringe width from the window's frame. */);
5927
4b4deea2 5928 DEFVAR_PER_BUFFER ("right-fringe-width", &BVAR (current_buffer, right_fringe_width),
2ad8731a 5929 Qnil,
fb7ada5f 5930 doc: /* Width of this buffer's right fringe (in pixels).
2ad8731a
KS
5931A value of 0 means no right fringe is shown in this buffer's window.
5932A value of nil means to use the right fringe width from the window's frame. */);
5933
4b4deea2 5934 DEFVAR_PER_BUFFER ("fringes-outside-margins", &BVAR (current_buffer, fringes_outside_margins),
2ad8731a 5935 Qnil,
fb7ada5f 5936 doc: /* Non-nil means to display fringes outside display margins.
2ad8731a
KS
5937A value of nil means to display fringes between margins and buffer text. */);
5938
4b4deea2 5939 DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width),
2ad8731a 5940 Qnil,
fb7ada5f 5941 doc: /* Width of this buffer's scroll bars in pixels.
2ad8731a
KS
5942A value of nil means to use the scroll bar width from the window's frame. */);
5943
4b4deea2 5944 DEFVAR_PER_BUFFER ("vertical-scroll-bar", &BVAR (current_buffer, vertical_scroll_bar_type),
2ad8731a 5945 Qnil,
fb7ada5f 5946 doc: /* Position of this buffer's vertical scroll bar.
7c6b2007 5947The value takes effect whenever you tell a window to display this buffer;
188577ce 5948for instance, with `set-window-buffer' or when `display-buffer' displays it.
7c6b2007 5949
fc2c8887
RS
5950A value of `left' or `right' means put the vertical scroll bar at that side
5951of the window; a value of nil means don't show any vertical scroll bars.
5952A value of t (the default) means do whatever the window's frame specifies. */);
2ad8731a 5953
0552666b 5954 DEFVAR_PER_BUFFER ("indicate-empty-lines",
4b4deea2 5955 &BVAR (current_buffer, indicate_empty_lines), Qnil,
fb7ada5f 5956 doc: /* Visually indicate empty lines after the buffer end.
018ba359
PJ
5957If non-nil, a bitmap is displayed in the left fringe of a window on
5958window-systems. */);
177c0ea7 5959
6b61353c 5960 DEFVAR_PER_BUFFER ("indicate-buffer-boundaries",
4b4deea2 5961 &BVAR (current_buffer, indicate_buffer_boundaries), Qnil,
fb7ada5f 5962 doc: /* Visually indicate buffer boundaries and scrolling.
6b61353c
KH
5963If non-nil, the first and last line of the buffer are marked in the fringe
5964of a window on window-systems with angle bitmaps, or if the window can be
5965scrolled, the top and bottom line of the window are marked with up and down
5966arrow bitmaps.
b2229037
KS
5967
5968If value is a symbol `left' or `right', both angle and arrow bitmaps
79e3497d 5969are displayed in the left or right fringe, resp. Any other value
845a78b4 5970that doesn't look like an alist means display the angle bitmaps in
79e3497d 5971the left fringe but no arrows.
b2229037 5972
79e3497d
RS
5973You can exercise more precise control by using an alist as the
5974value. Each alist element (INDICATOR . POSITION) specifies
5975where to show one of the indicators. INDICATOR is one of `top',
b2229037
KS
5976`bottom', `up', `down', or t, which specifies the default position,
5977and POSITION is one of `left', `right', or nil, meaning do not show
5978this indicator.
5979
5980For example, ((top . left) (t . right)) places the top angle bitmap in
5981left fringe, the bottom angle bitmap in right fringe, and both arrow
6b61353c 5982bitmaps in right fringe. To show just the angle bitmaps in the left
b2229037 5983fringe, but no arrow bitmaps, use ((top . left) (bottom . left)). */);
6b61353c 5984
c6a46372 5985 DEFVAR_PER_BUFFER ("fringe-indicator-alist",
4b4deea2 5986 &BVAR (current_buffer, fringe_indicator_alist), Qnil,
fb7ada5f 5987 doc: /* Mapping from logical to physical fringe indicator bitmaps.
c6a46372
KS
5988The value is an alist where each element (INDICATOR . BITMAPS)
5989specifies the fringe bitmaps used to display a specific logical
5990fringe indicator.
5991
5992INDICATOR specifies the logical indicator type which is one of the
5993following symbols: `truncation' , `continuation', `overlay-arrow',
14fb5704 5994`top', `bottom', `top-bottom', `up', `down', empty-line', or `unknown'.
c6a46372 5995
14fb5704 5996BITMAPS is a list of symbols (LEFT RIGHT [LEFT1 RIGHT1]) which specifies
c6a46372
KS
5997the actual bitmap shown in the left or right fringe for the logical
5998indicator. LEFT and RIGHT are the bitmaps shown in the left and/or
5999right fringe for the specific indicator. The LEFT1 or RIGHT1 bitmaps
14fb5704
JB
6000are used only for the `bottom' and `top-bottom' indicators when the
6001last (only) line has no final newline. BITMAPS may also be a single
c6a46372
KS
6002symbol which is used in both left and right fringes. */);
6003
6004 DEFVAR_PER_BUFFER ("fringe-cursor-alist",
4b4deea2 6005 &BVAR (current_buffer, fringe_cursor_alist), Qnil,
fb7ada5f 6006 doc: /* Mapping from logical to physical fringe cursor bitmaps.
c6a46372
KS
6007The value is an alist where each element (CURSOR . BITMAP)
6008specifies the fringe bitmaps used to display a specific logical
6009cursor type in the fringe.
6010
6011CURSOR specifies the logical cursor type which is one of the following
6012symbols: `box' , `hollow', `bar', `hbar', or `hollow-small'. The last
6013one is used to show a hollow cursor on narrow lines display lines
6014where the normal hollow cursor will not fit.
6015
6016BITMAP is the corresponding fringe bitmap shown for the logical
6017cursor type. */);
6018
0552666b 6019 DEFVAR_PER_BUFFER ("scroll-up-aggressively",
4b4deea2 6020 &BVAR (current_buffer, scroll_up_aggressively), Qnil,
4e0692c1
RS
6021 doc: /* How far to scroll windows upward.
6022If you move point off the bottom, the window scrolls automatically.
426a9163 6023This variable controls how far it scrolls. The value nil, the default,
4e0692c1
RS
6024means scroll to center point. A fraction means scroll to put point
6025that fraction of the window's height from the bottom of the window.
d765e3a3
JB
6026When the value is 0.0, point goes at the bottom line, which in the
6027simple case that you moved off with C-f means scrolling just one line.
60281.0 means point goes at the top, so that in that simple case, the
6029window scrolls by a full window height. Meaningful values are
175e9712 6030between 0.0 and 1.0, inclusive. */);
177c0ea7 6031
0552666b 6032 DEFVAR_PER_BUFFER ("scroll-down-aggressively",
4b4deea2 6033 &BVAR (current_buffer, scroll_down_aggressively), Qnil,
4e0692c1
RS
6034 doc: /* How far to scroll windows downward.
6035If you move point off the top, the window scrolls automatically.
426a9163 6036This variable controls how far it scrolls. The value nil, the default,
4e0692c1
RS
6037means scroll to center point. A fraction means scroll to put point
6038that fraction of the window's height from the top of the window.
d765e3a3
JB
6039When the value is 0.0, point goes at the top line, which in the
6040simple case that you moved off with C-b means scrolling just one line.
60411.0 means point goes at the bottom, so that in that simple case, the
6042window scrolls by a full window height. Meaningful values are
175e9712 6043between 0.0 and 1.0, inclusive. */);
177c0ea7 6044
1ab256cb
RM
6045/*DEFVAR_LISP ("debug-check-symbol", &Vcheck_symbol,
6046 "Don't ask.");
6047*/
1ab256cb 6048
29208e82 6049 DEFVAR_LISP ("before-change-functions", Vbefore_change_functions,
7ee72033 6050 doc: /* List of functions to call before each text change.
018ba359
PJ
6051Two arguments are passed to each function: the positions of
6052the beginning and end of the range of old text to be changed.
6053\(For an insertion, the beginning and end are at the same place.)
6054No information is given about the length of the text after the change.
6055
6056Buffer changes made while executing the `before-change-functions'
6057don't call any before-change or after-change functions.
7b2bf907 6058That's because `inhibit-modification-hooks' is temporarily set non-nil.
018ba359
PJ
6059
6060If an unhandled error happens in running these functions,
6061the variable's value remains nil. That prevents the error
6062from happening repeatedly and making Emacs nonfunctional. */);
5f079267
RS
6063 Vbefore_change_functions = Qnil;
6064
29208e82 6065 DEFVAR_LISP ("after-change-functions", Vafter_change_functions,
eacdfade 6066 doc: /* List of functions to call after each text change.
018ba359
PJ
6067Three arguments are passed to each function: the positions of
6068the beginning and end of the range of changed text,
6069and the length in bytes of the pre-change text replaced by that range.
6070\(For an insertion, the pre-change length is zero;
6071for a deletion, that length is the number of bytes deleted,
6072and the post-change beginning and end are at the same place.)
6073
6074Buffer changes made while executing the `after-change-functions'
6075don't call any before-change or after-change functions.
7b2bf907 6076That's because `inhibit-modification-hooks' is temporarily set non-nil.
018ba359
PJ
6077
6078If an unhandled error happens in running these functions,
6079the variable's value remains nil. That prevents the error
6080from happening repeatedly and making Emacs nonfunctional. */);
5f079267
RS
6081 Vafter_change_functions = Qnil;
6082
29208e82 6083 DEFVAR_LISP ("first-change-hook", Vfirst_change_hook,
efc7e75f 6084 doc: /* A list of functions to call before changing a buffer which is unmodified.
018ba359 6085The functions are run using the `run-hooks' function. */);
dbc4e1c1 6086 Vfirst_change_hook = Qnil;
1ab256cb 6087
4b4deea2 6088 DEFVAR_PER_BUFFER ("buffer-undo-list", &BVAR (current_buffer, undo_list), Qnil,
7ee72033 6089 doc: /* List of undo entries in current buffer.
018ba359
PJ
6090Recent changes come first; older changes follow newer.
6091
6092An entry (BEG . END) represents an insertion which begins at
6093position BEG and ends at position END.
6094
6095An entry (TEXT . POSITION) represents the deletion of the string TEXT
6096from (abs POSITION). If POSITION is positive, point was at the front
6097of the text being deleted; if negative, point was at the end.
6098
d35af63c
PE
6099An entry (t HIGH LOW USEC PSEC) indicates that the buffer was previously
6100unmodified; (HIGH LOW USEC PSEC) is in the same style as (current-time)
6101and is the visited file's modification time, as of that time. If the
018ba359
PJ
6102modification time of the most recent save is different, this entry is
6103obsolete.
6104
6105An entry (nil PROPERTY VALUE BEG . END) indicates that a text property
6106was modified between BEG and END. PROPERTY is the property name,
6107and VALUE is the old value.
6108
7405f386
KS
6109An entry (apply FUN-NAME . ARGS) means undo the change with
6110\(apply FUN-NAME ARGS).
6111
6112An entry (apply DELTA BEG END FUN-NAME . ARGS) supports selective undo
6113in the active region. BEG and END is the range affected by this entry
6114and DELTA is the number of bytes added or deleted in that range by
6115this change.
c6c7dc03 6116
018ba359
PJ
6117An entry (MARKER . DISTANCE) indicates that the marker MARKER
6118was adjusted in position by the offset DISTANCE (an integer).
6119
6120An entry of the form POSITION indicates that point was at the buffer
6121location given by the integer. Undoing an entry of this form places
6122point at POSITION.
6123
b4c4f2f4
JB
6124Entries with value `nil' mark undo boundaries. The undo command treats
6125the changes between two undo boundaries as a single step to be undone.
018ba359
PJ
6126
6127If the value of the variable is t, undo information is not recorded. */);
6128
4b4deea2 6129 DEFVAR_PER_BUFFER ("mark-active", &BVAR (current_buffer, mark_active), Qnil,
7ee72033 6130 doc: /* Non-nil means the mark and region are currently active in this buffer. */);
018ba359 6131
4b4deea2 6132 DEFVAR_PER_BUFFER ("cache-long-line-scans", &BVAR (current_buffer, cache_long_line_scans), Qnil,
7ee72033 6133 doc: /* Non-nil means that Emacs should use caches to handle long lines more quickly.
018ba359
PJ
6134
6135Normally, the line-motion functions work by scanning the buffer for
5629f29b
DK
6136newlines. Columnar operations (like `move-to-column' and
6137`compute-motion') also work by scanning the buffer, summing character
018ba359
PJ
6138widths as they go. This works well for ordinary text, but if the
6139buffer's lines are very long (say, more than 500 characters), these
6140motion functions will take longer to execute. Emacs may also take
6141longer to update the display.
6142
5629f29b 6143If `cache-long-line-scans' is non-nil, these motion functions cache the
018ba359
PJ
6144results of their scans, and consult the cache to avoid rescanning
6145regions of the buffer until the text is modified. The caches are most
6146beneficial when they prevent the most searching---that is, when the
6147buffer contains long lines and large regions of characters with the
6148same, fixed screen width.
6149
5629f29b 6150When `cache-long-line-scans' is non-nil, processing short lines will
018ba359
PJ
6151become slightly slower (because of the overhead of consulting the
6152cache), and the caches will use memory roughly proportional to the
6153number of newlines and characters whose screen width varies.
6154
6155The caches require no explicit maintenance; their accuracy is
6156maintained internally by the Emacs primitives. Enabling or disabling
6157the cache should not affect the behavior of any of the motion
6158functions; it should only affect their performance. */);
6159
4b4deea2 6160 DEFVAR_PER_BUFFER ("point-before-scroll", &BVAR (current_buffer, point_before_scroll), Qnil,
7ee72033 6161 doc: /* Value of point before the last series of scroll operations, or nil. */);
018ba359 6162
4b4deea2 6163 DEFVAR_PER_BUFFER ("buffer-file-format", &BVAR (current_buffer, file_format), Qnil,
7ee72033 6164 doc: /* List of formats to use when saving this buffer.
018ba359 6165Formats are defined by `format-alist'. This variable is
a9b9a780 6166set when a file is visited. */);
be9aafdd 6167
71ed49fa 6168 DEFVAR_PER_BUFFER ("buffer-auto-save-file-format",
4b4deea2 6169 &BVAR (current_buffer, auto_save_file_format), Qnil,
fb7ada5f 6170 doc: /* Format in which to write auto-save files.
71ed49fa
LT
6171Should be a list of symbols naming formats that are defined in `format-alist'.
6172If it is t, which is the default, auto-save files are written in the
6173same format as a regular save would use. */);
6174
3cb719bd 6175 DEFVAR_PER_BUFFER ("buffer-invisibility-spec",
4b4deea2 6176 &BVAR (current_buffer, invisibility_spec), Qnil,
7ee72033 6177 doc: /* Invisibility spec of this buffer.
018ba359
PJ
6178The default is t, which means that text is invisible
6179if it has a non-nil `invisible' property.
6180If the value is a list, a text character is invisible if its `invisible'
b49dd850 6181property is an element in that list (or is a list with members in common).
018ba359
PJ
6182If an element is a cons cell of the form (PROP . ELLIPSIS),
6183then characters with property value PROP are invisible,
6184and they have an ellipsis as well if ELLIPSIS is non-nil. */);
3cb719bd 6185
7962a441 6186 DEFVAR_PER_BUFFER ("buffer-display-count",
4b4deea2 6187 &BVAR (current_buffer, display_count), Qnil,
7ee72033 6188 doc: /* A number incremented each time this buffer is displayed in a window.
018ba359 6189The function `set-window-buffer' increments it. */);
3fd364db
RS
6190
6191 DEFVAR_PER_BUFFER ("buffer-display-time",
4b4deea2 6192 &BVAR (current_buffer, display_time), Qnil,
7ee72033 6193 doc: /* Time stamp updated each time this buffer is displayed in a window.
018ba359
PJ
6194The function `set-window-buffer' updates this variable
6195to the value obtained by calling `current-time'.
6196If the buffer has never been shown in a window, the value is nil. */);
6197
29208e82 6198 DEFVAR_LISP ("transient-mark-mode", Vtransient_mark_mode,
9d794026
GM
6199 doc: /* Non-nil if Transient Mark mode is enabled.
6200See the command `transient-mark-mode' for a description of this minor mode.
6201
6202Non-nil also enables highlighting of the region whenever the mark is active.
6203The variable `highlight-nonselected-windows' controls whether to highlight
6204all windows or just the selected window.
6205
f49d1f52 6206Lisp programs may give this variable certain special values:
9d794026 6207
f49d1f52
SM
6208- A value of `lambda' enables Transient Mark mode temporarily.
6209 It is disabled again after any subsequent action that would
6210 normally deactivate the mark (e.g. buffer modification).
6211
6212- A value of (only . OLDVAL) enables Transient Mark mode
6213 temporarily. After any subsequent point motion command that is
6214 not shift-translated, or any other action that would normally
6215 deactivate the mark (e.g. buffer modification), the value of
6216 `transient-mark-mode' is set to OLDVAL. */);
c48f61ef
RS
6217 Vtransient_mark_mode = Qnil;
6218
29208e82 6219 DEFVAR_LISP ("inhibit-read-only", Vinhibit_read_only,
fb7ada5f 6220 doc: /* Non-nil means disregard read-only status of buffers or characters.
018ba359
PJ
6221If the value is t, disregard `buffer-read-only' and all `read-only'
6222text properties. If the value is a list, disregard `buffer-read-only'
6223and disregard a `read-only' text property if the property value
6224is a member of the list. */);
a96b68f1
RS
6225 Vinhibit_read_only = Qnil;
6226
4b4deea2 6227 DEFVAR_PER_BUFFER ("cursor-type", &BVAR (current_buffer, cursor_type), Qnil,
f6e22881 6228 doc: /* Cursor to use when this buffer is in the selected window.
018ba359
PJ
6229Values are interpreted as follows:
6230
b8dc613f
JB
6231 t use the cursor specified for the frame
6232 nil don't display a cursor
6233 box display a filled box cursor
6234 hollow display a hollow box cursor
6235 bar display a vertical bar cursor with default width
6236 (bar . WIDTH) display a vertical bar cursor with width WIDTH
6237 hbar display a horizontal bar cursor with default height
b4234f4c 6238 (hbar . HEIGHT) display a horizontal bar cursor with height HEIGHT
b8dc613f 6239 ANYTHING ELSE display a hollow box cursor
cd8d5236 6240
e08b1705
MR
6241When the buffer is displayed in a non-selected window, the
6242cursor's appearance is instead controlled by the variable
6243`cursor-in-non-selected-windows'. */);
bb2ec976 6244
a3bbced0 6245 DEFVAR_PER_BUFFER ("line-spacing",
4b4deea2 6246 &BVAR (current_buffer, extra_line_spacing), Qnil,
7ee72033 6247 doc: /* Additional space to put between lines when displaying a buffer.
3ba010e5
EZ
6248The space is measured in pixels, and put below lines on graphic displays,
6249see `display-graphic-p'.
60ebfdf3 6250If value is a floating point number, it specifies the spacing relative
fc961256 6251to the default frame line height. A value of nil means add no extra space. */);
a3bbced0 6252
0124c5bd 6253 DEFVAR_PER_BUFFER ("cursor-in-non-selected-windows",
4b4deea2 6254 &BVAR (current_buffer, cursor_in_non_selected_windows), Qnil,
fb7ada5f 6255 doc: /* Non-nil means show a cursor in non-selected windows.
66c6abf0
GM
6256If nil, only shows a cursor in the selected window.
6257If t, displays a cursor related to the usual cursor type
6258\(a solid box becomes hollow, a bar becomes a narrower bar).
6259You can also specify the cursor type as in the `cursor-type' variable.
6260Use Custom to set this variable and update the display." */);
0124c5bd 6261
29208e82 6262 DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions,
f6e22881
JB
6263 doc: /* List of functions called with no args to query before killing a buffer.
6264The buffer being killed will be current while the functions are running.
b7e8d081
MR
6265
6266If any of them returns nil, the buffer is not killed. Functions run by
6267this hook are supposed to not change the current buffer. */);
dcdffbf6
RS
6268 Vkill_buffer_query_functions = Qnil;
6269
29208e82 6270 DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook,
43ed3b8d
CY
6271 doc: /* Normal hook run before changing the major mode of a buffer.
6272The function `kill-all-local-variables' runs this before doing anything else. */);
6273 Vchange_major_mode_hook = Qnil;
cd3520a4 6274 DEFSYM (Qchange_major_mode_hook, "change-major-mode-hook");
43ed3b8d 6275
9397e56f
MR
6276 DEFVAR_LISP ("buffer-list-update-hook", Vbuffer_list_update_hook,
6277 doc: /* Hook run when the buffer list changes.
6278Functions running this hook are `get-buffer-create',
6279`make-indirect-buffer', `rename-buffer', `kill-buffer',
96a72ee9 6280and `bury-buffer-internal'. */);
9397e56f 6281 Vbuffer_list_update_hook = Qnil;
cd3520a4 6282 DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");
9397e56f 6283
0dc88e60 6284 defsubr (&Sbuffer_live_p);
1ab256cb
RM
6285 defsubr (&Sbuffer_list);
6286 defsubr (&Sget_buffer);
6287 defsubr (&Sget_file_buffer);
6288 defsubr (&Sget_buffer_create);
336cd056 6289 defsubr (&Smake_indirect_buffer);
01050cb5 6290 defsubr (&Sgenerate_new_buffer_name);
1ab256cb 6291 defsubr (&Sbuffer_name);
1ab256cb 6292 defsubr (&Sbuffer_file_name);
336cd056 6293 defsubr (&Sbuffer_base_buffer);
79aa712d 6294 defsubr (&Sbuffer_local_value);
1ab256cb
RM
6295 defsubr (&Sbuffer_local_variables);
6296 defsubr (&Sbuffer_modified_p);
6297 defsubr (&Sset_buffer_modified_p);
6298 defsubr (&Sbuffer_modified_tick);
3e145152 6299 defsubr (&Sbuffer_chars_modified_tick);
1ab256cb
RM
6300 defsubr (&Srename_buffer);
6301 defsubr (&Sother_buffer);
1ab256cb
RM
6302 defsubr (&Sbuffer_enable_undo);
6303 defsubr (&Skill_buffer);
e4ed06f1 6304 defsubr (&Sbury_buffer_internal);
a9ee7a59 6305 defsubr (&Sset_buffer_major_mode);
1ab256cb
RM
6306 defsubr (&Scurrent_buffer);
6307 defsubr (&Sset_buffer);
6308 defsubr (&Sbarf_if_buffer_read_only);
3ac81adb 6309 defsubr (&Serase_buffer);
13cda5f9 6310 defsubr (&Sbuffer_swap_text);
3ac81adb 6311 defsubr (&Sset_buffer_multibyte);
1ab256cb 6312 defsubr (&Skill_all_local_variables);
2eec3b4e 6313
52f8ec73 6314 defsubr (&Soverlayp);
2eec3b4e
RS
6315 defsubr (&Smake_overlay);
6316 defsubr (&Sdelete_overlay);
6317 defsubr (&Smove_overlay);
8ebafa8d
JB
6318 defsubr (&Soverlay_start);
6319 defsubr (&Soverlay_end);
6320 defsubr (&Soverlay_buffer);
6321 defsubr (&Soverlay_properties);
2eec3b4e 6322 defsubr (&Soverlays_at);
74514898 6323 defsubr (&Soverlays_in);
2eec3b4e 6324 defsubr (&Snext_overlay_change);
239c932b 6325 defsubr (&Sprevious_overlay_change);
2eec3b4e
RS
6326 defsubr (&Soverlay_recenter);
6327 defsubr (&Soverlay_lists);
6328 defsubr (&Soverlay_get);
6329 defsubr (&Soverlay_put);
a8c21b48 6330 defsubr (&Srestore_buffer_modified_p);
1ab256cb
RM
6331}
6332
dfcf069d 6333void
d3da34e0 6334keys_of_buffer (void)
1ab256cb
RM
6335{
6336 initial_define_key (control_x_map, 'b', "switch-to-buffer");
6337 initial_define_key (control_x_map, 'k', "kill-buffer");
4158c17d
RM
6338
6339 /* This must not be in syms_of_buffer, because Qdisabled is not
6340 initialized when that function gets called. */
d67b4f80 6341 Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt);
1ab256cb 6342}