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