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