(inhibit_modification_hooks): New variable.
[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
70e77119
AS
1738 /* Do nothing if nothing actually changes. */
1739 if (NILP (flag) == NILP (current_buffer->enable_multibyte_characters))
1740 return flag;
1741
b05525fa
RS
1742 /* It would be better to update the list,
1743 but this is good enough for now. */
1744 if (! EQ (current_buffer->undo_list, Qt))
1745 current_buffer->undo_list = Qnil;
1746
3ac81adb
RS
1747 /* If the cached position is for this buffer, clear it out. */
1748 clear_charpos_cache (current_buffer);
1749
1750 if (NILP (flag))
1751 {
1752 /* Do this first, so it can use CHAR_TO_BYTE
1753 to calculate the old correspondences. */
1754 set_intervals_multibyte (0);
1755
1756 current_buffer->enable_multibyte_characters = Qnil;
1757
1758 Z = Z_BYTE;
1759 BEGV = BEGV_BYTE;
1760 ZV = ZV_BYTE;
1761 GPT = GPT_BYTE;
1762 TEMP_SET_PT_BOTH (PT_BYTE, PT_BYTE);
1763
1764 tail = BUF_MARKERS (current_buffer);
1765 while (XSYMBOL (tail) != XSYMBOL (Qnil))
1766 {
1767 XMARKER (tail)->charpos = XMARKER (tail)->bytepos;
1768 tail = XMARKER (tail)->chain;
1769 }
1770 }
1771 else
1772 {
673c57d2
KH
1773 /* Be sure not to have a multibyte sequence striding over the GAP.
1774 Ex: We change this: "...abc\201\241\241 _GAP_ \241\241\241..."
1775 to: "...abc _GAP_ \201\241\241\241\241\241..." */
1776
1777 if (GPT_BYTE > 1 && GPT_BYTE < Z_BYTE
1778 && ! CHAR_HEAD_P (*(GAP_END_ADDR)))
1779 {
1780 unsigned char *p = GPT_ADDR - 1;
1781
1782 while (! CHAR_HEAD_P (*p) && p > BEG_ADDR) p--;
1783 if (BASE_LEADING_CODE_P (*p))
1784 {
1785 int new_gpt = GPT_BYTE - (GPT_ADDR - p);
1786
1787 move_gap_both (new_gpt, new_gpt);
1788 }
1789 }
1790
3ac81adb
RS
1791 /* Do this first, so that chars_in_text asks the right question.
1792 set_intervals_multibyte needs it too. */
1793 current_buffer->enable_multibyte_characters = Qt;
1794
b05525fa 1795 GPT_BYTE = advance_to_char_boundary (GPT_BYTE);
3ac81adb 1796 GPT = chars_in_text (BEG_ADDR, GPT_BYTE - BEG_BYTE) + BEG;
b05525fa 1797
673c57d2 1798 Z = chars_in_text (GAP_END_ADDR, Z_BYTE - GPT_BYTE) + GPT;
b05525fa
RS
1799
1800 BEGV_BYTE = advance_to_char_boundary (BEGV_BYTE);
3ac81adb 1801 if (BEGV_BYTE > GPT_BYTE)
673c57d2 1802 BEGV = chars_in_text (GAP_END_ADDR, BEGV_BYTE - GPT_BYTE) + GPT;
3ac81adb
RS
1803 else
1804 BEGV = chars_in_text (BEG_ADDR, BEGV_BYTE - BEG_BYTE) + BEG;
b05525fa
RS
1805
1806 ZV_BYTE = advance_to_char_boundary (ZV_BYTE);
3ac81adb 1807 if (ZV_BYTE > GPT_BYTE)
673c57d2 1808 ZV = chars_in_text (GAP_END_ADDR, ZV_BYTE - GPT_BYTE) + GPT;
3ac81adb
RS
1809 else
1810 ZV = chars_in_text (BEG_ADDR, ZV_BYTE - BEG_BYTE) + BEG;
b05525fa
RS
1811
1812 {
1813 int pt_byte = advance_to_char_boundary (PT_BYTE);
1814 int pt;
1815
1816 if (pt_byte > GPT_BYTE)
673c57d2 1817 pt = chars_in_text (GAP_END_ADDR, pt_byte - GPT_BYTE) + GPT;
b05525fa
RS
1818 else
1819 pt = chars_in_text (BEG_ADDR, pt_byte - BEG_BYTE) + BEG;
1820 TEMP_SET_PT_BOTH (pt, pt_byte);
1821 }
3ac81adb
RS
1822
1823 tail = markers = BUF_MARKERS (current_buffer);
95fb069b
RS
1824
1825 /* This prevents BYTE_TO_CHAR (that is, buf_bytepos_to_charpos) from
1826 getting confused by the markers that have not yet been updated.
1827 It is also a signal that it should never create a marker. */
3ac81adb
RS
1828 BUF_MARKERS (current_buffer) = Qnil;
1829
1830 while (XSYMBOL (tail) != XSYMBOL (Qnil))
1831 {
b05525fa
RS
1832 XMARKER (tail)->bytepos
1833 = advance_to_char_boundary (XMARKER (tail)->bytepos);
3ac81adb 1834 XMARKER (tail)->charpos = BYTE_TO_CHAR (XMARKER (tail)->bytepos);
b05525fa 1835
3ac81adb
RS
1836 tail = XMARKER (tail)->chain;
1837 }
b69f9797
RS
1838
1839 /* Make sure no markers were put on the chain
1840 while the chain value was incorrect. */
1841 if (! EQ (BUF_MARKERS (current_buffer), Qnil))
1842 abort ();
1843
3ac81adb
RS
1844 BUF_MARKERS (current_buffer) = markers;
1845
1846 /* Do this last, so it can calculate the new correspondences
1847 between chars and bytes. */
1848 set_intervals_multibyte (1);
1849 }
1850
1851 return flag;
1852}
1853\f
1ab256cb
RM
1854DEFUN ("kill-all-local-variables", Fkill_all_local_variables, Skill_all_local_variables,
1855 0, 0, 0,
1856 "Switch to Fundamental mode by killing current buffer's local variables.\n\
1857Most local variable bindings are eliminated so that the default values\n\
1858become effective once more. Also, the syntax table is set from\n\
1859`standard-syntax-table', the local keymap is set to nil,\n\
1860and the abbrev table from `fundamental-mode-abbrev-table'.\n\
1861This function also forces redisplay of the mode line.\n\
1862\n\
1863Every function to select a new major mode starts by\n\
1864calling this function.\n\n\
1865As a special exception, local variables whose names have\n\
c5a15222
RS
1866a non-nil `permanent-local' property are not eliminated by this function.\n\
1867\n\
1868The first thing this function does is run\n\
1869the normal hook `change-major-mode-hook'.")
1ab256cb
RM
1870 ()
1871{
1872 register Lisp_Object alist, sym, tem;
1873 Lisp_Object oalist;
7410477a 1874
fd186f07
RS
1875 if (!NILP (Vrun_hooks))
1876 call1 (Vrun_hooks, intern ("change-major-mode-hook"));
1ab256cb
RM
1877 oalist = current_buffer->local_var_alist;
1878
2f3f993b
RS
1879 /* Make sure none of the bindings in oalist
1880 remain swapped in, in their symbols. */
1ab256cb 1881
2f3f993b 1882 swap_out_buffer_local_variables (current_buffer);
1ab256cb
RM
1883
1884 /* Actually eliminate all local bindings of this buffer. */
1885
13de9290 1886 reset_buffer_local_variables (current_buffer, 0);
1ab256cb
RM
1887
1888 /* Redisplay mode lines; we are changing major mode. */
1889
1890 update_mode_lines++;
1891
1892 /* Any which are supposed to be permanent,
1893 make local again, with the same values they had. */
1894
265a9e55 1895 for (alist = oalist; !NILP (alist); alist = XCONS (alist)->cdr)
1ab256cb
RM
1896 {
1897 sym = XCONS (XCONS (alist)->car)->car;
1898 tem = Fget (sym, Qpermanent_local);
265a9e55 1899 if (! NILP (tem))
01050cb5
RM
1900 {
1901 Fmake_local_variable (sym);
1902 Fset (sym, XCONS (XCONS (alist)->car)->cdr);
1903 }
1ab256cb
RM
1904 }
1905
1906 /* Force mode-line redisplay. Useful here because all major mode
1907 commands call this function. */
1908 update_mode_lines++;
1909
1910 return Qnil;
1911}
2f3f993b
RS
1912
1913/* Make sure no local variables remain set up with buffer B
1914 for their current values. */
1915
1916static void
1917swap_out_buffer_local_variables (b)
1918 struct buffer *b;
1919{
1920 Lisp_Object oalist, alist, sym, tem, buffer;
1921
1922 XSETBUFFER (buffer, b);
1923 oalist = b->local_var_alist;
1924
1925 for (alist = oalist; !NILP (alist); alist = XCONS (alist)->cdr)
1926 {
1927 sym = XCONS (XCONS (alist)->car)->car;
1928
1929 /* Need not do anything if some other buffer's binding is now encached. */
3d871c85 1930 tem = XBUFFER_LOCAL_VALUE (XSYMBOL (sym)->value)->buffer;
2f3f993b
RS
1931 if (XBUFFER (tem) == current_buffer)
1932 {
1933 /* Symbol is set up for this buffer's old local value.
1934 Set it up for the current buffer with the default value. */
1935
3d871c85 1936 tem = XBUFFER_LOCAL_VALUE (XSYMBOL (sym)->value)->cdr;
2f3f993b
RS
1937 /* Store the symbol's current value into the alist entry
1938 it is currently set up for. This is so that, if the
1939 local is marked permanent, and we make it local again
1940 later in Fkill_all_local_variables, we don't lose the value. */
1941 XCONS (XCONS (tem)->car)->cdr
3d871c85 1942 = do_symval_forwarding (XBUFFER_LOCAL_VALUE (XSYMBOL (sym)->value)->realvalue);
2f3f993b
RS
1943 /* Switch to the symbol's default-value alist entry. */
1944 XCONS (tem)->car = tem;
1945 /* Mark it as current for buffer B. */
3d871c85 1946 XBUFFER_LOCAL_VALUE (XSYMBOL (sym)->value)->buffer = buffer;
2f3f993b 1947 /* Store the current value into any forwarding in the symbol. */
3d871c85
RS
1948 store_symval_forwarding (sym,
1949 XBUFFER_LOCAL_VALUE (XSYMBOL (sym)->value)->realvalue,
2f3f993b
RS
1950 XCONS (tem)->cdr);
1951 }
1952 }
1953}
1ab256cb 1954\f
2eec3b4e
RS
1955/* Find all the overlays in the current buffer that contain position POS.
1956 Return the number found, and store them in a vector in *VEC_PTR.
1957 Store in *LEN_PTR the size allocated for the vector.
52f8ec73
JB
1958 Store in *NEXT_PTR the next position after POS where an overlay starts,
1959 or ZV if there are no more overlays.
bbbe9545 1960 Store in *PREV_PTR the previous position before POS where an overlay ends,
239c932b
RS
1961 or BEGV if there are no previous overlays.
1962 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
2eec3b4e
RS
1963
1964 *VEC_PTR and *LEN_PTR should contain a valid vector and size
61d54cd5
RS
1965 when this function is called.
1966
1967 If EXTEND is non-zero, we make the vector bigger if necessary.
1968 If EXTEND is zero, we never extend the vector,
1969 and we store only as many overlays as will fit.
1970 But we still return the total number of overlays. */
2eec3b4e
RS
1971
1972int
239c932b 1973overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr, prev_ptr)
2eec3b4e 1974 int pos;
61d54cd5 1975 int extend;
2eec3b4e
RS
1976 Lisp_Object **vec_ptr;
1977 int *len_ptr;
1978 int *next_ptr;
239c932b 1979 int *prev_ptr;
1ab256cb 1980{
2eec3b4e
RS
1981 Lisp_Object tail, overlay, start, end, result;
1982 int idx = 0;
1983 int len = *len_ptr;
1984 Lisp_Object *vec = *vec_ptr;
1985 int next = ZV;
239c932b 1986 int prev = BEGV;
61d54cd5
RS
1987 int inhibit_storing = 0;
1988
2eec3b4e 1989 for (tail = current_buffer->overlays_before;
8fc0589a 1990 GC_CONSP (tail);
2eec3b4e
RS
1991 tail = XCONS (tail)->cdr)
1992 {
239c932b 1993 int startpos, endpos;
52f8ec73 1994
2eec3b4e 1995 overlay = XCONS (tail)->car;
1ab256cb 1996
2eec3b4e
RS
1997 start = OVERLAY_START (overlay);
1998 end = OVERLAY_END (overlay);
239c932b
RS
1999 endpos = OVERLAY_POSITION (end);
2000 if (endpos < pos)
2001 {
2002 if (prev < endpos)
2003 prev = endpos;
2004 break;
2005 }
2006 if (endpos == pos)
2007 continue;
2eec3b4e
RS
2008 startpos = OVERLAY_POSITION (start);
2009 if (startpos <= pos)
2010 {
2011 if (idx == len)
2012 {
61d54cd5
RS
2013 /* The supplied vector is full.
2014 Either make it bigger, or don't store any more in it. */
2015 if (extend)
2016 {
2017 *len_ptr = len *= 2;
2018 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
2019 *vec_ptr = vec;
2020 }
2021 else
2022 inhibit_storing = 1;
2eec3b4e 2023 }
61d54cd5
RS
2024
2025 if (!inhibit_storing)
2026 vec[idx] = overlay;
2027 /* Keep counting overlays even if we can't return them all. */
2028 idx++;
2eec3b4e
RS
2029 }
2030 else if (startpos < next)
2031 next = startpos;
2032 }
2033
2034 for (tail = current_buffer->overlays_after;
8fc0589a 2035 GC_CONSP (tail);
2eec3b4e 2036 tail = XCONS (tail)->cdr)
1ab256cb 2037 {
239c932b 2038 int startpos, endpos;
52f8ec73 2039
2eec3b4e 2040 overlay = XCONS (tail)->car;
2eec3b4e
RS
2041
2042 start = OVERLAY_START (overlay);
2043 end = OVERLAY_END (overlay);
2044 startpos = OVERLAY_POSITION (start);
52f8ec73 2045 if (pos < startpos)
2eec3b4e
RS
2046 {
2047 if (startpos < next)
2048 next = startpos;
2049 break;
2050 }
239c932b
RS
2051 endpos = OVERLAY_POSITION (end);
2052 if (pos < endpos)
2eec3b4e
RS
2053 {
2054 if (idx == len)
2055 {
61d54cd5
RS
2056 if (extend)
2057 {
2058 *len_ptr = len *= 2;
2059 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
2060 *vec_ptr = vec;
2061 }
2062 else
2063 inhibit_storing = 1;
2eec3b4e 2064 }
61d54cd5
RS
2065
2066 if (!inhibit_storing)
2067 vec[idx] = overlay;
2068 idx++;
2eec3b4e 2069 }
239c932b
RS
2070 else if (endpos < pos && endpos > prev)
2071 prev = endpos;
1ab256cb
RM
2072 }
2073
239c932b
RS
2074 if (next_ptr)
2075 *next_ptr = next;
2076 if (prev_ptr)
2077 *prev_ptr = prev;
2eec3b4e
RS
2078 return idx;
2079}
74514898
RS
2080\f
2081/* Find all the overlays in the current buffer that overlap the range BEG-END
2a3eeee7
RS
2082 or are empty at BEG.
2083
74514898
RS
2084 Return the number found, and store them in a vector in *VEC_PTR.
2085 Store in *LEN_PTR the size allocated for the vector.
2086 Store in *NEXT_PTR the next position after POS where an overlay starts,
2087 or ZV if there are no more overlays.
2088 Store in *PREV_PTR the previous position before POS where an overlay ends,
2089 or BEGV if there are no previous overlays.
2090 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
2091
2092 *VEC_PTR and *LEN_PTR should contain a valid vector and size
2093 when this function is called.
2094
2095 If EXTEND is non-zero, we make the vector bigger if necessary.
2096 If EXTEND is zero, we never extend the vector,
2097 and we store only as many overlays as will fit.
2098 But we still return the total number of overlays. */
2099
2100int
2101overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr)
2102 int beg, end;
2103 int extend;
2104 Lisp_Object **vec_ptr;
2105 int *len_ptr;
2106 int *next_ptr;
2107 int *prev_ptr;
2108{
2109 Lisp_Object tail, overlay, ostart, oend, result;
2110 int idx = 0;
2111 int len = *len_ptr;
2112 Lisp_Object *vec = *vec_ptr;
2113 int next = ZV;
2114 int prev = BEGV;
2115 int inhibit_storing = 0;
2116
2117 for (tail = current_buffer->overlays_before;
2118 GC_CONSP (tail);
2119 tail = XCONS (tail)->cdr)
2120 {
2121 int startpos, endpos;
2122
2123 overlay = XCONS (tail)->car;
2124
2125 ostart = OVERLAY_START (overlay);
2126 oend = OVERLAY_END (overlay);
2127 endpos = OVERLAY_POSITION (oend);
2128 if (endpos < beg)
2129 {
2130 if (prev < endpos)
2131 prev = endpos;
2132 break;
2133 }
2134 startpos = OVERLAY_POSITION (ostart);
2135 /* Count an interval if it either overlaps the range
2a3eeee7 2136 or is empty at the start of the range. */
74514898 2137 if ((beg < endpos && startpos < end)
2a3eeee7 2138 || (startpos == endpos && beg == endpos))
74514898
RS
2139 {
2140 if (idx == len)
2141 {
2142 /* The supplied vector is full.
2143 Either make it bigger, or don't store any more in it. */
2144 if (extend)
2145 {
2146 *len_ptr = len *= 2;
2147 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
2148 *vec_ptr = vec;
2149 }
2150 else
2151 inhibit_storing = 1;
2152 }
2153
2154 if (!inhibit_storing)
2155 vec[idx] = overlay;
2156 /* Keep counting overlays even if we can't return them all. */
2157 idx++;
2158 }
2159 else if (startpos < next)
2160 next = startpos;
2161 }
2162
2163 for (tail = current_buffer->overlays_after;
2164 GC_CONSP (tail);
2165 tail = XCONS (tail)->cdr)
2166 {
2167 int startpos, endpos;
2168
2169 overlay = XCONS (tail)->car;
2170
2171 ostart = OVERLAY_START (overlay);
2172 oend = OVERLAY_END (overlay);
2173 startpos = OVERLAY_POSITION (ostart);
2174 if (end < startpos)
2175 {
2176 if (startpos < next)
2177 next = startpos;
2178 break;
2179 }
2180 endpos = OVERLAY_POSITION (oend);
2a3eeee7
RS
2181 /* Count an interval if it either overlaps the range
2182 or is empty at the start of the range. */
74514898 2183 if ((beg < endpos && startpos < end)
2a3eeee7 2184 || (startpos == endpos && beg == endpos))
74514898
RS
2185 {
2186 if (idx == len)
2187 {
2188 if (extend)
2189 {
2190 *len_ptr = len *= 2;
2191 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
2192 *vec_ptr = vec;
2193 }
2194 else
2195 inhibit_storing = 1;
2196 }
2197
2198 if (!inhibit_storing)
2199 vec[idx] = overlay;
2200 idx++;
2201 }
2202 else if (endpos < beg && endpos > prev)
2203 prev = endpos;
2204 }
fc04fa47 2205
74514898
RS
2206 if (next_ptr)
2207 *next_ptr = next;
2208 if (prev_ptr)
2209 *prev_ptr = prev;
2210 return idx;
2211}
2212\f
fc04fa47
KH
2213/* Fast function to just test if we're at an overlay boundary. */
2214int
2215overlay_touches_p (pos)
2216 int pos;
2217{
2218 Lisp_Object tail, overlay;
2219
2220 for (tail = current_buffer->overlays_before; GC_CONSP (tail);
2221 tail = XCONS (tail)->cdr)
2222 {
2223 int endpos;
2224
2225 overlay = XCONS (tail)->car;
2226 if (!GC_OVERLAYP (overlay))
2227 abort ();
2228
2229 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2230 if (endpos < pos)
2231 break;
2232 if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos)
2233 return 1;
2234 }
2235
2236 for (tail = current_buffer->overlays_after; GC_CONSP (tail);
2237 tail = XCONS (tail)->cdr)
2238 {
2239 int startpos;
2240
2241 overlay = XCONS (tail)->car;
2242 if (!GC_OVERLAYP (overlay))
2243 abort ();
2244
2245 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2246 if (pos < startpos)
2247 break;
2248 if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
2249 return 1;
2250 }
2251 return 0;
2252}
2eec3b4e 2253\f
5985d248
KH
2254struct sortvec
2255{
2256 Lisp_Object overlay;
2257 int beg, end;
2258 int priority;
2259};
2260
2261static int
dfcf069d
AS
2262compare_overlays (v1, v2)
2263 const void *v1, *v2;
5985d248 2264{
dfcf069d
AS
2265 const struct sortvec *s1 = (const struct sortvec *) v1;
2266 const struct sortvec *s2 = (const struct sortvec *) v2;
5985d248
KH
2267 if (s1->priority != s2->priority)
2268 return s1->priority - s2->priority;
2269 if (s1->beg != s2->beg)
2270 return s1->beg - s2->beg;
2271 if (s1->end != s2->end)
2272 return s2->end - s1->end;
2273 return 0;
2274}
2275
2276/* Sort an array of overlays by priority. The array is modified in place.
2277 The return value is the new size; this may be smaller than the original
2278 size if some of the overlays were invalid or were window-specific. */
2279int
2280sort_overlays (overlay_vec, noverlays, w)
2281 Lisp_Object *overlay_vec;
2282 int noverlays;
2283 struct window *w;
2284{
2285 int i, j;
2286 struct sortvec *sortvec;
2287 sortvec = (struct sortvec *) alloca (noverlays * sizeof (struct sortvec));
2288
2289 /* Put the valid and relevant overlays into sortvec. */
2290
2291 for (i = 0, j = 0; i < noverlays; i++)
2292 {
0fa767e7 2293 Lisp_Object tem;
c99fc30f 2294 Lisp_Object overlay;
5985d248 2295
c99fc30f 2296 overlay = overlay_vec[i];
5985d248
KH
2297 if (OVERLAY_VALID (overlay)
2298 && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0
2299 && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0)
2300 {
0fa767e7
KH
2301 /* If we're interested in a specific window, then ignore
2302 overlays that are limited to some other window. */
2303 if (w)
5985d248 2304 {
0fa767e7
KH
2305 Lisp_Object window;
2306
2307 window = Foverlay_get (overlay, Qwindow);
a7a60ce9 2308 if (WINDOWP (window) && XWINDOW (window) != w)
0fa767e7 2309 continue;
5985d248 2310 }
0fa767e7
KH
2311
2312 /* This overlay is good and counts: put it into sortvec. */
2313 sortvec[j].overlay = overlay;
2314 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
2315 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
2316 tem = Foverlay_get (overlay, Qpriority);
2317 if (INTEGERP (tem))
2318 sortvec[j].priority = XINT (tem);
2319 else
2320 sortvec[j].priority = 0;
2321 j++;
5985d248
KH
2322 }
2323 }
2324 noverlays = j;
2325
2326 /* Sort the overlays into the proper order: increasing priority. */
2327
2328 if (noverlays > 1)
2329 qsort (sortvec, noverlays, sizeof (struct sortvec), compare_overlays);
2330
2331 for (i = 0; i < noverlays; i++)
2332 overlay_vec[i] = sortvec[i].overlay;
2333 return (noverlays);
2334}
2335\f
bbbe9545
KH
2336struct sortstr
2337{
cb26008f 2338 Lisp_Object string, string2;
bbbe9545
KH
2339 int size;
2340 int priority;
2341};
2342
e8185fa8
KH
2343struct sortstrlist
2344{
2345 struct sortstr *buf; /* An array that expands as needed; never freed. */
2346 int size; /* Allocated length of that array. */
2347 int used; /* How much of the array is currently in use. */
2348 int bytes; /* Total length of the strings in buf. */
2349};
2350
2351/* Buffers for storing information about the overlays touching a given
2352 position. These could be automatic variables in overlay_strings, but
2353 it's more efficient to hold onto the memory instead of repeatedly
2354 allocating and freeing it. */
2355static struct sortstrlist overlay_heads, overlay_tails;
9492daf2 2356static unsigned char *overlay_str_buf;
e8185fa8
KH
2357
2358/* Allocated length of overlay_str_buf. */
2359static int overlay_str_len;
2360
bbbe9545
KH
2361/* A comparison function suitable for passing to qsort. */
2362static int
2363cmp_for_strings (as1, as2)
2364 char *as1, *as2;
2365{
2366 struct sortstr *s1 = (struct sortstr *)as1;
2367 struct sortstr *s2 = (struct sortstr *)as2;
2368 if (s1->size != s2->size)
2369 return s2->size - s1->size;
2370 if (s1->priority != s2->priority)
2371 return s1->priority - s2->priority;
2372 return 0;
2373}
2374
e8185fa8 2375static void
cb26008f 2376record_overlay_string (ssl, str, str2, pri, size)
e8185fa8 2377 struct sortstrlist *ssl;
cb26008f 2378 Lisp_Object str, str2, pri;
e8185fa8
KH
2379 int size;
2380{
43d27a72
RS
2381 int nbytes;
2382
e8185fa8
KH
2383 if (ssl->used == ssl->size)
2384 {
2385 if (ssl->buf)
2386 ssl->size *= 2;
2387 else
2388 ssl->size = 5;
2389 ssl->buf = ((struct sortstr *)
2390 xrealloc (ssl->buf, ssl->size * sizeof (struct sortstr)));
2391 }
2392 ssl->buf[ssl->used].string = str;
cb26008f 2393 ssl->buf[ssl->used].string2 = str2;
e8185fa8
KH
2394 ssl->buf[ssl->used].size = size;
2395 ssl->buf[ssl->used].priority = (INTEGERP (pri) ? XINT (pri) : 0);
2396 ssl->used++;
43d27a72
RS
2397
2398 if (NILP (current_buffer->enable_multibyte_characters))
2399 nbytes = XSTRING (str)->size;
2400 else if (! STRING_MULTIBYTE (str))
2401 nbytes = count_size_as_multibyte (XSTRING (str)->data,
fc932ac6 2402 STRING_BYTES (XSTRING (str)));
43d27a72 2403 else
fc932ac6 2404 nbytes = STRING_BYTES (XSTRING (str));
43d27a72
RS
2405
2406 ssl->bytes += nbytes;
2407
cb26008f 2408 if (STRINGP (str2))
43d27a72
RS
2409 {
2410 if (NILP (current_buffer->enable_multibyte_characters))
2411 nbytes = XSTRING (str2)->size;
2412 else if (! STRING_MULTIBYTE (str2))
2413 nbytes = count_size_as_multibyte (XSTRING (str2)->data,
fc932ac6 2414 STRING_BYTES (XSTRING (str2)));
43d27a72 2415 else
fc932ac6 2416 nbytes = STRING_BYTES (XSTRING (str2));
43d27a72
RS
2417
2418 ssl->bytes += nbytes;
2419 }
e8185fa8 2420}
bbbe9545
KH
2421
2422/* Return the concatenation of the strings associated with overlays that
2423 begin or end at POS, ignoring overlays that are specific to a window
2424 other than W. The strings are concatenated in the appropriate order:
2425 shorter overlays nest inside longer ones, and higher priority inside
cb26008f
KH
2426 lower. Normally all of the after-strings come first, but zero-sized
2427 overlays have their after-strings ride along with the before-strings
2428 because it would look strange to print them inside-out.
2429
2430 Returns the string length, and stores the contents indirectly through
2431 PSTR, if that variable is non-null. The string may be overwritten by
2432 subsequent calls. */
6b5d3b89 2433
bbbe9545
KH
2434int
2435overlay_strings (pos, w, pstr)
2436 int pos;
2437 struct window *w;
6b5d3b89 2438 unsigned char **pstr;
bbbe9545 2439{
e8185fa8 2440 Lisp_Object ov, overlay, window, str;
bbbe9545 2441 int startpos, endpos;
43d27a72 2442 int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
bbbe9545 2443
e8185fa8
KH
2444 overlay_heads.used = overlay_heads.bytes = 0;
2445 overlay_tails.used = overlay_tails.bytes = 0;
bbbe9545
KH
2446 for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCONS (ov)->cdr)
2447 {
2448 overlay = XCONS (ov)->car;
2449 if (!OVERLAYP (overlay))
2450 abort ();
2451
2452 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2453 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2454 if (endpos < pos)
2455 break;
2456 if (endpos != pos && startpos != pos)
2457 continue;
2458 window = Foverlay_get (overlay, Qwindow);
2459 if (WINDOWP (window) && XWINDOW (window) != w)
2460 continue;
e8185fa8
KH
2461 if (startpos == pos
2462 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
2463 record_overlay_string (&overlay_heads, str,
cb26008f
KH
2464 (startpos == endpos
2465 ? Foverlay_get (overlay, Qafter_string)
2466 : Qnil),
2467 Foverlay_get (overlay, Qpriority),
2468 endpos - startpos);
2469 else if (endpos == pos
2470 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
2471 record_overlay_string (&overlay_tails, str, Qnil,
e8185fa8
KH
2472 Foverlay_get (overlay, Qpriority),
2473 endpos - startpos);
bbbe9545
KH
2474 }
2475 for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCONS (ov)->cdr)
2476 {
2477 overlay = XCONS (ov)->car;
2478 if (!OVERLAYP (overlay))
2479 abort ();
2480
2481 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2482 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2483 if (startpos > pos)
2484 break;
e8185fa8
KH
2485 if (endpos != pos && startpos != pos)
2486 continue;
2487 window = Foverlay_get (overlay, Qwindow);
2488 if (WINDOWP (window) && XWINDOW (window) != w)
2489 continue;
e8185fa8
KH
2490 if (startpos == pos
2491 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
2492 record_overlay_string (&overlay_heads, str,
cb26008f
KH
2493 (startpos == endpos
2494 ? Foverlay_get (overlay, Qafter_string)
2495 : Qnil),
2496 Foverlay_get (overlay, Qpriority),
2497 endpos - startpos);
2498 else if (endpos == pos
2499 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
2500 record_overlay_string (&overlay_tails, str, Qnil,
e8185fa8
KH
2501 Foverlay_get (overlay, Qpriority),
2502 endpos - startpos);
bbbe9545 2503 }
e8185fa8
KH
2504 if (overlay_tails.used > 1)
2505 qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr),
2506 cmp_for_strings);
2507 if (overlay_heads.used > 1)
2508 qsort (overlay_heads.buf, overlay_heads.used, sizeof (struct sortstr),
2509 cmp_for_strings);
2510 if (overlay_heads.bytes || overlay_tails.bytes)
bbbe9545 2511 {
e8185fa8 2512 Lisp_Object tem;
bbbe9545 2513 int i;
9f4d7cde 2514 unsigned char *p;
e8185fa8 2515 int total = overlay_heads.bytes + overlay_tails.bytes;
bbbe9545
KH
2516
2517 if (total > overlay_str_len)
9f4d7cde
RS
2518 {
2519 overlay_str_len = total;
2520 overlay_str_buf = (unsigned char *)xrealloc (overlay_str_buf,
2521 total);
2522 }
bbbe9545 2523 p = overlay_str_buf;
e8185fa8 2524 for (i = overlay_tails.used; --i >= 0;)
bbbe9545 2525 {
43d27a72 2526 int nbytes;
e8185fa8 2527 tem = overlay_tails.buf[i].string;
fc932ac6
RS
2528 nbytes = copy_text (XSTRING (tem)->data, p,
2529 STRING_BYTES (XSTRING (tem)),
43d27a72
RS
2530 STRING_MULTIBYTE (tem), multibyte);
2531 p += nbytes;
bbbe9545 2532 }
e8185fa8 2533 for (i = 0; i < overlay_heads.used; ++i)
bbbe9545 2534 {
43d27a72 2535 int nbytes;
e8185fa8 2536 tem = overlay_heads.buf[i].string;
fc932ac6
RS
2537 nbytes = copy_text (XSTRING (tem)->data, p,
2538 STRING_BYTES (XSTRING (tem)),
43d27a72
RS
2539 STRING_MULTIBYTE (tem), multibyte);
2540 p += nbytes;
cb26008f
KH
2541 tem = overlay_heads.buf[i].string2;
2542 if (STRINGP (tem))
2543 {
43d27a72 2544 nbytes = copy_text (XSTRING (tem)->data, p,
fc932ac6 2545 STRING_BYTES (XSTRING (tem)),
43d27a72
RS
2546 STRING_MULTIBYTE (tem), multibyte);
2547 p += nbytes;
cb26008f 2548 }
bbbe9545 2549 }
cb26008f
KH
2550 if (p != overlay_str_buf + total)
2551 abort ();
bbbe9545
KH
2552 if (pstr)
2553 *pstr = overlay_str_buf;
e8185fa8 2554 return total;
bbbe9545 2555 }
e8185fa8 2556 return 0;
bbbe9545
KH
2557}
2558\f
5c4f68f1 2559/* Shift overlays in BUF's overlay lists, to center the lists at POS. */
1ab256cb 2560
2eec3b4e 2561void
5c4f68f1
JB
2562recenter_overlay_lists (buf, pos)
2563 struct buffer *buf;
2eec3b4e
RS
2564 int pos;
2565{
2566 Lisp_Object overlay, tail, next, prev, beg, end;
2567
2568 /* See if anything in overlays_before should move to overlays_after. */
2569
2570 /* We don't strictly need prev in this loop; it should always be nil.
2571 But we use it for symmetry and in case that should cease to be true
2572 with some future change. */
2573 prev = Qnil;
5c4f68f1 2574 for (tail = buf->overlays_before;
2eec3b4e
RS
2575 CONSP (tail);
2576 prev = tail, tail = next)
1ab256cb 2577 {
2eec3b4e
RS
2578 next = XCONS (tail)->cdr;
2579 overlay = XCONS (tail)->car;
2580
2581 /* If the overlay is not valid, get rid of it. */
2582 if (!OVERLAY_VALID (overlay))
52f8ec73
JB
2583#if 1
2584 abort ();
2585#else
2eec3b4e
RS
2586 {
2587 /* Splice the cons cell TAIL out of overlays_before. */
2588 if (!NILP (prev))
2589 XCONS (prev)->cdr = next;
2590 else
5c4f68f1 2591 buf->overlays_before = next;
2eec3b4e
RS
2592 tail = prev;
2593 continue;
2594 }
52f8ec73 2595#endif
1ab256cb 2596
2eec3b4e
RS
2597 beg = OVERLAY_START (overlay);
2598 end = OVERLAY_END (overlay);
1ab256cb 2599
2eec3b4e 2600 if (OVERLAY_POSITION (end) > pos)
1ab256cb 2601 {
2eec3b4e
RS
2602 /* OVERLAY needs to be moved. */
2603 int where = OVERLAY_POSITION (beg);
2604 Lisp_Object other, other_prev;
2605
2606 /* Splice the cons cell TAIL out of overlays_before. */
2607 if (!NILP (prev))
2608 XCONS (prev)->cdr = next;
2609 else
5c4f68f1 2610 buf->overlays_before = next;
2eec3b4e
RS
2611
2612 /* Search thru overlays_after for where to put it. */
2613 other_prev = Qnil;
5c4f68f1 2614 for (other = buf->overlays_after;
2eec3b4e
RS
2615 CONSP (other);
2616 other_prev = other, other = XCONS (other)->cdr)
1ab256cb 2617 {
2eec3b4e
RS
2618 Lisp_Object otherbeg, otheroverlay, follower;
2619 int win;
2620
2621 otheroverlay = XCONS (other)->car;
2622 if (! OVERLAY_VALID (otheroverlay))
52f8ec73 2623 abort ();
2eec3b4e
RS
2624
2625 otherbeg = OVERLAY_START (otheroverlay);
2626 if (OVERLAY_POSITION (otherbeg) >= where)
2627 break;
1ab256cb 2628 }
2eec3b4e
RS
2629
2630 /* Add TAIL to overlays_after before OTHER. */
2631 XCONS (tail)->cdr = other;
2632 if (!NILP (other_prev))
2633 XCONS (other_prev)->cdr = tail;
1ab256cb 2634 else
5c4f68f1 2635 buf->overlays_after = tail;
2eec3b4e 2636 tail = prev;
1ab256cb 2637 }
2eec3b4e
RS
2638 else
2639 /* We've reached the things that should stay in overlays_before.
2640 All the rest of overlays_before must end even earlier,
2641 so stop now. */
2642 break;
2643 }
2644
2645 /* See if anything in overlays_after should be in overlays_before. */
2646 prev = Qnil;
5c4f68f1 2647 for (tail = buf->overlays_after;
2eec3b4e
RS
2648 CONSP (tail);
2649 prev = tail, tail = next)
2650 {
2651 next = XCONS (tail)->cdr;
2652 overlay = XCONS (tail)->car;
2653
2654 /* If the overlay is not valid, get rid of it. */
2655 if (!OVERLAY_VALID (overlay))
52f8ec73
JB
2656#if 1
2657 abort ();
2658#else
2eec3b4e
RS
2659 {
2660 /* Splice the cons cell TAIL out of overlays_after. */
2661 if (!NILP (prev))
2662 XCONS (prev)->cdr = next;
2663 else
5c4f68f1 2664 buf->overlays_after = next;
2eec3b4e
RS
2665 tail = prev;
2666 continue;
2667 }
52f8ec73 2668#endif
2eec3b4e
RS
2669
2670 beg = OVERLAY_START (overlay);
2671 end = OVERLAY_END (overlay);
2672
2673 /* Stop looking, when we know that nothing further
2674 can possibly end before POS. */
2675 if (OVERLAY_POSITION (beg) > pos)
2676 break;
2677
2678 if (OVERLAY_POSITION (end) <= pos)
2679 {
2680 /* OVERLAY needs to be moved. */
2681 int where = OVERLAY_POSITION (end);
2682 Lisp_Object other, other_prev;
2683
2684 /* Splice the cons cell TAIL out of overlays_after. */
2685 if (!NILP (prev))
2686 XCONS (prev)->cdr = next;
2687 else
5c4f68f1 2688 buf->overlays_after = next;
2eec3b4e
RS
2689
2690 /* Search thru overlays_before for where to put it. */
2691 other_prev = Qnil;
5c4f68f1 2692 for (other = buf->overlays_before;
2eec3b4e
RS
2693 CONSP (other);
2694 other_prev = other, other = XCONS (other)->cdr)
2695 {
2696 Lisp_Object otherend, otheroverlay;
2697 int win;
2698
2699 otheroverlay = XCONS (other)->car;
2700 if (! OVERLAY_VALID (otheroverlay))
52f8ec73 2701 abort ();
2eec3b4e
RS
2702
2703 otherend = OVERLAY_END (otheroverlay);
2704 if (OVERLAY_POSITION (otherend) <= where)
2705 break;
2706 }
2707
2708 /* Add TAIL to overlays_before before OTHER. */
2709 XCONS (tail)->cdr = other;
2710 if (!NILP (other_prev))
2711 XCONS (other_prev)->cdr = tail;
2712 else
5c4f68f1 2713 buf->overlays_before = tail;
2eec3b4e
RS
2714 tail = prev;
2715 }
2716 }
2717
8d7a4592 2718 XSETFASTINT (buf->overlay_center, pos);
2eec3b4e 2719}
2b1bdf65 2720
423cdb46
KH
2721void
2722adjust_overlays_for_insert (pos, length)
2723 int pos;
2724 int length;
2725{
2726 /* After an insertion, the lists are still sorted properly,
2727 but we may need to update the value of the overlay center. */
2728 if (XFASTINT (current_buffer->overlay_center) >= pos)
2729 XSETFASTINT (current_buffer->overlay_center,
2730 XFASTINT (current_buffer->overlay_center) + length);
2731}
2732
2733void
2734adjust_overlays_for_delete (pos, length)
2735 int pos;
2736 int length;
2737{
2738 if (XFASTINT (current_buffer->overlay_center) < pos)
2739 /* The deletion was to our right. No change needed; the before- and
2740 after-lists are still consistent. */
2741 ;
2742 else if (XFASTINT (current_buffer->overlay_center) > pos + length)
2743 /* The deletion was to our left. We need to adjust the center value
2744 to account for the change in position, but the lists are consistent
2745 given the new value. */
2746 XSETFASTINT (current_buffer->overlay_center,
2747 XFASTINT (current_buffer->overlay_center) - length);
2748 else
2749 /* We're right in the middle. There might be things on the after-list
2750 that now belong on the before-list. Recentering will move them,
2751 and also update the center point. */
2752 recenter_overlay_lists (current_buffer, pos);
2753}
2754
2b1bdf65
KH
2755/* Fix up overlays that were garbled as a result of permuting markers
2756 in the range START through END. Any overlay with at least one
2757 endpoint in this range will need to be unlinked from the overlay
2758 list and reinserted in its proper place.
2759 Such an overlay might even have negative size at this point.
2760 If so, we'll reverse the endpoints. Can you think of anything
2761 better to do in this situation? */
2762void
2763fix_overlays_in_range (start, end)
2764 register int start, end;
2765{
2766 Lisp_Object tem, overlay;
2767 Lisp_Object before_list, after_list;
2768 Lisp_Object *ptail, *pbefore = &before_list, *pafter = &after_list;
2769 int startpos, endpos;
2770
2771 /* This algorithm shifts links around instead of consing and GCing.
2772 The loop invariant is that before_list (resp. after_list) is a
2773 well-formed list except that its last element, the one that
2774 *pbefore (resp. *pafter) points to, is still uninitialized.
2775 So it's not a bug that before_list isn't initialized, although
2776 it may look strange. */
2777 for (ptail = &current_buffer->overlays_before; CONSP (*ptail);)
2778 {
2779 overlay = XCONS (*ptail)->car;
2780 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2781 if (endpos < start)
2782 break;
2783 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2784 if (endpos < end
2785 || (startpos >= start && startpos < end))
2786 {
2787 /* If the overlay is backwards, fix that now. */
2788 if (startpos > endpos)
2789 {
2790 int tem;
2c99f3ea
RS
2791 Fset_marker (OVERLAY_START (overlay), make_number (endpos),
2792 Qnil);
2793 Fset_marker (OVERLAY_END (overlay), make_number (startpos),
2794 Qnil);
2b1bdf65
KH
2795 tem = startpos; startpos = endpos; endpos = tem;
2796 }
2797 /* Add it to the end of the wrong list. Later on,
2798 recenter_overlay_lists will move it to the right place. */
2799 if (endpos < XINT (current_buffer->overlay_center))
2800 {
2801 *pafter = *ptail;
2802 pafter = &XCONS (*ptail)->cdr;
2803 }
2804 else
2805 {
2806 *pbefore = *ptail;
2807 pbefore = &XCONS (*ptail)->cdr;
2808 }
2809 *ptail = XCONS (*ptail)->cdr;
2810 }
2811 else
2812 ptail = &XCONS (*ptail)->cdr;
2813 }
2814 for (ptail = &current_buffer->overlays_after; CONSP (*ptail);)
2815 {
2816 overlay = XCONS (*ptail)->car;
2817 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2818 if (startpos >= end)
2819 break;
2820 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2821 if (startpos >= start
2822 || (endpos >= start && endpos < end))
2823 {
2824 if (startpos > endpos)
2825 {
2826 int tem;
2c99f3ea
RS
2827 Fset_marker (OVERLAY_START (overlay), make_number (endpos),
2828 Qnil);
2829 Fset_marker (OVERLAY_END (overlay), make_number (startpos),
2830 Qnil);
2b1bdf65
KH
2831 tem = startpos; startpos = endpos; endpos = tem;
2832 }
2833 if (endpos < XINT (current_buffer->overlay_center))
2834 {
2835 *pafter = *ptail;
2836 pafter = &XCONS (*ptail)->cdr;
2837 }
2838 else
2839 {
2840 *pbefore = *ptail;
2841 pbefore = &XCONS (*ptail)->cdr;
2842 }
2843 *ptail = XCONS (*ptail)->cdr;
2844 }
2845 else
2846 ptail = &XCONS (*ptail)->cdr;
2847 }
2848
2849 /* Splice the constructed (wrong) lists into the buffer's lists,
2850 and let the recenter function make it sane again. */
2851 *pbefore = current_buffer->overlays_before;
2852 current_buffer->overlays_before = before_list;
2853 recenter_overlay_lists (current_buffer,
2854 XINT (current_buffer->overlay_center));
2855
2856 *pafter = current_buffer->overlays_after;
2857 current_buffer->overlays_after = after_list;
2858 recenter_overlay_lists (current_buffer,
2859 XINT (current_buffer->overlay_center));
2860}
3b06f880
KH
2861
2862/* We have two types of overlay: the one whose ending marker is
2863 after-insertion-marker (this is the usual case) and the one whose
2864 ending marker is before-insertion-marker. When `overlays_before'
2865 contains overlays of the latter type and the former type in this
2866 order and both overlays end at inserting position, inserting a text
2867 increases only the ending marker of the latter type, which results
2868 in incorrect ordering of `overlays_before'.
2869
2870 This function fixes ordering of overlays in the slot
2871 `overlays_before' of the buffer *BP. Before the insertion, `point'
2872 was at PREV, and now is at POS. */
2873
01136e9b 2874void
3b06f880
KH
2875fix_overlays_before (bp, prev, pos)
2876 struct buffer *bp;
2877 int prev, pos;
2878{
2879 Lisp_Object *tailp = &bp->overlays_before;
2880 Lisp_Object *right_place;
2881 int end;
2882
2883 /* After the insertion, the several overlays may be in incorrect
2884 order. The possibility is that, in the list `overlays_before',
2885 an overlay which ends at POS appears after an overlay which ends
2886 at PREV. Since POS is greater than PREV, we must fix the
2887 ordering of these overlays, by moving overlays ends at POS before
2888 the overlays ends at PREV. */
2889
2890 /* At first, find a place where disordered overlays should be linked
2891 in. It is where an overlay which end before POS exists. (i.e. an
2892 overlay whose ending marker is after-insertion-marker if disorder
2893 exists). */
2894 while (!NILP (*tailp)
2895 && ((end = OVERLAY_POSITION (OVERLAY_END (XCONS (*tailp)->car)))
2896 >= pos))
2897 tailp = &XCONS (*tailp)->cdr;
2898
2899 /* If we don't find such an overlay,
2900 or the found one ends before PREV,
2901 or the found one is the last one in the list,
2902 we don't have to fix anything. */
2903 if (NILP (*tailp)
2904 || end < prev
2905 || NILP (XCONS (*tailp)->cdr))
2906 return;
2907
2908 right_place = tailp;
2909 tailp = &XCONS (*tailp)->cdr;
2910
2911 /* Now, end position of overlays in the list *TAILP should be before
2912 or equal to PREV. In the loop, an overlay which ends at POS is
2913 moved ahead to the place pointed by RIGHT_PLACE. If we found an
2914 overlay which ends before PREV, the remaining overlays are in
2915 correct order. */
2916 while (!NILP (*tailp))
2917 {
2918 end = OVERLAY_POSITION (OVERLAY_END (XCONS (*tailp)->car));
2919
2920 if (end == pos)
2921 { /* This overlay is disordered. */
2922 Lisp_Object found = *tailp;
2923
2924 /* Unlink the found overlay. */
2925 *tailp = XCONS (found)->cdr;
2926 /* Move an overlay at RIGHT_PLACE to the next of the found one. */
2927 XCONS (found)->cdr = *right_place;
2928 /* Link it into the right place. */
2929 *right_place = found;
2930 }
2931 else if (end == prev)
2932 tailp = &XCONS (*tailp)->cdr;
2933 else /* No more disordered overlay. */
2934 break;
2935 }
2936}
2eec3b4e 2937\f
52f8ec73
JB
2938DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
2939 "Return t if OBJECT is an overlay.")
2940 (object)
2941 Lisp_Object object;
2942{
2943 return (OVERLAYP (object) ? Qt : Qnil);
2944}
2945
acac2700 2946DEFUN ("make-overlay", Fmake_overlay, Smake_overlay, 2, 5, 0,
5c4f68f1
JB
2947 "Create a new overlay with range BEG to END in BUFFER.\n\
2948If omitted, BUFFER defaults to the current buffer.\n\
acac2700
RS
2949BEG and END may be integers or markers.\n\
2950The fourth arg FRONT-ADVANCE, if non-nil, makes the\n\
2951front delimiter advance when text is inserted there.\n\
2952The fifth arg REAR-ADVANCE, if non-nil, makes the\n\
2953rear delimiter advance when text is inserted there.")
2954 (beg, end, buffer, front_advance, rear_advance)
5c4f68f1 2955 Lisp_Object beg, end, buffer;
acac2700 2956 Lisp_Object front_advance, rear_advance;
2eec3b4e
RS
2957{
2958 Lisp_Object overlay;
5c4f68f1 2959 struct buffer *b;
2eec3b4e 2960
5c4f68f1 2961 if (NILP (buffer))
67180c6a 2962 XSETBUFFER (buffer, current_buffer);
883047b9
JB
2963 else
2964 CHECK_BUFFER (buffer, 2);
2965 if (MARKERP (beg)
2966 && ! EQ (Fmarker_buffer (beg), buffer))
2967 error ("Marker points into wrong buffer");
2968 if (MARKERP (end)
2969 && ! EQ (Fmarker_buffer (end), buffer))
2970 error ("Marker points into wrong buffer");
2eec3b4e 2971
883047b9
JB
2972 CHECK_NUMBER_COERCE_MARKER (beg, 1);
2973 CHECK_NUMBER_COERCE_MARKER (end, 1);
5c4f68f1 2974
883047b9 2975 if (XINT (beg) > XINT (end))
5c4f68f1 2976 {
c99fc30f
KH
2977 Lisp_Object temp;
2978 temp = beg; beg = end; end = temp;
5c4f68f1 2979 }
883047b9
JB
2980
2981 b = XBUFFER (buffer);
2982
2983 beg = Fset_marker (Fmake_marker (), beg, buffer);
2984 end = Fset_marker (Fmake_marker (), end, buffer);
5c4f68f1 2985
acac2700
RS
2986 if (!NILP (front_advance))
2987 XMARKER (beg)->insertion_type = 1;
2988 if (!NILP (rear_advance))
2989 XMARKER (end)->insertion_type = 1;
597dd755 2990
48e2e3ba 2991 overlay = allocate_misc ();
89ca3e1b 2992 XMISCTYPE (overlay) = Lisp_Misc_Overlay;
48e2e3ba
KH
2993 XOVERLAY (overlay)->start = beg;
2994 XOVERLAY (overlay)->end = end;
2995 XOVERLAY (overlay)->plist = Qnil;
2eec3b4e
RS
2996
2997 /* Put the new overlay on the wrong list. */
2998 end = OVERLAY_END (overlay);
5c4f68f1
JB
2999 if (OVERLAY_POSITION (end) < XINT (b->overlay_center))
3000 b->overlays_after = Fcons (overlay, b->overlays_after);
2eec3b4e 3001 else
5c4f68f1 3002 b->overlays_before = Fcons (overlay, b->overlays_before);
2eec3b4e
RS
3003
3004 /* This puts it in the right list, and in the right order. */
5c4f68f1 3005 recenter_overlay_lists (b, XINT (b->overlay_center));
2eec3b4e 3006
b61982dd
JB
3007 /* We don't need to redisplay the region covered by the overlay, because
3008 the overlay has no properties at the moment. */
3009
2eec3b4e
RS
3010 return overlay;
3011}
876aa27c
RS
3012\f
3013/* Mark a section of BUF as needing redisplay because of overlays changes. */
3014
3015static void
3016modify_overlay (buf, start, end)
3017 struct buffer *buf;
3018 int start, end;
3019{
3020 if (start == end)
3021 return;
3022
3023 if (start > end)
3024 {
3025 int temp = start;
3026 start = end; end = temp;
3027 }
3028
3029 /* If this is a buffer not in the selected window,
3030 we must do other windows. */
3031 if (buf != XBUFFER (XWINDOW (selected_window)->buffer))
3032 windows_or_buffers_changed = 1;
3033 /* If it's not current, we can't use beg_unchanged, end_unchanged for it. */
3034 else if (buf != current_buffer)
3035 windows_or_buffers_changed = 1;
3036 /* If multiple windows show this buffer, we must do other windows. */
3037 else if (buffer_shared > 1)
3038 windows_or_buffers_changed = 1;
3039 else
3040 {
3041 if (unchanged_modified == MODIFF
3042 && overlay_unchanged_modified == OVERLAY_MODIFF)
3043 {
3044 beg_unchanged = start - BEG;
3045 end_unchanged = Z - end;
3046 }
3047 else
3048 {
3049 if (Z - end < end_unchanged)
3050 end_unchanged = Z - end;
3051 if (start - BEG < beg_unchanged)
3052 beg_unchanged = start - BEG;
3053 }
3054 }
3055
d8b9150f 3056 ++BUF_OVERLAY_MODIFF (buf);
876aa27c 3057}
2eec3b4e 3058
876aa27c 3059\f\f
2e34157c
RS
3060Lisp_Object Fdelete_overlay ();
3061
5c4f68f1
JB
3062DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
3063 "Set the endpoints of OVERLAY to BEG and END in BUFFER.\n\
3ece337a
JB
3064If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.\n\
3065If BUFFER is omitted, and OVERLAY is in no buffer, put it in the current\n\
3066buffer.")
5c4f68f1
JB
3067 (overlay, beg, end, buffer)
3068 Lisp_Object overlay, beg, end, buffer;
2eec3b4e 3069{
0a4469c9
RS
3070 struct buffer *b, *ob;
3071 Lisp_Object obuffer;
3072 int count = specpdl_ptr - specpdl;
5c4f68f1 3073
52f8ec73 3074 CHECK_OVERLAY (overlay, 0);
5c4f68f1
JB
3075 if (NILP (buffer))
3076 buffer = Fmarker_buffer (OVERLAY_START (overlay));
3ece337a 3077 if (NILP (buffer))
67180c6a 3078 XSETBUFFER (buffer, current_buffer);
5c4f68f1 3079 CHECK_BUFFER (buffer, 3);
883047b9
JB
3080
3081 if (MARKERP (beg)
3082 && ! EQ (Fmarker_buffer (beg), buffer))
3083 error ("Marker points into wrong buffer");
3084 if (MARKERP (end)
3085 && ! EQ (Fmarker_buffer (end), buffer))
3086 error ("Marker points into wrong buffer");
3087
b61982dd
JB
3088 CHECK_NUMBER_COERCE_MARKER (beg, 1);
3089 CHECK_NUMBER_COERCE_MARKER (end, 1);
3090
9d7608b7
KH
3091 if (XINT (beg) == XINT (end) && ! NILP (Foverlay_get (overlay, Qevaporate)))
3092 return Fdelete_overlay (overlay);
0a4469c9 3093
b61982dd
JB
3094 if (XINT (beg) > XINT (end))
3095 {
c99fc30f
KH
3096 Lisp_Object temp;
3097 temp = beg; beg = end; end = temp;
b61982dd
JB
3098 }
3099
9d7608b7
KH
3100 specbind (Qinhibit_quit, Qt);
3101
0a4469c9 3102 obuffer = Fmarker_buffer (OVERLAY_START (overlay));
5c4f68f1 3103 b = XBUFFER (buffer);
0a4469c9 3104 ob = XBUFFER (obuffer);
2eec3b4e 3105
c82ed728 3106 /* If the overlay has changed buffers, do a thorough redisplay. */
0a4469c9 3107 if (!EQ (buffer, obuffer))
50760c4a
RS
3108 {
3109 /* Redisplay where the overlay was. */
3110 if (!NILP (obuffer))
3111 {
2e34157c
RS
3112 int o_beg;
3113 int o_end;
50760c4a 3114
80509f2f
RS
3115 o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3116 o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
50760c4a 3117
2e34157c 3118 modify_overlay (ob, o_beg, o_end);
50760c4a
RS
3119 }
3120
3121 /* Redisplay where the overlay is going to be. */
876aa27c 3122 modify_overlay (b, XINT (beg), XINT (end));
50760c4a 3123 }
c82ed728
JB
3124 else
3125 /* Redisplay the area the overlay has just left, or just enclosed. */
3126 {
2e34157c 3127 int o_beg, o_end;
c82ed728
JB
3128 int change_beg, change_end;
3129
80509f2f
RS
3130 o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3131 o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
c82ed728 3132
2e34157c
RS
3133 if (o_beg == XINT (beg))
3134 modify_overlay (b, o_end, XINT (end));
3135 else if (o_end == XINT (end))
3136 modify_overlay (b, o_beg, XINT (beg));
c82ed728
JB
3137 else
3138 {
2e34157c
RS
3139 if (XINT (beg) < o_beg) o_beg = XINT (beg);
3140 if (XINT (end) > o_end) o_end = XINT (end);
3141 modify_overlay (b, o_beg, o_end);
c82ed728
JB
3142 }
3143 }
b61982dd 3144
0a4469c9
RS
3145 if (!NILP (obuffer))
3146 {
3147 ob->overlays_before = Fdelq (overlay, ob->overlays_before);
3148 ob->overlays_after = Fdelq (overlay, ob->overlays_after);
3149 }
5c4f68f1
JB
3150
3151 Fset_marker (OVERLAY_START (overlay), beg, buffer);
3152 Fset_marker (OVERLAY_END (overlay), end, buffer);
2eec3b4e
RS
3153
3154 /* Put the overlay on the wrong list. */
3155 end = OVERLAY_END (overlay);
5c4f68f1
JB
3156 if (OVERLAY_POSITION (end) < XINT (b->overlay_center))
3157 b->overlays_after = Fcons (overlay, b->overlays_after);
2eec3b4e 3158 else
5c4f68f1 3159 b->overlays_before = Fcons (overlay, b->overlays_before);
2eec3b4e
RS
3160
3161 /* This puts it in the right list, and in the right order. */
5c4f68f1 3162 recenter_overlay_lists (b, XINT (b->overlay_center));
2eec3b4e 3163
0a4469c9 3164 return unbind_to (count, overlay);
2eec3b4e
RS
3165}
3166
3167DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
5c4f68f1 3168 "Delete the overlay OVERLAY from its buffer.")
2eec3b4e 3169 (overlay)
5c4f68f1 3170 Lisp_Object overlay;
2eec3b4e 3171{
0a4469c9 3172 Lisp_Object buffer;
5c4f68f1 3173 struct buffer *b;
0a4469c9 3174 int count = specpdl_ptr - specpdl;
5c4f68f1 3175
52f8ec73
JB
3176 CHECK_OVERLAY (overlay, 0);
3177
0a4469c9
RS
3178 buffer = Fmarker_buffer (OVERLAY_START (overlay));
3179 if (NILP (buffer))
3180 return Qnil;
3181
3182 b = XBUFFER (buffer);
3183
3184 specbind (Qinhibit_quit, Qt);
5c4f68f1
JB
3185
3186 b->overlays_before = Fdelq (overlay, b->overlays_before);
3187 b->overlays_after = Fdelq (overlay, b->overlays_after);
3188
876aa27c 3189 modify_overlay (b,
8231a9aa
RS
3190 marker_position (OVERLAY_START (overlay)),
3191 marker_position (OVERLAY_END (overlay)));
b61982dd 3192
3ece337a
JB
3193 Fset_marker (OVERLAY_START (overlay), Qnil, Qnil);
3194 Fset_marker (OVERLAY_END (overlay), Qnil, Qnil);
3195
0a4469c9 3196 return unbind_to (count, Qnil);
2eec3b4e
RS
3197}
3198\f
8ebafa8d
JB
3199/* Overlay dissection functions. */
3200
3201DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
3202 "Return the position at which OVERLAY starts.")
3203 (overlay)
3204 Lisp_Object overlay;
3205{
3206 CHECK_OVERLAY (overlay, 0);
3207
3208 return (Fmarker_position (OVERLAY_START (overlay)));
3209}
3210
3211DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
3212 "Return the position at which OVERLAY ends.")
3213 (overlay)
3214 Lisp_Object overlay;
3215{
3216 CHECK_OVERLAY (overlay, 0);
3217
3218 return (Fmarker_position (OVERLAY_END (overlay)));
3219}
3220
3221DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
3222 "Return the buffer OVERLAY belongs to.")
3223 (overlay)
3224 Lisp_Object overlay;
3225{
3226 CHECK_OVERLAY (overlay, 0);
3227
3228 return Fmarker_buffer (OVERLAY_START (overlay));
3229}
3230
3231DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
3232 "Return a list of the properties on OVERLAY.\n\
3233This is a copy of OVERLAY's plist; modifying its conses has no effect on\n\
3234OVERLAY.")
3235 (overlay)
3236 Lisp_Object overlay;
3237{
3238 CHECK_OVERLAY (overlay, 0);
3239
48e2e3ba 3240 return Fcopy_sequence (XOVERLAY (overlay)->plist);
8ebafa8d
JB
3241}
3242
3243\f
2eec3b4e 3244DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
eb8c3be9 3245 "Return a list of the overlays that contain position POS.")
2eec3b4e
RS
3246 (pos)
3247 Lisp_Object pos;
3248{
3249 int noverlays;
2eec3b4e
RS
3250 Lisp_Object *overlay_vec;
3251 int len;
3252 Lisp_Object result;
3253
3254 CHECK_NUMBER_COERCE_MARKER (pos, 0);
3255
3256 len = 10;
3257 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
3258
3259 /* Put all the overlays we want in a vector in overlay_vec.
3260 Store the length in len. */
2a77a7d7
RS
3261 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
3262 (int *) 0, (int *) 0);
2eec3b4e
RS
3263
3264 /* Make a list of them all. */
3265 result = Flist (noverlays, overlay_vec);
3266
9ac0d9e0 3267 xfree (overlay_vec);
2eec3b4e
RS
3268 return result;
3269}
3270
74514898 3271DEFUN ("overlays-in", Foverlays_in, Soverlays_in, 2, 2, 0,
2a3eeee7
RS
3272 "Return a list of the overlays that overlap the region BEG ... END.\n\
3273Overlap means that at least one character is contained within the overlay\n\
3274and also contained within the specified region.\n\
3275Empty overlays are included in the result if they are located at BEG\n\
3276or between BEG and END.")
74514898
RS
3277 (beg, end)
3278 Lisp_Object beg, end;
3279{
3280 int noverlays;
3281 Lisp_Object *overlay_vec;
3282 int len;
3283 Lisp_Object result;
3284
3285 CHECK_NUMBER_COERCE_MARKER (beg, 0);
3286 CHECK_NUMBER_COERCE_MARKER (end, 0);
3287
3288 len = 10;
3289 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
3290
3291 /* Put all the overlays we want in a vector in overlay_vec.
3292 Store the length in len. */
3293 noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len,
3294 (int *) 0, (int *) 0);
3295
3296 /* Make a list of them all. */
3297 result = Flist (noverlays, overlay_vec);
3298
3299 xfree (overlay_vec);
3300 return result;
3301}
3302
2eec3b4e
RS
3303DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change,
3304 1, 1, 0,
bbe20e81
KH
3305 "Return the next position after POS where an overlay starts or ends.\n\
3306If there are no more overlay boundaries after POS, return (point-max).")
2eec3b4e
RS
3307 (pos)
3308 Lisp_Object pos;
3309{
3310 int noverlays;
3311 int endpos;
3312 Lisp_Object *overlay_vec;
3313 int len;
2eec3b4e
RS
3314 int i;
3315
3316 CHECK_NUMBER_COERCE_MARKER (pos, 0);
3317
3318 len = 10;
3319 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
3320
3321 /* Put all the overlays we want in a vector in overlay_vec.
3322 Store the length in len.
3323 endpos gets the position where the next overlay starts. */
2a77a7d7
RS
3324 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
3325 &endpos, (int *) 0);
2eec3b4e
RS
3326
3327 /* If any of these overlays ends before endpos,
3328 use its ending point instead. */
3329 for (i = 0; i < noverlays; i++)
3330 {
3331 Lisp_Object oend;
3332 int oendpos;
3333
3334 oend = OVERLAY_END (overlay_vec[i]);
3335 oendpos = OVERLAY_POSITION (oend);
3336 if (oendpos < endpos)
3337 endpos = oendpos;
1ab256cb
RM
3338 }
3339
9ac0d9e0 3340 xfree (overlay_vec);
2eec3b4e
RS
3341 return make_number (endpos);
3342}
239c932b
RS
3343
3344DEFUN ("previous-overlay-change", Fprevious_overlay_change,
3345 Sprevious_overlay_change, 1, 1, 0,
3346 "Return the previous position before POS where an overlay starts or ends.\n\
624bbdc4 3347If there are no more overlay boundaries before POS, return (point-min).")
239c932b
RS
3348 (pos)
3349 Lisp_Object pos;
3350{
3351 int noverlays;
3352 int prevpos;
3353 Lisp_Object *overlay_vec;
3354 int len;
3355 int i;
624bbdc4 3356 Lisp_Object tail;
239c932b
RS
3357
3358 CHECK_NUMBER_COERCE_MARKER (pos, 0);
3359
3360 len = 10;
3361 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
3362
624bbdc4
RS
3363 /* At beginning of buffer, we know the answer;
3364 avoid bug subtracting 1 below. */
3365 if (XINT (pos) == BEGV)
3366 return pos;
3367
239c932b
RS
3368 /* Put all the overlays we want in a vector in overlay_vec.
3369 Store the length in len.
3370 prevpos gets the position of an overlay end. */
2a77a7d7
RS
3371 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
3372 (int *) 0, &prevpos);
239c932b 3373
624bbdc4 3374 /* If any of these overlays starts after prevpos,
239c932b
RS
3375 maybe use its starting point instead. */
3376 for (i = 0; i < noverlays; i++)
3377 {
3378 Lisp_Object ostart;
3379 int ostartpos;
3380
3381 ostart = OVERLAY_START (overlay_vec[i]);
3382 ostartpos = OVERLAY_POSITION (ostart);
3383 if (ostartpos > prevpos && ostartpos < XINT (pos))
3384 prevpos = ostartpos;
3385 }
3386
624bbdc4
RS
3387 /* If any overlay ends at pos, consider its starting point too. */
3388 for (tail = current_buffer->overlays_before;
3389 GC_CONSP (tail);
3390 tail = XCONS (tail)->cdr)
3391 {
3392 Lisp_Object overlay, ostart;
3393 int ostartpos;
3394
3395 overlay = XCONS (tail)->car;
3396
3397 ostart = OVERLAY_START (overlay);
3398 ostartpos = OVERLAY_POSITION (ostart);
3399 if (ostartpos > prevpos && ostartpos < XINT (pos))
3400 prevpos = ostartpos;
3401 }
3402
239c932b
RS
3403 xfree (overlay_vec);
3404 return make_number (prevpos);
3405}
2eec3b4e
RS
3406\f
3407/* These functions are for debugging overlays. */
3408
3409DEFUN ("overlay-lists", Foverlay_lists, Soverlay_lists, 0, 0, 0,
3410 "Return a pair of lists giving all the overlays of the current buffer.\n\
3411The car has all the overlays before the overlay center;\n\
bbe20e81 3412the cdr has all the overlays after the overlay center.\n\
2eec3b4e
RS
3413Recentering overlays moves overlays between these lists.\n\
3414The lists you get are copies, so that changing them has no effect.\n\
3415However, the overlays you get are the real objects that the buffer uses.")
3416 ()
3417{
3418 Lisp_Object before, after;
3419 before = current_buffer->overlays_before;
3420 if (CONSP (before))
3421 before = Fcopy_sequence (before);
3422 after = current_buffer->overlays_after;
3423 if (CONSP (after))
3424 after = Fcopy_sequence (after);
3425
3426 return Fcons (before, after);
3427}
3428
3429DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
3430 "Recenter the overlays of the current buffer around position POS.")
3431 (pos)
3432 Lisp_Object pos;
3433{
3434 CHECK_NUMBER_COERCE_MARKER (pos, 0);
3435
5c4f68f1 3436 recenter_overlay_lists (current_buffer, XINT (pos));
2eec3b4e
RS
3437 return Qnil;
3438}
3439\f
3440DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0,
a2428fa2 3441 "Get the property of overlay OVERLAY with property name PROP.")
2eec3b4e
RS
3442 (overlay, prop)
3443 Lisp_Object overlay, prop;
3444{
cab4777e 3445 Lisp_Object plist, fallback;
52f8ec73
JB
3446
3447 CHECK_OVERLAY (overlay, 0);
3448
cab4777e
RS
3449 fallback = Qnil;
3450
48e2e3ba 3451 for (plist = XOVERLAY (overlay)->plist;
2eec3b4e
RS
3452 CONSP (plist) && CONSP (XCONS (plist)->cdr);
3453 plist = XCONS (XCONS (plist)->cdr)->cdr)
3454 {
3455 if (EQ (XCONS (plist)->car, prop))
3456 return XCONS (XCONS (plist)->cdr)->car;
cab4777e
RS
3457 else if (EQ (XCONS (plist)->car, Qcategory))
3458 {
3459 Lisp_Object tem;
3460 tem = Fcar (Fcdr (plist));
3461 if (SYMBOLP (tem))
3462 fallback = Fget (tem, prop);
3463 }
2eec3b4e 3464 }
52f8ec73 3465
cab4777e 3466 return fallback;
2eec3b4e
RS
3467}
3468
3469DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
3470 "Set one property of overlay OVERLAY: give property PROP value VALUE.")
3471 (overlay, prop, value)
3472 Lisp_Object overlay, prop, value;
3473{
48e2e3ba 3474 Lisp_Object tail, buffer;
9d7608b7 3475 int changed;
2eec3b4e 3476
52f8ec73 3477 CHECK_OVERLAY (overlay, 0);
b61982dd 3478
274a9425
RS
3479 buffer = Fmarker_buffer (OVERLAY_START (overlay));
3480
48e2e3ba 3481 for (tail = XOVERLAY (overlay)->plist;
2eec3b4e
RS
3482 CONSP (tail) && CONSP (XCONS (tail)->cdr);
3483 tail = XCONS (XCONS (tail)->cdr)->cdr)
274a9425
RS
3484 if (EQ (XCONS (tail)->car, prop))
3485 {
9d7608b7
KH
3486 changed = !EQ (XCONS (XCONS (tail)->cdr)->car, value);
3487 XCONS (XCONS (tail)->cdr)->car = value;
3488 goto found;
274a9425 3489 }
9d7608b7
KH
3490 /* It wasn't in the list, so add it to the front. */
3491 changed = !NILP (value);
48e2e3ba
KH
3492 XOVERLAY (overlay)->plist
3493 = Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist));
9d7608b7
KH
3494 found:
3495 if (! NILP (buffer))
3496 {
3497 if (changed)
876aa27c 3498 modify_overlay (XBUFFER (buffer),
9d7608b7
KH
3499 marker_position (OVERLAY_START (overlay)),
3500 marker_position (OVERLAY_END (overlay)));
3501 if (EQ (prop, Qevaporate) && ! NILP (value)
3502 && (OVERLAY_POSITION (OVERLAY_START (overlay))
3503 == OVERLAY_POSITION (OVERLAY_END (overlay))))
3504 Fdelete_overlay (overlay);
3505 }
2eec3b4e 3506 return value;
1ab256cb
RM
3507}
3508\f
9115729e
KH
3509/* Subroutine of report_overlay_modification. */
3510
3511/* Lisp vector holding overlay hook functions to call.
3512 Vector elements come in pairs.
3513 Each even-index element is a list of hook functions.
3514 The following odd-index element is the overlay they came from.
3515
3516 Before the buffer change, we fill in this vector
3517 as we call overlay hook functions.
3518 After the buffer change, we get the functions to call from this vector.
3519 This way we always call the same functions before and after the change. */
3520static Lisp_Object last_overlay_modification_hooks;
3521
3522/* Number of elements actually used in last_overlay_modification_hooks. */
3523static int last_overlay_modification_hooks_used;
3524
3525/* Add one functionlist/overlay pair
3526 to the end of last_overlay_modification_hooks. */
3527
3528static void
3529add_overlay_mod_hooklist (functionlist, overlay)
3530 Lisp_Object functionlist, overlay;
3531{
3532 int oldsize = XVECTOR (last_overlay_modification_hooks)->size;
3533
3534 if (last_overlay_modification_hooks_used == oldsize)
3535 {
3536 Lisp_Object old;
3537 old = last_overlay_modification_hooks;
3538 last_overlay_modification_hooks
3539 = Fmake_vector (make_number (oldsize * 2), Qnil);
0b1f1b09
RS
3540 bcopy (XVECTOR (old)->contents,
3541 XVECTOR (last_overlay_modification_hooks)->contents,
9115729e
KH
3542 sizeof (Lisp_Object) * oldsize);
3543 }
3544 XVECTOR (last_overlay_modification_hooks)->contents[last_overlay_modification_hooks_used++] = functionlist;
3545 XVECTOR (last_overlay_modification_hooks)->contents[last_overlay_modification_hooks_used++] = overlay;
3546}
3547\f
173f2a64
RS
3548/* Run the modification-hooks of overlays that include
3549 any part of the text in START to END.
9115729e
KH
3550 If this change is an insertion, also
3551 run the insert-before-hooks of overlay starting at END,
930a9140
RS
3552 and the insert-after-hooks of overlay ending at START.
3553
3554 This is called both before and after the modification.
3555 AFTER is nonzero when we call after the modification.
3556
9115729e
KH
3557 ARG1, ARG2, ARG3 are arguments to pass to the hook functions.
3558 When AFTER is nonzero, they are the start position,
3559 the position after the inserted new text,
3560 and the length of deleted or replaced old text. */
173f2a64
RS
3561
3562void
930a9140 3563report_overlay_modification (start, end, after, arg1, arg2, arg3)
173f2a64 3564 Lisp_Object start, end;
930a9140
RS
3565 int after;
3566 Lisp_Object arg1, arg2, arg3;
173f2a64
RS
3567{
3568 Lisp_Object prop, overlay, tail;
9115729e
KH
3569 /* 1 if this change is an insertion. */
3570 int insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end));
55b48893 3571 int tail_copied;
930a9140 3572 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
55b48893
RS
3573
3574 overlay = Qnil;
3575 tail = Qnil;
930a9140 3576 GCPRO5 (overlay, tail, arg1, arg2, arg3);
173f2a64 3577
9115729e
KH
3578 if (after)
3579 {
3580 /* Call the functions recorded in last_overlay_modification_hooks
3581 rather than scanning the overlays again.
3582 First copy the vector contents, in case some of these hooks
3583 do subsequent modification of the buffer. */
3584 int size = last_overlay_modification_hooks_used;
3585 Lisp_Object *copy = (Lisp_Object *) alloca (size * sizeof (Lisp_Object));
3586 int i;
3587
3588 bcopy (XVECTOR (last_overlay_modification_hooks)->contents,
3589 copy, size * sizeof (Lisp_Object));
3590 gcpro1.var = copy;
3591 gcpro1.nvars = size;
3592
3593 for (i = 0; i < size;)
3594 {
3595 Lisp_Object prop, overlay;
3596 prop = copy[i++];
3597 overlay = copy[i++];
3598 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
3599 }
3600 UNGCPRO;
3601 return;
3602 }
3603
3604 /* We are being called before a change.
3605 Scan the overlays to find the functions to call. */
3606 last_overlay_modification_hooks_used = 0;
55b48893 3607 tail_copied = 0;
173f2a64
RS
3608 for (tail = current_buffer->overlays_before;
3609 CONSP (tail);
3610 tail = XCONS (tail)->cdr)
3611 {
3612 int startpos, endpos;
be8b1c6b 3613 Lisp_Object ostart, oend;
173f2a64
RS
3614
3615 overlay = XCONS (tail)->car;
3616
3617 ostart = OVERLAY_START (overlay);
3618 oend = OVERLAY_END (overlay);
3619 endpos = OVERLAY_POSITION (oend);
3620 if (XFASTINT (start) > endpos)
3621 break;
3622 startpos = OVERLAY_POSITION (ostart);
9115729e
KH
3623 if (insertion && (XFASTINT (start) == startpos
3624 || XFASTINT (end) == startpos))
173f2a64
RS
3625 {
3626 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
5fb5aa33
RS
3627 if (!NILP (prop))
3628 {
3629 /* Copy TAIL in case the hook recenters the overlay lists. */
55b48893
RS
3630 if (!tail_copied)
3631 tail = Fcopy_sequence (tail);
3632 tail_copied = 1;
930a9140 3633 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 3634 }
173f2a64 3635 }
9115729e
KH
3636 if (insertion && (XFASTINT (start) == endpos
3637 || XFASTINT (end) == endpos))
173f2a64
RS
3638 {
3639 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
5fb5aa33
RS
3640 if (!NILP (prop))
3641 {
55b48893
RS
3642 if (!tail_copied)
3643 tail = Fcopy_sequence (tail);
3644 tail_copied = 1;
930a9140 3645 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 3646 }
173f2a64 3647 }
3bd13e92
KH
3648 /* Test for intersecting intervals. This does the right thing
3649 for both insertion and deletion. */
3650 if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
173f2a64
RS
3651 {
3652 prop = Foverlay_get (overlay, Qmodification_hooks);
5fb5aa33
RS
3653 if (!NILP (prop))
3654 {
55b48893
RS
3655 if (!tail_copied)
3656 tail = Fcopy_sequence (tail);
3657 tail_copied = 1;
930a9140 3658 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 3659 }
173f2a64
RS
3660 }
3661 }
3662
55b48893 3663 tail_copied = 0;
173f2a64
RS
3664 for (tail = current_buffer->overlays_after;
3665 CONSP (tail);
3666 tail = XCONS (tail)->cdr)
3667 {
3668 int startpos, endpos;
be8b1c6b 3669 Lisp_Object ostart, oend;
173f2a64
RS
3670
3671 overlay = XCONS (tail)->car;
3672
3673 ostart = OVERLAY_START (overlay);
3674 oend = OVERLAY_END (overlay);
3675 startpos = OVERLAY_POSITION (ostart);
cdf0b096 3676 endpos = OVERLAY_POSITION (oend);
173f2a64
RS
3677 if (XFASTINT (end) < startpos)
3678 break;
9115729e
KH
3679 if (insertion && (XFASTINT (start) == startpos
3680 || XFASTINT (end) == startpos))
173f2a64
RS
3681 {
3682 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
5fb5aa33
RS
3683 if (!NILP (prop))
3684 {
55b48893
RS
3685 if (!tail_copied)
3686 tail = Fcopy_sequence (tail);
3687 tail_copied = 1;
930a9140 3688 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 3689 }
173f2a64 3690 }
9115729e
KH
3691 if (insertion && (XFASTINT (start) == endpos
3692 || XFASTINT (end) == endpos))
173f2a64
RS
3693 {
3694 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
5fb5aa33
RS
3695 if (!NILP (prop))
3696 {
55b48893
RS
3697 if (!tail_copied)
3698 tail = Fcopy_sequence (tail);
3699 tail_copied = 1;
930a9140 3700 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 3701 }
173f2a64 3702 }
3bd13e92
KH
3703 /* Test for intersecting intervals. This does the right thing
3704 for both insertion and deletion. */
3705 if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
173f2a64
RS
3706 {
3707 prop = Foverlay_get (overlay, Qmodification_hooks);
5fb5aa33
RS
3708 if (!NILP (prop))
3709 {
55b48893
RS
3710 if (!tail_copied)
3711 tail = Fcopy_sequence (tail);
3712 tail_copied = 1;
930a9140 3713 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 3714 }
173f2a64
RS
3715 }
3716 }
55b48893
RS
3717
3718 UNGCPRO;
173f2a64
RS
3719}
3720
3721static void
930a9140
RS
3722call_overlay_mod_hooks (list, overlay, after, arg1, arg2, arg3)
3723 Lisp_Object list, overlay;
3724 int after;
3725 Lisp_Object arg1, arg2, arg3;
173f2a64 3726{
930a9140 3727 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9115729e 3728
930a9140 3729 GCPRO4 (list, arg1, arg2, arg3);
9115729e
KH
3730 if (! after)
3731 add_overlay_mod_hooklist (list, overlay);
3732
173f2a64
RS
3733 while (!NILP (list))
3734 {
930a9140
RS
3735 if (NILP (arg3))
3736 call4 (Fcar (list), overlay, after ? Qt : Qnil, arg1, arg2);
3737 else
3738 call5 (Fcar (list), overlay, after ? Qt : Qnil, arg1, arg2, arg3);
173f2a64
RS
3739 list = Fcdr (list);
3740 }
3741 UNGCPRO;
3742}
9d7608b7
KH
3743
3744/* Delete any zero-sized overlays at position POS, if the `evaporate'
3745 property is set. */
3746void
3747evaporate_overlays (pos)
3748 int pos;
3749{
3750 Lisp_Object tail, overlay, hit_list;
3751
3752 hit_list = Qnil;
3753 if (pos <= XFASTINT (current_buffer->overlay_center))
3754 for (tail = current_buffer->overlays_before; CONSP (tail);
3755 tail = XCONS (tail)->cdr)
3756 {
3757 int endpos;
3758 overlay = XCONS (tail)->car;
3759 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3760 if (endpos < pos)
3761 break;
3762 if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos
c3935f9d 3763 && ! NILP (Foverlay_get (overlay, Qevaporate)))
9d7608b7
KH
3764 hit_list = Fcons (overlay, hit_list);
3765 }
3766 else
3767 for (tail = current_buffer->overlays_after; CONSP (tail);
3768 tail = XCONS (tail)->cdr)
3769 {
3770 int startpos;
889bf329 3771 overlay = XCONS (tail)->car;
9d7608b7
KH
3772 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3773 if (startpos > pos)
3774 break;
3775 if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
c3935f9d 3776 && ! NILP (Foverlay_get (overlay, Qevaporate)))
9d7608b7
KH
3777 hit_list = Fcons (overlay, hit_list);
3778 }
3779 for (; CONSP (hit_list); hit_list = XCONS (hit_list)->cdr)
3780 Fdelete_overlay (XCONS (hit_list)->car);
3781}
173f2a64 3782\f
54dfdeb0 3783/* Somebody has tried to store a value with an unacceptable type
1bf08baf
KH
3784 in the slot with offset OFFSET. */
3785
0fa3ba92 3786void
54dfdeb0
KH
3787buffer_slot_type_mismatch (offset)
3788 int offset;
0fa3ba92 3789{
54dfdeb0 3790 Lisp_Object sym;
0fa3ba92 3791 char *type_name;
54dfdeb0 3792 sym = *(Lisp_Object *)(offset + (char *)&buffer_local_symbols);
0fa3ba92
JB
3793 switch (XINT (*(Lisp_Object *)(offset + (char *)&buffer_local_types)))
3794 {
3795 case Lisp_Int: type_name = "integers"; break;
3796 case Lisp_String: type_name = "strings"; break;
0fa3ba92 3797 case Lisp_Symbol: type_name = "symbols"; break;
1bf08baf 3798
0fa3ba92
JB
3799 default:
3800 abort ();
3801 }
3802
1bf08baf 3803 error ("Only %s should be stored in the buffer-local variable %s",
54dfdeb0 3804 type_name, XSYMBOL (sym)->name->data);
0fa3ba92
JB
3805}
3806\f
dfcf069d 3807void
1ab256cb
RM
3808init_buffer_once ()
3809{
3810 register Lisp_Object tem;
3811
13de9290
RS
3812 buffer_permanent_local_flags = 0;
3813
1ab256cb
RM
3814 /* Make sure all markable slots in buffer_defaults
3815 are initialized reasonably, so mark_buffer won't choke. */
3816 reset_buffer (&buffer_defaults);
13de9290 3817 reset_buffer_local_variables (&buffer_defaults, 1);
1ab256cb 3818 reset_buffer (&buffer_local_symbols);
13de9290 3819 reset_buffer_local_variables (&buffer_local_symbols, 1);
336cd056
RS
3820 /* Prevent GC from getting confused. */
3821 buffer_defaults.text = &buffer_defaults.own_text;
3822 buffer_local_symbols.text = &buffer_local_symbols.own_text;
3823#ifdef USE_TEXT_PROPERTIES
3824 BUF_INTERVALS (&buffer_defaults) = 0;
3825 BUF_INTERVALS (&buffer_local_symbols) = 0;
3826#endif
67180c6a
KH
3827 XSETBUFFER (Vbuffer_defaults, &buffer_defaults);
3828 XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols);
1ab256cb
RM
3829
3830 /* Set up the default values of various buffer slots. */
3831 /* Must do these before making the first buffer! */
3832
3833 /* real setup is done in loaddefs.el */
3834 buffer_defaults.mode_line_format = build_string ("%-");
3835 buffer_defaults.abbrev_mode = Qnil;
3836 buffer_defaults.overwrite_mode = Qnil;
3837 buffer_defaults.case_fold_search = Qt;
3838 buffer_defaults.auto_fill_function = Qnil;
3839 buffer_defaults.selective_display = Qnil;
3840#ifndef old
3841 buffer_defaults.selective_display_ellipses = Qt;
3842#endif
3843 buffer_defaults.abbrev_table = Qnil;
3844 buffer_defaults.display_table = Qnil;
1ab256cb 3845 buffer_defaults.undo_list = Qnil;
c48f61ef 3846 buffer_defaults.mark_active = Qnil;
be9aafdd 3847 buffer_defaults.file_format = Qnil;
2eec3b4e
RS
3848 buffer_defaults.overlays_before = Qnil;
3849 buffer_defaults.overlays_after = Qnil;
bbbe9545 3850 XSETFASTINT (buffer_defaults.overlay_center, BEG);
1ab256cb 3851
8d7a4592 3852 XSETFASTINT (buffer_defaults.tab_width, 8);
1ab256cb
RM
3853 buffer_defaults.truncate_lines = Qnil;
3854 buffer_defaults.ctl_arrow = Qt;
3b06f880 3855 buffer_defaults.direction_reversed = Qnil;
1ab256cb 3856
f7975d07 3857#ifdef DOS_NT
0776cb1b 3858 buffer_defaults.buffer_file_type = Qnil; /* TEXT */
54ad07d3 3859#endif
a1a17b61 3860 buffer_defaults.enable_multibyte_characters = Qt;
c71b5d9b 3861 buffer_defaults.buffer_file_coding_system = Qnil;
8d7a4592
KH
3862 XSETFASTINT (buffer_defaults.fill_column, 70);
3863 XSETFASTINT (buffer_defaults.left_margin, 0);
28e969dd 3864 buffer_defaults.cache_long_line_scans = Qnil;
f6ed2e84 3865 buffer_defaults.file_truename = Qnil;
7962a441 3866 XSETFASTINT (buffer_defaults.display_count, 0);
3fd364db 3867 buffer_defaults.display_time = Qnil;
1ab256cb
RM
3868
3869 /* Assign the local-flags to the slots that have default values.
3870 The local flag is a bit that is used in the buffer
3871 to say that it has its own local value for the slot.
3872 The local flag bits are in the local_var_flags slot of the buffer. */
3873
3874 /* Nothing can work if this isn't true */
4d2f1389 3875 if (sizeof (EMACS_INT) != sizeof (Lisp_Object)) abort ();
1ab256cb
RM
3876
3877 /* 0 means not a lisp var, -1 means always local, else mask */
3878 bzero (&buffer_local_flags, sizeof buffer_local_flags);
aab80822
KH
3879 XSETINT (buffer_local_flags.filename, -1);
3880 XSETINT (buffer_local_flags.directory, -1);
3881 XSETINT (buffer_local_flags.backed_up, -1);
3882 XSETINT (buffer_local_flags.save_length, -1);
3883 XSETINT (buffer_local_flags.auto_save_file_name, -1);
3884 XSETINT (buffer_local_flags.read_only, -1);
3885 XSETINT (buffer_local_flags.major_mode, -1);
3886 XSETINT (buffer_local_flags.mode_name, -1);
3887 XSETINT (buffer_local_flags.undo_list, -1);
3888 XSETINT (buffer_local_flags.mark_active, -1);
943e065b 3889 XSETINT (buffer_local_flags.point_before_scroll, -1);
f6ed2e84 3890 XSETINT (buffer_local_flags.file_truename, -1);
3cb719bd 3891 XSETINT (buffer_local_flags.invisibility_spec, -1);
55ac8536 3892 XSETINT (buffer_local_flags.file_format, -1);
7962a441 3893 XSETINT (buffer_local_flags.display_count, -1);
3fd364db 3894 XSETINT (buffer_local_flags.display_time, -1);
1bf08baf 3895 XSETINT (buffer_local_flags.enable_multibyte_characters, -1);
8d7a4592
KH
3896
3897 XSETFASTINT (buffer_local_flags.mode_line_format, 1);
3898 XSETFASTINT (buffer_local_flags.abbrev_mode, 2);
3899 XSETFASTINT (buffer_local_flags.overwrite_mode, 4);
3900 XSETFASTINT (buffer_local_flags.case_fold_search, 8);
3901 XSETFASTINT (buffer_local_flags.auto_fill_function, 0x10);
3902 XSETFASTINT (buffer_local_flags.selective_display, 0x20);
1ab256cb 3903#ifndef old
8d7a4592 3904 XSETFASTINT (buffer_local_flags.selective_display_ellipses, 0x40);
1ab256cb 3905#endif
8d7a4592
KH
3906 XSETFASTINT (buffer_local_flags.tab_width, 0x80);
3907 XSETFASTINT (buffer_local_flags.truncate_lines, 0x100);
3908 XSETFASTINT (buffer_local_flags.ctl_arrow, 0x200);
3909 XSETFASTINT (buffer_local_flags.fill_column, 0x400);
3910 XSETFASTINT (buffer_local_flags.left_margin, 0x800);
3911 XSETFASTINT (buffer_local_flags.abbrev_table, 0x1000);
3912 XSETFASTINT (buffer_local_flags.display_table, 0x2000);
f7975d07 3913#ifdef DOS_NT
8d7a4592 3914 XSETFASTINT (buffer_local_flags.buffer_file_type, 0x4000);
13de9290
RS
3915 /* Make this one a permanent local. */
3916 buffer_permanent_local_flags |= 0x4000;
54ad07d3 3917#endif
2e716096
RS
3918 XSETFASTINT (buffer_local_flags.syntax_table, 0x8000);
3919 XSETFASTINT (buffer_local_flags.cache_long_line_scans, 0x10000);
3b06f880
KH
3920 XSETFASTINT (buffer_local_flags.category_table, 0x20000);
3921 XSETFASTINT (buffer_local_flags.direction_reversed, 0x40000);
1bf08baf 3922 XSETFASTINT (buffer_local_flags.buffer_file_coding_system, 0x80000);
a1a17b61
KH
3923 /* Make this one a permanent local. */
3924 buffer_permanent_local_flags |= 0x80000;
c71b5d9b 3925
1ab256cb
RM
3926 Vbuffer_alist = Qnil;
3927 current_buffer = 0;
3928 all_buffers = 0;
3929
3930 QSFundamental = build_string ("Fundamental");
3931
3932 Qfundamental_mode = intern ("fundamental-mode");
3933 buffer_defaults.major_mode = Qfundamental_mode;
3934
3935 Qmode_class = intern ("mode-class");
3936
3937 Qprotected_field = intern ("protected-field");
3938
3939 Qpermanent_local = intern ("permanent-local");
3940
3941 Qkill_buffer_hook = intern ("kill-buffer-hook");
3942
3943 Vprin1_to_string_buffer = Fget_buffer_create (build_string (" prin1"));
000f8083 3944
1ab256cb
RM
3945 /* super-magic invisible buffer */
3946 Vbuffer_alist = Qnil;
3947
ffd56f97 3948 Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
7775635d
KH
3949
3950 inhibit_modification_hooks = 0;
1ab256cb
RM
3951}
3952
dfcf069d 3953void
1ab256cb
RM
3954init_buffer ()
3955{
3956 char buf[MAXPATHLEN+1];
2381d133
JB
3957 char *pwd;
3958 struct stat dotstat, pwdstat;
136351b7 3959 Lisp_Object temp;
f7975d07 3960 int rc;
1ab256cb
RM
3961
3962 Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
3d871c85
RS
3963 if (NILP (buffer_defaults.enable_multibyte_characters))
3964 Fset_buffer_multibyte (Qnil);
2381d133
JB
3965
3966 /* If PWD is accurate, use it instead of calling getwd. This is faster
3967 when PWD is right, and may avoid a fatal error. */
309f2a6e
RS
3968 if ((pwd = getenv ("PWD")) != 0
3969 && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
2381d133
JB
3970 && stat (pwd, &pwdstat) == 0
3971 && stat (".", &dotstat) == 0
3972 && dotstat.st_ino == pwdstat.st_ino
3973 && dotstat.st_dev == pwdstat.st_dev
3974 && strlen (pwd) < MAXPATHLEN)
3975 strcpy (buf, pwd);
6335beb0
RS
3976#ifdef HAVE_GETCWD
3977 else if (getcwd (buf, MAXPATHLEN+1) == 0)
9dde47f5 3978 fatal ("`getcwd' failed: %s\n", strerror (errno));
6335beb0 3979#else
2381d133 3980 else if (getwd (buf) == 0)
cf1e6391 3981 fatal ("`getwd' failed: %s\n", buf);
6335beb0 3982#endif
1ab256cb
RM
3983
3984#ifndef VMS
3985 /* Maybe this should really use some standard subroutine
3986 whose definition is filename syntax dependent. */
f7975d07
RS
3987 rc = strlen (buf);
3988 if (!(IS_DIRECTORY_SEP (buf[rc - 1])))
3989 {
3990 buf[rc] = DIRECTORY_SEP;
3991 buf[rc + 1] = '\0';
3992 }
1ab256cb 3993#endif /* not VMS */
0995fa35 3994
1ab256cb 3995 current_buffer->directory = build_string (buf);
136351b7 3996
0995fa35
RS
3997 /* Add /: to the front of the name
3998 if it would otherwise be treated as magic. */
3999 temp = Ffind_file_name_handler (current_buffer->directory, Qt);
81ab2e07
KH
4000 if (! NILP (temp)
4001 /* If the default dir is just /, TEMP is non-nil
4002 because of the ange-ftp completion handler.
4003 However, it is not necessary to turn / into /:/.
4004 So avoid doing that. */
4005 && strcmp ("/", XSTRING (current_buffer->directory)->data))
0995fa35
RS
4006 current_buffer->directory
4007 = concat2 (build_string ("/:"), current_buffer->directory);
4008
136351b7
RS
4009 temp = get_minibuffer (0);
4010 XBUFFER (temp)->directory = current_buffer->directory;
1ab256cb
RM
4011}
4012
4013/* initialize the buffer routines */
dfcf069d 4014void
1ab256cb
RM
4015syms_of_buffer ()
4016{
188d4d11
RM
4017 extern Lisp_Object Qdisabled;
4018
9115729e
KH
4019 staticpro (&last_overlay_modification_hooks);
4020 last_overlay_modification_hooks
4021 = Fmake_vector (make_number (10), Qnil);
4022
1ab256cb
RM
4023 staticpro (&Vbuffer_defaults);
4024 staticpro (&Vbuffer_local_symbols);
4025 staticpro (&Qfundamental_mode);
4026 staticpro (&Qmode_class);
4027 staticpro (&QSFundamental);
4028 staticpro (&Vbuffer_alist);
4029 staticpro (&Qprotected_field);
4030 staticpro (&Qpermanent_local);
4031 staticpro (&Qkill_buffer_hook);
22378665 4032 Qoverlayp = intern ("overlayp");
52f8ec73 4033 staticpro (&Qoverlayp);
9d7608b7
KH
4034 Qevaporate = intern ("evaporate");
4035 staticpro (&Qevaporate);
294d215f 4036 Qmodification_hooks = intern ("modification-hooks");
22378665 4037 staticpro (&Qmodification_hooks);
294d215f 4038 Qinsert_in_front_hooks = intern ("insert-in-front-hooks");
22378665 4039 staticpro (&Qinsert_in_front_hooks);
294d215f 4040 Qinsert_behind_hooks = intern ("insert-behind-hooks");
22378665 4041 staticpro (&Qinsert_behind_hooks);
5fe0b67e 4042 Qget_file_buffer = intern ("get-file-buffer");
22378665 4043 staticpro (&Qget_file_buffer);
5985d248
KH
4044 Qpriority = intern ("priority");
4045 staticpro (&Qpriority);
4046 Qwindow = intern ("window");
4047 staticpro (&Qwindow);
bbbe9545
KH
4048 Qbefore_string = intern ("before-string");
4049 staticpro (&Qbefore_string);
4050 Qafter_string = intern ("after-string");
4051 staticpro (&Qafter_string);
22378665
RS
4052 Qfirst_change_hook = intern ("first-change-hook");
4053 staticpro (&Qfirst_change_hook);
4054 Qbefore_change_functions = intern ("before-change-functions");
4055 staticpro (&Qbefore_change_functions);
4056 Qafter_change_functions = intern ("after-change-functions");
4057 staticpro (&Qafter_change_functions);
1ab256cb
RM
4058
4059 Fput (Qprotected_field, Qerror_conditions,
4060 Fcons (Qprotected_field, Fcons (Qerror, Qnil)));
4061 Fput (Qprotected_field, Qerror_message,
4062 build_string ("Attempt to modify a protected field"));
4063
4064 /* All these use DEFVAR_LISP_NOPRO because the slots in
4065 buffer_defaults will all be marked via Vbuffer_defaults. */
4066
4067 DEFVAR_LISP_NOPRO ("default-mode-line-format",
4068 &buffer_defaults.mode_line_format,
4069 "Default value of `mode-line-format' for buffers that don't override it.\n\
4070This is the same as (default-value 'mode-line-format).");
4071
4072 DEFVAR_LISP_NOPRO ("default-abbrev-mode",
4073 &buffer_defaults.abbrev_mode,
4074 "Default value of `abbrev-mode' for buffers that do not override it.\n\
4075This is the same as (default-value 'abbrev-mode).");
4076
4077 DEFVAR_LISP_NOPRO ("default-ctl-arrow",
4078 &buffer_defaults.ctl_arrow,
4079 "Default value of `ctl-arrow' for buffers that do not override it.\n\
4080This is the same as (default-value 'ctl-arrow).");
4081
3b06f880
KH
4082 DEFVAR_LISP_NOPRO ("default-direction-reversed",
4083 &buffer_defaults.direction_reversed,
4084 "Default value of `direction_reversed' for buffers that do not override it.\n\
4085 This is the same as (default-value 'direction-reversed).");
4086
a1a17b61
KH
4087 DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters",
4088 &buffer_defaults.enable_multibyte_characters,
4089 "Default value of `enable-multibyte-characters' for buffers not overriding it.\n\
4090 This is the same as (default-value 'enable-multibyte-characters).");
4091
c71b5d9b
KH
4092 DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system",
4093 &buffer_defaults.buffer_file_coding_system,
4094 "Default value of `buffer-file-coding-system' for buffers not overriding it.\n\
4095 This is the same as (default-value 'buffer-file-coding-system).");
4096
1ab256cb
RM
4097 DEFVAR_LISP_NOPRO ("default-truncate-lines",
4098 &buffer_defaults.truncate_lines,
4099 "Default value of `truncate-lines' for buffers that do not override it.\n\
4100This is the same as (default-value 'truncate-lines).");
4101
4102 DEFVAR_LISP_NOPRO ("default-fill-column",
4103 &buffer_defaults.fill_column,
4104 "Default value of `fill-column' for buffers that do not override it.\n\
4105This is the same as (default-value 'fill-column).");
4106
4107 DEFVAR_LISP_NOPRO ("default-left-margin",
4108 &buffer_defaults.left_margin,
4109 "Default value of `left-margin' for buffers that do not override it.\n\
4110This is the same as (default-value 'left-margin).");
4111
4112 DEFVAR_LISP_NOPRO ("default-tab-width",
4113 &buffer_defaults.tab_width,
4114 "Default value of `tab-width' for buffers that do not override it.\n\
4115This is the same as (default-value 'tab-width).");
4116
4117 DEFVAR_LISP_NOPRO ("default-case-fold-search",
4118 &buffer_defaults.case_fold_search,
4119 "Default value of `case-fold-search' for buffers that don't override it.\n\
4120This is the same as (default-value 'case-fold-search).");
4121
f7975d07 4122#ifdef DOS_NT
54ad07d3
RS
4123 DEFVAR_LISP_NOPRO ("default-buffer-file-type",
4124 &buffer_defaults.buffer_file_type,
4125 "Default file type for buffers that do not override it.\n\
4126This is the same as (default-value 'buffer-file-type).\n\
4127The file type is nil for text, t for binary.");
4128#endif
4129
0fa3ba92
JB
4130 DEFVAR_PER_BUFFER ("mode-line-format", &current_buffer->mode_line_format,
4131 Qnil, 0);
1ab256cb
RM
4132
4133/* This doc string is too long for cpp; cpp dies if it isn't in a comment.
4134 But make-docfile finds it!
4135 DEFVAR_PER_BUFFER ("mode-line-format", &current_buffer->mode_line_format,
bec44fd6 4136 Qnil,
1ab256cb
RM
4137 "Template for displaying mode line for current buffer.\n\
4138Each buffer has its own value of this variable.\n\
4139Value may be a string, a symbol or a list or cons cell.\n\
4140For a symbol, its value is used (but it is ignored if t or nil).\n\
4141 A string appearing directly as the value of a symbol is processed verbatim\n\
4142 in that the %-constructs below are not recognized.\n\
4143For a list whose car is a symbol, the symbol's value is taken,\n\
4144 and if that is non-nil, the cadr of the list is processed recursively.\n\
4145 Otherwise, the caddr of the list (if there is one) is processed.\n\
4146For a list whose car is a string or list, each element is processed\n\
4147 recursively and the results are effectively concatenated.\n\
4148For a list whose car is an integer, the cdr of the list is processed\n\
4149 and padded (if the number is positive) or truncated (if negative)\n\
4150 to the width specified by that number.\n\
4151A string is printed verbatim in the mode line except for %-constructs:\n\
4152 (%-constructs are allowed when the string is the entire mode-line-format\n\
4153 or when it is found in a cons-cell or a list)\n\
4154 %b -- print buffer name. %f -- print visited file name.\n\
5d516f2d 4155 %F -- print frame name.\n\
c2ff34f7
RS
4156 %* -- print %, * or hyphen. %+ -- print *, % or hyphen.\n\
4157 % means buffer is read-only and * means it is modified.\n\
4158 For a modified read-only buffer, %* gives % and %+ gives *.\n\
a97c374a 4159 %s -- print process status. %l -- print the current line number.\n\
07924294 4160 %c -- print the current column number (this makes editing slower).\n\
6a567ad8
RS
4161 To make the column number update correctly in all cases,\n\
4162 `column-number-mode' must be non-nil.\n\
dd24e6a6 4163 %p -- print percent of buffer above top of window, or Top, Bot or All.\n\
9d130ffc 4164 %P -- print percent of buffer above bottom of window, perhaps plus Top,\n\
dd24e6a6 4165 or print Bottom or All.\n\
1ab256cb 4166 %n -- print Narrow if appropriate.\n\
b77087c5 4167 %t -- print T if file is text, B if binary.\n\
1ab256cb
RM
4168 %[ -- print one [ for each recursive editing level. %] similar.\n\
4169 %% -- print %. %- -- print infinitely many dashes.\n\
4170Decimal digits after the % specify field width to which to pad.");
4171*/
4172
4173 DEFVAR_LISP_NOPRO ("default-major-mode", &buffer_defaults.major_mode,
4174 "*Major mode for new buffers. Defaults to `fundamental-mode'.\n\
4175nil here means use current buffer's major mode.");
4176
4177 DEFVAR_PER_BUFFER ("major-mode", &current_buffer->major_mode,
0fa3ba92 4178 make_number (Lisp_Symbol),
1ab256cb
RM
4179 "Symbol for current buffer's major mode.");
4180
4181 DEFVAR_PER_BUFFER ("mode-name", &current_buffer->mode_name,
0fa3ba92 4182 make_number (Lisp_String),
1ab256cb
RM
4183 "Pretty name of current buffer's major mode (a string).");
4184
0fa3ba92 4185 DEFVAR_PER_BUFFER ("abbrev-mode", &current_buffer->abbrev_mode, Qnil,
1ab256cb
RM
4186 "Non-nil turns on automatic expansion of abbrevs as they are inserted.\n\
4187Automatically becomes buffer-local when set in any fashion.");
4188
4189 DEFVAR_PER_BUFFER ("case-fold-search", &current_buffer->case_fold_search,
0fa3ba92 4190 Qnil,
1ab256cb
RM
4191 "*Non-nil if searches should ignore case.\n\
4192Automatically becomes buffer-local when set in any fashion.");
4193
4194 DEFVAR_PER_BUFFER ("fill-column", &current_buffer->fill_column,
0fa3ba92 4195 make_number (Lisp_Int),
1ab256cb
RM
4196 "*Column beyond which automatic line-wrapping should happen.\n\
4197Automatically becomes buffer-local when set in any fashion.");
4198
4199 DEFVAR_PER_BUFFER ("left-margin", &current_buffer->left_margin,
0fa3ba92 4200 make_number (Lisp_Int),
1ab256cb
RM
4201 "*Column for the default indent-line-function to indent to.\n\
4202Linefeed indents to this column in Fundamental mode.\n\
4203Automatically becomes buffer-local when set in any fashion.");
4204
4205 DEFVAR_PER_BUFFER ("tab-width", &current_buffer->tab_width,
0fa3ba92 4206 make_number (Lisp_Int),
1ab256cb
RM
4207 "*Distance between tab stops (for display of tab characters), in columns.\n\
4208Automatically becomes buffer-local when set in any fashion.");
4209
0fa3ba92 4210 DEFVAR_PER_BUFFER ("ctl-arrow", &current_buffer->ctl_arrow, Qnil,
1ab256cb 4211 "*Non-nil means display control chars with uparrow.\n\
6a99d31d 4212A value of nil means use backslash and octal digits.\n\
1ab256cb
RM
4213Automatically becomes buffer-local when set in any fashion.\n\
4214This variable does not apply to characters whose display is specified\n\
4215in the current display table (if there is one).");
4216
3b06f880 4217 DEFVAR_PER_BUFFER ("enable-multibyte-characters",
1bf08baf
KH
4218 &current_buffer->enable_multibyte_characters,
4219 make_number (-1),
ed218f73
DL
4220 "*Non-nil means the buffer contents are regarded as multi-byte characters.\n\
4221Otherwise they are regarded as unibyte. This affects the display,\n\
4222file I/O and the behavior of various editing commands.");
3b06f880 4223
c71b5d9b
KH
4224 DEFVAR_PER_BUFFER ("buffer-file-coding-system",
4225 &current_buffer->buffer_file_coding_system, Qnil,
4226 "Coding system to be used for encoding the buffer contents on saving.\n\
4227If it is nil, the buffer is saved without any code conversion unless\n\
6c0316ae 4228some coding system is specified in `file-coding-system-alist'\n\
c71b5d9b
KH
4229for the buffer file.\n\
4230\n\
4231This variable is never applied to a way of decoding\n\
4232a file while reading it.");
4233
3b06f880
KH
4234 DEFVAR_PER_BUFFER ("direction-reversed", &current_buffer->direction_reversed,
4235 Qnil,
4236 "*Non-nil means lines in the buffer are displayed right to left.");
4237
0fa3ba92 4238 DEFVAR_PER_BUFFER ("truncate-lines", &current_buffer->truncate_lines, Qnil,
1ab256cb
RM
4239 "*Non-nil means do not display continuation lines;\n\
4240give each line of text one screen line.\n\
4241Automatically becomes buffer-local when set in any fashion.\n\
4242\n\
4243Note that this is overridden by the variable\n\
4244`truncate-partial-width-windows' if that variable is non-nil\n\
502b9b64 4245and this buffer is not full-frame width.");
1ab256cb 4246
f7975d07 4247#ifdef DOS_NT
54ad07d3
RS
4248 DEFVAR_PER_BUFFER ("buffer-file-type", &current_buffer->buffer_file_type,
4249 Qnil,
006d3d34
RS
4250 "Non-nil if the visited file is a binary file.\n\
4251This variable is meaningful on MS-DOG and Windows NT.\n\
4252On those systems, it is automatically local in every buffer.\n\
e0585c64 4253On other systems, this variable is normally always nil.");
54ad07d3
RS
4254#endif
4255
1ab256cb 4256 DEFVAR_PER_BUFFER ("default-directory", &current_buffer->directory,
0fa3ba92 4257 make_number (Lisp_String),
1ab256cb
RM
4258 "Name of default directory of current buffer. Should end with slash.\n\
4259Each buffer has its own value of this variable.");
4260
4261 DEFVAR_PER_BUFFER ("auto-fill-function", &current_buffer->auto_fill_function,
0fa3ba92 4262 Qnil,
1ab256cb 4263 "Function called (if non-nil) to perform auto-fill.\n\
54158e68 4264It is called after self-inserting a space or newline.\n\
1ab256cb 4265Each buffer has its own value of this variable.\n\
54158e68
KH
4266NOTE: This variable is not a hook;\n\
4267its value may not be a list of functions.");
1ab256cb
RM
4268
4269 DEFVAR_PER_BUFFER ("buffer-file-name", &current_buffer->filename,
0fa3ba92 4270 make_number (Lisp_String),
1ab256cb
RM
4271 "Name of file visited in current buffer, or nil if not visiting a file.\n\
4272Each buffer has its own value of this variable.");
4273
f6ed2e84
RS
4274 DEFVAR_PER_BUFFER ("buffer-file-truename", &current_buffer->file_truename,
4275 make_number (Lisp_String),
bb4c204e 4276 "Abbreviated truename of file visited in current buffer, or nil if none.\n\
b1c03e64
RS
4277The truename of a file is calculated by `file-truename'\n\
4278and then abbreviated with `abbreviate-file-name'.\n\
f6ed2e84
RS
4279Each buffer has its own value of this variable.");
4280
1ab256cb 4281 DEFVAR_PER_BUFFER ("buffer-auto-save-file-name",
3f5fcd47 4282 &current_buffer->auto_save_file_name,
0fa3ba92 4283 make_number (Lisp_String),
1ab256cb
RM
4284 "Name of file for auto-saving current buffer,\n\
4285or nil if buffer should not be auto-saved.\n\
4286Each buffer has its own value of this variable.");
4287
0fa3ba92 4288 DEFVAR_PER_BUFFER ("buffer-read-only", &current_buffer->read_only, Qnil,
1ab256cb
RM
4289 "Non-nil if this buffer is read-only.\n\
4290Each buffer has its own value of this variable.");
4291
0fa3ba92 4292 DEFVAR_PER_BUFFER ("buffer-backed-up", &current_buffer->backed_up, Qnil,
1ab256cb
RM
4293 "Non-nil if this buffer's file has been backed up.\n\
4294Backing up is done before the first time the file is saved.\n\
4295Each buffer has its own value of this variable.");
4296
4297 DEFVAR_PER_BUFFER ("buffer-saved-size", &current_buffer->save_length,
0fa3ba92 4298 make_number (Lisp_Int),
1ab256cb
RM
4299 "Length of current buffer when last read in, saved or auto-saved.\n\
43000 initially.\n\
4301Each buffer has its own value of this variable.");
4302
4303 DEFVAR_PER_BUFFER ("selective-display", &current_buffer->selective_display,
0fa3ba92 4304 Qnil,
1ab256cb
RM
4305 "Non-nil enables selective display:\n\
4306Integer N as value means display only lines\n\
4307 that start with less than n columns of space.\n\
4308A value of t means, after a ^M, all the rest of the line is invisible.\n\
4309 Then ^M's in the file are written into files as newlines.\n\n\
4310Automatically becomes buffer-local when set in any fashion.");
4311
4312#ifndef old
4313 DEFVAR_PER_BUFFER ("selective-display-ellipses",
4314 &current_buffer->selective_display_ellipses,
0fa3ba92 4315 Qnil,
1ab256cb
RM
4316 "t means display ... on previous line when a line is invisible.\n\
4317Automatically becomes buffer-local when set in any fashion.");
4318#endif
4319
0fa3ba92 4320 DEFVAR_PER_BUFFER ("overwrite-mode", &current_buffer->overwrite_mode, Qnil,
1ab256cb 4321 "Non-nil if self-insertion should replace existing text.\n\
5e05d0a5
RS
4322The value should be one of `overwrite-mode-textual',\n\
4323`overwrite-mode-binary', or nil.\n\
4324If it is `overwrite-mode-textual', self-insertion still\n\
6bbb0d4a 4325inserts at the end of a line, and inserts when point is before a tab,\n\
2e94b813 4326until the tab is filled in.\n\
6bbb0d4a 4327If `overwrite-mode-binary', self-insertion replaces newlines and tabs too.\n\
1ab256cb
RM
4328Automatically becomes buffer-local when set in any fashion.");
4329
54939090
RS
4330#if 0 /* The doc string is too long for some compilers,
4331 but make-docfile can find it in this comment. */
1ab256cb 4332 DEFVAR_PER_BUFFER ("buffer-display-table", &current_buffer->display_table,
5d305367 4333 Qnil,
1ab256cb
RM
4334 "Display table that controls display of the contents of current buffer.\n\
4335Automatically becomes buffer-local when set in any fashion.\n\
6fdc249f
EN
4336The display table is a char-table created with `make-display-table'.\n\
4337The ordinary char-table elements control how to display each possible text\n\
4338character. Each value should be a vector of characters or nil;\n\
1ab256cb 4339nil means display the character in the default fashion.\n\
6fdc249f
EN
4340There are six extra slots to control the display of\n\
4341 the end of a truncated screen line (extra-slot 0, a single character);\n\
4342 the end of a continued line (extra-slot 1, a single character);\n\
6158b3b0 4343 the escape character used to display character codes in octal\n\
6fdc249f
EN
4344 (extra-slot 2, a single character);\n\
4345 the character used as an arrow for control characters (extra-slot 3,\n\
6158b3b0 4346 a single character);\n\
6fdc249f 4347 the decoration indicating the presence of invisible lines (extra-slot 4,\n\
a45e35e1
JB
4348 a vector of characters);\n\
4349 the character used to draw the border between side-by-side windows\n\
6fdc249f
EN
4350 (extra-slot 5, a single character).\n\
4351See also the functions `display-table-slot' and `set-display-table-slot'.\n\
1ab256cb
RM
4352If this variable is nil, the value of `standard-display-table' is used.\n\
4353Each window can have its own, overriding display table.");
54939090
RS
4354#endif
4355 DEFVAR_PER_BUFFER ("buffer-display-table", &current_buffer->display_table,
de15914a 4356 Qnil, 0);
1ab256cb 4357
1ab256cb
RM
4358/*DEFVAR_LISP ("debug-check-symbol", &Vcheck_symbol,
4359 "Don't ask.");
4360*/
01050cb5 4361 DEFVAR_LISP ("before-change-function", &Vbefore_change_function,
f0724bcb 4362 "If non-nil, a function to call before each text change (obsolete).\n\
1ab256cb
RM
4363Two arguments are passed to the function: the positions of\n\
4364the beginning and end of the range of old text to be changed.\n\
4365\(For an insertion, the beginning and end are at the same place.)\n\
4366No information is given about the length of the text after the change.\n\
1ab256cb 4367\n\
5f079267 4368Buffer changes made while executing the `before-change-function'\n\
b86344d0
RS
4369don't call any before-change or after-change functions.\n\
4370That's because these variables are temporarily set to nil.\n\
4371As a result, a hook function cannot straightforwardly alter the value of\n\
4372these variables. See the Emacs Lisp manual for a way of\n\
f0724bcb
RS
4373accomplishing an equivalent result by using other variables.\n\n\
4374This variable is obsolete; use `before-change-functions' instead.");
1ab256cb
RM
4375 Vbefore_change_function = Qnil;
4376
4377 DEFVAR_LISP ("after-change-function", &Vafter_change_function,
f0724bcb 4378 "If non-nil, a Function to call after each text change (obsolete).\n\
1ab256cb
RM
4379Three arguments are passed to the function: the positions of\n\
4380the beginning and end of the range of changed text,\n\
4381and the length of the pre-change text replaced by that range.\n\
4382\(For an insertion, the pre-change length is zero;\n\
839dd834 4383for a deletion, that length is the number of bytes deleted,\n\
1ab256cb
RM
4384and the post-change beginning and end are at the same place.)\n\
4385\n\
5f079267 4386Buffer changes made while executing the `after-change-function'\n\
b86344d0
RS
4387don't call any before-change or after-change functions.\n\
4388That's because these variables are temporarily set to nil.\n\
4389As a result, a hook function cannot straightforwardly alter the value of\n\
4390these variables. See the Emacs Lisp manual for a way of\n\
f0724bcb
RS
4391accomplishing an equivalent result by using other variables.\n\n\
4392This variable is obsolete; use `after-change-functions' instead.");
1ab256cb
RM
4393 Vafter_change_function = Qnil;
4394
5f079267
RS
4395 DEFVAR_LISP ("before-change-functions", &Vbefore_change_functions,
4396 "List of functions to call before each text change.\n\
4397Two arguments are passed to each function: the positions of\n\
4398the beginning and end of the range of old text to be changed.\n\
4399\(For an insertion, the beginning and end are at the same place.)\n\
4400No information is given about the length of the text after the change.\n\
5f079267
RS
4401\n\
4402Buffer changes made while executing the `before-change-functions'\n\
b86344d0
RS
4403don't call any before-change or after-change functions.\n\
4404That's because these variables are temporarily set to nil.\n\
4405As a result, a hook function cannot straightforwardly alter the value of\n\
4406these variables. See the Emacs Lisp manual for a way of\n\
d59698c4 4407accomplishing an equivalent result by using other variables.");
5f079267
RS
4408 Vbefore_change_functions = Qnil;
4409
4410 DEFVAR_LISP ("after-change-functions", &Vafter_change_functions,
4411 "List of function to call after each text change.\n\
4412Three arguments are passed to each function: the positions of\n\
4413the beginning and end of the range of changed text,\n\
839dd834 4414and the length in bytes of the pre-change text replaced by that range.\n\
5f079267 4415\(For an insertion, the pre-change length is zero;\n\
839dd834 4416for a deletion, that length is the number of bytes deleted,\n\
5f079267
RS
4417and the post-change beginning and end are at the same place.)\n\
4418\n\
4419Buffer changes made while executing the `after-change-functions'\n\
b86344d0
RS
4420don't call any before-change or after-change functions.\n\
4421That's because these variables are temporarily set to nil.\n\
4422As a result, a hook function cannot straightforwardly alter the value of\n\
4423these variables. See the Emacs Lisp manual for a way of\n\
d59698c4 4424accomplishing an equivalent result by using other variables.");
b86344d0 4425
5f079267
RS
4426 Vafter_change_functions = Qnil;
4427
dbc4e1c1
JB
4428 DEFVAR_LISP ("first-change-hook", &Vfirst_change_hook,
4429 "A list of functions to call before changing a buffer which is unmodified.\n\
4430The functions are run using the `run-hooks' function.");
4431 Vfirst_change_hook = Qnil;
1ab256cb 4432
54939090
RS
4433#if 0 /* The doc string is too long for some compilers,
4434 but make-docfile can find it in this comment. */
3f5fcd47 4435 DEFVAR_PER_BUFFER ("buffer-undo-list", &current_buffer->undo_list, Qnil,
1ab256cb 4436 "List of undo entries in current buffer.\n\
3fd364db 4437This variable is always local in all buffers.\n\
1ab256cb
RM
4438Recent changes come first; older changes follow newer.\n\
4439\n\
630f4018
KH
4440An entry (BEG . END) represents an insertion which begins at\n\
4441position BEG and ends at position END.\n\
1ab256cb
RM
4442\n\
4443An entry (TEXT . POSITION) represents the deletion of the string TEXT\n\
4444from (abs POSITION). If POSITION is positive, point was at the front\n\
4445of the text being deleted; if negative, point was at the end.\n\
4446\n\
6c0df54a
RS
4447An entry (t HIGH . LOW) indicates that the buffer previously had\n\
4448\"unmodified\" status. HIGH and LOW are the high and low 16-bit portions\n\
4449of the visited file's modification time, as of that time. If the\n\
4450modification time of the most recent save is different, this entry is\n\
1ab256cb
RM
4451obsolete.\n\
4452\n\
6c0df54a
RS
4453An entry (nil PROPERTY VALUE BEG . END) indicates that a text property\n\
4454was modified between BEG and END. PROPERTY is the property name,\n\
4455and VALUE is the old value.\n\
483c1fd3 4456\n\
da1c183c
RS
4457An entry (MARKER . DISTANCE) indicates that the marker MARKER\n\
4458was adjusted in position by the offset DISTANCE (an integer).\n\
4459\n\
bec44fd6
JB
4460An entry of the form POSITION indicates that point was at the buffer\n\
4461location given by the integer. Undoing an entry of this form places\n\
4462point at POSITION.\n\
4463\n\
1ab256cb
RM
4464nil marks undo boundaries. The undo command treats the changes\n\
4465between two undo boundaries as a single step to be undone.\n\
4466\n\
bec44fd6 4467If the value of the variable is t, undo information is not recorded.");
54939090
RS
4468#endif
4469 DEFVAR_PER_BUFFER ("buffer-undo-list", &current_buffer->undo_list, Qnil,
de15914a 4470 0);
1ab256cb 4471
c48f61ef
RS
4472 DEFVAR_PER_BUFFER ("mark-active", &current_buffer->mark_active, Qnil,
4473 "Non-nil means the mark and region are currently active in this buffer.\n\
4474Automatically local in all buffers.");
4475
28e969dd 4476 DEFVAR_PER_BUFFER ("cache-long-line-scans", &current_buffer->cache_long_line_scans, Qnil,
f0c5b712
JB
4477 "Non-nil means that Emacs should use caches to handle long lines more quickly.\n\
4478This variable is buffer-local, in all buffers.\n\
28e969dd 4479\n\
f0c5b712
JB
4480Normally, the line-motion functions work by scanning the buffer for\n\
4481newlines. Columnar operations (like move-to-column and\n\
4482compute-motion) also work by scanning the buffer, summing character\n\
4483widths as they go. This works well for ordinary text, but if the\n\
28e969dd 4484buffer's lines are very long (say, more than 500 characters), these\n\
f0c5b712
JB
4485motion functions will take longer to execute. Emacs may also take\n\
4486longer to update the display.\n\
28e969dd 4487\n\
f0c5b712
JB
4488If cache-long-line-scans is non-nil, these motion functions cache the\n\
4489results of their scans, and consult the cache to avoid rescanning\n\
4490regions of the buffer until the text is modified. The caches are most\n\
4491beneficial when they prevent the most searching---that is, when the\n\
4492buffer contains long lines and large regions of characters with the\n\
4493same, fixed screen width.\n\
28e969dd 4494\n\
f0c5b712
JB
4495When cache-long-line-scans is non-nil, processing short lines will\n\
4496become slightly slower (because of the overhead of consulting the\n\
4497cache), and the caches will use memory roughly proportional to the\n\
4498number of newlines and characters whose screen width varies.\n\
4499\n\
4500The caches require no explicit maintenance; their accuracy is\n\
4501maintained internally by the Emacs primitives. Enabling or disabling\n\
4502the cache should not affect the behavior of any of the motion\n\
4503functions; it should only affect their performance.");
28e969dd 4504
943e065b 4505 DEFVAR_PER_BUFFER ("point-before-scroll", &current_buffer->point_before_scroll, Qnil,
3fd364db
RS
4506 "Value of point before the last series of scroll operations, or nil.\n\
4507This variable is always local in all buffers.");
943e065b 4508
be9aafdd
BG
4509 DEFVAR_PER_BUFFER ("buffer-file-format", &current_buffer->file_format, Qnil,
4510 "List of formats to use when saving this buffer.\n\
3fd364db 4511This variable is always local in all buffers.\n\
be9aafdd
BG
4512Formats are defined by `format-alist'. This variable is\n\
4513set when a file is visited. Automatically local in all buffers.");
4514
3cb719bd
RS
4515 DEFVAR_PER_BUFFER ("buffer-invisibility-spec",
4516 &current_buffer->invisibility_spec, Qnil,
4517 "Invisibility spec of this buffer.\n\
3fd364db 4518This variable is always local in all buffers.\n\
3cb719bd
RS
4519The default is t, which means that text is invisible\n\
4520if it has a non-nil `invisible' property.\n\
4521If the value is a list, a text character is invisible if its `invisible'\n\
4522property is an element in that list.\n\
554216ad
KH
4523If an element is a cons cell of the form (PROP . ELLIPSIS),\n\
4524then characters with property value PROP are invisible,\n\
3cb719bd
RS
4525and they have an ellipsis as well if ELLIPSIS is non-nil.");
4526
7962a441
RS
4527 DEFVAR_PER_BUFFER ("buffer-display-count",
4528 &current_buffer->display_count, Qnil,
3fd364db
RS
4529 "A number incremented each time this buffer is displayed in a window.\n\
4530This variable is always local in all buffers.\n\
4531The function `set-window-buffer increments it.");
4532
4533 DEFVAR_PER_BUFFER ("buffer-display-time",
4534 &current_buffer->display_time, Qnil,
4535 "Time stamp updated each time this buffer is displayed in a window.\n\
4536This variable is always local in all buffers.\n\
4537The function `set-window-buffer' updates this variable\n\
4538to the value obtained by calling `current-time'.\n\
4539If the buffer has never been shown in a window, the value is nil.");
7962a441 4540
c48f61ef 4541 DEFVAR_LISP ("transient-mark-mode", &Vtransient_mark_mode,
319c537c
RS
4542 "*Non-nil means deactivate the mark when the buffer contents change.\n\
4543Non-nil also enables highlighting of the region whenever the mark is active.\n\
4544The variable `highlight-nonselected-windows' controls whether to highlight\n\
4545all windows or just the selected window.");
c48f61ef
RS
4546 Vtransient_mark_mode = Qnil;
4547
0a4469c9 4548 DEFVAR_LISP ("inhibit-read-only", &Vinhibit_read_only,
a96b68f1
RS
4549 "*Non-nil means disregard read-only status of buffers or characters.\n\
4550If the value is t, disregard `buffer-read-only' and all `read-only'\n\
4551text properties. If the value is a list, disregard `buffer-read-only'\n\
4552and disregard a `read-only' text property if the property value\n\
4553is a member of the list.");
4554 Vinhibit_read_only = Qnil;
4555
dcdffbf6
RS
4556 DEFVAR_LISP ("kill-buffer-query-functions", &Vkill_buffer_query_functions,
4557 "List of functions called with no args to query before killing a buffer.");
4558 Vkill_buffer_query_functions = Qnil;
4559
0dc88e60 4560 defsubr (&Sbuffer_live_p);
1ab256cb
RM
4561 defsubr (&Sbuffer_list);
4562 defsubr (&Sget_buffer);
4563 defsubr (&Sget_file_buffer);
4564 defsubr (&Sget_buffer_create);
336cd056 4565 defsubr (&Smake_indirect_buffer);
01050cb5 4566 defsubr (&Sgenerate_new_buffer_name);
1ab256cb
RM
4567 defsubr (&Sbuffer_name);
4568/*defsubr (&Sbuffer_number);*/
4569 defsubr (&Sbuffer_file_name);
336cd056 4570 defsubr (&Sbuffer_base_buffer);
1ab256cb
RM
4571 defsubr (&Sbuffer_local_variables);
4572 defsubr (&Sbuffer_modified_p);
4573 defsubr (&Sset_buffer_modified_p);
4574 defsubr (&Sbuffer_modified_tick);
4575 defsubr (&Srename_buffer);
4576 defsubr (&Sother_buffer);
4577 defsubr (&Sbuffer_disable_undo);
4578 defsubr (&Sbuffer_enable_undo);
4579 defsubr (&Skill_buffer);
a9ee7a59 4580 defsubr (&Sset_buffer_major_mode);
1ab256cb
RM
4581 defsubr (&Sswitch_to_buffer);
4582 defsubr (&Spop_to_buffer);
4583 defsubr (&Scurrent_buffer);
4584 defsubr (&Sset_buffer);
4585 defsubr (&Sbarf_if_buffer_read_only);
4586 defsubr (&Sbury_buffer);
3ac81adb
RS
4587 defsubr (&Serase_buffer);
4588 defsubr (&Sset_buffer_multibyte);
1ab256cb 4589 defsubr (&Skill_all_local_variables);
2eec3b4e 4590
52f8ec73 4591 defsubr (&Soverlayp);
2eec3b4e
RS
4592 defsubr (&Smake_overlay);
4593 defsubr (&Sdelete_overlay);
4594 defsubr (&Smove_overlay);
8ebafa8d
JB
4595 defsubr (&Soverlay_start);
4596 defsubr (&Soverlay_end);
4597 defsubr (&Soverlay_buffer);
4598 defsubr (&Soverlay_properties);
2eec3b4e 4599 defsubr (&Soverlays_at);
74514898 4600 defsubr (&Soverlays_in);
2eec3b4e 4601 defsubr (&Snext_overlay_change);
239c932b 4602 defsubr (&Sprevious_overlay_change);
2eec3b4e
RS
4603 defsubr (&Soverlay_recenter);
4604 defsubr (&Soverlay_lists);
4605 defsubr (&Soverlay_get);
4606 defsubr (&Soverlay_put);
1ab256cb
RM
4607}
4608
dfcf069d 4609void
1ab256cb
RM
4610keys_of_buffer ()
4611{
4612 initial_define_key (control_x_map, 'b', "switch-to-buffer");
4613 initial_define_key (control_x_map, 'k', "kill-buffer");
4158c17d
RM
4614
4615 /* This must not be in syms_of_buffer, because Qdisabled is not
4616 initialized when that function gets called. */
4617 Fput (intern ("erase-buffer"), Qdisabled, Qt);
1ab256cb 4618}