Check for termios.h. Check for setpgid.
[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;
0dc6f165 474 b->last_selected_window = Qnil;
fb2030e3
RS
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 523 b->invisibility_spec = Qt;
2e716096
RS
524#ifndef DOS_NT
525 b->buffer_file_type = Qnil;
526#endif
3cb719bd 527
1ab256cb
RM
528#if 0
529 b->sort_table = XSTRING (Vascii_sort_table);
530 b->folding_sort_table = XSTRING (Vascii_folding_sort_table);
531#endif /* 0 */
532
13de9290 533 /* Reset all (or most) per-buffer variables to their defaults. */
1ab256cb 534 b->local_var_alist = Qnil;
13de9290 535 b->local_var_flags &= dont_reset;
1ab256cb
RM
536
537 /* For each slot that has a default value,
538 copy that into the slot. */
539
540 for (offset = (char *)&buffer_local_flags.name - (char *)&buffer_local_flags;
541 offset < sizeof (struct buffer);
4d2f1389 542 offset += sizeof (Lisp_Object)) /* sizeof EMACS_INT == sizeof Lisp_Object */
aab80822
KH
543 {
544 int flag = XINT (*(Lisp_Object *)(offset + (char *)&buffer_local_flags));
13de9290
RS
545 if ((flag > 0
546 /* Don't reset a permanent local. */
547 && ! (dont_reset & flag))
548 || flag == -2)
549 *(Lisp_Object *)(offset + (char *)b)
550 = *(Lisp_Object *)(offset + (char *)&buffer_defaults);
aab80822 551 }
1ab256cb
RM
552}
553
01050cb5
RM
554/* We split this away from generate-new-buffer, because rename-buffer
555 and set-visited-file-name ought to be able to use this to really
556 rename the buffer properly. */
557
558DEFUN ("generate-new-buffer-name", Fgenerate_new_buffer_name, Sgenerate_new_buffer_name,
c273e647 559 1, 2, 0,
01050cb5
RM
560 "Return a string that is the name of no existing buffer based on NAME.\n\
561If there is no live buffer named NAME, then return NAME.\n\
1ab256cb 562Otherwise modify name by appending `<NUMBER>', incrementing NUMBER\n\
c273e647 563until an unused name is found, and then return that name.\n\
03bdd54c 564Optional second argument IGNORE specifies a name that is okay to use\n\
c273e647 565\(if it is in the sequence to be tried)\n\
e8b3a22d 566even if a buffer with that name exists.")
c273e647
RS
567 (name, ignore)
568 register Lisp_Object name, ignore;
1ab256cb
RM
569{
570 register Lisp_Object gentemp, tem;
571 int count;
572 char number[10];
573
574 CHECK_STRING (name, 0);
575
576 tem = Fget_buffer (name);
265a9e55 577 if (NILP (tem))
01050cb5 578 return name;
1ab256cb
RM
579
580 count = 1;
581 while (1)
582 {
583 sprintf (number, "<%d>", ++count);
584 gentemp = concat2 (name, build_string (number));
638e4fc3 585 tem = Fstring_equal (gentemp, ignore);
c273e647
RS
586 if (!NILP (tem))
587 return gentemp;
1ab256cb 588 tem = Fget_buffer (gentemp);
265a9e55 589 if (NILP (tem))
01050cb5 590 return gentemp;
1ab256cb
RM
591 }
592}
593
594\f
595DEFUN ("buffer-name", Fbuffer_name, Sbuffer_name, 0, 1, 0,
596 "Return the name of BUFFER, as a string.\n\
01050cb5 597With no argument or nil as argument, return the name of the current buffer.")
1ab256cb
RM
598 (buffer)
599 register Lisp_Object buffer;
600{
265a9e55 601 if (NILP (buffer))
1ab256cb
RM
602 return current_buffer->name;
603 CHECK_BUFFER (buffer, 0);
604 return XBUFFER (buffer)->name;
605}
606
607DEFUN ("buffer-file-name", Fbuffer_file_name, Sbuffer_file_name, 0, 1, 0,
608 "Return name of file BUFFER is visiting, or nil if none.\n\
609No argument or nil as argument means use the current buffer.")
610 (buffer)
611 register Lisp_Object buffer;
612{
265a9e55 613 if (NILP (buffer))
1ab256cb
RM
614 return current_buffer->filename;
615 CHECK_BUFFER (buffer, 0);
616 return XBUFFER (buffer)->filename;
617}
618
336cd056
RS
619DEFUN ("buffer-base-buffer", Fbuffer_base_buffer, Sbuffer_base_buffer,
620 0, 1, 0,
621 "Return the base buffer of indirect buffer BUFFER.\n\
622If BUFFER is not indirect, return nil.")
623 (buffer)
624 register Lisp_Object buffer;
625{
626 struct buffer *base;
627 Lisp_Object base_buffer;
628
629 if (NILP (buffer))
630 base = current_buffer->base_buffer;
631 else
632 {
633 CHECK_BUFFER (buffer, 0);
634 base = XBUFFER (buffer)->base_buffer;
635 }
636
637 if (! base)
638 return Qnil;
639 XSETBUFFER (base_buffer, base);
640 return base_buffer;
641}
642
1ab256cb
RM
643DEFUN ("buffer-local-variables", Fbuffer_local_variables,
644 Sbuffer_local_variables, 0, 1, 0,
645 "Return an alist of variables that are buffer-local in BUFFER.\n\
553defa4
RS
646Most elements look like (SYMBOL . VALUE), describing one variable.\n\
647For a symbol that is locally unbound, just the symbol appears in the value.\n\
1ab256cb
RM
648Note that storing new VALUEs in these elements doesn't change the variables.\n\
649No argument or nil as argument means use current buffer as BUFFER.")
650 (buffer)
651 register Lisp_Object buffer;
652{
653 register struct buffer *buf;
553defa4 654 register Lisp_Object result;
1ab256cb 655
265a9e55 656 if (NILP (buffer))
1ab256cb
RM
657 buf = current_buffer;
658 else
659 {
660 CHECK_BUFFER (buffer, 0);
661 buf = XBUFFER (buffer);
662 }
663
553defa4
RS
664 result = Qnil;
665
1ab256cb 666 {
553defa4
RS
667 register Lisp_Object tail;
668 for (tail = buf->local_var_alist; CONSP (tail); tail = XCONS (tail)->cdr)
1ab256cb 669 {
553defa4
RS
670 Lisp_Object val, elt;
671
672 elt = XCONS (tail)->car;
673
e0585c64
RS
674 /* Reference each variable in the alist in buf.
675 If inquiring about the current buffer, this gets the current values,
676 so store them into the alist so the alist is up to date.
677 If inquiring about some other buffer, this swaps out any values
678 for that buffer, making the alist up to date automatically. */
679 val = find_symbol_value (XCONS (elt)->car);
680 /* Use the current buffer value only if buf is the current buffer. */
681 if (buf != current_buffer)
553defa4
RS
682 val = XCONS (elt)->cdr;
683
684 /* If symbol is unbound, put just the symbol in the list. */
685 if (EQ (val, Qunbound))
686 result = Fcons (XCONS (elt)->car, result);
687 /* Otherwise, put (symbol . value) in the list. */
688 else
689 result = Fcons (Fcons (XCONS (elt)->car, val), result);
1ab256cb
RM
690 }
691 }
692
1ab256cb
RM
693 /* Add on all the variables stored in special slots. */
694 {
695 register int offset, mask;
696
697 for (offset = (char *)&buffer_local_symbols.name - (char *)&buffer_local_symbols;
698 offset < sizeof (struct buffer);
4d2f1389 699 offset += (sizeof (EMACS_INT))) /* sizeof EMACS_INT == sizeof Lisp_Object */
1ab256cb 700 {
aab80822 701 mask = XINT (*(Lisp_Object *)(offset + (char *)&buffer_local_flags));
1ab256cb 702 if (mask == -1 || (buf->local_var_flags & mask))
aab80822
KH
703 if (SYMBOLP (*(Lisp_Object *)(offset
704 + (char *)&buffer_local_symbols)))
705 result = Fcons (Fcons (*((Lisp_Object *)
706 (offset + (char *)&buffer_local_symbols)),
553defa4
RS
707 *(Lisp_Object *)(offset + (char *)buf)),
708 result);
1ab256cb
RM
709 }
710 }
553defa4
RS
711
712 return result;
1ab256cb
RM
713}
714
715\f
716DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p,
717 0, 1, 0,
718 "Return t if BUFFER was modified since its file was last read or saved.\n\
719No argument or nil as argument means use current buffer as BUFFER.")
720 (buffer)
721 register Lisp_Object buffer;
722{
723 register struct buffer *buf;
265a9e55 724 if (NILP (buffer))
1ab256cb
RM
725 buf = current_buffer;
726 else
727 {
728 CHECK_BUFFER (buffer, 0);
729 buf = XBUFFER (buffer);
730 }
731
336cd056 732 return BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf) ? Qt : Qnil;
1ab256cb
RM
733}
734
735DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p,
736 1, 1, 0,
737 "Mark current buffer as modified or unmodified according to FLAG.\n\
738A non-nil FLAG means mark the buffer modified.")
739 (flag)
740 register Lisp_Object flag;
741{
742 register int already;
743 register Lisp_Object fn;
744
745#ifdef CLASH_DETECTION
746 /* If buffer becoming modified, lock the file.
747 If buffer becoming unmodified, unlock the file. */
748
60f4dd23 749 fn = current_buffer->file_truename;
265a9e55 750 if (!NILP (fn))
1ab256cb 751 {
336cd056 752 already = SAVE_MODIFF < MODIFF;
265a9e55 753 if (!already && !NILP (flag))
1ab256cb 754 lock_file (fn);
265a9e55 755 else if (already && NILP (flag))
1ab256cb
RM
756 unlock_file (fn);
757 }
758#endif /* CLASH_DETECTION */
759
336cd056 760 SAVE_MODIFF = NILP (flag) ? MODIFF : 0;
1ab256cb
RM
761 update_mode_lines++;
762 return flag;
763}
764
765DEFUN ("buffer-modified-tick", Fbuffer_modified_tick, Sbuffer_modified_tick,
766 0, 1, 0,
767 "Return BUFFER's tick counter, incremented for each change in text.\n\
768Each buffer has a tick counter which is incremented each time the text in\n\
769that buffer is changed. It wraps around occasionally.\n\
770No argument or nil as argument means use current buffer as BUFFER.")
771 (buffer)
772 register Lisp_Object buffer;
773{
774 register struct buffer *buf;
265a9e55 775 if (NILP (buffer))
1ab256cb
RM
776 buf = current_buffer;
777 else
778 {
779 CHECK_BUFFER (buffer, 0);
780 buf = XBUFFER (buffer);
781 }
782
783 return make_number (BUF_MODIFF (buf));
784}
785\f
01050cb5 786DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2,
4c7e5f09 787 "sRename buffer (to new name): \nP",
1ab256cb 788 "Change current buffer's name to NEWNAME (a string).\n\
3bd779aa 789If second arg UNIQUE is nil or omitted, it is an error if a\n\
01050cb5 790buffer named NEWNAME already exists.\n\
3bd779aa 791If UNIQUE is non-nil, come up with a new name using\n\
01050cb5 792`generate-new-buffer-name'.\n\
3bd779aa
RS
793Interactively, you can set UNIQUE with a prefix argument.\n\
794We return the name we actually gave the buffer.\n\
1ab256cb 795This does not change the name of the visited file (if any).")
489c043a
RS
796 (newname, unique)
797 register Lisp_Object newname, unique;
1ab256cb
RM
798{
799 register Lisp_Object tem, buf;
800
489c043a 801 CHECK_STRING (newname, 0);
d59698c4 802
489c043a 803 if (XSTRING (newname)->size == 0)
d59698c4
RS
804 error ("Empty string is invalid as a buffer name");
805
489c043a 806 tem = Fget_buffer (newname);
c059b5ea
RM
807 /* Don't short-circuit if UNIQUE is t. That is a useful way to rename
808 the buffer automatically so you can create another with the original name.
809 It makes UNIQUE equivalent to
489c043a 810 (rename-buffer (generate-new-buffer-name NEWNAME)). */
c059b5ea 811 if (NILP (unique) && XBUFFER (tem) == current_buffer)
fb5eba9c 812 return current_buffer->name;
265a9e55 813 if (!NILP (tem))
01050cb5 814 {
3bd779aa 815 if (!NILP (unique))
489c043a 816 newname = Fgenerate_new_buffer_name (newname, current_buffer->name);
01050cb5 817 else
489c043a 818 error ("Buffer name `%s' is in use", XSTRING (newname)->data);
01050cb5 819 }
1ab256cb 820
489c043a 821 current_buffer->name = newname;
76f590d7
JB
822
823 /* Catch redisplay's attention. Unless we do this, the mode lines for
824 any windows displaying current_buffer will stay unchanged. */
825 update_mode_lines++;
826
67180c6a 827 XSETBUFFER (buf, current_buffer);
489c043a 828 Fsetcar (Frassq (buf, Vbuffer_alist), newname);
cf058e49
KH
829 if (NILP (current_buffer->filename)
830 && !NILP (current_buffer->auto_save_file_name))
1ab256cb 831 call0 (intern ("rename-auto-save-file"));
fb5eba9c
RS
832 /* Refetch since that last call may have done GC. */
833 return current_buffer->name;
1ab256cb
RM
834}
835
a0ebb746 836DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 2, 0,
1ab256cb 837 "Return most recently selected buffer other than BUFFER.\n\
a0ebb746
JB
838Buffers not visible in windows are preferred to visible buffers,\n\
839unless optional second argument VISIBLE-OK is non-nil.\n\
1ab256cb
RM
840If no other buffer exists, the buffer `*scratch*' is returned.\n\
841If BUFFER is omitted or nil, some interesting buffer is returned.")
a0ebb746
JB
842 (buffer, visible_ok)
843 register Lisp_Object buffer, visible_ok;
1ab256cb 844{
89132f25 845 Lisp_Object Fset_buffer_major_mode ();
1ab256cb
RM
846 register Lisp_Object tail, buf, notsogood, tem;
847 notsogood = Qnil;
848
265a9e55 849 for (tail = Vbuffer_alist; !NILP (tail); tail = Fcdr (tail))
1ab256cb
RM
850 {
851 buf = Fcdr (Fcar (tail));
852 if (EQ (buf, buffer))
853 continue;
854 if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
855 continue;
04ae1b48
RS
856 /* If the selected frame has a buffer_predicate,
857 disregard buffers that don't fit the predicate. */
858 tem = frame_buffer_predicate ();
859 if (!NILP (tem))
860 {
861 tem = call1 (tem, buf);
862 if (NILP (tem))
863 continue;
864 }
04ae1b48 865
a0ebb746 866 if (NILP (visible_ok))
db732e5a 867 tem = Fget_buffer_window (buf, Qt);
a0ebb746
JB
868 else
869 tem = Qnil;
265a9e55 870 if (NILP (tem))
1ab256cb 871 return buf;
265a9e55 872 if (NILP (notsogood))
1ab256cb
RM
873 notsogood = buf;
874 }
265a9e55 875 if (!NILP (notsogood))
1ab256cb 876 return notsogood;
89132f25
KH
877 buf = Fget_buffer_create (build_string ("*scratch*"));
878 Fset_buffer_major_mode (buf);
879 return buf;
1ab256cb
RM
880}
881\f
316784fb
KH
882DEFUN ("buffer-disable-undo", Fbuffer_disable_undo, Sbuffer_disable_undo,
883 0, 1, "",
5b8bcf48
RS
884 "Make BUFFER stop keeping undo information.\n\
885No argument or nil as argument means do this for the current buffer.")
ffd56f97
JB
886 (buffer)
887 register Lisp_Object buffer;
1ab256cb 888{
ffd56f97
JB
889 Lisp_Object real_buffer;
890
891 if (NILP (buffer))
67180c6a 892 XSETBUFFER (real_buffer, current_buffer);
ffd56f97
JB
893 else
894 {
895 real_buffer = Fget_buffer (buffer);
896 if (NILP (real_buffer))
897 nsberror (buffer);
898 }
899
900 XBUFFER (real_buffer)->undo_list = Qt;
901
1ab256cb
RM
902 return Qnil;
903}
904
905DEFUN ("buffer-enable-undo", Fbuffer_enable_undo, Sbuffer_enable_undo,
906 0, 1, "",
907 "Start keeping undo information for buffer BUFFER.\n\
908No argument or nil as argument means do this for the current buffer.")
ffd56f97
JB
909 (buffer)
910 register Lisp_Object buffer;
1ab256cb 911{
ffd56f97 912 Lisp_Object real_buffer;
1ab256cb 913
ffd56f97 914 if (NILP (buffer))
67180c6a 915 XSETBUFFER (real_buffer, current_buffer);
1ab256cb
RM
916 else
917 {
ffd56f97
JB
918 real_buffer = Fget_buffer (buffer);
919 if (NILP (real_buffer))
920 nsberror (buffer);
1ab256cb
RM
921 }
922
ffd56f97
JB
923 if (EQ (XBUFFER (real_buffer)->undo_list, Qt))
924 XBUFFER (real_buffer)->undo_list = Qnil;
1ab256cb
RM
925
926 return Qnil;
927}
928
929/*
930 DEFVAR_LISP ("kill-buffer-hook", no_cell, "\
931Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\
932The buffer being killed will be current while the hook is running.\n\
933See `kill-buffer'."
934 */
935DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 1, 1, "bKill buffer: ",
936 "Kill the buffer BUFFER.\n\
937The argument may be a buffer or may be the name of a buffer.\n\
938An argument of nil means kill the current buffer.\n\n\
939Value is t if the buffer is actually killed, nil if user says no.\n\n\
940The value of `kill-buffer-hook' (which may be local to that buffer),\n\
941if not void, is a list of functions to be called, with no arguments,\n\
942before the buffer is actually killed. The buffer to be killed is current\n\
943when the hook functions are called.\n\n\
944Any processes that have this buffer as the `process-buffer' are killed\n\
b64d7442 945with SIGHUP.")
a25f13ae
KH
946 (buffer)
947 Lisp_Object buffer;
1ab256cb
RM
948{
949 Lisp_Object buf;
950 register struct buffer *b;
951 register Lisp_Object tem;
952 register struct Lisp_Marker *m;
953 struct gcpro gcpro1, gcpro2;
954
a25f13ae 955 if (NILP (buffer))
1ab256cb
RM
956 buf = Fcurrent_buffer ();
957 else
a25f13ae 958 buf = Fget_buffer (buffer);
265a9e55 959 if (NILP (buf))
a25f13ae 960 nsberror (buffer);
1ab256cb
RM
961
962 b = XBUFFER (buf);
963
4a4a9db5
KH
964 /* Avoid trouble for buffer already dead. */
965 if (NILP (b->name))
966 return Qnil;
967
1ab256cb 968 /* Query if the buffer is still modified. */
265a9e55 969 if (INTERACTIVE && !NILP (b->filename)
336cd056 970 && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
1ab256cb 971 {
a25f13ae 972 GCPRO1 (buf);
1ab256cb
RM
973 tem = do_yes_or_no_p (format1 ("Buffer %s modified; kill anyway? ",
974 XSTRING (b->name)->data));
975 UNGCPRO;
265a9e55 976 if (NILP (tem))
1ab256cb
RM
977 return Qnil;
978 }
979
dcdffbf6 980 /* Run hooks with the buffer to be killed the current buffer. */
1ab256cb
RM
981 {
982 register Lisp_Object val;
983 int count = specpdl_ptr - specpdl;
dcdffbf6 984 Lisp_Object list;
1ab256cb
RM
985
986 record_unwind_protect (save_excursion_restore, save_excursion_save ());
987 set_buffer_internal (b);
dcdffbf6
RS
988
989 /* First run the query functions; if any query is answered no,
990 don't kill the buffer. */
991 for (list = Vkill_buffer_query_functions; !NILP (list); list = Fcdr (list))
992 {
993 tem = call0 (Fcar (list));
994 if (NILP (tem))
995 return unbind_to (count, Qnil);
996 }
997
998 /* Then run the hooks. */
fd186f07
RS
999 if (!NILP (Vrun_hooks))
1000 call1 (Vrun_hooks, Qkill_buffer_hook);
1ab256cb
RM
1001 unbind_to (count, Qnil);
1002 }
1003
1004 /* We have no more questions to ask. Verify that it is valid
1005 to kill the buffer. This must be done after the questions
1006 since anything can happen within do_yes_or_no_p. */
1007
1008 /* Don't kill the minibuffer now current. */
1009 if (EQ (buf, XWINDOW (minibuf_window)->buffer))
1010 return Qnil;
1011
265a9e55 1012 if (NILP (b->name))
1ab256cb
RM
1013 return Qnil;
1014
336cd056
RS
1015 /* When we kill a base buffer, kill all its indirect buffers.
1016 We do it at this stage so nothing terrible happens if they
1017 ask questions or their hooks get errors. */
1018 if (! b->base_buffer)
1019 {
1020 struct buffer *other;
1021
1022 GCPRO1 (buf);
1023
1024 for (other = all_buffers; other; other = other->next)
4a4a9db5
KH
1025 /* all_buffers contains dead buffers too;
1026 don't re-kill them. */
1027 if (other->base_buffer == b && !NILP (other->name))
336cd056
RS
1028 {
1029 Lisp_Object buf;
1030 XSETBUFFER (buf, other);
1031 Fkill_buffer (buf);
1032 }
1033
1034 UNGCPRO;
1035 }
1036
1ab256cb
RM
1037 /* Make this buffer not be current.
1038 In the process, notice if this is the sole visible buffer
1039 and give up if so. */
1040 if (b == current_buffer)
1041 {
172a9c1f 1042 tem = Fother_buffer (buf, Qnil);
1ab256cb
RM
1043 Fset_buffer (tem);
1044 if (b == current_buffer)
1045 return Qnil;
1046 }
1047
1048 /* Now there is no question: we can kill the buffer. */
1049
1050#ifdef CLASH_DETECTION
1051 /* Unlock this buffer's file, if it is locked. */
1052 unlock_buffer (b);
1053#endif /* CLASH_DETECTION */
1054
1ab256cb 1055 kill_buffer_processes (buf);
1ab256cb
RM
1056
1057 tem = Vinhibit_quit;
1058 Vinhibit_quit = Qt;
00550f94 1059 replace_buffer_in_all_windows (buf);
b26dd9cb 1060 Vbuffer_alist = Fdelq (Frassq (buf, Vbuffer_alist), Vbuffer_alist);
1ab256cb
RM
1061 Vinhibit_quit = tem;
1062
9b59d6d0 1063 /* Delete any auto-save file, if we saved it in this session. */
a7a60ce9 1064 if (STRINGP (b->auto_save_file_name)
e95a0b39
RS
1065 && b->auto_save_modified != 0
1066 && SAVE_MODIFF < b->auto_save_modified)
1ab256cb
RM
1067 {
1068 Lisp_Object tem;
1069 tem = Fsymbol_value (intern ("delete-auto-save-files"));
265a9e55 1070 if (! NILP (tem))
cbb6a418 1071 internal_delete_file (b->auto_save_file_name);
1ab256cb
RM
1072 }
1073
4a4a9db5
KH
1074 if (b->base_buffer)
1075 {
1076 /* Unchain all markers that belong to this indirect buffer.
1077 Don't unchain the markers that belong to the base buffer
1078 or its other indirect buffers. */
1079 for (tem = BUF_MARKERS (b); !NILP (tem); )
1080 {
1081 Lisp_Object next;
1082 m = XMARKER (tem);
1083 next = m->chain;
1084 if (m->buffer == b)
1085 unchain_marker (tem);
1086 tem = next;
1087 }
1088 }
1089 else
1ab256cb 1090 {
4a4a9db5 1091 /* Unchain all markers of this buffer and its indirect buffers.
336cd056 1092 and leave them pointing nowhere. */
4a4a9db5 1093 for (tem = BUF_MARKERS (b); !NILP (tem); )
336cd056
RS
1094 {
1095 m = XMARKER (tem);
1096 m->buffer = 0;
1097 tem = m->chain;
1098 m->chain = Qnil;
1099 }
1100 BUF_MARKERS (b) = Qnil;
1ab256cb 1101
336cd056
RS
1102#ifdef USE_TEXT_PROPERTIES
1103 BUF_INTERVALS (b) = NULL_INTERVAL;
1104#endif
1105
1106 /* Perhaps we should explicitly free the interval tree here... */
1107 }
33f7013e 1108
2f3f993b
RS
1109 /* Reset the local variables, so that this buffer's local values
1110 won't be protected from GC. They would be protected
1111 if they happened to remain encached in their symbols.
1112 This gets rid of them for certain. */
1113 swap_out_buffer_local_variables (b);
13de9290 1114 reset_buffer_local_variables (b, 1);
2f3f993b 1115
1ab256cb 1116 b->name = Qnil;
336cd056 1117
9ac0d9e0 1118 BLOCK_INPUT;
336cd056
RS
1119 if (! b->base_buffer)
1120 BUFFER_FREE (BUF_BEG_ADDR (b));
1121
28e969dd
JB
1122 if (b->newline_cache)
1123 {
1124 free_region_cache (b->newline_cache);
1125 b->newline_cache = 0;
1126 }
1127 if (b->width_run_cache)
1128 {
1129 free_region_cache (b->width_run_cache);
1130 b->width_run_cache = 0;
1131 }
1132 b->width_table = Qnil;
9ac0d9e0 1133 UNBLOCK_INPUT;
1ab256cb
RM
1134 b->undo_list = Qnil;
1135
1136 return Qt;
1137}
1138\f
36a8c287
JB
1139/* Move the assoc for buffer BUF to the front of buffer-alist. Since
1140 we do this each time BUF is selected visibly, the more recently
1141 selected buffers are always closer to the front of the list. This
1142 means that other_buffer is more likely to choose a relevant buffer. */
1ab256cb
RM
1143
1144record_buffer (buf)
1145 Lisp_Object buf;
1146{
1147 register Lisp_Object link, prev;
1148
1149 prev = Qnil;
1150 for (link = Vbuffer_alist; CONSP (link); link = XCONS (link)->cdr)
1151 {
1152 if (EQ (XCONS (XCONS (link)->car)->cdr, buf))
1153 break;
1154 prev = link;
1155 }
1156
36a8c287
JB
1157 /* Effectively do Vbuffer_alist = Fdelq (link, Vbuffer_alist);
1158 we cannot use Fdelq itself here because it allows quitting. */
1ab256cb 1159
265a9e55 1160 if (NILP (prev))
1ab256cb
RM
1161 Vbuffer_alist = XCONS (Vbuffer_alist)->cdr;
1162 else
1163 XCONS (prev)->cdr = XCONS (XCONS (prev)->cdr)->cdr;
1164
1165 XCONS(link)->cdr = Vbuffer_alist;
1166 Vbuffer_alist = link;
1167}
1168
a9ee7a59
KH
1169DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0,
1170 "Set an appropriate major mode for BUFFER, according to `default-major-mode'.\n\
1171Use this function before selecting the buffer, since it may need to inspect\n\
1172the current buffer's major mode.")
a2428fa2
EN
1173 (buffer)
1174 Lisp_Object buffer;
a9ee7a59
KH
1175{
1176 int count;
1177 Lisp_Object function;
1178
1179 function = buffer_defaults.major_mode;
1180 if (NILP (function) && NILP (Fget (current_buffer->major_mode, Qmode_class)))
1181 function = current_buffer->major_mode;
1182
1183 if (NILP (function) || EQ (function, Qfundamental_mode))
1184 return Qnil;
1185
1186 count = specpdl_ptr - specpdl;
1187
1188 /* To select a nonfundamental mode,
1189 select the buffer temporarily and then call the mode function. */
1190
1191 record_unwind_protect (save_excursion_restore, save_excursion_save ());
1192
a2428fa2 1193 Fset_buffer (buffer);
a9ee7a59
KH
1194 call0 (function);
1195
1196 return unbind_to (count, Qnil);
1197}
1198
1ab256cb
RM
1199DEFUN ("switch-to-buffer", Fswitch_to_buffer, Sswitch_to_buffer, 1, 2, "BSwitch to buffer: ",
1200 "Select buffer BUFFER in the current window.\n\
1201BUFFER may be a buffer or a buffer name.\n\
1202Optional second arg NORECORD non-nil means\n\
1203do not put this buffer at the front of the list of recently selected ones.\n\
1204\n\
1205WARNING: This is NOT the way to work on another buffer temporarily\n\
1206within a Lisp program! Use `set-buffer' instead. That avoids messing with\n\
1207the window-buffer correspondences.")
a25f13ae
KH
1208 (buffer, norecord)
1209 Lisp_Object buffer, norecord;
1ab256cb
RM
1210{
1211 register Lisp_Object buf;
1212 Lisp_Object tem;
1213
1214 if (EQ (minibuf_window, selected_window))
1215 error ("Cannot switch buffers in minibuffer window");
1216 tem = Fwindow_dedicated_p (selected_window);
265a9e55 1217 if (!NILP (tem))
1ab256cb
RM
1218 error ("Cannot switch buffers in a dedicated window");
1219
a25f13ae 1220 if (NILP (buffer))
172a9c1f 1221 buf = Fother_buffer (Fcurrent_buffer (), Qnil);
1ab256cb 1222 else
a9ee7a59 1223 {
a25f13ae 1224 buf = Fget_buffer (buffer);
a9ee7a59
KH
1225 if (NILP (buf))
1226 {
a25f13ae 1227 buf = Fget_buffer_create (buffer);
a9ee7a59
KH
1228 Fset_buffer_major_mode (buf);
1229 }
1230 }
1ab256cb 1231 Fset_buffer (buf);
265a9e55 1232 if (NILP (norecord))
1ab256cb
RM
1233 record_buffer (buf);
1234
1235 Fset_window_buffer (EQ (selected_window, minibuf_window)
5fcd022d
JB
1236 ? Fnext_window (minibuf_window, Qnil, Qnil)
1237 : selected_window,
1ab256cb
RM
1238 buf);
1239
e8b3a22d 1240 return buf;
1ab256cb
RM
1241}
1242
1243DEFUN ("pop-to-buffer", Fpop_to_buffer, Spop_to_buffer, 1, 2, 0,
1244 "Select buffer BUFFER in some window, preferably a different one.\n\
1245If BUFFER is nil, then some other buffer is chosen.\n\
1246If `pop-up-windows' is non-nil, windows can be split to do this.\n\
1247If optional second arg OTHER-WINDOW is non-nil, insist on finding another\n\
405615e5
RS
1248window even if BUFFER is already visible in the selected window.\n\
1249This uses the function `display-buffer' as a subroutine; see the documentation\n\
1250of `display-buffer' for additional customization information.")
a2428fa2
EN
1251 (buffer, other_window)
1252 Lisp_Object buffer, other_window;
1ab256cb
RM
1253{
1254 register Lisp_Object buf;
a25f13ae 1255 if (NILP (buffer))
172a9c1f 1256 buf = Fother_buffer (Fcurrent_buffer (), Qnil);
1ab256cb 1257 else
7c2087ee 1258 {
a25f13ae 1259 buf = Fget_buffer (buffer);
7c2087ee
RS
1260 if (NILP (buf))
1261 {
a25f13ae 1262 buf = Fget_buffer_create (buffer);
7c2087ee
RS
1263 Fset_buffer_major_mode (buf);
1264 }
1265 }
1ab256cb
RM
1266 Fset_buffer (buf);
1267 record_buffer (buf);
a2428fa2 1268 Fselect_window (Fdisplay_buffer (buf, other_window));
e8b3a22d 1269 return buf;
1ab256cb
RM
1270}
1271
1272DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
1273 "Return the current buffer as a Lisp object.")
1274 ()
1275{
1276 register Lisp_Object buf;
67180c6a 1277 XSETBUFFER (buf, current_buffer);
1ab256cb
RM
1278 return buf;
1279}
1280\f
c7aa5005 1281/* Set the current buffer to B. */
1ab256cb
RM
1282
1283void
1284set_buffer_internal (b)
1285 register struct buffer *b;
1286{
1287 register struct buffer *old_buf;
1288 register Lisp_Object tail, valcontents;
a7a60ce9 1289 Lisp_Object tem;
1ab256cb
RM
1290
1291 if (current_buffer == b)
1292 return;
1293
1294 windows_or_buffers_changed = 1;
c7aa5005
KH
1295 set_buffer_internal_1 (b);
1296}
1297
1298/* Set the current buffer to B, and do not set windows_or_buffers_changed.
1299 This is used by redisplay. */
1300
1301void
1302set_buffer_internal_1 (b)
1303 register struct buffer *b;
1304{
1305 register struct buffer *old_buf;
1306 register Lisp_Object tail, valcontents;
1307 Lisp_Object tem;
1308
1309 if (current_buffer == b)
1310 return;
1311
1ab256cb
RM
1312 old_buf = current_buffer;
1313 current_buffer = b;
1314 last_known_column_point = -1; /* invalidate indentation cache */
1315
336cd056
RS
1316 if (old_buf)
1317 {
1318 /* Put the undo list back in the base buffer, so that it appears
1319 that an indirect buffer shares the undo list of its base. */
1320 if (old_buf->base_buffer)
1321 old_buf->base_buffer->undo_list = old_buf->undo_list;
1322
1323 /* If the old current buffer has markers to record PT, BEGV and ZV
1324 when it is not current, update them now. */
1325 if (! NILP (old_buf->pt_marker))
1326 {
1327 Lisp_Object obuf;
1328 XSETBUFFER (obuf, old_buf);
1329 Fset_marker (old_buf->pt_marker, BUF_PT (old_buf), obuf);
1330 }
1331 if (! NILP (old_buf->begv_marker))
1332 {
1333 Lisp_Object obuf;
1334 XSETBUFFER (obuf, old_buf);
1335 Fset_marker (old_buf->begv_marker, BUF_BEGV (old_buf), obuf);
1336 }
1337 if (! NILP (old_buf->zv_marker))
1338 {
1339 Lisp_Object obuf;
1340 XSETBUFFER (obuf, old_buf);
1341 Fset_marker (old_buf->zv_marker, BUF_ZV (old_buf), obuf);
1342 }
1343 }
1344
1345 /* Get the undo list from the base buffer, so that it appears
1346 that an indirect buffer shares the undo list of its base. */
1347 if (b->base_buffer)
1348 b->undo_list = b->base_buffer->undo_list;
1349
1350 /* If the new current buffer has markers to record PT, BEGV and ZV
1351 when it is not current, fetch them now. */
1352 if (! NILP (b->pt_marker))
1353 BUF_PT (b) = marker_position (b->pt_marker);
1354 if (! NILP (b->begv_marker))
1355 BUF_BEGV (b) = marker_position (b->begv_marker);
1356 if (! NILP (b->zv_marker))
1357 BUF_ZV (b) = marker_position (b->zv_marker);
1358
1ab256cb
RM
1359 /* Look down buffer's list of local Lisp variables
1360 to find and update any that forward into C variables. */
1361
265a9e55 1362 for (tail = b->local_var_alist; !NILP (tail); tail = XCONS (tail)->cdr)
1ab256cb
RM
1363 {
1364 valcontents = XSYMBOL (XCONS (XCONS (tail)->car)->car)->value;
a7a60ce9
KH
1365 if ((BUFFER_LOCAL_VALUEP (valcontents)
1366 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
fdc6e516 1367 && (tem = XBUFFER_LOCAL_VALUE (valcontents)->car,
a7a60ce9 1368 (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
1ab256cb
RM
1369 /* Just reference the variable
1370 to cause it to become set for this buffer. */
1371 Fsymbol_value (XCONS (XCONS (tail)->car)->car);
1372 }
1373
1374 /* Do the same with any others that were local to the previous buffer */
1375
1376 if (old_buf)
265a9e55 1377 for (tail = old_buf->local_var_alist; !NILP (tail); tail = XCONS (tail)->cdr)
1ab256cb
RM
1378 {
1379 valcontents = XSYMBOL (XCONS (XCONS (tail)->car)->car)->value;
a7a60ce9
KH
1380 if ((BUFFER_LOCAL_VALUEP (valcontents)
1381 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
fdc6e516 1382 && (tem = XBUFFER_LOCAL_VALUE (valcontents)->car,
a7a60ce9 1383 (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
1ab256cb
RM
1384 /* Just reference the variable
1385 to cause it to become set for this buffer. */
1386 Fsymbol_value (XCONS (XCONS (tail)->car)->car);
1387 }
1388}
1389
336cd056 1390/* Switch to buffer B temporarily for redisplay purposes.
bbbe9545 1391 This avoids certain things that don't need to be done within redisplay. */
336cd056
RS
1392
1393void
1394set_buffer_temp (b)
1395 struct buffer *b;
1396{
1397 register struct buffer *old_buf;
1398
1399 if (current_buffer == b)
1400 return;
1401
1402 old_buf = current_buffer;
1403 current_buffer = b;
1404
1405 if (old_buf)
1406 {
1407 /* If the old current buffer has markers to record PT, BEGV and ZV
1408 when it is not current, update them now. */
1409 if (! NILP (old_buf->pt_marker))
1410 {
1411 Lisp_Object obuf;
1412 XSETBUFFER (obuf, old_buf);
1413 Fset_marker (old_buf->pt_marker, BUF_PT (old_buf), obuf);
1414 }
1415 if (! NILP (old_buf->begv_marker))
1416 {
1417 Lisp_Object obuf;
1418 XSETBUFFER (obuf, old_buf);
1419 Fset_marker (old_buf->begv_marker, BUF_BEGV (old_buf), obuf);
1420 }
1421 if (! NILP (old_buf->zv_marker))
1422 {
1423 Lisp_Object obuf;
1424 XSETBUFFER (obuf, old_buf);
1425 Fset_marker (old_buf->zv_marker, BUF_ZV (old_buf), obuf);
1426 }
1427 }
1428
1429 /* If the new current buffer has markers to record PT, BEGV and ZV
1430 when it is not current, fetch them now. */
1431 if (! NILP (b->pt_marker))
1432 BUF_PT (b) = marker_position (b->pt_marker);
1433 if (! NILP (b->begv_marker))
1434 BUF_BEGV (b) = marker_position (b->begv_marker);
1435 if (! NILP (b->zv_marker))
1436 BUF_ZV (b) = marker_position (b->zv_marker);
1437}
1438
1ab256cb
RM
1439DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0,
1440 "Make the buffer BUFFER current for editing operations.\n\
1441BUFFER may be a buffer or the name of an existing buffer.\n\
1442See also `save-excursion' when you want to make a buffer current temporarily.\n\
1443This function does not display the buffer, so its effect ends\n\
1444when the current command terminates.\n\
1445Use `switch-to-buffer' or `pop-to-buffer' to switch buffers permanently.")
a25f13ae
KH
1446 (buffer)
1447 register Lisp_Object buffer;
1ab256cb 1448{
a25f13ae
KH
1449 register Lisp_Object buf;
1450 buf = Fget_buffer (buffer);
1451 if (NILP (buf))
1452 nsberror (buffer);
1453 if (NILP (XBUFFER (buf)->name))
1ab256cb 1454 error ("Selecting deleted buffer");
a25f13ae
KH
1455 set_buffer_internal (XBUFFER (buf));
1456 return buf;
1ab256cb
RM
1457}
1458\f
1459DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
1460 Sbarf_if_buffer_read_only, 0, 0, 0,
1461 "Signal a `buffer-read-only' error if the current buffer is read-only.")
1462 ()
1463{
a96b68f1
RS
1464 if (!NILP (current_buffer->read_only)
1465 && NILP (Vinhibit_read_only))
1ab256cb
RM
1466 Fsignal (Qbuffer_read_only, (Fcons (Fcurrent_buffer (), Qnil)));
1467 return Qnil;
1468}
1469
1470DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "",
1471 "Put BUFFER at the end of the list of all buffers.\n\
1472There it is the least likely candidate for `other-buffer' to return;\n\
528415e7 1473thus, the least likely buffer for \\[switch-to-buffer] to select by default.\n\
a5611885
JB
1474If BUFFER is nil or omitted, bury the current buffer.\n\
1475Also, if BUFFER is nil or omitted, remove the current buffer from the\n\
1476selected window if it is displayed there.")
a2428fa2
EN
1477 (buffer)
1478 register Lisp_Object buffer;
1ab256cb 1479{
b271272a 1480 /* Figure out what buffer we're going to bury. */
a2428fa2 1481 if (NILP (buffer))
a5611885 1482 {
a2428fa2 1483 XSETBUFFER (buffer, current_buffer);
a5611885
JB
1484
1485 /* If we're burying the current buffer, unshow it. */
a2428fa2 1486 Fswitch_to_buffer (Fother_buffer (buffer, Qnil), Qnil);
a5611885 1487 }
1ab256cb
RM
1488 else
1489 {
1490 Lisp_Object buf1;
1491
a2428fa2 1492 buf1 = Fget_buffer (buffer);
265a9e55 1493 if (NILP (buf1))
a2428fa2
EN
1494 nsberror (buffer);
1495 buffer = buf1;
b271272a
JB
1496 }
1497
a2428fa2 1498 /* Move buffer to the end of the buffer list. */
b271272a
JB
1499 {
1500 register Lisp_Object aelt, link;
1501
a2428fa2 1502 aelt = Frassq (buffer, Vbuffer_alist);
b271272a
JB
1503 link = Fmemq (aelt, Vbuffer_alist);
1504 Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
1505 XCONS (link)->cdr = Qnil;
1506 Vbuffer_alist = nconc2 (Vbuffer_alist, link);
1507 }
1ab256cb 1508
1ab256cb
RM
1509 return Qnil;
1510}
1511\f
c922bc55 1512DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*",
1ab256cb 1513 "Delete the entire contents of the current buffer.\n\
2950a20e 1514Any narrowing restriction in effect (see `narrow-to-region') is removed,\n\
1ab256cb
RM
1515so the buffer is truly empty after this.")
1516 ()
1517{
1518 Fwiden ();
1519 del_range (BEG, Z);
1520 current_buffer->last_window_start = 1;
1521 /* Prevent warnings, or suspension of auto saving, that would happen
1522 if future size is less than past size. Use of erase-buffer
1523 implies that the future text is not really related to the past text. */
8d7a4592 1524 XSETFASTINT (current_buffer->save_length, 0);
1ab256cb
RM
1525 return Qnil;
1526}
1527
1528validate_region (b, e)
1529 register Lisp_Object *b, *e;
1530{
1ab256cb
RM
1531 CHECK_NUMBER_COERCE_MARKER (*b, 0);
1532 CHECK_NUMBER_COERCE_MARKER (*e, 1);
1533
1534 if (XINT (*b) > XINT (*e))
1535 {
03192067
KH
1536 Lisp_Object tem;
1537 tem = *b; *b = *e; *e = tem;
1ab256cb
RM
1538 }
1539
1540 if (!(BEGV <= XINT (*b) && XINT (*b) <= XINT (*e)
1541 && XINT (*e) <= ZV))
1542 args_out_of_range (*b, *e);
1543}
1544\f
1ab256cb
RM
1545DEFUN ("kill-all-local-variables", Fkill_all_local_variables, Skill_all_local_variables,
1546 0, 0, 0,
1547 "Switch to Fundamental mode by killing current buffer's local variables.\n\
1548Most local variable bindings are eliminated so that the default values\n\
1549become effective once more. Also, the syntax table is set from\n\
1550`standard-syntax-table', the local keymap is set to nil,\n\
1551and the abbrev table from `fundamental-mode-abbrev-table'.\n\
1552This function also forces redisplay of the mode line.\n\
1553\n\
1554Every function to select a new major mode starts by\n\
1555calling this function.\n\n\
1556As a special exception, local variables whose names have\n\
c5a15222
RS
1557a non-nil `permanent-local' property are not eliminated by this function.\n\
1558\n\
1559The first thing this function does is run\n\
1560the normal hook `change-major-mode-hook'.")
1ab256cb
RM
1561 ()
1562{
1563 register Lisp_Object alist, sym, tem;
1564 Lisp_Object oalist;
7410477a 1565
fd186f07
RS
1566 if (!NILP (Vrun_hooks))
1567 call1 (Vrun_hooks, intern ("change-major-mode-hook"));
1ab256cb
RM
1568 oalist = current_buffer->local_var_alist;
1569
2f3f993b
RS
1570 /* Make sure none of the bindings in oalist
1571 remain swapped in, in their symbols. */
1ab256cb 1572
2f3f993b 1573 swap_out_buffer_local_variables (current_buffer);
1ab256cb
RM
1574
1575 /* Actually eliminate all local bindings of this buffer. */
1576
13de9290 1577 reset_buffer_local_variables (current_buffer, 0);
1ab256cb
RM
1578
1579 /* Redisplay mode lines; we are changing major mode. */
1580
1581 update_mode_lines++;
1582
1583 /* Any which are supposed to be permanent,
1584 make local again, with the same values they had. */
1585
265a9e55 1586 for (alist = oalist; !NILP (alist); alist = XCONS (alist)->cdr)
1ab256cb
RM
1587 {
1588 sym = XCONS (XCONS (alist)->car)->car;
1589 tem = Fget (sym, Qpermanent_local);
265a9e55 1590 if (! NILP (tem))
01050cb5
RM
1591 {
1592 Fmake_local_variable (sym);
1593 Fset (sym, XCONS (XCONS (alist)->car)->cdr);
1594 }
1ab256cb
RM
1595 }
1596
1597 /* Force mode-line redisplay. Useful here because all major mode
1598 commands call this function. */
1599 update_mode_lines++;
1600
1601 return Qnil;
1602}
2f3f993b
RS
1603
1604/* Make sure no local variables remain set up with buffer B
1605 for their current values. */
1606
1607static void
1608swap_out_buffer_local_variables (b)
1609 struct buffer *b;
1610{
1611 Lisp_Object oalist, alist, sym, tem, buffer;
1612
1613 XSETBUFFER (buffer, b);
1614 oalist = b->local_var_alist;
1615
1616 for (alist = oalist; !NILP (alist); alist = XCONS (alist)->cdr)
1617 {
1618 sym = XCONS (XCONS (alist)->car)->car;
1619
1620 /* Need not do anything if some other buffer's binding is now encached. */
1621 tem = XCONS (XBUFFER_LOCAL_VALUE (XSYMBOL (sym)->value)->cdr)->car;
1622 if (XBUFFER (tem) == current_buffer)
1623 {
1624 /* Symbol is set up for this buffer's old local value.
1625 Set it up for the current buffer with the default value. */
1626
1627 tem = XCONS (XBUFFER_LOCAL_VALUE (XSYMBOL (sym)->value)->cdr)->cdr;
1628 /* Store the symbol's current value into the alist entry
1629 it is currently set up for. This is so that, if the
1630 local is marked permanent, and we make it local again
1631 later in Fkill_all_local_variables, we don't lose the value. */
1632 XCONS (XCONS (tem)->car)->cdr
1633 = do_symval_forwarding (XBUFFER_LOCAL_VALUE (XSYMBOL (sym)->value)->car);
1634 /* Switch to the symbol's default-value alist entry. */
1635 XCONS (tem)->car = tem;
1636 /* Mark it as current for buffer B. */
1637 XCONS (XBUFFER_LOCAL_VALUE (XSYMBOL (sym)->value)->cdr)->car
1638 = buffer;
1639 /* Store the current value into any forwarding in the symbol. */
1640 store_symval_forwarding (sym, XBUFFER_LOCAL_VALUE (XSYMBOL (sym)->value)->car,
1641 XCONS (tem)->cdr);
1642 }
1643 }
1644}
1ab256cb 1645\f
2eec3b4e
RS
1646/* Find all the overlays in the current buffer that contain position POS.
1647 Return the number found, and store them in a vector in *VEC_PTR.
1648 Store in *LEN_PTR the size allocated for the vector.
52f8ec73
JB
1649 Store in *NEXT_PTR the next position after POS where an overlay starts,
1650 or ZV if there are no more overlays.
bbbe9545 1651 Store in *PREV_PTR the previous position before POS where an overlay ends,
239c932b
RS
1652 or BEGV if there are no previous overlays.
1653 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
2eec3b4e
RS
1654
1655 *VEC_PTR and *LEN_PTR should contain a valid vector and size
61d54cd5
RS
1656 when this function is called.
1657
1658 If EXTEND is non-zero, we make the vector bigger if necessary.
1659 If EXTEND is zero, we never extend the vector,
1660 and we store only as many overlays as will fit.
1661 But we still return the total number of overlays. */
2eec3b4e
RS
1662
1663int
239c932b 1664overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr, prev_ptr)
2eec3b4e 1665 int pos;
61d54cd5 1666 int extend;
2eec3b4e
RS
1667 Lisp_Object **vec_ptr;
1668 int *len_ptr;
1669 int *next_ptr;
239c932b 1670 int *prev_ptr;
1ab256cb 1671{
2eec3b4e
RS
1672 Lisp_Object tail, overlay, start, end, result;
1673 int idx = 0;
1674 int len = *len_ptr;
1675 Lisp_Object *vec = *vec_ptr;
1676 int next = ZV;
239c932b 1677 int prev = BEGV;
61d54cd5
RS
1678 int inhibit_storing = 0;
1679
2eec3b4e 1680 for (tail = current_buffer->overlays_before;
8fc0589a 1681 GC_CONSP (tail);
2eec3b4e
RS
1682 tail = XCONS (tail)->cdr)
1683 {
239c932b 1684 int startpos, endpos;
52f8ec73 1685
2eec3b4e 1686 overlay = XCONS (tail)->car;
1ab256cb 1687
2eec3b4e
RS
1688 start = OVERLAY_START (overlay);
1689 end = OVERLAY_END (overlay);
239c932b
RS
1690 endpos = OVERLAY_POSITION (end);
1691 if (endpos < pos)
1692 {
1693 if (prev < endpos)
1694 prev = endpos;
1695 break;
1696 }
1697 if (endpos == pos)
1698 continue;
2eec3b4e
RS
1699 startpos = OVERLAY_POSITION (start);
1700 if (startpos <= pos)
1701 {
1702 if (idx == len)
1703 {
61d54cd5
RS
1704 /* The supplied vector is full.
1705 Either make it bigger, or don't store any more in it. */
1706 if (extend)
1707 {
1708 *len_ptr = len *= 2;
1709 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
1710 *vec_ptr = vec;
1711 }
1712 else
1713 inhibit_storing = 1;
2eec3b4e 1714 }
61d54cd5
RS
1715
1716 if (!inhibit_storing)
1717 vec[idx] = overlay;
1718 /* Keep counting overlays even if we can't return them all. */
1719 idx++;
2eec3b4e
RS
1720 }
1721 else if (startpos < next)
1722 next = startpos;
1723 }
1724
1725 for (tail = current_buffer->overlays_after;
8fc0589a 1726 GC_CONSP (tail);
2eec3b4e 1727 tail = XCONS (tail)->cdr)
1ab256cb 1728 {
239c932b 1729 int startpos, endpos;
52f8ec73 1730
2eec3b4e 1731 overlay = XCONS (tail)->car;
2eec3b4e
RS
1732
1733 start = OVERLAY_START (overlay);
1734 end = OVERLAY_END (overlay);
1735 startpos = OVERLAY_POSITION (start);
52f8ec73 1736 if (pos < startpos)
2eec3b4e
RS
1737 {
1738 if (startpos < next)
1739 next = startpos;
1740 break;
1741 }
239c932b
RS
1742 endpos = OVERLAY_POSITION (end);
1743 if (pos < endpos)
2eec3b4e
RS
1744 {
1745 if (idx == len)
1746 {
61d54cd5
RS
1747 if (extend)
1748 {
1749 *len_ptr = len *= 2;
1750 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
1751 *vec_ptr = vec;
1752 }
1753 else
1754 inhibit_storing = 1;
2eec3b4e 1755 }
61d54cd5
RS
1756
1757 if (!inhibit_storing)
1758 vec[idx] = overlay;
1759 idx++;
2eec3b4e 1760 }
239c932b
RS
1761 else if (endpos < pos && endpos > prev)
1762 prev = endpos;
1ab256cb
RM
1763 }
1764
239c932b
RS
1765 if (next_ptr)
1766 *next_ptr = next;
1767 if (prev_ptr)
1768 *prev_ptr = prev;
2eec3b4e
RS
1769 return idx;
1770}
74514898
RS
1771\f
1772/* Find all the overlays in the current buffer that overlap the range BEG-END
2a3eeee7
RS
1773 or are empty at BEG.
1774
74514898
RS
1775 Return the number found, and store them in a vector in *VEC_PTR.
1776 Store in *LEN_PTR the size allocated for the vector.
1777 Store in *NEXT_PTR the next position after POS where an overlay starts,
1778 or ZV if there are no more overlays.
1779 Store in *PREV_PTR the previous position before POS where an overlay ends,
1780 or BEGV if there are no previous overlays.
1781 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
1782
1783 *VEC_PTR and *LEN_PTR should contain a valid vector and size
1784 when this function is called.
1785
1786 If EXTEND is non-zero, we make the vector bigger if necessary.
1787 If EXTEND is zero, we never extend the vector,
1788 and we store only as many overlays as will fit.
1789 But we still return the total number of overlays. */
1790
1791int
1792overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr)
1793 int beg, end;
1794 int extend;
1795 Lisp_Object **vec_ptr;
1796 int *len_ptr;
1797 int *next_ptr;
1798 int *prev_ptr;
1799{
1800 Lisp_Object tail, overlay, ostart, oend, result;
1801 int idx = 0;
1802 int len = *len_ptr;
1803 Lisp_Object *vec = *vec_ptr;
1804 int next = ZV;
1805 int prev = BEGV;
1806 int inhibit_storing = 0;
1807
1808 for (tail = current_buffer->overlays_before;
1809 GC_CONSP (tail);
1810 tail = XCONS (tail)->cdr)
1811 {
1812 int startpos, endpos;
1813
1814 overlay = XCONS (tail)->car;
1815
1816 ostart = OVERLAY_START (overlay);
1817 oend = OVERLAY_END (overlay);
1818 endpos = OVERLAY_POSITION (oend);
1819 if (endpos < beg)
1820 {
1821 if (prev < endpos)
1822 prev = endpos;
1823 break;
1824 }
1825 startpos = OVERLAY_POSITION (ostart);
1826 /* Count an interval if it either overlaps the range
2a3eeee7 1827 or is empty at the start of the range. */
74514898 1828 if ((beg < endpos && startpos < end)
2a3eeee7 1829 || (startpos == endpos && beg == endpos))
74514898
RS
1830 {
1831 if (idx == len)
1832 {
1833 /* The supplied vector is full.
1834 Either make it bigger, or don't store any more in it. */
1835 if (extend)
1836 {
1837 *len_ptr = len *= 2;
1838 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
1839 *vec_ptr = vec;
1840 }
1841 else
1842 inhibit_storing = 1;
1843 }
1844
1845 if (!inhibit_storing)
1846 vec[idx] = overlay;
1847 /* Keep counting overlays even if we can't return them all. */
1848 idx++;
1849 }
1850 else if (startpos < next)
1851 next = startpos;
1852 }
1853
1854 for (tail = current_buffer->overlays_after;
1855 GC_CONSP (tail);
1856 tail = XCONS (tail)->cdr)
1857 {
1858 int startpos, endpos;
1859
1860 overlay = XCONS (tail)->car;
1861
1862 ostart = OVERLAY_START (overlay);
1863 oend = OVERLAY_END (overlay);
1864 startpos = OVERLAY_POSITION (ostart);
1865 if (end < startpos)
1866 {
1867 if (startpos < next)
1868 next = startpos;
1869 break;
1870 }
1871 endpos = OVERLAY_POSITION (oend);
2a3eeee7
RS
1872 /* Count an interval if it either overlaps the range
1873 or is empty at the start of the range. */
74514898 1874 if ((beg < endpos && startpos < end)
2a3eeee7 1875 || (startpos == endpos && beg == endpos))
74514898
RS
1876 {
1877 if (idx == len)
1878 {
1879 if (extend)
1880 {
1881 *len_ptr = len *= 2;
1882 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
1883 *vec_ptr = vec;
1884 }
1885 else
1886 inhibit_storing = 1;
1887 }
1888
1889 if (!inhibit_storing)
1890 vec[idx] = overlay;
1891 idx++;
1892 }
1893 else if (endpos < beg && endpos > prev)
1894 prev = endpos;
1895 }
fc04fa47 1896
74514898
RS
1897 if (next_ptr)
1898 *next_ptr = next;
1899 if (prev_ptr)
1900 *prev_ptr = prev;
1901 return idx;
1902}
1903\f
fc04fa47
KH
1904/* Fast function to just test if we're at an overlay boundary. */
1905int
1906overlay_touches_p (pos)
1907 int pos;
1908{
1909 Lisp_Object tail, overlay;
1910
1911 for (tail = current_buffer->overlays_before; GC_CONSP (tail);
1912 tail = XCONS (tail)->cdr)
1913 {
1914 int endpos;
1915
1916 overlay = XCONS (tail)->car;
1917 if (!GC_OVERLAYP (overlay))
1918 abort ();
1919
1920 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
1921 if (endpos < pos)
1922 break;
1923 if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos)
1924 return 1;
1925 }
1926
1927 for (tail = current_buffer->overlays_after; GC_CONSP (tail);
1928 tail = XCONS (tail)->cdr)
1929 {
1930 int startpos;
1931
1932 overlay = XCONS (tail)->car;
1933 if (!GC_OVERLAYP (overlay))
1934 abort ();
1935
1936 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
1937 if (pos < startpos)
1938 break;
1939 if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
1940 return 1;
1941 }
1942 return 0;
1943}
2eec3b4e 1944\f
5985d248
KH
1945struct sortvec
1946{
1947 Lisp_Object overlay;
1948 int beg, end;
1949 int priority;
1950};
1951
1952static int
1953compare_overlays (s1, s2)
1954 struct sortvec *s1, *s2;
1955{
1956 if (s1->priority != s2->priority)
1957 return s1->priority - s2->priority;
1958 if (s1->beg != s2->beg)
1959 return s1->beg - s2->beg;
1960 if (s1->end != s2->end)
1961 return s2->end - s1->end;
1962 return 0;
1963}
1964
1965/* Sort an array of overlays by priority. The array is modified in place.
1966 The return value is the new size; this may be smaller than the original
1967 size if some of the overlays were invalid or were window-specific. */
1968int
1969sort_overlays (overlay_vec, noverlays, w)
1970 Lisp_Object *overlay_vec;
1971 int noverlays;
1972 struct window *w;
1973{
1974 int i, j;
1975 struct sortvec *sortvec;
1976 sortvec = (struct sortvec *) alloca (noverlays * sizeof (struct sortvec));
1977
1978 /* Put the valid and relevant overlays into sortvec. */
1979
1980 for (i = 0, j = 0; i < noverlays; i++)
1981 {
0fa767e7 1982 Lisp_Object tem;
c99fc30f 1983 Lisp_Object overlay;
5985d248 1984
c99fc30f 1985 overlay = overlay_vec[i];
5985d248
KH
1986 if (OVERLAY_VALID (overlay)
1987 && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0
1988 && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0)
1989 {
0fa767e7
KH
1990 /* If we're interested in a specific window, then ignore
1991 overlays that are limited to some other window. */
1992 if (w)
5985d248 1993 {
0fa767e7
KH
1994 Lisp_Object window;
1995
1996 window = Foverlay_get (overlay, Qwindow);
a7a60ce9 1997 if (WINDOWP (window) && XWINDOW (window) != w)
0fa767e7 1998 continue;
5985d248 1999 }
0fa767e7
KH
2000
2001 /* This overlay is good and counts: put it into sortvec. */
2002 sortvec[j].overlay = overlay;
2003 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
2004 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
2005 tem = Foverlay_get (overlay, Qpriority);
2006 if (INTEGERP (tem))
2007 sortvec[j].priority = XINT (tem);
2008 else
2009 sortvec[j].priority = 0;
2010 j++;
5985d248
KH
2011 }
2012 }
2013 noverlays = j;
2014
2015 /* Sort the overlays into the proper order: increasing priority. */
2016
2017 if (noverlays > 1)
2018 qsort (sortvec, noverlays, sizeof (struct sortvec), compare_overlays);
2019
2020 for (i = 0; i < noverlays; i++)
2021 overlay_vec[i] = sortvec[i].overlay;
2022 return (noverlays);
2023}
2024\f
bbbe9545
KH
2025struct sortstr
2026{
cb26008f 2027 Lisp_Object string, string2;
bbbe9545
KH
2028 int size;
2029 int priority;
2030};
2031
e8185fa8
KH
2032struct sortstrlist
2033{
2034 struct sortstr *buf; /* An array that expands as needed; never freed. */
2035 int size; /* Allocated length of that array. */
2036 int used; /* How much of the array is currently in use. */
2037 int bytes; /* Total length of the strings in buf. */
2038};
2039
2040/* Buffers for storing information about the overlays touching a given
2041 position. These could be automatic variables in overlay_strings, but
2042 it's more efficient to hold onto the memory instead of repeatedly
2043 allocating and freeing it. */
2044static struct sortstrlist overlay_heads, overlay_tails;
2045static char *overlay_str_buf;
2046
2047/* Allocated length of overlay_str_buf. */
2048static int overlay_str_len;
2049
bbbe9545
KH
2050/* A comparison function suitable for passing to qsort. */
2051static int
2052cmp_for_strings (as1, as2)
2053 char *as1, *as2;
2054{
2055 struct sortstr *s1 = (struct sortstr *)as1;
2056 struct sortstr *s2 = (struct sortstr *)as2;
2057 if (s1->size != s2->size)
2058 return s2->size - s1->size;
2059 if (s1->priority != s2->priority)
2060 return s1->priority - s2->priority;
2061 return 0;
2062}
2063
e8185fa8 2064static void
cb26008f 2065record_overlay_string (ssl, str, str2, pri, size)
e8185fa8 2066 struct sortstrlist *ssl;
cb26008f 2067 Lisp_Object str, str2, pri;
e8185fa8
KH
2068 int size;
2069{
2070 if (ssl->used == ssl->size)
2071 {
2072 if (ssl->buf)
2073 ssl->size *= 2;
2074 else
2075 ssl->size = 5;
2076 ssl->buf = ((struct sortstr *)
2077 xrealloc (ssl->buf, ssl->size * sizeof (struct sortstr)));
2078 }
2079 ssl->buf[ssl->used].string = str;
cb26008f 2080 ssl->buf[ssl->used].string2 = str2;
e8185fa8
KH
2081 ssl->buf[ssl->used].size = size;
2082 ssl->buf[ssl->used].priority = (INTEGERP (pri) ? XINT (pri) : 0);
2083 ssl->used++;
2084 ssl->bytes += XSTRING (str)->size;
cb26008f
KH
2085 if (STRINGP (str2))
2086 ssl->bytes += XSTRING (str2)->size;
e8185fa8 2087}
bbbe9545
KH
2088
2089/* Return the concatenation of the strings associated with overlays that
2090 begin or end at POS, ignoring overlays that are specific to a window
2091 other than W. The strings are concatenated in the appropriate order:
2092 shorter overlays nest inside longer ones, and higher priority inside
cb26008f
KH
2093 lower. Normally all of the after-strings come first, but zero-sized
2094 overlays have their after-strings ride along with the before-strings
2095 because it would look strange to print them inside-out.
2096
2097 Returns the string length, and stores the contents indirectly through
2098 PSTR, if that variable is non-null. The string may be overwritten by
2099 subsequent calls. */
bbbe9545
KH
2100int
2101overlay_strings (pos, w, pstr)
2102 int pos;
2103 struct window *w;
2104 char **pstr;
2105{
e8185fa8 2106 Lisp_Object ov, overlay, window, str;
bbbe9545
KH
2107 int startpos, endpos;
2108
e8185fa8
KH
2109 overlay_heads.used = overlay_heads.bytes = 0;
2110 overlay_tails.used = overlay_tails.bytes = 0;
bbbe9545
KH
2111 for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCONS (ov)->cdr)
2112 {
2113 overlay = XCONS (ov)->car;
2114 if (!OVERLAYP (overlay))
2115 abort ();
2116
2117 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2118 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2119 if (endpos < pos)
2120 break;
2121 if (endpos != pos && startpos != pos)
2122 continue;
2123 window = Foverlay_get (overlay, Qwindow);
2124 if (WINDOWP (window) && XWINDOW (window) != w)
2125 continue;
e8185fa8
KH
2126 if (startpos == pos
2127 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
2128 record_overlay_string (&overlay_heads, str,
cb26008f
KH
2129 (startpos == endpos
2130 ? Foverlay_get (overlay, Qafter_string)
2131 : Qnil),
2132 Foverlay_get (overlay, Qpriority),
2133 endpos - startpos);
2134 else if (endpos == pos
2135 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
2136 record_overlay_string (&overlay_tails, str, Qnil,
e8185fa8
KH
2137 Foverlay_get (overlay, Qpriority),
2138 endpos - startpos);
bbbe9545
KH
2139 }
2140 for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCONS (ov)->cdr)
2141 {
2142 overlay = XCONS (ov)->car;
2143 if (!OVERLAYP (overlay))
2144 abort ();
2145
2146 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2147 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2148 if (startpos > pos)
2149 break;
e8185fa8
KH
2150 if (endpos != pos && startpos != pos)
2151 continue;
2152 window = Foverlay_get (overlay, Qwindow);
2153 if (WINDOWP (window) && XWINDOW (window) != w)
2154 continue;
e8185fa8
KH
2155 if (startpos == pos
2156 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
2157 record_overlay_string (&overlay_heads, str,
cb26008f
KH
2158 (startpos == endpos
2159 ? Foverlay_get (overlay, Qafter_string)
2160 : Qnil),
2161 Foverlay_get (overlay, Qpriority),
2162 endpos - startpos);
2163 else if (endpos == pos
2164 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
2165 record_overlay_string (&overlay_tails, str, Qnil,
e8185fa8
KH
2166 Foverlay_get (overlay, Qpriority),
2167 endpos - startpos);
bbbe9545 2168 }
e8185fa8
KH
2169 if (overlay_tails.used > 1)
2170 qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr),
2171 cmp_for_strings);
2172 if (overlay_heads.used > 1)
2173 qsort (overlay_heads.buf, overlay_heads.used, sizeof (struct sortstr),
2174 cmp_for_strings);
2175 if (overlay_heads.bytes || overlay_tails.bytes)
bbbe9545 2176 {
e8185fa8 2177 Lisp_Object tem;
bbbe9545
KH
2178 int i;
2179 char *p;
e8185fa8 2180 int total = overlay_heads.bytes + overlay_tails.bytes;
bbbe9545
KH
2181
2182 if (total > overlay_str_len)
e8185fa8
KH
2183 overlay_str_buf = (char *)xrealloc (overlay_str_buf,
2184 overlay_str_len = total);
bbbe9545 2185 p = overlay_str_buf;
e8185fa8 2186 for (i = overlay_tails.used; --i >= 0;)
bbbe9545 2187 {
e8185fa8 2188 tem = overlay_tails.buf[i].string;
bbbe9545
KH
2189 bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size);
2190 p += XSTRING (tem)->size;
2191 }
e8185fa8 2192 for (i = 0; i < overlay_heads.used; ++i)
bbbe9545 2193 {
e8185fa8 2194 tem = overlay_heads.buf[i].string;
bbbe9545
KH
2195 bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size);
2196 p += XSTRING (tem)->size;
cb26008f
KH
2197 tem = overlay_heads.buf[i].string2;
2198 if (STRINGP (tem))
2199 {
2200 bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size);
2201 p += XSTRING (tem)->size;
2202 }
bbbe9545 2203 }
cb26008f
KH
2204 if (p != overlay_str_buf + total)
2205 abort ();
bbbe9545
KH
2206 if (pstr)
2207 *pstr = overlay_str_buf;
e8185fa8 2208 return total;
bbbe9545 2209 }
e8185fa8 2210 return 0;
bbbe9545
KH
2211}
2212\f
5c4f68f1 2213/* Shift overlays in BUF's overlay lists, to center the lists at POS. */
1ab256cb 2214
2eec3b4e 2215void
5c4f68f1
JB
2216recenter_overlay_lists (buf, pos)
2217 struct buffer *buf;
2eec3b4e
RS
2218 int pos;
2219{
2220 Lisp_Object overlay, tail, next, prev, beg, end;
2221
2222 /* See if anything in overlays_before should move to overlays_after. */
2223
2224 /* We don't strictly need prev in this loop; it should always be nil.
2225 But we use it for symmetry and in case that should cease to be true
2226 with some future change. */
2227 prev = Qnil;
5c4f68f1 2228 for (tail = buf->overlays_before;
2eec3b4e
RS
2229 CONSP (tail);
2230 prev = tail, tail = next)
1ab256cb 2231 {
2eec3b4e
RS
2232 next = XCONS (tail)->cdr;
2233 overlay = XCONS (tail)->car;
2234
2235 /* If the overlay is not valid, get rid of it. */
2236 if (!OVERLAY_VALID (overlay))
52f8ec73
JB
2237#if 1
2238 abort ();
2239#else
2eec3b4e
RS
2240 {
2241 /* Splice the cons cell TAIL out of overlays_before. */
2242 if (!NILP (prev))
2243 XCONS (prev)->cdr = next;
2244 else
5c4f68f1 2245 buf->overlays_before = next;
2eec3b4e
RS
2246 tail = prev;
2247 continue;
2248 }
52f8ec73 2249#endif
1ab256cb 2250
2eec3b4e
RS
2251 beg = OVERLAY_START (overlay);
2252 end = OVERLAY_END (overlay);
1ab256cb 2253
2eec3b4e 2254 if (OVERLAY_POSITION (end) > pos)
1ab256cb 2255 {
2eec3b4e
RS
2256 /* OVERLAY needs to be moved. */
2257 int where = OVERLAY_POSITION (beg);
2258 Lisp_Object other, other_prev;
2259
2260 /* Splice the cons cell TAIL out of overlays_before. */
2261 if (!NILP (prev))
2262 XCONS (prev)->cdr = next;
2263 else
5c4f68f1 2264 buf->overlays_before = next;
2eec3b4e
RS
2265
2266 /* Search thru overlays_after for where to put it. */
2267 other_prev = Qnil;
5c4f68f1 2268 for (other = buf->overlays_after;
2eec3b4e
RS
2269 CONSP (other);
2270 other_prev = other, other = XCONS (other)->cdr)
1ab256cb 2271 {
2eec3b4e
RS
2272 Lisp_Object otherbeg, otheroverlay, follower;
2273 int win;
2274
2275 otheroverlay = XCONS (other)->car;
2276 if (! OVERLAY_VALID (otheroverlay))
52f8ec73 2277 abort ();
2eec3b4e
RS
2278
2279 otherbeg = OVERLAY_START (otheroverlay);
2280 if (OVERLAY_POSITION (otherbeg) >= where)
2281 break;
1ab256cb 2282 }
2eec3b4e
RS
2283
2284 /* Add TAIL to overlays_after before OTHER. */
2285 XCONS (tail)->cdr = other;
2286 if (!NILP (other_prev))
2287 XCONS (other_prev)->cdr = tail;
1ab256cb 2288 else
5c4f68f1 2289 buf->overlays_after = tail;
2eec3b4e 2290 tail = prev;
1ab256cb 2291 }
2eec3b4e
RS
2292 else
2293 /* We've reached the things that should stay in overlays_before.
2294 All the rest of overlays_before must end even earlier,
2295 so stop now. */
2296 break;
2297 }
2298
2299 /* See if anything in overlays_after should be in overlays_before. */
2300 prev = Qnil;
5c4f68f1 2301 for (tail = buf->overlays_after;
2eec3b4e
RS
2302 CONSP (tail);
2303 prev = tail, tail = next)
2304 {
2305 next = XCONS (tail)->cdr;
2306 overlay = XCONS (tail)->car;
2307
2308 /* If the overlay is not valid, get rid of it. */
2309 if (!OVERLAY_VALID (overlay))
52f8ec73
JB
2310#if 1
2311 abort ();
2312#else
2eec3b4e
RS
2313 {
2314 /* Splice the cons cell TAIL out of overlays_after. */
2315 if (!NILP (prev))
2316 XCONS (prev)->cdr = next;
2317 else
5c4f68f1 2318 buf->overlays_after = next;
2eec3b4e
RS
2319 tail = prev;
2320 continue;
2321 }
52f8ec73 2322#endif
2eec3b4e
RS
2323
2324 beg = OVERLAY_START (overlay);
2325 end = OVERLAY_END (overlay);
2326
2327 /* Stop looking, when we know that nothing further
2328 can possibly end before POS. */
2329 if (OVERLAY_POSITION (beg) > pos)
2330 break;
2331
2332 if (OVERLAY_POSITION (end) <= pos)
2333 {
2334 /* OVERLAY needs to be moved. */
2335 int where = OVERLAY_POSITION (end);
2336 Lisp_Object other, other_prev;
2337
2338 /* Splice the cons cell TAIL out of overlays_after. */
2339 if (!NILP (prev))
2340 XCONS (prev)->cdr = next;
2341 else
5c4f68f1 2342 buf->overlays_after = next;
2eec3b4e
RS
2343
2344 /* Search thru overlays_before for where to put it. */
2345 other_prev = Qnil;
5c4f68f1 2346 for (other = buf->overlays_before;
2eec3b4e
RS
2347 CONSP (other);
2348 other_prev = other, other = XCONS (other)->cdr)
2349 {
2350 Lisp_Object otherend, otheroverlay;
2351 int win;
2352
2353 otheroverlay = XCONS (other)->car;
2354 if (! OVERLAY_VALID (otheroverlay))
52f8ec73 2355 abort ();
2eec3b4e
RS
2356
2357 otherend = OVERLAY_END (otheroverlay);
2358 if (OVERLAY_POSITION (otherend) <= where)
2359 break;
2360 }
2361
2362 /* Add TAIL to overlays_before before OTHER. */
2363 XCONS (tail)->cdr = other;
2364 if (!NILP (other_prev))
2365 XCONS (other_prev)->cdr = tail;
2366 else
5c4f68f1 2367 buf->overlays_before = tail;
2eec3b4e
RS
2368 tail = prev;
2369 }
2370 }
2371
8d7a4592 2372 XSETFASTINT (buf->overlay_center, pos);
2eec3b4e 2373}
2b1bdf65 2374
423cdb46
KH
2375void
2376adjust_overlays_for_insert (pos, length)
2377 int pos;
2378 int length;
2379{
2380 /* After an insertion, the lists are still sorted properly,
2381 but we may need to update the value of the overlay center. */
2382 if (XFASTINT (current_buffer->overlay_center) >= pos)
2383 XSETFASTINT (current_buffer->overlay_center,
2384 XFASTINT (current_buffer->overlay_center) + length);
2385}
2386
2387void
2388adjust_overlays_for_delete (pos, length)
2389 int pos;
2390 int length;
2391{
2392 if (XFASTINT (current_buffer->overlay_center) < pos)
2393 /* The deletion was to our right. No change needed; the before- and
2394 after-lists are still consistent. */
2395 ;
2396 else if (XFASTINT (current_buffer->overlay_center) > pos + length)
2397 /* The deletion was to our left. We need to adjust the center value
2398 to account for the change in position, but the lists are consistent
2399 given the new value. */
2400 XSETFASTINT (current_buffer->overlay_center,
2401 XFASTINT (current_buffer->overlay_center) - length);
2402 else
2403 /* We're right in the middle. There might be things on the after-list
2404 that now belong on the before-list. Recentering will move them,
2405 and also update the center point. */
2406 recenter_overlay_lists (current_buffer, pos);
2407}
2408
2b1bdf65
KH
2409/* Fix up overlays that were garbled as a result of permuting markers
2410 in the range START through END. Any overlay with at least one
2411 endpoint in this range will need to be unlinked from the overlay
2412 list and reinserted in its proper place.
2413 Such an overlay might even have negative size at this point.
2414 If so, we'll reverse the endpoints. Can you think of anything
2415 better to do in this situation? */
2416void
2417fix_overlays_in_range (start, end)
2418 register int start, end;
2419{
2420 Lisp_Object tem, overlay;
2421 Lisp_Object before_list, after_list;
2422 Lisp_Object *ptail, *pbefore = &before_list, *pafter = &after_list;
2423 int startpos, endpos;
2424
2425 /* This algorithm shifts links around instead of consing and GCing.
2426 The loop invariant is that before_list (resp. after_list) is a
2427 well-formed list except that its last element, the one that
2428 *pbefore (resp. *pafter) points to, is still uninitialized.
2429 So it's not a bug that before_list isn't initialized, although
2430 it may look strange. */
2431 for (ptail = &current_buffer->overlays_before; CONSP (*ptail);)
2432 {
2433 overlay = XCONS (*ptail)->car;
2434 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2435 if (endpos < start)
2436 break;
2437 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2438 if (endpos < end
2439 || (startpos >= start && startpos < end))
2440 {
2441 /* If the overlay is backwards, fix that now. */
2442 if (startpos > endpos)
2443 {
2444 int tem;
2445 Fset_marker (OVERLAY_START (overlay), endpos, Qnil);
2446 Fset_marker (OVERLAY_END (overlay), startpos, Qnil);
2447 tem = startpos; startpos = endpos; endpos = tem;
2448 }
2449 /* Add it to the end of the wrong list. Later on,
2450 recenter_overlay_lists will move it to the right place. */
2451 if (endpos < XINT (current_buffer->overlay_center))
2452 {
2453 *pafter = *ptail;
2454 pafter = &XCONS (*ptail)->cdr;
2455 }
2456 else
2457 {
2458 *pbefore = *ptail;
2459 pbefore = &XCONS (*ptail)->cdr;
2460 }
2461 *ptail = XCONS (*ptail)->cdr;
2462 }
2463 else
2464 ptail = &XCONS (*ptail)->cdr;
2465 }
2466 for (ptail = &current_buffer->overlays_after; CONSP (*ptail);)
2467 {
2468 overlay = XCONS (*ptail)->car;
2469 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2470 if (startpos >= end)
2471 break;
2472 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2473 if (startpos >= start
2474 || (endpos >= start && endpos < end))
2475 {
2476 if (startpos > endpos)
2477 {
2478 int tem;
2479 Fset_marker (OVERLAY_START (overlay), endpos, Qnil);
2480 Fset_marker (OVERLAY_END (overlay), startpos, Qnil);
2481 tem = startpos; startpos = endpos; endpos = tem;
2482 }
2483 if (endpos < XINT (current_buffer->overlay_center))
2484 {
2485 *pafter = *ptail;
2486 pafter = &XCONS (*ptail)->cdr;
2487 }
2488 else
2489 {
2490 *pbefore = *ptail;
2491 pbefore = &XCONS (*ptail)->cdr;
2492 }
2493 *ptail = XCONS (*ptail)->cdr;
2494 }
2495 else
2496 ptail = &XCONS (*ptail)->cdr;
2497 }
2498
2499 /* Splice the constructed (wrong) lists into the buffer's lists,
2500 and let the recenter function make it sane again. */
2501 *pbefore = current_buffer->overlays_before;
2502 current_buffer->overlays_before = before_list;
2503 recenter_overlay_lists (current_buffer,
2504 XINT (current_buffer->overlay_center));
2505
2506 *pafter = current_buffer->overlays_after;
2507 current_buffer->overlays_after = after_list;
2508 recenter_overlay_lists (current_buffer,
2509 XINT (current_buffer->overlay_center));
2510}
2eec3b4e 2511\f
52f8ec73
JB
2512DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
2513 "Return t if OBJECT is an overlay.")
2514 (object)
2515 Lisp_Object object;
2516{
2517 return (OVERLAYP (object) ? Qt : Qnil);
2518}
2519
acac2700 2520DEFUN ("make-overlay", Fmake_overlay, Smake_overlay, 2, 5, 0,
5c4f68f1
JB
2521 "Create a new overlay with range BEG to END in BUFFER.\n\
2522If omitted, BUFFER defaults to the current buffer.\n\
acac2700
RS
2523BEG and END may be integers or markers.\n\
2524The fourth arg FRONT-ADVANCE, if non-nil, makes the\n\
2525front delimiter advance when text is inserted there.\n\
2526The fifth arg REAR-ADVANCE, if non-nil, makes the\n\
2527rear delimiter advance when text is inserted there.")
2528 (beg, end, buffer, front_advance, rear_advance)
5c4f68f1 2529 Lisp_Object beg, end, buffer;
acac2700 2530 Lisp_Object front_advance, rear_advance;
2eec3b4e
RS
2531{
2532 Lisp_Object overlay;
5c4f68f1 2533 struct buffer *b;
2eec3b4e 2534
5c4f68f1 2535 if (NILP (buffer))
67180c6a 2536 XSETBUFFER (buffer, current_buffer);
883047b9
JB
2537 else
2538 CHECK_BUFFER (buffer, 2);
2539 if (MARKERP (beg)
2540 && ! EQ (Fmarker_buffer (beg), buffer))
2541 error ("Marker points into wrong buffer");
2542 if (MARKERP (end)
2543 && ! EQ (Fmarker_buffer (end), buffer))
2544 error ("Marker points into wrong buffer");
2eec3b4e 2545
883047b9
JB
2546 CHECK_NUMBER_COERCE_MARKER (beg, 1);
2547 CHECK_NUMBER_COERCE_MARKER (end, 1);
5c4f68f1 2548
883047b9 2549 if (XINT (beg) > XINT (end))
5c4f68f1 2550 {
c99fc30f
KH
2551 Lisp_Object temp;
2552 temp = beg; beg = end; end = temp;
5c4f68f1 2553 }
883047b9
JB
2554
2555 b = XBUFFER (buffer);
2556
2557 beg = Fset_marker (Fmake_marker (), beg, buffer);
2558 end = Fset_marker (Fmake_marker (), end, buffer);
5c4f68f1 2559
acac2700
RS
2560 if (!NILP (front_advance))
2561 XMARKER (beg)->insertion_type = 1;
2562 if (!NILP (rear_advance))
2563 XMARKER (end)->insertion_type = 1;
597dd755 2564
48e2e3ba 2565 overlay = allocate_misc ();
89ca3e1b 2566 XMISCTYPE (overlay) = Lisp_Misc_Overlay;
48e2e3ba
KH
2567 XOVERLAY (overlay)->start = beg;
2568 XOVERLAY (overlay)->end = end;
2569 XOVERLAY (overlay)->plist = Qnil;
2eec3b4e
RS
2570
2571 /* Put the new overlay on the wrong list. */
2572 end = OVERLAY_END (overlay);
5c4f68f1
JB
2573 if (OVERLAY_POSITION (end) < XINT (b->overlay_center))
2574 b->overlays_after = Fcons (overlay, b->overlays_after);
2eec3b4e 2575 else
5c4f68f1 2576 b->overlays_before = Fcons (overlay, b->overlays_before);
2eec3b4e
RS
2577
2578 /* This puts it in the right list, and in the right order. */
5c4f68f1 2579 recenter_overlay_lists (b, XINT (b->overlay_center));
2eec3b4e 2580
b61982dd
JB
2581 /* We don't need to redisplay the region covered by the overlay, because
2582 the overlay has no properties at the moment. */
2583
2eec3b4e
RS
2584 return overlay;
2585}
2586
5c4f68f1
JB
2587DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
2588 "Set the endpoints of OVERLAY to BEG and END in BUFFER.\n\
3ece337a
JB
2589If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.\n\
2590If BUFFER is omitted, and OVERLAY is in no buffer, put it in the current\n\
2591buffer.")
5c4f68f1
JB
2592 (overlay, beg, end, buffer)
2593 Lisp_Object overlay, beg, end, buffer;
2eec3b4e 2594{
0a4469c9
RS
2595 struct buffer *b, *ob;
2596 Lisp_Object obuffer;
2597 int count = specpdl_ptr - specpdl;
5c4f68f1 2598
52f8ec73 2599 CHECK_OVERLAY (overlay, 0);
5c4f68f1
JB
2600 if (NILP (buffer))
2601 buffer = Fmarker_buffer (OVERLAY_START (overlay));
3ece337a 2602 if (NILP (buffer))
67180c6a 2603 XSETBUFFER (buffer, current_buffer);
5c4f68f1 2604 CHECK_BUFFER (buffer, 3);
883047b9
JB
2605
2606 if (MARKERP (beg)
2607 && ! EQ (Fmarker_buffer (beg), buffer))
2608 error ("Marker points into wrong buffer");
2609 if (MARKERP (end)
2610 && ! EQ (Fmarker_buffer (end), buffer))
2611 error ("Marker points into wrong buffer");
2612
b61982dd
JB
2613 CHECK_NUMBER_COERCE_MARKER (beg, 1);
2614 CHECK_NUMBER_COERCE_MARKER (end, 1);
2615
9d7608b7
KH
2616 if (XINT (beg) == XINT (end) && ! NILP (Foverlay_get (overlay, Qevaporate)))
2617 return Fdelete_overlay (overlay);
0a4469c9 2618
b61982dd
JB
2619 if (XINT (beg) > XINT (end))
2620 {
c99fc30f
KH
2621 Lisp_Object temp;
2622 temp = beg; beg = end; end = temp;
b61982dd
JB
2623 }
2624
9d7608b7
KH
2625 specbind (Qinhibit_quit, Qt);
2626
0a4469c9 2627 obuffer = Fmarker_buffer (OVERLAY_START (overlay));
5c4f68f1 2628 b = XBUFFER (buffer);
0a4469c9 2629 ob = XBUFFER (obuffer);
2eec3b4e 2630
c82ed728 2631 /* If the overlay has changed buffers, do a thorough redisplay. */
0a4469c9 2632 if (!EQ (buffer, obuffer))
50760c4a
RS
2633 {
2634 /* Redisplay where the overlay was. */
2635 if (!NILP (obuffer))
2636 {
2637 Lisp_Object o_beg;
2638 Lisp_Object o_end;
2639
2640 o_beg = OVERLAY_START (overlay);
2641 o_end = OVERLAY_END (overlay);
2642 o_beg = OVERLAY_POSITION (o_beg);
2643 o_end = OVERLAY_POSITION (o_end);
2644
efd90478 2645 redisplay_region (ob, XINT (o_beg), XINT (o_end));
50760c4a
RS
2646 }
2647
2648 /* Redisplay where the overlay is going to be. */
efd90478 2649 redisplay_region (b, XINT (beg), XINT (end));
50760c4a 2650 }
c82ed728
JB
2651 else
2652 /* Redisplay the area the overlay has just left, or just enclosed. */
2653 {
be8b1c6b
RS
2654 Lisp_Object o_beg;
2655 Lisp_Object o_end;
c82ed728
JB
2656 int change_beg, change_end;
2657
be8b1c6b
RS
2658 o_beg = OVERLAY_START (overlay);
2659 o_end = OVERLAY_END (overlay);
c82ed728
JB
2660 o_beg = OVERLAY_POSITION (o_beg);
2661 o_end = OVERLAY_POSITION (o_end);
2662
2663 if (XINT (o_beg) == XINT (beg))
2664 redisplay_region (b, XINT (o_end), XINT (end));
2665 else if (XINT (o_end) == XINT (end))
2666 redisplay_region (b, XINT (o_beg), XINT (beg));
2667 else
2668 {
2669 if (XINT (beg) < XINT (o_beg)) o_beg = beg;
2670 if (XINT (end) > XINT (o_end)) o_end = end;
2671 redisplay_region (b, XINT (o_beg), XINT (o_end));
2672 }
2673 }
b61982dd 2674
0a4469c9
RS
2675 if (!NILP (obuffer))
2676 {
2677 ob->overlays_before = Fdelq (overlay, ob->overlays_before);
2678 ob->overlays_after = Fdelq (overlay, ob->overlays_after);
2679 }
5c4f68f1
JB
2680
2681 Fset_marker (OVERLAY_START (overlay), beg, buffer);
2682 Fset_marker (OVERLAY_END (overlay), end, buffer);
2eec3b4e
RS
2683
2684 /* Put the overlay on the wrong list. */
2685 end = OVERLAY_END (overlay);
5c4f68f1
JB
2686 if (OVERLAY_POSITION (end) < XINT (b->overlay_center))
2687 b->overlays_after = Fcons (overlay, b->overlays_after);
2eec3b4e 2688 else
5c4f68f1 2689 b->overlays_before = Fcons (overlay, b->overlays_before);
2eec3b4e
RS
2690
2691 /* This puts it in the right list, and in the right order. */
5c4f68f1 2692 recenter_overlay_lists (b, XINT (b->overlay_center));
2eec3b4e 2693
0a4469c9 2694 return unbind_to (count, overlay);
2eec3b4e
RS
2695}
2696
2697DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
5c4f68f1 2698 "Delete the overlay OVERLAY from its buffer.")
2eec3b4e 2699 (overlay)
5c4f68f1 2700 Lisp_Object overlay;
2eec3b4e 2701{
0a4469c9 2702 Lisp_Object buffer;
5c4f68f1 2703 struct buffer *b;
0a4469c9 2704 int count = specpdl_ptr - specpdl;
5c4f68f1 2705
52f8ec73
JB
2706 CHECK_OVERLAY (overlay, 0);
2707
0a4469c9
RS
2708 buffer = Fmarker_buffer (OVERLAY_START (overlay));
2709 if (NILP (buffer))
2710 return Qnil;
2711
2712 b = XBUFFER (buffer);
2713
2714 specbind (Qinhibit_quit, Qt);
5c4f68f1
JB
2715
2716 b->overlays_before = Fdelq (overlay, b->overlays_before);
2717 b->overlays_after = Fdelq (overlay, b->overlays_after);
2718
b61982dd 2719 redisplay_region (b,
a927f5c9
RS
2720 marker_position (OVERLAY_START (overlay)),
2721 marker_position (OVERLAY_END (overlay)));
b61982dd 2722
3ece337a
JB
2723 Fset_marker (OVERLAY_START (overlay), Qnil, Qnil);
2724 Fset_marker (OVERLAY_END (overlay), Qnil, Qnil);
2725
0a4469c9 2726 return unbind_to (count, Qnil);
2eec3b4e
RS
2727}
2728\f
8ebafa8d
JB
2729/* Overlay dissection functions. */
2730
2731DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
2732 "Return the position at which OVERLAY starts.")
2733 (overlay)
2734 Lisp_Object overlay;
2735{
2736 CHECK_OVERLAY (overlay, 0);
2737
2738 return (Fmarker_position (OVERLAY_START (overlay)));
2739}
2740
2741DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
2742 "Return the position at which OVERLAY ends.")
2743 (overlay)
2744 Lisp_Object overlay;
2745{
2746 CHECK_OVERLAY (overlay, 0);
2747
2748 return (Fmarker_position (OVERLAY_END (overlay)));
2749}
2750
2751DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
2752 "Return the buffer OVERLAY belongs to.")
2753 (overlay)
2754 Lisp_Object overlay;
2755{
2756 CHECK_OVERLAY (overlay, 0);
2757
2758 return Fmarker_buffer (OVERLAY_START (overlay));
2759}
2760
2761DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
2762 "Return a list of the properties on OVERLAY.\n\
2763This is a copy of OVERLAY's plist; modifying its conses has no effect on\n\
2764OVERLAY.")
2765 (overlay)
2766 Lisp_Object overlay;
2767{
2768 CHECK_OVERLAY (overlay, 0);
2769
48e2e3ba 2770 return Fcopy_sequence (XOVERLAY (overlay)->plist);
8ebafa8d
JB
2771}
2772
2773\f
2eec3b4e 2774DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
eb8c3be9 2775 "Return a list of the overlays that contain position POS.")
2eec3b4e
RS
2776 (pos)
2777 Lisp_Object pos;
2778{
2779 int noverlays;
2eec3b4e
RS
2780 Lisp_Object *overlay_vec;
2781 int len;
2782 Lisp_Object result;
2783
2784 CHECK_NUMBER_COERCE_MARKER (pos, 0);
2785
2786 len = 10;
2787 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
2788
2789 /* Put all the overlays we want in a vector in overlay_vec.
2790 Store the length in len. */
2a77a7d7
RS
2791 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
2792 (int *) 0, (int *) 0);
2eec3b4e
RS
2793
2794 /* Make a list of them all. */
2795 result = Flist (noverlays, overlay_vec);
2796
9ac0d9e0 2797 xfree (overlay_vec);
2eec3b4e
RS
2798 return result;
2799}
2800
74514898 2801DEFUN ("overlays-in", Foverlays_in, Soverlays_in, 2, 2, 0,
2a3eeee7
RS
2802 "Return a list of the overlays that overlap the region BEG ... END.\n\
2803Overlap means that at least one character is contained within the overlay\n\
2804and also contained within the specified region.\n\
2805Empty overlays are included in the result if they are located at BEG\n\
2806or between BEG and END.")
74514898
RS
2807 (beg, end)
2808 Lisp_Object beg, end;
2809{
2810 int noverlays;
2811 Lisp_Object *overlay_vec;
2812 int len;
2813 Lisp_Object result;
2814
2815 CHECK_NUMBER_COERCE_MARKER (beg, 0);
2816 CHECK_NUMBER_COERCE_MARKER (end, 0);
2817
2818 len = 10;
2819 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
2820
2821 /* Put all the overlays we want in a vector in overlay_vec.
2822 Store the length in len. */
2823 noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len,
2824 (int *) 0, (int *) 0);
2825
2826 /* Make a list of them all. */
2827 result = Flist (noverlays, overlay_vec);
2828
2829 xfree (overlay_vec);
2830 return result;
2831}
2832
2eec3b4e
RS
2833DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change,
2834 1, 1, 0,
bbe20e81
KH
2835 "Return the next position after POS where an overlay starts or ends.\n\
2836If there are no more overlay boundaries after POS, return (point-max).")
2eec3b4e
RS
2837 (pos)
2838 Lisp_Object pos;
2839{
2840 int noverlays;
2841 int endpos;
2842 Lisp_Object *overlay_vec;
2843 int len;
2eec3b4e
RS
2844 int i;
2845
2846 CHECK_NUMBER_COERCE_MARKER (pos, 0);
2847
2848 len = 10;
2849 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
2850
2851 /* Put all the overlays we want in a vector in overlay_vec.
2852 Store the length in len.
2853 endpos gets the position where the next overlay starts. */
2a77a7d7
RS
2854 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
2855 &endpos, (int *) 0);
2eec3b4e
RS
2856
2857 /* If any of these overlays ends before endpos,
2858 use its ending point instead. */
2859 for (i = 0; i < noverlays; i++)
2860 {
2861 Lisp_Object oend;
2862 int oendpos;
2863
2864 oend = OVERLAY_END (overlay_vec[i]);
2865 oendpos = OVERLAY_POSITION (oend);
2866 if (oendpos < endpos)
2867 endpos = oendpos;
1ab256cb
RM
2868 }
2869
9ac0d9e0 2870 xfree (overlay_vec);
2eec3b4e
RS
2871 return make_number (endpos);
2872}
239c932b
RS
2873
2874DEFUN ("previous-overlay-change", Fprevious_overlay_change,
2875 Sprevious_overlay_change, 1, 1, 0,
2876 "Return the previous position before POS where an overlay starts or ends.\n\
624bbdc4 2877If there are no more overlay boundaries before POS, return (point-min).")
239c932b
RS
2878 (pos)
2879 Lisp_Object pos;
2880{
2881 int noverlays;
2882 int prevpos;
2883 Lisp_Object *overlay_vec;
2884 int len;
2885 int i;
624bbdc4 2886 Lisp_Object tail;
239c932b
RS
2887
2888 CHECK_NUMBER_COERCE_MARKER (pos, 0);
2889
2890 len = 10;
2891 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
2892
624bbdc4
RS
2893 /* At beginning of buffer, we know the answer;
2894 avoid bug subtracting 1 below. */
2895 if (XINT (pos) == BEGV)
2896 return pos;
2897
239c932b
RS
2898 /* Put all the overlays we want in a vector in overlay_vec.
2899 Store the length in len.
2900 prevpos gets the position of an overlay end. */
2a77a7d7
RS
2901 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
2902 (int *) 0, &prevpos);
239c932b 2903
624bbdc4 2904 /* If any of these overlays starts after prevpos,
239c932b
RS
2905 maybe use its starting point instead. */
2906 for (i = 0; i < noverlays; i++)
2907 {
2908 Lisp_Object ostart;
2909 int ostartpos;
2910
2911 ostart = OVERLAY_START (overlay_vec[i]);
2912 ostartpos = OVERLAY_POSITION (ostart);
2913 if (ostartpos > prevpos && ostartpos < XINT (pos))
2914 prevpos = ostartpos;
2915 }
2916
624bbdc4
RS
2917 /* If any overlay ends at pos, consider its starting point too. */
2918 for (tail = current_buffer->overlays_before;
2919 GC_CONSP (tail);
2920 tail = XCONS (tail)->cdr)
2921 {
2922 Lisp_Object overlay, ostart;
2923 int ostartpos;
2924
2925 overlay = XCONS (tail)->car;
2926
2927 ostart = OVERLAY_START (overlay);
2928 ostartpos = OVERLAY_POSITION (ostart);
2929 if (ostartpos > prevpos && ostartpos < XINT (pos))
2930 prevpos = ostartpos;
2931 }
2932
239c932b
RS
2933 xfree (overlay_vec);
2934 return make_number (prevpos);
2935}
2eec3b4e
RS
2936\f
2937/* These functions are for debugging overlays. */
2938
2939DEFUN ("overlay-lists", Foverlay_lists, Soverlay_lists, 0, 0, 0,
2940 "Return a pair of lists giving all the overlays of the current buffer.\n\
2941The car has all the overlays before the overlay center;\n\
bbe20e81 2942the cdr has all the overlays after the overlay center.\n\
2eec3b4e
RS
2943Recentering overlays moves overlays between these lists.\n\
2944The lists you get are copies, so that changing them has no effect.\n\
2945However, the overlays you get are the real objects that the buffer uses.")
2946 ()
2947{
2948 Lisp_Object before, after;
2949 before = current_buffer->overlays_before;
2950 if (CONSP (before))
2951 before = Fcopy_sequence (before);
2952 after = current_buffer->overlays_after;
2953 if (CONSP (after))
2954 after = Fcopy_sequence (after);
2955
2956 return Fcons (before, after);
2957}
2958
2959DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
2960 "Recenter the overlays of the current buffer around position POS.")
2961 (pos)
2962 Lisp_Object pos;
2963{
2964 CHECK_NUMBER_COERCE_MARKER (pos, 0);
2965
5c4f68f1 2966 recenter_overlay_lists (current_buffer, XINT (pos));
2eec3b4e
RS
2967 return Qnil;
2968}
2969\f
2970DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0,
a2428fa2 2971 "Get the property of overlay OVERLAY with property name PROP.")
2eec3b4e
RS
2972 (overlay, prop)
2973 Lisp_Object overlay, prop;
2974{
cab4777e 2975 Lisp_Object plist, fallback;
52f8ec73
JB
2976
2977 CHECK_OVERLAY (overlay, 0);
2978
cab4777e
RS
2979 fallback = Qnil;
2980
48e2e3ba 2981 for (plist = XOVERLAY (overlay)->plist;
2eec3b4e
RS
2982 CONSP (plist) && CONSP (XCONS (plist)->cdr);
2983 plist = XCONS (XCONS (plist)->cdr)->cdr)
2984 {
2985 if (EQ (XCONS (plist)->car, prop))
2986 return XCONS (XCONS (plist)->cdr)->car;
cab4777e
RS
2987 else if (EQ (XCONS (plist)->car, Qcategory))
2988 {
2989 Lisp_Object tem;
2990 tem = Fcar (Fcdr (plist));
2991 if (SYMBOLP (tem))
2992 fallback = Fget (tem, prop);
2993 }
2eec3b4e 2994 }
52f8ec73 2995
cab4777e 2996 return fallback;
2eec3b4e
RS
2997}
2998
2999DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
3000 "Set one property of overlay OVERLAY: give property PROP value VALUE.")
3001 (overlay, prop, value)
3002 Lisp_Object overlay, prop, value;
3003{
48e2e3ba 3004 Lisp_Object tail, buffer;
9d7608b7 3005 int changed;
2eec3b4e 3006
52f8ec73 3007 CHECK_OVERLAY (overlay, 0);
b61982dd 3008
274a9425
RS
3009 buffer = Fmarker_buffer (OVERLAY_START (overlay));
3010
48e2e3ba 3011 for (tail = XOVERLAY (overlay)->plist;
2eec3b4e
RS
3012 CONSP (tail) && CONSP (XCONS (tail)->cdr);
3013 tail = XCONS (XCONS (tail)->cdr)->cdr)
274a9425
RS
3014 if (EQ (XCONS (tail)->car, prop))
3015 {
9d7608b7
KH
3016 changed = !EQ (XCONS (XCONS (tail)->cdr)->car, value);
3017 XCONS (XCONS (tail)->cdr)->car = value;
3018 goto found;
274a9425 3019 }
9d7608b7
KH
3020 /* It wasn't in the list, so add it to the front. */
3021 changed = !NILP (value);
48e2e3ba
KH
3022 XOVERLAY (overlay)->plist
3023 = Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist));
9d7608b7
KH
3024 found:
3025 if (! NILP (buffer))
3026 {
3027 if (changed)
3028 redisplay_region (XBUFFER (buffer),
3029 marker_position (OVERLAY_START (overlay)),
3030 marker_position (OVERLAY_END (overlay)));
3031 if (EQ (prop, Qevaporate) && ! NILP (value)
3032 && (OVERLAY_POSITION (OVERLAY_START (overlay))
3033 == OVERLAY_POSITION (OVERLAY_END (overlay))))
3034 Fdelete_overlay (overlay);
3035 }
2eec3b4e 3036 return value;
1ab256cb
RM
3037}
3038\f
9115729e
KH
3039/* Subroutine of report_overlay_modification. */
3040
3041/* Lisp vector holding overlay hook functions to call.
3042 Vector elements come in pairs.
3043 Each even-index element is a list of hook functions.
3044 The following odd-index element is the overlay they came from.
3045
3046 Before the buffer change, we fill in this vector
3047 as we call overlay hook functions.
3048 After the buffer change, we get the functions to call from this vector.
3049 This way we always call the same functions before and after the change. */
3050static Lisp_Object last_overlay_modification_hooks;
3051
3052/* Number of elements actually used in last_overlay_modification_hooks. */
3053static int last_overlay_modification_hooks_used;
3054
3055/* Add one functionlist/overlay pair
3056 to the end of last_overlay_modification_hooks. */
3057
3058static void
3059add_overlay_mod_hooklist (functionlist, overlay)
3060 Lisp_Object functionlist, overlay;
3061{
3062 int oldsize = XVECTOR (last_overlay_modification_hooks)->size;
3063
3064 if (last_overlay_modification_hooks_used == oldsize)
3065 {
3066 Lisp_Object old;
3067 old = last_overlay_modification_hooks;
3068 last_overlay_modification_hooks
3069 = Fmake_vector (make_number (oldsize * 2), Qnil);
0b1f1b09
RS
3070 bcopy (XVECTOR (old)->contents,
3071 XVECTOR (last_overlay_modification_hooks)->contents,
9115729e
KH
3072 sizeof (Lisp_Object) * oldsize);
3073 }
3074 XVECTOR (last_overlay_modification_hooks)->contents[last_overlay_modification_hooks_used++] = functionlist;
3075 XVECTOR (last_overlay_modification_hooks)->contents[last_overlay_modification_hooks_used++] = overlay;
3076}
3077\f
173f2a64
RS
3078/* Run the modification-hooks of overlays that include
3079 any part of the text in START to END.
9115729e
KH
3080 If this change is an insertion, also
3081 run the insert-before-hooks of overlay starting at END,
930a9140
RS
3082 and the insert-after-hooks of overlay ending at START.
3083
3084 This is called both before and after the modification.
3085 AFTER is nonzero when we call after the modification.
3086
9115729e
KH
3087 ARG1, ARG2, ARG3 are arguments to pass to the hook functions.
3088 When AFTER is nonzero, they are the start position,
3089 the position after the inserted new text,
3090 and the length of deleted or replaced old text. */
173f2a64
RS
3091
3092void
930a9140 3093report_overlay_modification (start, end, after, arg1, arg2, arg3)
173f2a64 3094 Lisp_Object start, end;
930a9140
RS
3095 int after;
3096 Lisp_Object arg1, arg2, arg3;
173f2a64
RS
3097{
3098 Lisp_Object prop, overlay, tail;
9115729e
KH
3099 /* 1 if this change is an insertion. */
3100 int insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end));
55b48893 3101 int tail_copied;
930a9140 3102 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
55b48893
RS
3103
3104 overlay = Qnil;
3105 tail = Qnil;
930a9140 3106 GCPRO5 (overlay, tail, arg1, arg2, arg3);
173f2a64 3107
9115729e
KH
3108 if (after)
3109 {
3110 /* Call the functions recorded in last_overlay_modification_hooks
3111 rather than scanning the overlays again.
3112 First copy the vector contents, in case some of these hooks
3113 do subsequent modification of the buffer. */
3114 int size = last_overlay_modification_hooks_used;
3115 Lisp_Object *copy = (Lisp_Object *) alloca (size * sizeof (Lisp_Object));
3116 int i;
3117
3118 bcopy (XVECTOR (last_overlay_modification_hooks)->contents,
3119 copy, size * sizeof (Lisp_Object));
3120 gcpro1.var = copy;
3121 gcpro1.nvars = size;
3122
3123 for (i = 0; i < size;)
3124 {
3125 Lisp_Object prop, overlay;
3126 prop = copy[i++];
3127 overlay = copy[i++];
3128 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
3129 }
3130 UNGCPRO;
3131 return;
3132 }
3133
3134 /* We are being called before a change.
3135 Scan the overlays to find the functions to call. */
3136 last_overlay_modification_hooks_used = 0;
55b48893 3137 tail_copied = 0;
173f2a64
RS
3138 for (tail = current_buffer->overlays_before;
3139 CONSP (tail);
3140 tail = XCONS (tail)->cdr)
3141 {
3142 int startpos, endpos;
be8b1c6b 3143 Lisp_Object ostart, oend;
173f2a64
RS
3144
3145 overlay = XCONS (tail)->car;
3146
3147 ostart = OVERLAY_START (overlay);
3148 oend = OVERLAY_END (overlay);
3149 endpos = OVERLAY_POSITION (oend);
3150 if (XFASTINT (start) > endpos)
3151 break;
3152 startpos = OVERLAY_POSITION (ostart);
9115729e
KH
3153 if (insertion && (XFASTINT (start) == startpos
3154 || XFASTINT (end) == startpos))
173f2a64
RS
3155 {
3156 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
5fb5aa33
RS
3157 if (!NILP (prop))
3158 {
3159 /* Copy TAIL in case the hook recenters the overlay lists. */
55b48893
RS
3160 if (!tail_copied)
3161 tail = Fcopy_sequence (tail);
3162 tail_copied = 1;
930a9140 3163 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 3164 }
173f2a64 3165 }
9115729e
KH
3166 if (insertion && (XFASTINT (start) == endpos
3167 || XFASTINT (end) == endpos))
173f2a64
RS
3168 {
3169 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
5fb5aa33
RS
3170 if (!NILP (prop))
3171 {
55b48893
RS
3172 if (!tail_copied)
3173 tail = Fcopy_sequence (tail);
3174 tail_copied = 1;
930a9140 3175 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 3176 }
173f2a64 3177 }
3bd13e92
KH
3178 /* Test for intersecting intervals. This does the right thing
3179 for both insertion and deletion. */
3180 if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
173f2a64
RS
3181 {
3182 prop = Foverlay_get (overlay, Qmodification_hooks);
5fb5aa33
RS
3183 if (!NILP (prop))
3184 {
55b48893
RS
3185 if (!tail_copied)
3186 tail = Fcopy_sequence (tail);
3187 tail_copied = 1;
930a9140 3188 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 3189 }
173f2a64
RS
3190 }
3191 }
3192
55b48893 3193 tail_copied = 0;
173f2a64
RS
3194 for (tail = current_buffer->overlays_after;
3195 CONSP (tail);
3196 tail = XCONS (tail)->cdr)
3197 {
3198 int startpos, endpos;
be8b1c6b 3199 Lisp_Object ostart, oend;
173f2a64
RS
3200
3201 overlay = XCONS (tail)->car;
3202
3203 ostart = OVERLAY_START (overlay);
3204 oend = OVERLAY_END (overlay);
3205 startpos = OVERLAY_POSITION (ostart);
cdf0b096 3206 endpos = OVERLAY_POSITION (oend);
173f2a64
RS
3207 if (XFASTINT (end) < startpos)
3208 break;
9115729e
KH
3209 if (insertion && (XFASTINT (start) == startpos
3210 || XFASTINT (end) == startpos))
173f2a64
RS
3211 {
3212 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
5fb5aa33
RS
3213 if (!NILP (prop))
3214 {
55b48893
RS
3215 if (!tail_copied)
3216 tail = Fcopy_sequence (tail);
3217 tail_copied = 1;
930a9140 3218 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 3219 }
173f2a64 3220 }
9115729e
KH
3221 if (insertion && (XFASTINT (start) == endpos
3222 || XFASTINT (end) == endpos))
173f2a64
RS
3223 {
3224 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
5fb5aa33
RS
3225 if (!NILP (prop))
3226 {
55b48893
RS
3227 if (!tail_copied)
3228 tail = Fcopy_sequence (tail);
3229 tail_copied = 1;
930a9140 3230 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 3231 }
173f2a64 3232 }
3bd13e92
KH
3233 /* Test for intersecting intervals. This does the right thing
3234 for both insertion and deletion. */
3235 if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
173f2a64
RS
3236 {
3237 prop = Foverlay_get (overlay, Qmodification_hooks);
5fb5aa33
RS
3238 if (!NILP (prop))
3239 {
55b48893
RS
3240 if (!tail_copied)
3241 tail = Fcopy_sequence (tail);
3242 tail_copied = 1;
930a9140 3243 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 3244 }
173f2a64
RS
3245 }
3246 }
55b48893
RS
3247
3248 UNGCPRO;
173f2a64
RS
3249}
3250
3251static void
930a9140
RS
3252call_overlay_mod_hooks (list, overlay, after, arg1, arg2, arg3)
3253 Lisp_Object list, overlay;
3254 int after;
3255 Lisp_Object arg1, arg2, arg3;
173f2a64 3256{
930a9140 3257 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9115729e 3258
930a9140 3259 GCPRO4 (list, arg1, arg2, arg3);
9115729e
KH
3260 if (! after)
3261 add_overlay_mod_hooklist (list, overlay);
3262
173f2a64
RS
3263 while (!NILP (list))
3264 {
930a9140
RS
3265 if (NILP (arg3))
3266 call4 (Fcar (list), overlay, after ? Qt : Qnil, arg1, arg2);
3267 else
3268 call5 (Fcar (list), overlay, after ? Qt : Qnil, arg1, arg2, arg3);
173f2a64
RS
3269 list = Fcdr (list);
3270 }
3271 UNGCPRO;
3272}
9d7608b7
KH
3273
3274/* Delete any zero-sized overlays at position POS, if the `evaporate'
3275 property is set. */
3276void
3277evaporate_overlays (pos)
3278 int pos;
3279{
3280 Lisp_Object tail, overlay, hit_list;
3281
3282 hit_list = Qnil;
3283 if (pos <= XFASTINT (current_buffer->overlay_center))
3284 for (tail = current_buffer->overlays_before; CONSP (tail);
3285 tail = XCONS (tail)->cdr)
3286 {
3287 int endpos;
3288 overlay = XCONS (tail)->car;
3289 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3290 if (endpos < pos)
3291 break;
3292 if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos
c3935f9d 3293 && ! NILP (Foverlay_get (overlay, Qevaporate)))
9d7608b7
KH
3294 hit_list = Fcons (overlay, hit_list);
3295 }
3296 else
3297 for (tail = current_buffer->overlays_after; CONSP (tail);
3298 tail = XCONS (tail)->cdr)
3299 {
3300 int startpos;
889bf329 3301 overlay = XCONS (tail)->car;
9d7608b7
KH
3302 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3303 if (startpos > pos)
3304 break;
3305 if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
c3935f9d 3306 && ! NILP (Foverlay_get (overlay, Qevaporate)))
9d7608b7
KH
3307 hit_list = Fcons (overlay, hit_list);
3308 }
3309 for (; CONSP (hit_list); hit_list = XCONS (hit_list)->cdr)
3310 Fdelete_overlay (XCONS (hit_list)->car);
3311}
173f2a64 3312\f
54dfdeb0
KH
3313/* Somebody has tried to store a value with an unacceptable type
3314 into the buffer-local slot with offset OFFSET. */
0fa3ba92 3315void
54dfdeb0
KH
3316buffer_slot_type_mismatch (offset)
3317 int offset;
0fa3ba92 3318{
54dfdeb0 3319 Lisp_Object sym;
0fa3ba92 3320 char *type_name;
54dfdeb0 3321 sym = *(Lisp_Object *)(offset + (char *)&buffer_local_symbols);
0fa3ba92
JB
3322 switch (XINT (*(Lisp_Object *)(offset + (char *)&buffer_local_types)))
3323 {
3324 case Lisp_Int: type_name = "integers"; break;
3325 case Lisp_String: type_name = "strings"; break;
0fa3ba92 3326 case Lisp_Symbol: type_name = "symbols"; break;
0fa3ba92
JB
3327 default:
3328 abort ();
3329 }
3330
3331 error ("only %s should be stored in the buffer-local variable %s",
54dfdeb0 3332 type_name, XSYMBOL (sym)->name->data);
0fa3ba92
JB
3333}
3334\f
1ab256cb
RM
3335init_buffer_once ()
3336{
3337 register Lisp_Object tem;
3338
13de9290
RS
3339 buffer_permanent_local_flags = 0;
3340
1ab256cb
RM
3341 /* Make sure all markable slots in buffer_defaults
3342 are initialized reasonably, so mark_buffer won't choke. */
3343 reset_buffer (&buffer_defaults);
13de9290 3344 reset_buffer_local_variables (&buffer_defaults, 1);
1ab256cb 3345 reset_buffer (&buffer_local_symbols);
13de9290 3346 reset_buffer_local_variables (&buffer_local_symbols, 1);
336cd056
RS
3347 /* Prevent GC from getting confused. */
3348 buffer_defaults.text = &buffer_defaults.own_text;
3349 buffer_local_symbols.text = &buffer_local_symbols.own_text;
3350#ifdef USE_TEXT_PROPERTIES
3351 BUF_INTERVALS (&buffer_defaults) = 0;
3352 BUF_INTERVALS (&buffer_local_symbols) = 0;
3353#endif
67180c6a
KH
3354 XSETBUFFER (Vbuffer_defaults, &buffer_defaults);
3355 XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols);
1ab256cb
RM
3356
3357 /* Set up the default values of various buffer slots. */
3358 /* Must do these before making the first buffer! */
3359
3360 /* real setup is done in loaddefs.el */
3361 buffer_defaults.mode_line_format = build_string ("%-");
3362 buffer_defaults.abbrev_mode = Qnil;
3363 buffer_defaults.overwrite_mode = Qnil;
3364 buffer_defaults.case_fold_search = Qt;
3365 buffer_defaults.auto_fill_function = Qnil;
3366 buffer_defaults.selective_display = Qnil;
3367#ifndef old
3368 buffer_defaults.selective_display_ellipses = Qt;
3369#endif
3370 buffer_defaults.abbrev_table = Qnil;
3371 buffer_defaults.display_table = Qnil;
1ab256cb 3372 buffer_defaults.undo_list = Qnil;
c48f61ef 3373 buffer_defaults.mark_active = Qnil;
be9aafdd 3374 buffer_defaults.file_format = Qnil;
2eec3b4e
RS
3375 buffer_defaults.overlays_before = Qnil;
3376 buffer_defaults.overlays_after = Qnil;
bbbe9545 3377 XSETFASTINT (buffer_defaults.overlay_center, BEG);
1ab256cb 3378
8d7a4592 3379 XSETFASTINT (buffer_defaults.tab_width, 8);
1ab256cb
RM
3380 buffer_defaults.truncate_lines = Qnil;
3381 buffer_defaults.ctl_arrow = Qt;
3382
f7975d07 3383#ifdef DOS_NT
0776cb1b 3384 buffer_defaults.buffer_file_type = Qnil; /* TEXT */
54ad07d3 3385#endif
8d7a4592
KH
3386 XSETFASTINT (buffer_defaults.fill_column, 70);
3387 XSETFASTINT (buffer_defaults.left_margin, 0);
28e969dd 3388 buffer_defaults.cache_long_line_scans = Qnil;
f6ed2e84 3389 buffer_defaults.file_truename = Qnil;
1ab256cb
RM
3390
3391 /* Assign the local-flags to the slots that have default values.
3392 The local flag is a bit that is used in the buffer
3393 to say that it has its own local value for the slot.
3394 The local flag bits are in the local_var_flags slot of the buffer. */
3395
3396 /* Nothing can work if this isn't true */
4d2f1389 3397 if (sizeof (EMACS_INT) != sizeof (Lisp_Object)) abort ();
1ab256cb
RM
3398
3399 /* 0 means not a lisp var, -1 means always local, else mask */
3400 bzero (&buffer_local_flags, sizeof buffer_local_flags);
aab80822
KH
3401 XSETINT (buffer_local_flags.filename, -1);
3402 XSETINT (buffer_local_flags.directory, -1);
3403 XSETINT (buffer_local_flags.backed_up, -1);
3404 XSETINT (buffer_local_flags.save_length, -1);
3405 XSETINT (buffer_local_flags.auto_save_file_name, -1);
3406 XSETINT (buffer_local_flags.read_only, -1);
3407 XSETINT (buffer_local_flags.major_mode, -1);
3408 XSETINT (buffer_local_flags.mode_name, -1);
3409 XSETINT (buffer_local_flags.undo_list, -1);
3410 XSETINT (buffer_local_flags.mark_active, -1);
943e065b 3411 XSETINT (buffer_local_flags.point_before_scroll, -1);
f6ed2e84 3412 XSETINT (buffer_local_flags.file_truename, -1);
3cb719bd 3413 XSETINT (buffer_local_flags.invisibility_spec, -1);
55ac8536 3414 XSETINT (buffer_local_flags.file_format, -1);
8d7a4592
KH
3415
3416 XSETFASTINT (buffer_local_flags.mode_line_format, 1);
3417 XSETFASTINT (buffer_local_flags.abbrev_mode, 2);
3418 XSETFASTINT (buffer_local_flags.overwrite_mode, 4);
3419 XSETFASTINT (buffer_local_flags.case_fold_search, 8);
3420 XSETFASTINT (buffer_local_flags.auto_fill_function, 0x10);
3421 XSETFASTINT (buffer_local_flags.selective_display, 0x20);
1ab256cb 3422#ifndef old
8d7a4592 3423 XSETFASTINT (buffer_local_flags.selective_display_ellipses, 0x40);
1ab256cb 3424#endif
8d7a4592
KH
3425 XSETFASTINT (buffer_local_flags.tab_width, 0x80);
3426 XSETFASTINT (buffer_local_flags.truncate_lines, 0x100);
3427 XSETFASTINT (buffer_local_flags.ctl_arrow, 0x200);
3428 XSETFASTINT (buffer_local_flags.fill_column, 0x400);
3429 XSETFASTINT (buffer_local_flags.left_margin, 0x800);
3430 XSETFASTINT (buffer_local_flags.abbrev_table, 0x1000);
3431 XSETFASTINT (buffer_local_flags.display_table, 0x2000);
f7975d07 3432#ifdef DOS_NT
8d7a4592 3433 XSETFASTINT (buffer_local_flags.buffer_file_type, 0x4000);
13de9290
RS
3434 /* Make this one a permanent local. */
3435 buffer_permanent_local_flags |= 0x4000;
54ad07d3 3436#endif
2e716096
RS
3437 XSETFASTINT (buffer_local_flags.syntax_table, 0x8000);
3438 XSETFASTINT (buffer_local_flags.cache_long_line_scans, 0x10000);
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}