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