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