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