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