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