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