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