(define-charset): New args :min-code and :max-code.
[bpt/emacs.git] / src / buffer.c
CommitLineData
1ab256cb 1/* Buffer manipulation primitives for GNU Emacs.
cab1603f 2 Copyright (C) 1985,86,87,88,89,93,94,95,97,98, 1999, 2000, 2001, 2002
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 21
68c45bf0 22#include <config.h>
1ab256cb 23
2381d133
JB
24#include <sys/types.h>
25#include <sys/stat.h>
1ab256cb 26#include <sys/param.h>
9dde47f5 27#include <errno.h>
15e7873a 28#include <stdio.h>
9dde47f5 29
2538fae4 30#ifndef USE_CRT_DLL
9dde47f5 31extern int errno;
2538fae4 32#endif
1ab256cb
RM
33
34#ifndef MAXPATHLEN
35/* in 4.1, param.h fails to define this. */
36#define MAXPATHLEN 1024
37#endif /* not MAXPATHLEN */
38
dfcf069d
AS
39#ifdef HAVE_UNISTD_H
40#include <unistd.h>
41#endif
7ee72033 42
1ab256cb 43#include "lisp.h"
21cf4cf8 44#include "intervals.h"
1ab256cb
RM
45#include "window.h"
46#include "commands.h"
47#include "buffer.h"
8f348ed5 48#include "character.h"
28e969dd 49#include "region-cache.h"
1ab256cb 50#include "indent.h"
d014bf88 51#include "blockinput.h"
2538fae4 52#include "keyboard.h"
e35f6ff7 53#include "keymap.h"
08460cd4 54#include "frame.h"
1ab256cb
RM
55
56struct buffer *current_buffer; /* the current buffer */
57
58/* First buffer in chain of all buffers (in reverse order of creation).
59 Threaded through ->next. */
60
61struct buffer *all_buffers;
62
63/* This structure holds the default values of the buffer-local variables
64 defined with DEFVAR_PER_BUFFER, that have special slots in each buffer.
65 The default value occupies the same slot in this structure
66 as an individual buffer's value occupies in that buffer.
67 Setting the default value also goes through the alist of buffers
68 and stores into each buffer that does not say it has a local value. */
69
70struct buffer buffer_defaults;
71
72/* A Lisp_Object pointer to the above, used for staticpro */
73
74static Lisp_Object Vbuffer_defaults;
75
76/* This structure marks which slots in a buffer have corresponding
77 default values in buffer_defaults.
78 Each such slot has a nonzero value in this structure.
79 The value has only one nonzero bit.
80
81 When a buffer has its own local value for a slot,
7c02e886
GM
82 the entry for that slot (found in the same slot in this structure)
83 is turned on in the buffer's local_flags array.
1ab256cb
RM
84
85 If a slot in this structure is -1, then even though there may
86 be a DEFVAR_PER_BUFFER for the slot, there is no default value for it;
87 and the corresponding slot in buffer_defaults is not used.
88
89 If a slot is -2, then there is no DEFVAR_PER_BUFFER for it,
90 but there is a default value which is copied into each buffer.
91
92 If a slot in this structure is negative, then even though there may
93 be a DEFVAR_PER_BUFFER for the slot, there is no default value for it;
94 and the corresponding slot in buffer_defaults is not used.
95
96 If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is
97 zero, that is a bug */
98
99struct buffer buffer_local_flags;
100
101/* This structure holds the names of symbols whose values may be
102 buffer-local. It is indexed and accessed in the same way as the above. */
103
104struct buffer buffer_local_symbols;
105/* A Lisp_Object pointer to the above, used for staticpro */
106static Lisp_Object Vbuffer_local_symbols;
107
0fa3ba92
JB
108/* This structure holds the required types for the values in the
109 buffer-local slots. If a slot contains Qnil, then the
110 corresponding buffer slot may contain a value of any type. If a
111 slot contains an integer, then prospective values' tags must be
1bf08baf
KH
112 equal to that integer (except nil is always allowed).
113 When a tag does not match, the function
114 buffer_slot_type_mismatch will signal an error.
115
116 If a slot here contains -1, the corresponding variable is read-only. */
0fa3ba92
JB
117struct buffer buffer_local_types;
118
13de9290
RS
119/* Flags indicating which built-in buffer-local variables
120 are permanent locals. */
7313acd0 121static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
7c02e886
GM
122
123/* Number of per-buffer variables used. */
124
7313acd0 125int last_per_buffer_idx;
13de9290 126
1ab256cb 127Lisp_Object Fset_buffer ();
01050cb5 128void set_buffer_internal ();
c7aa5005 129void set_buffer_internal_1 ();
173f2a64 130static void call_overlay_mod_hooks ();
2f3f993b 131static void swap_out_buffer_local_variables ();
13de9290 132static void reset_buffer_local_variables ();
1ab256cb
RM
133
134/* Alist of all buffer names vs the buffers. */
135/* This used to be a variable, but is no longer,
136 to prevent lossage due to user rplac'ing this alist or its elements. */
137Lisp_Object Vbuffer_alist;
138
139/* Functions to call before and after each text change. */
5f079267
RS
140Lisp_Object Vbefore_change_functions;
141Lisp_Object Vafter_change_functions;
1ab256cb 142
c48f61ef
RS
143Lisp_Object Vtransient_mark_mode;
144
a96b68f1
RS
145/* t means ignore all read-only text properties.
146 A list means ignore such a property if its value is a member of the list.
147 Any non-nil value means ignore buffer-read-only. */
148Lisp_Object Vinhibit_read_only;
149
dcdffbf6
RS
150/* List of functions to call that can query about killing a buffer.
151 If any of these functions returns nil, we don't kill it. */
152Lisp_Object Vkill_buffer_query_functions;
153
dbc4e1c1
JB
154/* List of functions to call before changing an unmodified buffer. */
155Lisp_Object Vfirst_change_hook;
22378665 156
dbc4e1c1 157Lisp_Object Qfirst_change_hook;
22378665
RS
158Lisp_Object Qbefore_change_functions;
159Lisp_Object Qafter_change_functions;
1ab256cb 160
7775635d
KH
161/* If nonzero, all modification hooks are suppressed. */
162int inhibit_modification_hooks;
163
1ab256cb
RM
164Lisp_Object Qfundamental_mode, Qmode_class, Qpermanent_local;
165
166Lisp_Object Qprotected_field;
167
168Lisp_Object QSFundamental; /* A string "Fundamental" */
169
170Lisp_Object Qkill_buffer_hook;
171
5fe0b67e
RS
172Lisp_Object Qget_file_buffer;
173
52f8ec73
JB
174Lisp_Object Qoverlayp;
175
bbbe9545 176Lisp_Object Qpriority, Qwindow, Qevaporate, Qbefore_string, Qafter_string;
5985d248 177
294d215f
RS
178Lisp_Object Qmodification_hooks;
179Lisp_Object Qinsert_in_front_hooks;
180Lisp_Object Qinsert_behind_hooks;
181
b86af064
GM
182static void alloc_buffer_text P_ ((struct buffer *, size_t));
183static void free_buffer_text P_ ((struct buffer *b));
04e4cb3a 184static Lisp_Object copy_overlays P_ ((struct buffer *, Lisp_Object));
26f545d7 185static void modify_overlay P_ ((struct buffer *, int, int));
b86af064 186
cab1603f 187extern char * emacs_strerror P_ ((int));
b86af064 188
1ab256cb
RM
189/* For debugging; temporary. See set_buffer_internal. */
190/* Lisp_Object Qlisp_mode, Vcheck_symbol; */
191
01136e9b 192void
1ab256cb
RM
193nsberror (spec)
194 Lisp_Object spec;
195{
a7a60ce9 196 if (STRINGP (spec))
1ab256cb
RM
197 error ("No buffer named %s", XSTRING (spec)->data);
198 error ("Invalid buffer argument");
199}
200\f
0dc88e60 201DEFUN ("buffer-live-p", Fbuffer_live_p, Sbuffer_live_p, 1, 1, 0,
7ee72033
MB
202 doc: /* Return non-nil if OBJECT is a buffer which has not been killed.
203Value is nil if OBJECT is not a buffer or if it has been killed. */)
204 (object)
0dc88e60
RS
205 Lisp_Object object;
206{
207 return ((BUFFERP (object) && ! NILP (XBUFFER (object)->name))
208 ? Qt : Qnil);
209}
210
08460cd4 211DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0,
7ee72033
MB
212 doc: /* Return a list of all existing live buffers.
213If the optional arg FRAME is a frame, we return that frame's buffer list. */)
214 (frame)
08460cd4 215 Lisp_Object frame;
1ab256cb 216{
08460cd4
RS
217 Lisp_Object framelist, general;
218 general = Fmapcar (Qcdr, Vbuffer_alist);
219
220 if (FRAMEP (frame))
221 {
222 Lisp_Object tail;
223
b7826503 224 CHECK_FRAME (frame);
08460cd4
RS
225
226 framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
227
228 /* Remove from GENERAL any buffer that duplicates one in FRAMELIST. */
229 tail = framelist;
230 while (! NILP (tail))
231 {
7539e11f
KR
232 general = Fdelq (XCAR (tail), general);
233 tail = XCDR (tail);
08460cd4
RS
234 }
235 return nconc2 (framelist, general);
236 }
237
238 return general;
1ab256cb
RM
239}
240
04ae1b48
RS
241/* Like Fassoc, but use Fstring_equal to compare
242 (which ignores text properties),
243 and don't ever QUIT. */
244
245static Lisp_Object
246assoc_ignore_text_properties (key, list)
247 register Lisp_Object key;
248 Lisp_Object list;
249{
250 register Lisp_Object tail;
251 for (tail = list; !NILP (tail); tail = Fcdr (tail))
252 {
253 register Lisp_Object elt, tem;
254 elt = Fcar (tail);
255 tem = Fstring_equal (Fcar (elt), key);
256 if (!NILP (tem))
257 return elt;
258 }
259 return Qnil;
260}
261
1ab256cb 262DEFUN ("get-buffer", Fget_buffer, Sget_buffer, 1, 1, 0,
7ee72033 263 doc: /* Return the buffer named NAME (a string).
018ba359 264If there is no live buffer named NAME, return nil.
7ee72033
MB
265NAME may also be a buffer; if so, the value is that buffer. */)
266 (name)
1ab256cb
RM
267 register Lisp_Object name;
268{
a7a60ce9 269 if (BUFFERP (name))
1ab256cb 270 return name;
b7826503 271 CHECK_STRING (name);
1ab256cb 272
04ae1b48 273 return Fcdr (assoc_ignore_text_properties (name, Vbuffer_alist));
1ab256cb
RM
274}
275
276DEFUN ("get-file-buffer", Fget_file_buffer, Sget_file_buffer, 1, 1, 0,
7ee72033 277 doc: /* Return the buffer visiting file FILENAME (a string).
018ba359
PJ
278The buffer's `buffer-file-name' must match exactly the expansion of FILENAME.
279If there is no such live buffer, return nil.
7ee72033
MB
280See also `find-buffer-visiting'. */)
281 (filename)
1ab256cb
RM
282 register Lisp_Object filename;
283{
284 register Lisp_Object tail, buf, tem;
5fe0b67e
RS
285 Lisp_Object handler;
286
b7826503 287 CHECK_STRING (filename);
1ab256cb
RM
288 filename = Fexpand_file_name (filename, Qnil);
289
5fe0b67e
RS
290 /* If the file name has special constructs in it,
291 call the corresponding file handler. */
a617e913 292 handler = Ffind_file_name_handler (filename, Qget_file_buffer);
5fe0b67e
RS
293 if (!NILP (handler))
294 return call2 (handler, Qget_file_buffer, filename);
295
7539e11f 296 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
1ab256cb 297 {
7539e11f 298 buf = Fcdr (XCAR (tail));
a7a60ce9
KH
299 if (!BUFFERP (buf)) continue;
300 if (!STRINGP (XBUFFER (buf)->filename)) continue;
1ab256cb 301 tem = Fstring_equal (XBUFFER (buf)->filename, filename);
265a9e55 302 if (!NILP (tem))
1ab256cb
RM
303 return buf;
304 }
305 return Qnil;
306}
307
52e01189
RS
308Lisp_Object
309get_truename_buffer (filename)
310 register Lisp_Object filename;
311{
312 register Lisp_Object tail, buf, tem;
313
7539e11f 314 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
52e01189 315 {
7539e11f 316 buf = Fcdr (XCAR (tail));
52e01189
RS
317 if (!BUFFERP (buf)) continue;
318 if (!STRINGP (XBUFFER (buf)->file_truename)) continue;
319 tem = Fstring_equal (XBUFFER (buf)->file_truename, filename);
320 if (!NILP (tem))
321 return buf;
322 }
323 return Qnil;
324}
325
1ab256cb
RM
326/* Incremented for each buffer created, to assign the buffer number. */
327int buffer_count;
328
329DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 1, 0,
7ee72033 330 doc: /* Return the buffer named NAME, or create such a buffer and return it.
018ba359
PJ
331A new buffer is created if there is no live buffer named NAME.
332If NAME starts with a space, the new buffer does not keep undo information.
333If NAME is a buffer instead of a string, then it is the value returned.
7ee72033
MB
334The value is never nil. */)
335 (name)
1ab256cb
RM
336 register Lisp_Object name;
337{
a9ee7a59 338 register Lisp_Object buf;
1ab256cb
RM
339 register struct buffer *b;
340
341 buf = Fget_buffer (name);
265a9e55 342 if (!NILP (buf))
1ab256cb
RM
343 return buf;
344
31cd83e9
KH
345 if (XSTRING (name)->size == 0)
346 error ("Empty string for buffer name is not allowed");
347
a21260d9 348 b = (struct buffer *) allocate_buffer ();
1ab256cb 349
336cd056
RS
350 b->size = sizeof (struct buffer) / sizeof (EMACS_INT);
351
352 /* An ordinary buffer uses its own struct buffer_text. */
353 b->text = &b->own_text;
354 b->base_buffer = 0;
355
1ab256cb 356 BUF_GAP_SIZE (b) = 20;
9ac0d9e0 357 BLOCK_INPUT;
3b06f880
KH
358 /* We allocate extra 1-byte at the tail and keep it always '\0' for
359 anchoring a search. */
b86af064 360 alloc_buffer_text (b, BUF_GAP_SIZE (b) + 1);
9ac0d9e0 361 UNBLOCK_INPUT;
1ab256cb 362 if (! BUF_BEG_ADDR (b))
81841847 363 buffer_memory_full ();
1ab256cb
RM
364
365 BUF_PT (b) = 1;
366 BUF_GPT (b) = 1;
367 BUF_BEGV (b) = 1;
368 BUF_ZV (b) = 1;
369 BUF_Z (b) = 1;
3f236a40
RS
370 BUF_PT_BYTE (b) = 1;
371 BUF_GPT_BYTE (b) = 1;
372 BUF_BEGV_BYTE (b) = 1;
373 BUF_ZV_BYTE (b) = 1;
374 BUF_Z_BYTE (b) = 1;
1ab256cb 375 BUF_MODIFF (b) = 1;
2509d356 376 BUF_OVERLAY_MODIFF (b) = 1;
336cd056
RS
377 BUF_SAVE_MODIFF (b) = 1;
378 BUF_INTERVALS (b) = 0;
b5a225b4
GM
379 BUF_UNCHANGED_MODIFIED (b) = 1;
380 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1;
381 BUF_END_UNCHANGED (b) = 0;
382 BUF_BEG_UNCHANGED (b) = 0;
3b06f880 383 *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */
1ab256cb 384
28e969dd
JB
385 b->newline_cache = 0;
386 b->width_run_cache = 0;
387 b->width_table = Qnil;
b5a225b4 388 b->prevent_redisplay_optimizations_p = 1;
28e969dd 389
1ab256cb
RM
390 /* Put this on the chain of all buffers including killed ones. */
391 b->next = all_buffers;
392 all_buffers = b;
393
336cd056
RS
394 /* An ordinary buffer normally doesn't need markers
395 to handle BEGV and ZV. */
396 b->pt_marker = Qnil;
397 b->begv_marker = Qnil;
398 b->zv_marker = Qnil;
04ae1b48
RS
399
400 name = Fcopy_sequence (name);
a9800ae8 401 XSTRING (name)->intervals = NULL_INTERVAL;
1ab256cb 402 b->name = name;
04ae1b48 403
1ab256cb
RM
404 if (XSTRING (name)->data[0] != ' ')
405 b->undo_list = Qnil;
406 else
407 b->undo_list = Qt;
408
409 reset_buffer (b);
13de9290 410 reset_buffer_local_variables (b, 1);
1ab256cb
RM
411
412 /* Put this in the alist of all live buffers. */
67180c6a 413 XSETBUFFER (buf, b);
1ab256cb
RM
414 Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil));
415
416 b->mark = Fmake_marker ();
336cd056
RS
417 BUF_MARKERS (b) = Qnil;
418 b->name = name;
419 return buf;
420}
421
7e9d5818 422
04e4cb3a
GM
423/* Return a list of overlays which is a copy of the overlay list
424 LIST, but for buffer B. */
425
426static Lisp_Object
427copy_overlays (b, list)
428 struct buffer *b;
429 Lisp_Object list;
430{
431 Lisp_Object result, buffer;
432
433 XSETBUFFER (buffer, b);
434
435 for (result = Qnil; CONSP (list); list = XCDR (list))
436 {
437 Lisp_Object overlay, start, end, old_overlay;
438 int charpos;
439
440 old_overlay = XCAR (list);
441 charpos = marker_position (OVERLAY_START (old_overlay));
442 start = Fmake_marker ();
db3a49a6 443 Fset_marker (start, make_number (charpos), buffer);
04e4cb3a
GM
444 XMARKER (start)->insertion_type
445 = XMARKER (OVERLAY_START (old_overlay))->insertion_type;
446
447 charpos = marker_position (OVERLAY_END (old_overlay));
448 end = Fmake_marker ();
db3a49a6 449 Fset_marker (end, make_number (charpos), buffer);
04e4cb3a
GM
450 XMARKER (end)->insertion_type
451 = XMARKER (OVERLAY_END (old_overlay))->insertion_type;
452
453 overlay = allocate_misc ();
454 XMISCTYPE (overlay) = Lisp_Misc_Overlay;
455 OVERLAY_START (overlay) = start;
456 OVERLAY_END (overlay) = end;
457 OVERLAY_PLIST (overlay) = Fcopy_sequence (OVERLAY_PLIST (old_overlay));
458
459 result = Fcons (overlay, result);
460 }
461
462 return Fnreverse (result);
463}
464
465
7e9d5818
GM
466/* Clone per-buffer values of buffer FROM.
467
468 Buffer TO gets the same per-buffer values as FROM, with the
469 following exceptions: (1) TO's name is left untouched, (2) markers
470 are copied and made to refer to TO, and (3) overlay lists are
471 copied. */
472
473static void
474clone_per_buffer_values (from, to)
475 struct buffer *from, *to;
476{
477 Lisp_Object to_buffer;
478 int offset;
479
480 XSETBUFFER (to_buffer, to);
481
482 for (offset = PER_BUFFER_VAR_OFFSET (name) + sizeof (Lisp_Object);
483 offset < sizeof *to;
484 offset += sizeof (Lisp_Object))
485 {
486 Lisp_Object obj;
487
488 obj = PER_BUFFER_VALUE (from, offset);
489 if (MARKERP (obj))
490 {
491 struct Lisp_Marker *m = XMARKER (obj);
492 obj = Fmake_marker ();
493 XMARKER (obj)->insertion_type = m->insertion_type;
494 set_marker_both (obj, to_buffer, m->charpos, m->bytepos);
495 }
496
497 PER_BUFFER_VALUE (to, offset) = obj;
498 }
499
7e9d5818 500 bcopy (from->local_flags, to->local_flags, sizeof to->local_flags);
04e4cb3a
GM
501
502 to->overlays_before = copy_overlays (to, from->overlays_before);
503 to->overlays_after = copy_overlays (to, from->overlays_after);
7e9d5818
GM
504}
505
506
507DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, Smake_indirect_buffer,
508 2, 3,
193c3837 509 "bMake indirect buffer (to buffer): \nBName of indirect buffer: ",
7ee72033 510 doc: /* Create and return an indirect buffer for buffer BASE-BUFFER, named NAME.
018ba359
PJ
511BASE-BUFFER should be an existing buffer (or buffer name).
512NAME should be a string which is not the name of an existing buffer.
513Optional argument CLONE non-nil means preserve BASE-BUFFER's state,
514such as major and minor modes, in the indirect buffer.
7ee72033
MB
515CLONE nil means the indirect buffer's state is reset to default values. */)
516 (base_buffer, name, clone)
7e9d5818 517 Lisp_Object base_buffer, name, clone;
336cd056 518{
7e9d5818
GM
519 Lisp_Object buf;
520 struct buffer *b;
336cd056
RS
521
522 buf = Fget_buffer (name);
523 if (!NILP (buf))
524 error ("Buffer name `%s' is in use", XSTRING (name)->data);
525
526 base_buffer = Fget_buffer (base_buffer);
527 if (NILP (base_buffer))
1dd6a7ad 528 error ("No such buffer: `%s'", XSTRING (name)->data);
336cd056
RS
529
530 if (XSTRING (name)->size == 0)
531 error ("Empty string for buffer name is not allowed");
532
a21260d9 533 b = (struct buffer *) allocate_buffer ();
336cd056
RS
534 b->size = sizeof (struct buffer) / sizeof (EMACS_INT);
535
536 if (XBUFFER (base_buffer)->base_buffer)
537 b->base_buffer = XBUFFER (base_buffer)->base_buffer;
538 else
539 b->base_buffer = XBUFFER (base_buffer);
540
541 /* Use the base buffer's text object. */
542 b->text = b->base_buffer->text;
543
544 BUF_BEGV (b) = BUF_BEGV (b->base_buffer);
545 BUF_ZV (b) = BUF_ZV (b->base_buffer);
546 BUF_PT (b) = BUF_PT (b->base_buffer);
3f236a40
RS
547 BUF_BEGV_BYTE (b) = BUF_BEGV_BYTE (b->base_buffer);
548 BUF_ZV_BYTE (b) = BUF_ZV_BYTE (b->base_buffer);
549 BUF_PT_BYTE (b) = BUF_PT_BYTE (b->base_buffer);
336cd056
RS
550
551 b->newline_cache = 0;
552 b->width_run_cache = 0;
553 b->width_table = Qnil;
554
555 /* Put this on the chain of all buffers including killed ones. */
556 b->next = all_buffers;
557 all_buffers = b;
558
559 name = Fcopy_sequence (name);
a9800ae8 560 XSTRING (name)->intervals = NULL_INTERVAL;
336cd056
RS
561 b->name = name;
562
563 reset_buffer (b);
13de9290 564 reset_buffer_local_variables (b, 1);
336cd056
RS
565
566 /* Put this in the alist of all live buffers. */
567 XSETBUFFER (buf, b);
568 Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil));
569
570 b->mark = Fmake_marker ();
1ab256cb 571 b->name = name;
336cd056 572
abc9d959
RS
573 /* The multibyte status belongs to the base buffer. */
574 b->enable_multibyte_characters = b->base_buffer->enable_multibyte_characters;
575
336cd056
RS
576 /* Make sure the base buffer has markers for its narrowing. */
577 if (NILP (b->base_buffer->pt_marker))
578 {
579 b->base_buffer->pt_marker = Fmake_marker ();
3f236a40
RS
580 set_marker_both (b->base_buffer->pt_marker, base_buffer,
581 BUF_PT (b->base_buffer),
582 BUF_PT_BYTE (b->base_buffer));
336cd056
RS
583 }
584 if (NILP (b->base_buffer->begv_marker))
585 {
586 b->base_buffer->begv_marker = Fmake_marker ();
3f236a40
RS
587 set_marker_both (b->base_buffer->begv_marker, base_buffer,
588 BUF_BEGV (b->base_buffer),
589 BUF_BEGV_BYTE (b->base_buffer));
336cd056
RS
590 }
591 if (NILP (b->base_buffer->zv_marker))
592 {
593 b->base_buffer->zv_marker = Fmake_marker ();
3f236a40
RS
594 set_marker_both (b->base_buffer->zv_marker, base_buffer,
595 BUF_ZV (b->base_buffer),
596 BUF_ZV_BYTE (b->base_buffer));
26d84681 597 XMARKER (b->base_buffer->zv_marker)->insertion_type = 1;
336cd056
RS
598 }
599
7e9d5818
GM
600 if (NILP (clone))
601 {
602 /* Give the indirect buffer markers for its narrowing. */
603 b->pt_marker = Fmake_marker ();
604 set_marker_both (b->pt_marker, buf, BUF_PT (b), BUF_PT_BYTE (b));
605 b->begv_marker = Fmake_marker ();
606 set_marker_both (b->begv_marker, buf, BUF_BEGV (b), BUF_BEGV_BYTE (b));
607 b->zv_marker = Fmake_marker ();
608 set_marker_both (b->zv_marker, buf, BUF_ZV (b), BUF_ZV_BYTE (b));
609 XMARKER (b->zv_marker)->insertion_type = 1;
610 }
611 else
612 clone_per_buffer_values (b->base_buffer, b);
336cd056 613
a9ee7a59 614 return buf;
1ab256cb
RM
615}
616
bcd40520
RS
617/* Reinitialize everything about a buffer except its name and contents
618 and local variables. */
1ab256cb
RM
619
620void
621reset_buffer (b)
622 register struct buffer *b;
623{
624 b->filename = Qnil;
f6ed2e84 625 b->file_truename = Qnil;
1ab256cb
RM
626 b->directory = (current_buffer) ? current_buffer->directory : Qnil;
627 b->modtime = 0;
8d7a4592 628 XSETFASTINT (b->save_length, 0);
1ab256cb 629 b->last_window_start = 1;
8b264726 630 /* It is more conservative to start out "changed" than "unchanged". */
b5a225b4
GM
631 b->clip_changed = 0;
632 b->prevent_redisplay_optimizations_p = 1;
1ab256cb
RM
633 b->backed_up = Qnil;
634 b->auto_save_modified = 0;
84f6bcba 635 b->auto_save_failure_time = -1;
1ab256cb
RM
636 b->auto_save_file_name = Qnil;
637 b->read_only = Qnil;
2eec3b4e
RS
638 b->overlays_before = Qnil;
639 b->overlays_after = Qnil;
8d7a4592 640 XSETFASTINT (b->overlay_center, 1);
dfda7a7f 641 b->mark_active = Qnil;
943e065b 642 b->point_before_scroll = Qnil;
be9aafdd 643 b->file_format = Qnil;
0dc6f165 644 b->last_selected_window = Qnil;
7962a441 645 XSETINT (b->display_count, 0);
3fd364db 646 b->display_time = Qnil;
1bf08baf 647 b->enable_multibyte_characters = buffer_defaults.enable_multibyte_characters;
bb2ec976 648 b->cursor_type = buffer_defaults.cursor_type;
a3bbced0 649 b->extra_line_spacing = buffer_defaults.extra_line_spacing;
0522997d
RS
650
651 b->display_error_modiff = 0;
1ab256cb
RM
652}
653
bcd40520
RS
654/* Reset buffer B's local variables info.
655 Don't use this on a buffer that has already been in use;
656 it does not treat permanent locals consistently.
13de9290
RS
657 Instead, use Fkill_all_local_variables.
658
659 If PERMANENT_TOO is 1, then we reset permanent built-in
660 buffer-local variables. If PERMANENT_TOO is 0,
661 we preserve those. */
bcd40520 662
13de9290
RS
663static void
664reset_buffer_local_variables (b, permanent_too)
1ab256cb 665 register struct buffer *b;
13de9290 666 int permanent_too;
1ab256cb
RM
667{
668 register int offset;
7c02e886 669 int i;
1ab256cb
RM
670
671 /* Reset the major mode to Fundamental, together with all the
672 things that depend on the major mode.
673 default-major-mode is handled at a higher level.
674 We ignore it here. */
675 b->major_mode = Qfundamental_mode;
676 b->keymap = Qnil;
677 b->abbrev_table = Vfundamental_mode_abbrev_table;
678 b->mode_name = QSFundamental;
679 b->minor_modes = Qnil;
3446af9c
RS
680
681 /* If the standard case table has been altered and invalidated,
682 fix up its insides first. */
683 if (! (CHAR_TABLE_P (XCHAR_TABLE (Vascii_downcase_table)->extras[0])
684 && CHAR_TABLE_P (XCHAR_TABLE (Vascii_downcase_table)->extras[1])
685 && CHAR_TABLE_P (XCHAR_TABLE (Vascii_downcase_table)->extras[2])))
686 Fset_standard_case_table (Vascii_downcase_table);
687
1ab256cb 688 b->downcase_table = Vascii_downcase_table;
1e9b6335
RS
689 b->upcase_table = XCHAR_TABLE (Vascii_downcase_table)->extras[0];
690 b->case_canon_table = XCHAR_TABLE (Vascii_downcase_table)->extras[1];
691 b->case_eqv_table = XCHAR_TABLE (Vascii_downcase_table)->extras[2];
3cb719bd 692 b->invisibility_spec = Qt;
2e716096
RS
693#ifndef DOS_NT
694 b->buffer_file_type = Qnil;
695#endif
3cb719bd 696
1ab256cb
RM
697#if 0
698 b->sort_table = XSTRING (Vascii_sort_table);
699 b->folding_sort_table = XSTRING (Vascii_folding_sort_table);
700#endif /* 0 */
701
13de9290 702 /* Reset all (or most) per-buffer variables to their defaults. */
1ab256cb 703 b->local_var_alist = Qnil;
7313acd0 704 for (i = 0; i < last_per_buffer_idx; ++i)
7c02e886 705 if (permanent_too || buffer_permanent_local_flags[i] == 0)
7313acd0 706 SET_PER_BUFFER_VALUE_P (b, i, 0);
1ab256cb
RM
707
708 /* For each slot that has a default value,
709 copy that into the slot. */
710
7313acd0 711 for (offset = PER_BUFFER_VAR_OFFSET (name);
7c02e886
GM
712 offset < sizeof *b;
713 offset += sizeof (Lisp_Object))
aab80822 714 {
7313acd0 715 int idx = PER_BUFFER_IDX (offset);
7c02e886
GM
716 if ((idx > 0
717 && (permanent_too
718 || buffer_permanent_local_flags[idx] == 0))
719 /* Is -2 used anywhere? */
720 || idx == -2)
7313acd0 721 PER_BUFFER_VALUE (b, offset) = PER_BUFFER_DEFAULT (offset);
aab80822 722 }
1ab256cb
RM
723}
724
01050cb5
RM
725/* We split this away from generate-new-buffer, because rename-buffer
726 and set-visited-file-name ought to be able to use this to really
727 rename the buffer properly. */
728
729DEFUN ("generate-new-buffer-name", Fgenerate_new_buffer_name, Sgenerate_new_buffer_name,
efc7e75f 730 1, 2, 0,
7ee72033 731 doc: /* Return a string that is the name of no existing buffer based on NAME.
018ba359
PJ
732If there is no live buffer named NAME, then return NAME.
733Otherwise modify name by appending `<NUMBER>', incrementing NUMBER
734until an unused name is found, and then return that name.
735Optional second argument IGNORE specifies a name that is okay to use
736\(if it is in the sequence to be tried)
7ee72033
MB
737even if a buffer with that name exists. */)
738 (name, ignore)
c273e647 739 register Lisp_Object name, ignore;
1ab256cb
RM
740{
741 register Lisp_Object gentemp, tem;
742 int count;
743 char number[10];
744
b7826503 745 CHECK_STRING (name);
1ab256cb
RM
746
747 tem = Fget_buffer (name);
265a9e55 748 if (NILP (tem))
01050cb5 749 return name;
1ab256cb
RM
750
751 count = 1;
752 while (1)
753 {
754 sprintf (number, "<%d>", ++count);
755 gentemp = concat2 (name, build_string (number));
638e4fc3 756 tem = Fstring_equal (gentemp, ignore);
c273e647
RS
757 if (!NILP (tem))
758 return gentemp;
1ab256cb 759 tem = Fget_buffer (gentemp);
265a9e55 760 if (NILP (tem))
01050cb5 761 return gentemp;
1ab256cb
RM
762 }
763}
764
765\f
766DEFUN ("buffer-name", Fbuffer_name, Sbuffer_name, 0, 1, 0,
7ee72033
MB
767 doc: /* Return the name of BUFFER, as a string.
768With no argument or nil as argument, return the name of the current buffer. */)
769 (buffer)
1ab256cb
RM
770 register Lisp_Object buffer;
771{
265a9e55 772 if (NILP (buffer))
1ab256cb 773 return current_buffer->name;
b7826503 774 CHECK_BUFFER (buffer);
1ab256cb
RM
775 return XBUFFER (buffer)->name;
776}
777
778DEFUN ("buffer-file-name", Fbuffer_file_name, Sbuffer_file_name, 0, 1, 0,
7ee72033
MB
779 doc: /* Return name of file BUFFER is visiting, or nil if none.
780No argument or nil as argument means use the current buffer. */)
781 (buffer)
1ab256cb
RM
782 register Lisp_Object buffer;
783{
265a9e55 784 if (NILP (buffer))
1ab256cb 785 return current_buffer->filename;
b7826503 786 CHECK_BUFFER (buffer);
1ab256cb
RM
787 return XBUFFER (buffer)->filename;
788}
789
336cd056
RS
790DEFUN ("buffer-base-buffer", Fbuffer_base_buffer, Sbuffer_base_buffer,
791 0, 1, 0,
7ee72033
MB
792 doc: /* Return the base buffer of indirect buffer BUFFER.
793If BUFFER is not indirect, return nil. */)
794 (buffer)
336cd056
RS
795 register Lisp_Object buffer;
796{
797 struct buffer *base;
798 Lisp_Object base_buffer;
799
800 if (NILP (buffer))
801 base = current_buffer->base_buffer;
802 else
803 {
b7826503 804 CHECK_BUFFER (buffer);
336cd056
RS
805 base = XBUFFER (buffer)->base_buffer;
806 }
807
808 if (! base)
809 return Qnil;
810 XSETBUFFER (base_buffer, base);
811 return base_buffer;
812}
813
79aa712d
RS
814DEFUN ("buffer-local-value", Fbuffer_local_value,
815 Sbuffer_local_value, 2, 2, 0,
816 doc: /* Return the value of VARIABLE in BUFFER.
817If VARIABLE does not have a buffer-local binding in BUFFER, the value
818is the default binding of variable. */)
819 (symbol, buffer)
820 register Lisp_Object symbol;
821 register Lisp_Object buffer;
822{
823 register struct buffer *buf;
824 register Lisp_Object result;
825
ae69175b
RS
826 CHECK_SYMBOL (symbol);
827 CHECK_BUFFER (buffer);
79aa712d
RS
828 buf = XBUFFER (buffer);
829
830 /* Look in local_var_list */
831 result = Fassoc (symbol, buf->local_var_alist);
832 if (NILP (result))
833 {
834 int offset, idx;
835 int found = 0;
836
837 /* Look in special slots */
838 for (offset = PER_BUFFER_VAR_OFFSET (name);
839 offset < sizeof (struct buffer);
840 /* sizeof EMACS_INT == sizeof Lisp_Object */
841 offset += (sizeof (EMACS_INT)))
842 {
843 idx = PER_BUFFER_IDX (offset);
844 if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
845 && SYMBOLP (PER_BUFFER_SYMBOL (offset))
846 && EQ (PER_BUFFER_SYMBOL (offset), symbol))
847 {
848 result = PER_BUFFER_VALUE (buf, offset);
849 found = 1;
850 break;
851 }
852 }
853
854 if (!found)
855 result = Fdefault_value (symbol);
856 }
857 else
858 result = XCDR (result);
859
860 if (EQ (result, Qunbound))
861 return Fsignal (Qvoid_variable, Fcons (symbol, Qnil));
862
863 return result;
864}
865
1ab256cb 866DEFUN ("buffer-local-variables", Fbuffer_local_variables,
efc7e75f 867 Sbuffer_local_variables, 0, 1, 0,
7ee72033 868 doc: /* Return an alist of variables that are buffer-local in BUFFER.
018ba359
PJ
869Most elements look like (SYMBOL . VALUE), describing one variable.
870For a symbol that is locally unbound, just the symbol appears in the value.
871Note that storing new VALUEs in these elements doesn't change the variables.
7ee72033
MB
872No argument or nil as argument means use current buffer as BUFFER. */)
873 (buffer)
1ab256cb
RM
874 register Lisp_Object buffer;
875{
876 register struct buffer *buf;
553defa4 877 register Lisp_Object result;
1ab256cb 878
265a9e55 879 if (NILP (buffer))
1ab256cb
RM
880 buf = current_buffer;
881 else
882 {
b7826503 883 CHECK_BUFFER (buffer);
1ab256cb
RM
884 buf = XBUFFER (buffer);
885 }
886
553defa4
RS
887 result = Qnil;
888
1ab256cb 889 {
553defa4 890 register Lisp_Object tail;
7539e11f 891 for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
1ab256cb 892 {
553defa4
RS
893 Lisp_Object val, elt;
894
7539e11f 895 elt = XCAR (tail);
553defa4 896
e0585c64
RS
897 /* Reference each variable in the alist in buf.
898 If inquiring about the current buffer, this gets the current values,
899 so store them into the alist so the alist is up to date.
900 If inquiring about some other buffer, this swaps out any values
901 for that buffer, making the alist up to date automatically. */
7539e11f 902 val = find_symbol_value (XCAR (elt));
e0585c64
RS
903 /* Use the current buffer value only if buf is the current buffer. */
904 if (buf != current_buffer)
7539e11f 905 val = XCDR (elt);
553defa4
RS
906
907 /* If symbol is unbound, put just the symbol in the list. */
908 if (EQ (val, Qunbound))
7539e11f 909 result = Fcons (XCAR (elt), result);
553defa4
RS
910 /* Otherwise, put (symbol . value) in the list. */
911 else
7539e11f 912 result = Fcons (Fcons (XCAR (elt), val), result);
1ab256cb
RM
913 }
914 }
915
1ab256cb
RM
916 /* Add on all the variables stored in special slots. */
917 {
7c02e886 918 int offset, idx;
1ab256cb 919
7313acd0 920 for (offset = PER_BUFFER_VAR_OFFSET (name);
1ab256cb 921 offset < sizeof (struct buffer);
7c02e886
GM
922 /* sizeof EMACS_INT == sizeof Lisp_Object */
923 offset += (sizeof (EMACS_INT)))
1ab256cb 924 {
7313acd0
GM
925 idx = PER_BUFFER_IDX (offset);
926 if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
927 && SYMBOLP (PER_BUFFER_SYMBOL (offset)))
928 result = Fcons (Fcons (PER_BUFFER_SYMBOL (offset),
929 PER_BUFFER_VALUE (buf, offset)),
7c02e886 930 result);
1ab256cb
RM
931 }
932 }
553defa4
RS
933
934 return result;
1ab256cb
RM
935}
936
937\f
938DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p,
efc7e75f 939 0, 1, 0,
7ee72033
MB
940 doc: /* Return t if BUFFER was modified since its file was last read or saved.
941No argument or nil as argument means use current buffer as BUFFER. */)
942 (buffer)
1ab256cb
RM
943 register Lisp_Object buffer;
944{
945 register struct buffer *buf;
265a9e55 946 if (NILP (buffer))
1ab256cb
RM
947 buf = current_buffer;
948 else
949 {
b7826503 950 CHECK_BUFFER (buffer);
1ab256cb
RM
951 buf = XBUFFER (buffer);
952 }
953
336cd056 954 return BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf) ? Qt : Qnil;
1ab256cb
RM
955}
956
957DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p,
efc7e75f 958 1, 1, 0,
7ee72033
MB
959 doc: /* Mark current buffer as modified or unmodified according to FLAG.
960A non-nil FLAG means mark the buffer modified. */)
961 (flag)
1ab256cb
RM
962 register Lisp_Object flag;
963{
964 register int already;
965 register Lisp_Object fn;
8ec01c70 966 Lisp_Object buffer, window;
1ab256cb
RM
967
968#ifdef CLASH_DETECTION
969 /* If buffer becoming modified, lock the file.
970 If buffer becoming unmodified, unlock the file. */
971
60f4dd23 972 fn = current_buffer->file_truename;
90d456d2
KH
973 /* Test buffer-file-name so that binding it to nil is effective. */
974 if (!NILP (fn) && ! NILP (current_buffer->filename))
1ab256cb 975 {
336cd056 976 already = SAVE_MODIFF < MODIFF;
265a9e55 977 if (!already && !NILP (flag))
1ab256cb 978 lock_file (fn);
265a9e55 979 else if (already && NILP (flag))
1ab256cb
RM
980 unlock_file (fn);
981 }
982#endif /* CLASH_DETECTION */
983
336cd056 984 SAVE_MODIFF = NILP (flag) ? MODIFF : 0;
8ec01c70
GM
985
986 /* Set update_mode_lines only if buffer is displayed in some window.
987 Packages like jit-lock or lazy-lock preserve a buffer's modified
988 state by recording/restoring the state around blocks of code.
989 Setting update_mode_lines makes redisplay consider all windows
990 (on all frames). Stealth fontification of buffers not displayed
991 would incur additional redisplay costs if we'd set
992 update_modes_lines unconditionally.
993
994 Ideally, I think there should be another mechanism for fontifying
995 buffers without "modifying" buffers, or redisplay should be
996 smarter about updating the `*' in mode lines. --gerd */
997 XSETBUFFER (buffer, current_buffer);
998 window = Fget_buffer_window (buffer, Qt);
999 if (WINDOWP (window))
d57b83b3
GM
1000 {
1001 ++update_mode_lines;
1002 current_buffer->prevent_redisplay_optimizations_p = 1;
1003 }
8ec01c70 1004
1ab256cb
RM
1005 return flag;
1006}
1007
a8c21b48
GM
1008DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p,
1009 Srestore_buffer_modified_p, 1, 1, 0,
7ee72033 1010 doc: /* Like `set-buffer-modified-p', with a differences concerning redisplay.
018ba359 1011It is not ensured that mode lines will be updated to show the modified
7ee72033
MB
1012state of the current buffer. Use with care. */)
1013 (flag)
a8c21b48
GM
1014 Lisp_Object flag;
1015{
1016#ifdef CLASH_DETECTION
1017 Lisp_Object fn;
1018
1019 /* If buffer becoming modified, lock the file.
1020 If buffer becoming unmodified, unlock the file. */
1021
1022 fn = current_buffer->file_truename;
1023 /* Test buffer-file-name so that binding it to nil is effective. */
1024 if (!NILP (fn) && ! NILP (current_buffer->filename))
1025 {
1026 int already = SAVE_MODIFF < MODIFF;
1027 if (!already && !NILP (flag))
1028 lock_file (fn);
1029 else if (already && NILP (flag))
1030 unlock_file (fn);
1031 }
1032#endif /* CLASH_DETECTION */
1033
1034 SAVE_MODIFF = NILP (flag) ? MODIFF : 0;
1035 return flag;
1036}
1037
1ab256cb 1038DEFUN ("buffer-modified-tick", Fbuffer_modified_tick, Sbuffer_modified_tick,
efc7e75f 1039 0, 1, 0,
7ee72033 1040 doc: /* Return BUFFER's tick counter, incremented for each change in text.
018ba359
PJ
1041Each buffer has a tick counter which is incremented each time the text in
1042that buffer is changed. It wraps around occasionally.
7ee72033
MB
1043No argument or nil as argument means use current buffer as BUFFER. */)
1044 (buffer)
1ab256cb
RM
1045 register Lisp_Object buffer;
1046{
1047 register struct buffer *buf;
265a9e55 1048 if (NILP (buffer))
1ab256cb
RM
1049 buf = current_buffer;
1050 else
1051 {
b7826503 1052 CHECK_BUFFER (buffer);
1ab256cb
RM
1053 buf = XBUFFER (buffer);
1054 }
1055
1056 return make_number (BUF_MODIFF (buf));
1057}
1058\f
01050cb5 1059DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2,
4c7e5f09 1060 "sRename buffer (to new name): \nP",
7ee72033 1061 doc: /* Change current buffer's name to NEWNAME (a string).
018ba359
PJ
1062If second arg UNIQUE is nil or omitted, it is an error if a
1063buffer named NEWNAME already exists.
1064If UNIQUE is non-nil, come up with a new name using
1065`generate-new-buffer-name'.
1066Interactively, you can set UNIQUE with a prefix argument.
1067We return the name we actually gave the buffer.
7ee72033
MB
1068This does not change the name of the visited file (if any). */)
1069 (newname, unique)
489c043a 1070 register Lisp_Object newname, unique;
1ab256cb
RM
1071{
1072 register Lisp_Object tem, buf;
1073
b7826503 1074 CHECK_STRING (newname);
d59698c4 1075
489c043a 1076 if (XSTRING (newname)->size == 0)
d59698c4
RS
1077 error ("Empty string is invalid as a buffer name");
1078
489c043a 1079 tem = Fget_buffer (newname);
265a9e55 1080 if (!NILP (tem))
01050cb5 1081 {
8801a864
KR
1082 /* Don't short-circuit if UNIQUE is t. That is a useful way to
1083 rename the buffer automatically so you can create another
1084 with the original name. It makes UNIQUE equivalent to
1085 (rename-buffer (generate-new-buffer-name NEWNAME)). */
1086 if (NILP (unique) && XBUFFER (tem) == current_buffer)
1087 return current_buffer->name;
3bd779aa 1088 if (!NILP (unique))
489c043a 1089 newname = Fgenerate_new_buffer_name (newname, current_buffer->name);
01050cb5 1090 else
489c043a 1091 error ("Buffer name `%s' is in use", XSTRING (newname)->data);
01050cb5 1092 }
1ab256cb 1093
489c043a 1094 current_buffer->name = newname;
76f590d7
JB
1095
1096 /* Catch redisplay's attention. Unless we do this, the mode lines for
1097 any windows displaying current_buffer will stay unchanged. */
1098 update_mode_lines++;
1099
67180c6a 1100 XSETBUFFER (buf, current_buffer);
489c043a 1101 Fsetcar (Frassq (buf, Vbuffer_alist), newname);
cf058e49
KH
1102 if (NILP (current_buffer->filename)
1103 && !NILP (current_buffer->auto_save_file_name))
1ab256cb 1104 call0 (intern ("rename-auto-save-file"));
fb5eba9c
RS
1105 /* Refetch since that last call may have done GC. */
1106 return current_buffer->name;
1ab256cb
RM
1107}
1108
773fbdb9 1109DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0,
7ee72033 1110 doc: /* Return most recently selected buffer other than BUFFER.
018ba359
PJ
1111Buffers not visible in windows are preferred to visible buffers,
1112unless optional second argument VISIBLE-OK is non-nil.
1113If the optional third argument FRAME is non-nil, use that frame's
1114buffer list instead of the selected frame's buffer list.
1115If no other buffer exists, the buffer `*scratch*' is returned.
7ee72033
MB
1116If BUFFER is omitted or nil, some interesting buffer is returned. */)
1117 (buffer, visible_ok, frame)
773fbdb9 1118 register Lisp_Object buffer, visible_ok, frame;
1ab256cb 1119{
89132f25 1120 Lisp_Object Fset_buffer_major_mode ();
7962a441 1121 register Lisp_Object tail, buf, notsogood, tem, pred, add_ons;
1ab256cb
RM
1122 notsogood = Qnil;
1123
773fbdb9 1124 if (NILP (frame))
9ba9623d 1125 frame = selected_frame;
773fbdb9 1126
7962a441 1127 tail = Vbuffer_alist;
773fbdb9 1128 pred = frame_buffer_predicate (frame);
7962a441
RS
1129
1130 /* Consider buffers that have been seen in the selected frame
1131 before other buffers. */
1132
773fbdb9 1133 tem = frame_buffer_list (frame);
7962a441
RS
1134 add_ons = Qnil;
1135 while (CONSP (tem))
1136 {
7539e11f
KR
1137 if (BUFFERP (XCAR (tem)))
1138 add_ons = Fcons (Fcons (Qnil, XCAR (tem)), add_ons);
1139 tem = XCDR (tem);
7962a441
RS
1140 }
1141 tail = nconc2 (Fnreverse (add_ons), tail);
1142
1143 for (; !NILP (tail); tail = Fcdr (tail))
1ab256cb
RM
1144 {
1145 buf = Fcdr (Fcar (tail));
1146 if (EQ (buf, buffer))
1147 continue;
1148 if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
1149 continue;
04ae1b48
RS
1150 /* If the selected frame has a buffer_predicate,
1151 disregard buffers that don't fit the predicate. */
7962a441 1152 if (!NILP (pred))
04ae1b48 1153 {
7962a441 1154 tem = call1 (pred, buf);
04ae1b48
RS
1155 if (NILP (tem))
1156 continue;
1157 }
04ae1b48 1158
a0ebb746 1159 if (NILP (visible_ok))
66ffe51c 1160 tem = Fget_buffer_window (buf, Qvisible);
a0ebb746
JB
1161 else
1162 tem = Qnil;
265a9e55 1163 if (NILP (tem))
1ab256cb 1164 return buf;
265a9e55 1165 if (NILP (notsogood))
1ab256cb
RM
1166 notsogood = buf;
1167 }
265a9e55 1168 if (!NILP (notsogood))
1ab256cb 1169 return notsogood;
dba1a30a
GM
1170 buf = Fget_buffer (build_string ("*scratch*"));
1171 if (NILP (buf))
1172 {
1173 buf = Fget_buffer_create (build_string ("*scratch*"));
1174 Fset_buffer_major_mode (buf);
1175 }
89132f25 1176 return buf;
1ab256cb
RM
1177}
1178\f
316784fb
KH
1179DEFUN ("buffer-disable-undo", Fbuffer_disable_undo, Sbuffer_disable_undo,
1180 0, 1, "",
7ee72033
MB
1181 doc: /* Make BUFFER stop keeping undo information.
1182No argument or nil as argument means do this for the current buffer. */)
1183 (buffer)
ffd56f97 1184 register Lisp_Object buffer;
1ab256cb 1185{
ffd56f97
JB
1186 Lisp_Object real_buffer;
1187
1188 if (NILP (buffer))
67180c6a 1189 XSETBUFFER (real_buffer, current_buffer);
ffd56f97
JB
1190 else
1191 {
1192 real_buffer = Fget_buffer (buffer);
1193 if (NILP (real_buffer))
1194 nsberror (buffer);
1195 }
1196
1197 XBUFFER (real_buffer)->undo_list = Qt;
1198
1ab256cb
RM
1199 return Qnil;
1200}
1201
1202DEFUN ("buffer-enable-undo", Fbuffer_enable_undo, Sbuffer_enable_undo,
1203 0, 1, "",
7ee72033
MB
1204 doc: /* Start keeping undo information for buffer BUFFER.
1205No argument or nil as argument means do this for the current buffer. */)
1206 (buffer)
ffd56f97 1207 register Lisp_Object buffer;
1ab256cb 1208{
ffd56f97 1209 Lisp_Object real_buffer;
1ab256cb 1210
ffd56f97 1211 if (NILP (buffer))
67180c6a 1212 XSETBUFFER (real_buffer, current_buffer);
1ab256cb
RM
1213 else
1214 {
ffd56f97
JB
1215 real_buffer = Fget_buffer (buffer);
1216 if (NILP (real_buffer))
1217 nsberror (buffer);
1ab256cb
RM
1218 }
1219
ffd56f97
JB
1220 if (EQ (XBUFFER (real_buffer)->undo_list, Qt))
1221 XBUFFER (real_buffer)->undo_list = Qnil;
1ab256cb
RM
1222
1223 return Qnil;
1224}
1225
1226/*
1227 DEFVAR_LISP ("kill-buffer-hook", no_cell, "\
1228Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\
1229The buffer being killed will be current while the hook is running.\n\
1230See `kill-buffer'."
1231 */
1232DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 1, 1, "bKill buffer: ",
7ee72033 1233 doc: /* Kill the buffer BUFFER.
018ba359
PJ
1234The argument may be a buffer or may be the name of a buffer.
1235An argument of nil means kill the current buffer.
1236
1237Value is t if the buffer is actually killed, nil if user says no.
1238
1239The value of `kill-buffer-hook' (which may be local to that buffer),
1240if not void, is a list of functions to be called, with no arguments,
1241before the buffer is actually killed. The buffer to be killed is current
1242when the hook functions are called.
1243
1244Any processes that have this buffer as the `process-buffer' are killed
7ee72033
MB
1245with SIGHUP. */)
1246 (buffer)
a25f13ae 1247 Lisp_Object buffer;
1ab256cb
RM
1248{
1249 Lisp_Object buf;
1250 register struct buffer *b;
1251 register Lisp_Object tem;
1252 register struct Lisp_Marker *m;
6af718a4 1253 struct gcpro gcpro1;
1ab256cb 1254
a25f13ae 1255 if (NILP (buffer))
1ab256cb
RM
1256 buf = Fcurrent_buffer ();
1257 else
a25f13ae 1258 buf = Fget_buffer (buffer);
265a9e55 1259 if (NILP (buf))
a25f13ae 1260 nsberror (buffer);
1ab256cb
RM
1261
1262 b = XBUFFER (buf);
1263
4a4a9db5
KH
1264 /* Avoid trouble for buffer already dead. */
1265 if (NILP (b->name))
1266 return Qnil;
1267
1ab256cb 1268 /* Query if the buffer is still modified. */
265a9e55 1269 if (INTERACTIVE && !NILP (b->filename)
336cd056 1270 && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
1ab256cb 1271 {
a25f13ae 1272 GCPRO1 (buf);
1ab256cb
RM
1273 tem = do_yes_or_no_p (format1 ("Buffer %s modified; kill anyway? ",
1274 XSTRING (b->name)->data));
1275 UNGCPRO;
265a9e55 1276 if (NILP (tem))
1ab256cb
RM
1277 return Qnil;
1278 }
1279
dcdffbf6 1280 /* Run hooks with the buffer to be killed the current buffer. */
1ab256cb 1281 {
1ab256cb 1282 int count = specpdl_ptr - specpdl;
dcdffbf6 1283 Lisp_Object list;
1ab256cb
RM
1284
1285 record_unwind_protect (save_excursion_restore, save_excursion_save ());
1286 set_buffer_internal (b);
dcdffbf6
RS
1287
1288 /* First run the query functions; if any query is answered no,
1289 don't kill the buffer. */
1290 for (list = Vkill_buffer_query_functions; !NILP (list); list = Fcdr (list))
1291 {
1292 tem = call0 (Fcar (list));
1293 if (NILP (tem))
1294 return unbind_to (count, Qnil);
1295 }
1296
1297 /* Then run the hooks. */
f1597a3a 1298 Frun_hooks (1, &Qkill_buffer_hook);
1ab256cb
RM
1299 unbind_to (count, Qnil);
1300 }
1301
1302 /* We have no more questions to ask. Verify that it is valid
1303 to kill the buffer. This must be done after the questions
1304 since anything can happen within do_yes_or_no_p. */
1305
1306 /* Don't kill the minibuffer now current. */
1307 if (EQ (buf, XWINDOW (minibuf_window)->buffer))
1308 return Qnil;
1309
265a9e55 1310 if (NILP (b->name))
1ab256cb
RM
1311 return Qnil;
1312
336cd056
RS
1313 /* When we kill a base buffer, kill all its indirect buffers.
1314 We do it at this stage so nothing terrible happens if they
1315 ask questions or their hooks get errors. */
1316 if (! b->base_buffer)
1317 {
1318 struct buffer *other;
1319
1320 GCPRO1 (buf);
1321
1322 for (other = all_buffers; other; other = other->next)
4a4a9db5
KH
1323 /* all_buffers contains dead buffers too;
1324 don't re-kill them. */
1325 if (other->base_buffer == b && !NILP (other->name))
336cd056
RS
1326 {
1327 Lisp_Object buf;
1328 XSETBUFFER (buf, other);
1329 Fkill_buffer (buf);
1330 }
1331
1332 UNGCPRO;
1333 }
1334
1ab256cb
RM
1335 /* Make this buffer not be current.
1336 In the process, notice if this is the sole visible buffer
1337 and give up if so. */
1338 if (b == current_buffer)
1339 {
773fbdb9 1340 tem = Fother_buffer (buf, Qnil, Qnil);
1ab256cb
RM
1341 Fset_buffer (tem);
1342 if (b == current_buffer)
1343 return Qnil;
1344 }
1345
77270fac
GM
1346 /* Notice if the buffer to kill is the sole visible buffer
1347 when we're currently in the mini-buffer, and give up if so. */
1348 XSETBUFFER (tem, current_buffer);
1349 if (EQ (tem, XWINDOW (minibuf_window)->buffer))
1350 {
1351 tem = Fother_buffer (buf, Qnil, Qnil);
77270fac
GM
1352 if (EQ (buf, tem))
1353 return Qnil;
1354 }
1355
1ab256cb
RM
1356 /* Now there is no question: we can kill the buffer. */
1357
1358#ifdef CLASH_DETECTION
1359 /* Unlock this buffer's file, if it is locked. */
1360 unlock_buffer (b);
1361#endif /* CLASH_DETECTION */
1362
1ab256cb 1363 kill_buffer_processes (buf);
1ab256cb
RM
1364
1365 tem = Vinhibit_quit;
1366 Vinhibit_quit = Qt;
00550f94 1367 replace_buffer_in_all_windows (buf);
b26dd9cb 1368 Vbuffer_alist = Fdelq (Frassq (buf, Vbuffer_alist), Vbuffer_alist);
7962a441 1369 frames_discard_buffer (buf);
1ab256cb
RM
1370 Vinhibit_quit = tem;
1371
9cf712eb
RS
1372 /* Delete any auto-save file, if we saved it in this session.
1373 But not if the buffer is modified. */
a7a60ce9 1374 if (STRINGP (b->auto_save_file_name)
e95a0b39 1375 && b->auto_save_modified != 0
9cf712eb
RS
1376 && BUF_SAVE_MODIFF (b) < b->auto_save_modified
1377 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b))
1ab256cb
RM
1378 {
1379 Lisp_Object tem;
1380 tem = Fsymbol_value (intern ("delete-auto-save-files"));
265a9e55 1381 if (! NILP (tem))
cbb6a418 1382 internal_delete_file (b->auto_save_file_name);
1ab256cb
RM
1383 }
1384
4a4a9db5
KH
1385 if (b->base_buffer)
1386 {
1387 /* Unchain all markers that belong to this indirect buffer.
1388 Don't unchain the markers that belong to the base buffer
1389 or its other indirect buffers. */
1390 for (tem = BUF_MARKERS (b); !NILP (tem); )
1391 {
1392 Lisp_Object next;
1393 m = XMARKER (tem);
1394 next = m->chain;
1395 if (m->buffer == b)
1396 unchain_marker (tem);
1397 tem = next;
1398 }
1399 }
1400 else
1ab256cb 1401 {
4a4a9db5 1402 /* Unchain all markers of this buffer and its indirect buffers.
336cd056 1403 and leave them pointing nowhere. */
4a4a9db5 1404 for (tem = BUF_MARKERS (b); !NILP (tem); )
336cd056
RS
1405 {
1406 m = XMARKER (tem);
1407 m->buffer = 0;
1408 tem = m->chain;
1409 m->chain = Qnil;
1410 }
1411 BUF_MARKERS (b) = Qnil;
336cd056 1412 BUF_INTERVALS (b) = NULL_INTERVAL;
336cd056
RS
1413
1414 /* Perhaps we should explicitly free the interval tree here... */
1415 }
33f7013e 1416
2f3f993b
RS
1417 /* Reset the local variables, so that this buffer's local values
1418 won't be protected from GC. They would be protected
1419 if they happened to remain encached in their symbols.
1420 This gets rid of them for certain. */
1421 swap_out_buffer_local_variables (b);
13de9290 1422 reset_buffer_local_variables (b, 1);
2f3f993b 1423
1ab256cb 1424 b->name = Qnil;
336cd056 1425
9ac0d9e0 1426 BLOCK_INPUT;
336cd056 1427 if (! b->base_buffer)
b86af064 1428 free_buffer_text (b);
336cd056 1429
28e969dd
JB
1430 if (b->newline_cache)
1431 {
1432 free_region_cache (b->newline_cache);
1433 b->newline_cache = 0;
1434 }
1435 if (b->width_run_cache)
1436 {
1437 free_region_cache (b->width_run_cache);
1438 b->width_run_cache = 0;
1439 }
1440 b->width_table = Qnil;
9ac0d9e0 1441 UNBLOCK_INPUT;
1ab256cb
RM
1442 b->undo_list = Qnil;
1443
1444 return Qt;
1445}
1446\f
36a8c287
JB
1447/* Move the assoc for buffer BUF to the front of buffer-alist. Since
1448 we do this each time BUF is selected visibly, the more recently
1449 selected buffers are always closer to the front of the list. This
1450 means that other_buffer is more likely to choose a relevant buffer. */
1ab256cb 1451
01136e9b 1452void
1ab256cb
RM
1453record_buffer (buf)
1454 Lisp_Object buf;
1455{
1456 register Lisp_Object link, prev;
773fbdb9 1457 Lisp_Object frame;
9ba9623d 1458 frame = selected_frame;
1ab256cb
RM
1459
1460 prev = Qnil;
7539e11f 1461 for (link = Vbuffer_alist; CONSP (link); link = XCDR (link))
1ab256cb 1462 {
7539e11f 1463 if (EQ (XCDR (XCAR (link)), buf))
1ab256cb
RM
1464 break;
1465 prev = link;
1466 }
1467
36a8c287
JB
1468 /* Effectively do Vbuffer_alist = Fdelq (link, Vbuffer_alist);
1469 we cannot use Fdelq itself here because it allows quitting. */
1ab256cb 1470
265a9e55 1471 if (NILP (prev))
7539e11f 1472 Vbuffer_alist = XCDR (Vbuffer_alist);
1ab256cb 1473 else
f3fbd155 1474 XSETCDR (prev, XCDR (XCDR (prev)));
1ab256cb 1475
f3fbd155 1476 XSETCDR (link, Vbuffer_alist);
1ab256cb 1477 Vbuffer_alist = link;
7962a441
RS
1478
1479 /* Now move this buffer to the front of frame_buffer_list also. */
1480
1481 prev = Qnil;
773fbdb9 1482 for (link = frame_buffer_list (frame); CONSP (link);
7539e11f 1483 link = XCDR (link))
7962a441 1484 {
7539e11f 1485 if (EQ (XCAR (link), buf))
7962a441
RS
1486 break;
1487 prev = link;
1488 }
1489
1490 /* Effectively do delq. */
1491
1492 if (CONSP (link))
1493 {
1494 if (NILP (prev))
773fbdb9 1495 set_frame_buffer_list (frame,
7539e11f 1496 XCDR (frame_buffer_list (frame)));
7962a441 1497 else
f3fbd155 1498 XSETCDR (prev, XCDR (XCDR (prev)));
7962a441 1499
f3fbd155 1500 XSETCDR (link, frame_buffer_list (frame));
773fbdb9 1501 set_frame_buffer_list (frame, link);
7962a441
RS
1502 }
1503 else
773fbdb9 1504 set_frame_buffer_list (frame, Fcons (buf, frame_buffer_list (frame)));
1ab256cb
RM
1505}
1506
a9ee7a59 1507DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0,
7ee72033 1508 doc: /* Set an appropriate major mode for BUFFER.
864b90c9 1509For the *scratch* buffer, use `initial-major-mode', otherwise choose a mode
71a0f2c6 1510according to `default-major-mode'.
018ba359 1511Use this function before selecting the buffer, since it may need to inspect
7ee72033
MB
1512the current buffer's major mode. */)
1513 (buffer)
a2428fa2 1514 Lisp_Object buffer;
a9ee7a59
KH
1515{
1516 int count;
1517 Lisp_Object function;
1518
71a0f2c6
GM
1519 if (STRINGP (XBUFFER (buffer)->name)
1520 && strcmp (XSTRING (XBUFFER (buffer)->name)->data, "*scratch*") == 0)
1521 function = find_symbol_value (intern ("initial-major-mode"));
1522 else
1523 {
1524 function = buffer_defaults.major_mode;
1525 if (NILP (function)
1526 && NILP (Fget (current_buffer->major_mode, Qmode_class)))
1527 function = current_buffer->major_mode;
1528 }
1529
a9ee7a59
KH
1530 if (NILP (function) || EQ (function, Qfundamental_mode))
1531 return Qnil;
1532
1533 count = specpdl_ptr - specpdl;
1534
1535 /* To select a nonfundamental mode,
1536 select the buffer temporarily and then call the mode function. */
1537
1538 record_unwind_protect (save_excursion_restore, save_excursion_save ());
1539
a2428fa2 1540 Fset_buffer (buffer);
a9ee7a59
KH
1541 call0 (function);
1542
1543 return unbind_to (count, Qnil);
1544}
1545
2594e0fd
RS
1546/* If switching buffers in WINDOW would be an error, return
1547 a C string saying what the error would be. */
1548
1549char *
1550no_switch_window (window)
1551 Lisp_Object window;
1ab256cb 1552{
1ab256cb 1553 Lisp_Object tem;
2594e0fd
RS
1554 if (EQ (minibuf_window, window))
1555 return "Cannot switch buffers in minibuffer window";
1556 tem = Fwindow_dedicated_p (window);
265a9e55 1557 if (!NILP (tem))
2594e0fd
RS
1558 return "Cannot switch buffers in a dedicated window";
1559 return NULL;
1560}
1561
1562/* Switch to buffer BUFFER in the selected window.
1563 If NORECORD is non-nil, don't call record_buffer. */
1564
1565Lisp_Object
1566switch_to_buffer_1 (buffer, norecord)
1567 Lisp_Object buffer, norecord;
1568{
1569 register Lisp_Object buf;
1ab256cb 1570
a25f13ae 1571 if (NILP (buffer))
773fbdb9 1572 buf = Fother_buffer (Fcurrent_buffer (), Qnil, Qnil);
1ab256cb 1573 else
a9ee7a59 1574 {
a25f13ae 1575 buf = Fget_buffer (buffer);
a9ee7a59
KH
1576 if (NILP (buf))
1577 {
a25f13ae 1578 buf = Fget_buffer_create (buffer);
a9ee7a59
KH
1579 Fset_buffer_major_mode (buf);
1580 }
1581 }
1ab256cb 1582 Fset_buffer (buf);
265a9e55 1583 if (NILP (norecord))
1ab256cb
RM
1584 record_buffer (buf);
1585
1586 Fset_window_buffer (EQ (selected_window, minibuf_window)
5fcd022d
JB
1587 ? Fnext_window (minibuf_window, Qnil, Qnil)
1588 : selected_window,
1ab256cb
RM
1589 buf);
1590
cd0c235a 1591 return buf;
1ab256cb
RM
1592}
1593
2594e0fd 1594DEFUN ("switch-to-buffer", Fswitch_to_buffer, Sswitch_to_buffer, 1, 2, "BSwitch to buffer: ",
7ee72033 1595 doc: /* Select buffer BUFFER in the current window.
018ba359
PJ
1596BUFFER may be a buffer or a buffer name.
1597Optional second arg NORECORD non-nil means
1598do not put this buffer at the front of the list of recently selected ones.
1599
1600WARNING: This is NOT the way to work on another buffer temporarily
1601within a Lisp program! Use `set-buffer' instead. That avoids messing with
7ee72033
MB
1602the window-buffer correspondences. */)
1603 (buffer, norecord)
2594e0fd
RS
1604 Lisp_Object buffer, norecord;
1605{
1606 char *err;
1607
1608 err = no_switch_window (selected_window);
1609 if (err) error (err);
1610
1611 return switch_to_buffer_1 (buffer, norecord);
1612}
1613
cd0c235a 1614DEFUN ("pop-to-buffer", Fpop_to_buffer, Spop_to_buffer, 1, 3, 0,
7ee72033 1615 doc: /* Select buffer BUFFER in some window, preferably a different one.
018ba359
PJ
1616If BUFFER is nil, then some other buffer is chosen.
1617If `pop-up-windows' is non-nil, windows can be split to do this.
1618If optional second arg OTHER-WINDOW is non-nil, insist on finding another
1619window even if BUFFER is already visible in the selected window.
1620This uses the function `display-buffer' as a subroutine; see the documentation
1621of `display-buffer' for additional customization information.
1622
1623Optional third arg NORECORD non-nil means
7ee72033
MB
1624do not put this buffer at the front of the list of recently selected ones. */)
1625 (buffer, other_window, norecord)
6d12711f 1626 Lisp_Object buffer, other_window, norecord;
1ab256cb
RM
1627{
1628 register Lisp_Object buf;
a25f13ae 1629 if (NILP (buffer))
773fbdb9 1630 buf = Fother_buffer (Fcurrent_buffer (), Qnil, Qnil);
1ab256cb 1631 else
7c2087ee 1632 {
a25f13ae 1633 buf = Fget_buffer (buffer);
7c2087ee
RS
1634 if (NILP (buf))
1635 {
a25f13ae 1636 buf = Fget_buffer_create (buffer);
7c2087ee
RS
1637 Fset_buffer_major_mode (buf);
1638 }
1639 }
1ab256cb 1640 Fset_buffer (buf);
6d12711f 1641 if (NILP (norecord))
c58dab63 1642 /* This seems bogus since Fselect_window will call record_buffer anyway. */
6d12711f 1643 record_buffer (buf);
6b17d756 1644 Fselect_window (Fdisplay_buffer (buf, other_window, Qnil));
e8b3a22d 1645 return buf;
1ab256cb
RM
1646}
1647
1648DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
7ee72033
MB
1649 doc: /* Return the current buffer as a Lisp object. */)
1650 ()
1ab256cb
RM
1651{
1652 register Lisp_Object buf;
67180c6a 1653 XSETBUFFER (buf, current_buffer);
1ab256cb
RM
1654 return buf;
1655}
1656\f
7ec44ec6
GM
1657/* Set the current buffer to B.
1658
1659 We previously set windows_or_buffers_changed here to invalidate
1660 global unchanged information in beg_unchanged and end_unchanged.
1661 This is no longer necessary because we now compute unchanged
1662 information on a buffer-basis. Every action affecting other
1663 windows than the selected one requires a select_window at some
1664 time, and that increments windows_or_buffers_changed. */
1ab256cb
RM
1665
1666void
1667set_buffer_internal (b)
1668 register struct buffer *b;
1669{
b5a225b4 1670 if (current_buffer != b)
7ec44ec6 1671 set_buffer_internal_1 (b);
c7aa5005
KH
1672}
1673
1674/* Set the current buffer to B, and do not set windows_or_buffers_changed.
1675 This is used by redisplay. */
1676
1677void
1678set_buffer_internal_1 (b)
1679 register struct buffer *b;
1680{
1681 register struct buffer *old_buf;
1682 register Lisp_Object tail, valcontents;
1683 Lisp_Object tem;
1684
b86af064 1685#ifdef USE_MMAP_FOR_BUFFERS
684b01ee 1686 if (b->text->beg == NULL)
b86af064
GM
1687 enlarge_buffer_text (b, 0);
1688#endif /* USE_MMAP_FOR_BUFFERS */
684b01ee 1689
c7aa5005
KH
1690 if (current_buffer == b)
1691 return;
1692
1ab256cb
RM
1693 old_buf = current_buffer;
1694 current_buffer = b;
1695 last_known_column_point = -1; /* invalidate indentation cache */
1696
336cd056
RS
1697 if (old_buf)
1698 {
1699 /* Put the undo list back in the base buffer, so that it appears
1700 that an indirect buffer shares the undo list of its base. */
1701 if (old_buf->base_buffer)
1702 old_buf->base_buffer->undo_list = old_buf->undo_list;
1703
1704 /* If the old current buffer has markers to record PT, BEGV and ZV
1705 when it is not current, update them now. */
1706 if (! NILP (old_buf->pt_marker))
1707 {
1708 Lisp_Object obuf;
1709 XSETBUFFER (obuf, old_buf);
3f236a40
RS
1710 set_marker_both (old_buf->pt_marker, obuf,
1711 BUF_PT (old_buf), BUF_PT_BYTE (old_buf));
336cd056
RS
1712 }
1713 if (! NILP (old_buf->begv_marker))
1714 {
1715 Lisp_Object obuf;
1716 XSETBUFFER (obuf, old_buf);
3f236a40
RS
1717 set_marker_both (old_buf->begv_marker, obuf,
1718 BUF_BEGV (old_buf), BUF_BEGV_BYTE (old_buf));
336cd056
RS
1719 }
1720 if (! NILP (old_buf->zv_marker))
1721 {
1722 Lisp_Object obuf;
1723 XSETBUFFER (obuf, old_buf);
3f236a40
RS
1724 set_marker_both (old_buf->zv_marker, obuf,
1725 BUF_ZV (old_buf), BUF_ZV_BYTE (old_buf));
336cd056
RS
1726 }
1727 }
1728
1729 /* Get the undo list from the base buffer, so that it appears
1730 that an indirect buffer shares the undo list of its base. */
1731 if (b->base_buffer)
1732 b->undo_list = b->base_buffer->undo_list;
1733
1734 /* If the new current buffer has markers to record PT, BEGV and ZV
1735 when it is not current, fetch them now. */
1736 if (! NILP (b->pt_marker))
3f236a40
RS
1737 {
1738 BUF_PT (b) = marker_position (b->pt_marker);
1739 BUF_PT_BYTE (b) = marker_byte_position (b->pt_marker);
1740 }
336cd056 1741 if (! NILP (b->begv_marker))
3f236a40
RS
1742 {
1743 BUF_BEGV (b) = marker_position (b->begv_marker);
1744 BUF_BEGV_BYTE (b) = marker_byte_position (b->begv_marker);
1745 }
336cd056 1746 if (! NILP (b->zv_marker))
3f236a40
RS
1747 {
1748 BUF_ZV (b) = marker_position (b->zv_marker);
1749 BUF_ZV_BYTE (b) = marker_byte_position (b->zv_marker);
1750 }
336cd056 1751
1ab256cb
RM
1752 /* Look down buffer's list of local Lisp variables
1753 to find and update any that forward into C variables. */
1754
7539e11f 1755 for (tail = b->local_var_alist; !NILP (tail); tail = XCDR (tail))
1ab256cb 1756 {
f5c1dd0d 1757 valcontents = SYMBOL_VALUE (XCAR (XCAR (tail)));
a7a60ce9
KH
1758 if ((BUFFER_LOCAL_VALUEP (valcontents)
1759 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
3d871c85 1760 && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
a7a60ce9 1761 (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
1ab256cb
RM
1762 /* Just reference the variable
1763 to cause it to become set for this buffer. */
7539e11f 1764 Fsymbol_value (XCAR (XCAR (tail)));
1ab256cb
RM
1765 }
1766
1767 /* Do the same with any others that were local to the previous buffer */
1768
1769 if (old_buf)
7539e11f 1770 for (tail = old_buf->local_var_alist; !NILP (tail); tail = XCDR (tail))
1ab256cb 1771 {
f5c1dd0d 1772 valcontents = SYMBOL_VALUE (XCAR (XCAR (tail)));
a7a60ce9
KH
1773 if ((BUFFER_LOCAL_VALUEP (valcontents)
1774 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
3d871c85 1775 && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
a7a60ce9 1776 (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
1ab256cb
RM
1777 /* Just reference the variable
1778 to cause it to become set for this buffer. */
7539e11f 1779 Fsymbol_value (XCAR (XCAR (tail)));
1ab256cb
RM
1780 }
1781}
1782
336cd056 1783/* Switch to buffer B temporarily for redisplay purposes.
bbbe9545 1784 This avoids certain things that don't need to be done within redisplay. */
336cd056
RS
1785
1786void
1787set_buffer_temp (b)
1788 struct buffer *b;
1789{
1790 register struct buffer *old_buf;
1791
1792 if (current_buffer == b)
1793 return;
1794
1795 old_buf = current_buffer;
1796 current_buffer = b;
1797
1798 if (old_buf)
1799 {
1800 /* If the old current buffer has markers to record PT, BEGV and ZV
1801 when it is not current, update them now. */
1802 if (! NILP (old_buf->pt_marker))
1803 {
1804 Lisp_Object obuf;
1805 XSETBUFFER (obuf, old_buf);
3f236a40
RS
1806 set_marker_both (old_buf->pt_marker, obuf,
1807 BUF_PT (old_buf), BUF_PT_BYTE (old_buf));
336cd056
RS
1808 }
1809 if (! NILP (old_buf->begv_marker))
1810 {
1811 Lisp_Object obuf;
1812 XSETBUFFER (obuf, old_buf);
3f236a40
RS
1813 set_marker_both (old_buf->begv_marker, obuf,
1814 BUF_BEGV (old_buf), BUF_BEGV_BYTE (old_buf));
336cd056
RS
1815 }
1816 if (! NILP (old_buf->zv_marker))
1817 {
1818 Lisp_Object obuf;
1819 XSETBUFFER (obuf, old_buf);
3f236a40
RS
1820 set_marker_both (old_buf->zv_marker, obuf,
1821 BUF_ZV (old_buf), BUF_ZV_BYTE (old_buf));
336cd056
RS
1822 }
1823 }
1824
1825 /* If the new current buffer has markers to record PT, BEGV and ZV
1826 when it is not current, fetch them now. */
1827 if (! NILP (b->pt_marker))
3f236a40
RS
1828 {
1829 BUF_PT (b) = marker_position (b->pt_marker);
1830 BUF_PT_BYTE (b) = marker_byte_position (b->pt_marker);
1831 }
336cd056 1832 if (! NILP (b->begv_marker))
3f236a40
RS
1833 {
1834 BUF_BEGV (b) = marker_position (b->begv_marker);
1835 BUF_BEGV_BYTE (b) = marker_byte_position (b->begv_marker);
1836 }
336cd056 1837 if (! NILP (b->zv_marker))
3f236a40
RS
1838 {
1839 BUF_ZV (b) = marker_position (b->zv_marker);
1840 BUF_ZV_BYTE (b) = marker_byte_position (b->zv_marker);
1841 }
336cd056
RS
1842}
1843
1ab256cb 1844DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0,
7ee72033 1845 doc: /* Make the buffer BUFFER current for editing operations.
018ba359
PJ
1846BUFFER may be a buffer or the name of an existing buffer.
1847See also `save-excursion' when you want to make a buffer current temporarily.
1848This function does not display the buffer, so its effect ends
1849when the current command terminates.
7ee72033
MB
1850Use `switch-to-buffer' or `pop-to-buffer' to switch buffers permanently. */)
1851 (buffer)
a25f13ae 1852 register Lisp_Object buffer;
1ab256cb 1853{
a25f13ae
KH
1854 register Lisp_Object buf;
1855 buf = Fget_buffer (buffer);
1856 if (NILP (buf))
1857 nsberror (buffer);
1858 if (NILP (XBUFFER (buf)->name))
1ab256cb 1859 error ("Selecting deleted buffer");
a25f13ae
KH
1860 set_buffer_internal (XBUFFER (buf));
1861 return buf;
1ab256cb 1862}
d0628b06
RS
1863
1864/* Set the current buffer to BUFFER provided it is alive. */
1865
1866Lisp_Object
1867set_buffer_if_live (buffer)
1868 Lisp_Object buffer;
1869{
1870 if (! NILP (XBUFFER (buffer)->name))
1871 Fset_buffer (buffer);
1872 return Qnil;
1873}
1ab256cb
RM
1874\f
1875DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
1876 Sbarf_if_buffer_read_only, 0, 0, 0,
7ee72033
MB
1877 doc: /* Signal a `buffer-read-only' error if the current buffer is read-only. */)
1878 ()
1ab256cb 1879{
a96b68f1
RS
1880 if (!NILP (current_buffer->read_only)
1881 && NILP (Vinhibit_read_only))
1ab256cb
RM
1882 Fsignal (Qbuffer_read_only, (Fcons (Fcurrent_buffer (), Qnil)));
1883 return Qnil;
1884}
1885
1886DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "",
7ee72033 1887 doc: /* Put BUFFER at the end of the list of all buffers.
018ba359
PJ
1888There it is the least likely candidate for `other-buffer' to return;
1889thus, the least likely buffer for \\[switch-to-buffer] to select by default.
1890If BUFFER is nil or omitted, bury the current buffer.
1891Also, if BUFFER is nil or omitted, remove the current buffer from the
7ee72033
MB
1892selected window if it is displayed there. */)
1893 (buffer)
a2428fa2 1894 register Lisp_Object buffer;
1ab256cb 1895{
b271272a 1896 /* Figure out what buffer we're going to bury. */
a2428fa2 1897 if (NILP (buffer))
a5611885 1898 {
c58dab63 1899 Lisp_Object tem;
a2428fa2 1900 XSETBUFFER (buffer, current_buffer);
0a63b212 1901
c58dab63 1902 tem = Fwindow_buffer (selected_window);
0a63b212 1903 /* If we're burying the current buffer, unshow it. */
c58dab63 1904 if (EQ (buffer, tem))
a78e0303
PJ
1905 {
1906 if (NILP (Fwindow_dedicated_p (selected_window)))
1907 Fswitch_to_buffer (Fother_buffer (buffer, Qnil, Qnil), Qnil);
1908 else if (NILP (XWINDOW (selected_window)->parent))
1909 Ficonify_frame (Fwindow_frame (selected_window));
1910 else
1911 Fdelete_window (selected_window);
1912 }
a5611885 1913 }
1ab256cb
RM
1914 else
1915 {
1916 Lisp_Object buf1;
1917
a2428fa2 1918 buf1 = Fget_buffer (buffer);
265a9e55 1919 if (NILP (buf1))
a2428fa2
EN
1920 nsberror (buffer);
1921 buffer = buf1;
b271272a
JB
1922 }
1923
a1a8b28e
GM
1924 /* Move buffer to the end of the buffer list. Do nothing if the
1925 buffer is killed. */
1926 if (!NILP (XBUFFER (buffer)->name))
1927 {
1928 Lisp_Object aelt, link;
b271272a 1929
a1a8b28e
GM
1930 aelt = Frassq (buffer, Vbuffer_alist);
1931 link = Fmemq (aelt, Vbuffer_alist);
1932 Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
f3fbd155 1933 XSETCDR (link, Qnil);
a1a8b28e 1934 Vbuffer_alist = nconc2 (Vbuffer_alist, link);
1ab256cb 1935
a1a8b28e
GM
1936 frames_bury_buffer (buffer);
1937 }
dec989eb 1938
1ab256cb
RM
1939 return Qnil;
1940}
1941\f
c922bc55 1942DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*",
7ee72033 1943 doc: /* Delete the entire contents of the current buffer.
018ba359 1944Any narrowing restriction in effect (see `narrow-to-region') is removed,
7ee72033
MB
1945so the buffer is truly empty after this. */)
1946 ()
1ab256cb
RM
1947{
1948 Fwiden ();
c0d9a0c3
GM
1949
1950 del_range (BEG, Z);
c280bc6a 1951
1ab256cb
RM
1952 current_buffer->last_window_start = 1;
1953 /* Prevent warnings, or suspension of auto saving, that would happen
1954 if future size is less than past size. Use of erase-buffer
1955 implies that the future text is not really related to the past text. */
8d7a4592 1956 XSETFASTINT (current_buffer->save_length, 0);
1ab256cb
RM
1957 return Qnil;
1958}
1959
01136e9b 1960void
1ab256cb
RM
1961validate_region (b, e)
1962 register Lisp_Object *b, *e;
1963{
b7826503
PJ
1964 CHECK_NUMBER_COERCE_MARKER (*b);
1965 CHECK_NUMBER_COERCE_MARKER (*e);
1ab256cb
RM
1966
1967 if (XINT (*b) > XINT (*e))
1968 {
03192067
KH
1969 Lisp_Object tem;
1970 tem = *b; *b = *e; *e = tem;
1ab256cb
RM
1971 }
1972
1973 if (!(BEGV <= XINT (*b) && XINT (*b) <= XINT (*e)
1974 && XINT (*e) <= ZV))
1975 args_out_of_range (*b, *e);
1976}
1977\f
b05525fa
RS
1978/* Advance BYTE_POS up to a character boundary
1979 and return the adjusted position. */
1980
1981static int
1982advance_to_char_boundary (byte_pos)
1983 int byte_pos;
1984{
f8449323 1985 int c;
b05525fa 1986
f8449323
RS
1987 if (byte_pos == BEG)
1988 /* Beginning of buffer is always a character boundary. */
1989 return 1;
1990
1991 c = FETCH_BYTE (byte_pos);
1992 if (! CHAR_HEAD_P (c))
b05525fa 1993 {
1be6387d 1994 /* We should advance BYTE_POS only when C is a constituent of a
f8449323 1995 multibyte sequence. */
a9bcded1
KH
1996 int orig_byte_pos = byte_pos;
1997
1998 do
1999 {
2000 byte_pos--;
2001 c = FETCH_BYTE (byte_pos);
2002 }
2003 while (! CHAR_HEAD_P (c) && byte_pos > BEG);
f8449323 2004 INC_POS (byte_pos);
a9bcded1
KH
2005 if (byte_pos < orig_byte_pos)
2006 byte_pos = orig_byte_pos;
f8449323
RS
2007 /* If C is a constituent of a multibyte sequence, BYTE_POS was
2008 surely advance to the correct character boundary. If C is
2009 not, BYTE_POS was unchanged. */
b05525fa
RS
2010 }
2011
20773569 2012 return byte_pos;
b05525fa
RS
2013}
2014
3ac81adb
RS
2015DEFUN ("set-buffer-multibyte", Fset_buffer_multibyte, Sset_buffer_multibyte,
2016 1, 1, 0,
7ee72033 2017 doc: /* Set the multibyte flag of the current buffer to FLAG.
018ba359
PJ
2018If FLAG is t, this makes the buffer a multibyte buffer.
2019If FLAG is nil, this makes the buffer a single-byte buffer.
2020The buffer contents remain unchanged as a sequence of bytes
7ee72033
MB
2021but the contents viewed as characters do change. */)
2022 (flag)
3ac81adb
RS
2023 Lisp_Object flag;
2024{
2025 Lisp_Object tail, markers;
abc9d959 2026 struct buffer *other;
a9bcded1
KH
2027 int undo_enabled_p = !EQ (current_buffer->undo_list, Qt);
2028 int begv = BEGV, zv = ZV;
2029 int narrowed = (BEG != begv || Z != zv);
ed00559d 2030 int modified_p = !NILP (Fbuffer_modified_p (Qnil));
3ac81adb 2031
6e553d5e
RS
2032 if (current_buffer->base_buffer)
2033 error ("Cannot do `set-buffer-multibyte' on an indirect buffer");
2034
70e77119
AS
2035 /* Do nothing if nothing actually changes. */
2036 if (NILP (flag) == NILP (current_buffer->enable_multibyte_characters))
2037 return flag;
2038
b05525fa
RS
2039 /* It would be better to update the list,
2040 but this is good enough for now. */
a9bcded1
KH
2041 if (undo_enabled_p)
2042 current_buffer->undo_list = Qt;
b05525fa 2043
3ac81adb
RS
2044 /* If the cached position is for this buffer, clear it out. */
2045 clear_charpos_cache (current_buffer);
2046
a9bcded1
KH
2047 if (narrowed)
2048 Fwiden ();
2049
3ac81adb
RS
2050 if (NILP (flag))
2051 {
a9bcded1
KH
2052 int pos, stop;
2053 unsigned char *p;
2054
3ac81adb
RS
2055 /* Do this first, so it can use CHAR_TO_BYTE
2056 to calculate the old correspondences. */
2057 set_intervals_multibyte (0);
2058
2059 current_buffer->enable_multibyte_characters = Qnil;
2060
2061 Z = Z_BYTE;
2062 BEGV = BEGV_BYTE;
2063 ZV = ZV_BYTE;
2064 GPT = GPT_BYTE;
2065 TEMP_SET_PT_BOTH (PT_BYTE, PT_BYTE);
2066
2067 tail = BUF_MARKERS (current_buffer);
8801a864 2068 while (! NILP (tail))
3ac81adb
RS
2069 {
2070 XMARKER (tail)->charpos = XMARKER (tail)->bytepos;
2071 tail = XMARKER (tail)->chain;
2072 }
a9bcded1
KH
2073
2074 /* Convert multibyte form of 8-bit characters to unibyte. */
2075 pos = BEG;
2076 stop = GPT;
2077 p = BEG_ADDR;
2078 while (1)
2079 {
2080 int c, bytes;
2081
2082 if (pos == stop)
2083 {
2084 if (pos == Z)
2085 break;
2086 p = GAP_END_ADDR;
2087 stop = Z;
2088 }
8f348ed5
KH
2089 if (ASCII_BYTE_P (*p))
2090 p++, pos++;
2091 else if (CHAR_BYTE8_HEAD_P (*p))
a9bcded1 2092 {
31285a8f 2093 c = STRING_CHAR_AND_LENGTH (p, stop - pos, bytes);
a9bcded1
KH
2094 /* Delete all bytes for this 8-bit character but the
2095 last one, and change the last one to the charcter
2096 code. */
2097 bytes--;
2098 del_range_2 (pos, pos, pos + bytes, pos + bytes, 0);
2099 p = GAP_END_ADDR;
2100 *p++ = c;
2101 pos++;
2102 if (begv > pos)
2103 begv -= bytes;
2104 if (zv > pos)
2105 zv -= bytes;
2106 stop = Z;
2107 }
8f348ed5
KH
2108 else
2109 {
2110 bytes = BYTES_BY_CHAR_HEAD (*p);
2111 p += bytes, pos += bytes;
2112 }
a9bcded1
KH
2113 }
2114 if (narrowed)
2115 Fnarrow_to_region (make_number (begv), make_number (zv));
3ac81adb
RS
2116 }
2117 else
2118 {
a9bcded1
KH
2119 int pt = PT;
2120 int pos, stop;
8f348ed5 2121 unsigned char *p, *pend;
a9bcded1 2122
673c57d2 2123 /* Be sure not to have a multibyte sequence striding over the GAP.
8f348ed5
KH
2124 Ex: We change this: "...abc\302 _GAP_ \241def..."
2125 to: "...abc _GAP_ \302\241def..." */
673c57d2
KH
2126
2127 if (GPT_BYTE > 1 && GPT_BYTE < Z_BYTE
2128 && ! CHAR_HEAD_P (*(GAP_END_ADDR)))
2129 {
2130 unsigned char *p = GPT_ADDR - 1;
2131
2132 while (! CHAR_HEAD_P (*p) && p > BEG_ADDR) p--;
2133 if (BASE_LEADING_CODE_P (*p))
2134 {
2135 int new_gpt = GPT_BYTE - (GPT_ADDR - p);
2136
2137 move_gap_both (new_gpt, new_gpt);
2138 }
2139 }
2140
a9bcded1
KH
2141 /* Make the buffer contents valid as multibyte by converting
2142 8-bit characters to multibyte form. */
2143 pos = BEG;
2144 stop = GPT;
2145 p = BEG_ADDR;
8f348ed5 2146 pend = GPT_ADDR;
a9bcded1
KH
2147 while (1)
2148 {
2149 int bytes;
2150
2151 if (pos == stop)
2152 {
2153 if (pos == Z)
2154 break;
2155 p = GAP_END_ADDR;
8f348ed5 2156 pend = Z_ADDR;
a9bcded1
KH
2157 stop = Z;
2158 }
2159
8f348ed5 2160 if ((bytes = MULTIBYTE_LENGTH (p, pend)) > 0)
a9bcded1
KH
2161 p += bytes, pos += bytes;
2162 else
2163 {
2164 unsigned char tmp[MAX_MULTIBYTE_LENGTH];
8c2fc311 2165 int c = BYTE8_TO_CHAR (*p);
a9bcded1 2166
8c2fc311 2167 bytes = CHAR_STRING (c, tmp);
a9bcded1
KH
2168 *p = tmp[0];
2169 TEMP_SET_PT_BOTH (pos + 1, pos + 1);
2170 bytes--;
2171 insert_1_both (tmp + 1, bytes, bytes, 1, 0, 0);
2172 /* Now the gap is after the just inserted data. */
2173 pos = GPT;
2174 p = GAP_END_ADDR;
2175 if (pos <= begv)
2176 begv += bytes;
2177 if (pos <= zv)
2178 zv += bytes;
2179 if (pos <= pt)
2180 pt += bytes;
31285a8f 2181 pend = Z_ADDR;
a9bcded1
KH
2182 stop = Z;
2183 }
2184 }
2185
2186 if (pt != PT)
2187 TEMP_SET_PT (pt);
2188
2189 if (narrowed)
2190 Fnarrow_to_region (make_number (begv), make_number (zv));
2191
3ac81adb
RS
2192 /* Do this first, so that chars_in_text asks the right question.
2193 set_intervals_multibyte needs it too. */
2194 current_buffer->enable_multibyte_characters = Qt;
2195
b05525fa 2196 GPT_BYTE = advance_to_char_boundary (GPT_BYTE);
3ac81adb 2197 GPT = chars_in_text (BEG_ADDR, GPT_BYTE - BEG_BYTE) + BEG;
b05525fa 2198
673c57d2 2199 Z = chars_in_text (GAP_END_ADDR, Z_BYTE - GPT_BYTE) + GPT;
b05525fa
RS
2200
2201 BEGV_BYTE = advance_to_char_boundary (BEGV_BYTE);
3ac81adb 2202 if (BEGV_BYTE > GPT_BYTE)
673c57d2 2203 BEGV = chars_in_text (GAP_END_ADDR, BEGV_BYTE - GPT_BYTE) + GPT;
3ac81adb
RS
2204 else
2205 BEGV = chars_in_text (BEG_ADDR, BEGV_BYTE - BEG_BYTE) + BEG;
b05525fa
RS
2206
2207 ZV_BYTE = advance_to_char_boundary (ZV_BYTE);
3ac81adb 2208 if (ZV_BYTE > GPT_BYTE)
673c57d2 2209 ZV = chars_in_text (GAP_END_ADDR, ZV_BYTE - GPT_BYTE) + GPT;
3ac81adb
RS
2210 else
2211 ZV = chars_in_text (BEG_ADDR, ZV_BYTE - BEG_BYTE) + BEG;
b05525fa
RS
2212
2213 {
2214 int pt_byte = advance_to_char_boundary (PT_BYTE);
2215 int pt;
2216
2217 if (pt_byte > GPT_BYTE)
673c57d2 2218 pt = chars_in_text (GAP_END_ADDR, pt_byte - GPT_BYTE) + GPT;
b05525fa
RS
2219 else
2220 pt = chars_in_text (BEG_ADDR, pt_byte - BEG_BYTE) + BEG;
2221 TEMP_SET_PT_BOTH (pt, pt_byte);
2222 }
3ac81adb
RS
2223
2224 tail = markers = BUF_MARKERS (current_buffer);
95fb069b
RS
2225
2226 /* This prevents BYTE_TO_CHAR (that is, buf_bytepos_to_charpos) from
2227 getting confused by the markers that have not yet been updated.
2228 It is also a signal that it should never create a marker. */
3ac81adb
RS
2229 BUF_MARKERS (current_buffer) = Qnil;
2230
8801a864 2231 while (! NILP (tail))
3ac81adb 2232 {
b05525fa
RS
2233 XMARKER (tail)->bytepos
2234 = advance_to_char_boundary (XMARKER (tail)->bytepos);
3ac81adb 2235 XMARKER (tail)->charpos = BYTE_TO_CHAR (XMARKER (tail)->bytepos);
b05525fa 2236
3ac81adb
RS
2237 tail = XMARKER (tail)->chain;
2238 }
b69f9797
RS
2239
2240 /* Make sure no markers were put on the chain
2241 while the chain value was incorrect. */
2242 if (! EQ (BUF_MARKERS (current_buffer), Qnil))
2243 abort ();
2244
3ac81adb
RS
2245 BUF_MARKERS (current_buffer) = markers;
2246
2247 /* Do this last, so it can calculate the new correspondences
2248 between chars and bytes. */
2249 set_intervals_multibyte (1);
2250 }
2251
a9bcded1
KH
2252 if (undo_enabled_p)
2253 current_buffer->undo_list = Qnil;
2254
724b203f
GM
2255 /* Changing the multibyteness of a buffer means that all windows
2256 showing that buffer must be updated thoroughly. */
2257 current_buffer->prevent_redisplay_optimizations_p = 1;
2258 ++windows_or_buffers_changed;
2259
abc9d959
RS
2260 /* Copy this buffer's new multibyte status
2261 into all of its indirect buffers. */
2262 for (other = all_buffers; other; other = other->next)
2263 if (other->base_buffer == current_buffer && !NILP (other->name))
724b203f
GM
2264 {
2265 other->enable_multibyte_characters
2266 = current_buffer->enable_multibyte_characters;
2267 other->prevent_redisplay_optimizations_p = 1;
2268 }
abc9d959 2269
ed00559d
KH
2270 /* Restore the modifiedness of the buffer. */
2271 if (!modified_p && !NILP (Fbuffer_modified_p (Qnil)))
2272 Fset_buffer_modified_p (Qnil);
2273
3ac81adb
RS
2274 return flag;
2275}
2276\f
1ab256cb 2277DEFUN ("kill-all-local-variables", Fkill_all_local_variables, Skill_all_local_variables,
efc7e75f 2278 0, 0, 0,
7ee72033 2279 doc: /* Switch to Fundamental mode by killing current buffer's local variables.
018ba359
PJ
2280Most local variable bindings are eliminated so that the default values
2281become effective once more. Also, the syntax table is set from
2282`standard-syntax-table', the local keymap is set to nil,
2283and the abbrev table from `fundamental-mode-abbrev-table'.
2284This function also forces redisplay of the mode line.
2285
2286Every function to select a new major mode starts by
2287calling this function.
2288
2289As a special exception, local variables whose names have
2290a non-nil `permanent-local' property are not eliminated by this function.
2291
2292The first thing this function does is run
7ee72033
MB
2293the normal hook `change-major-mode-hook'. */)
2294 ()
1ab256cb
RM
2295{
2296 register Lisp_Object alist, sym, tem;
2297 Lisp_Object oalist;
7410477a 2298
fd186f07
RS
2299 if (!NILP (Vrun_hooks))
2300 call1 (Vrun_hooks, intern ("change-major-mode-hook"));
1ab256cb
RM
2301 oalist = current_buffer->local_var_alist;
2302
2f3f993b
RS
2303 /* Make sure none of the bindings in oalist
2304 remain swapped in, in their symbols. */
1ab256cb 2305
2f3f993b 2306 swap_out_buffer_local_variables (current_buffer);
1ab256cb
RM
2307
2308 /* Actually eliminate all local bindings of this buffer. */
2309
13de9290 2310 reset_buffer_local_variables (current_buffer, 0);
1ab256cb 2311
1ab256cb
RM
2312 /* Any which are supposed to be permanent,
2313 make local again, with the same values they had. */
2314
7539e11f 2315 for (alist = oalist; !NILP (alist); alist = XCDR (alist))
1ab256cb 2316 {
7539e11f 2317 sym = XCAR (XCAR (alist));
1ab256cb 2318 tem = Fget (sym, Qpermanent_local);
265a9e55 2319 if (! NILP (tem))
01050cb5
RM
2320 {
2321 Fmake_local_variable (sym);
7539e11f 2322 Fset (sym, XCDR (XCAR (alist)));
01050cb5 2323 }
1ab256cb
RM
2324 }
2325
2326 /* Force mode-line redisplay. Useful here because all major mode
2327 commands call this function. */
2328 update_mode_lines++;
2329
2330 return Qnil;
2331}
2f3f993b
RS
2332
2333/* Make sure no local variables remain set up with buffer B
2334 for their current values. */
2335
2336static void
2337swap_out_buffer_local_variables (b)
2338 struct buffer *b;
2339{
2340 Lisp_Object oalist, alist, sym, tem, buffer;
2341
2342 XSETBUFFER (buffer, b);
2343 oalist = b->local_var_alist;
2344
7539e11f 2345 for (alist = oalist; !NILP (alist); alist = XCDR (alist))
2f3f993b 2346 {
7539e11f 2347 sym = XCAR (XCAR (alist));
2f3f993b
RS
2348
2349 /* Need not do anything if some other buffer's binding is now encached. */
f5c1dd0d 2350 tem = XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer;
8801a864 2351 if (BUFFERP (tem) && XBUFFER (tem) == current_buffer)
2f3f993b
RS
2352 {
2353 /* Symbol is set up for this buffer's old local value.
2354 Set it up for the current buffer with the default value. */
2355
f5c1dd0d 2356 tem = XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->cdr;
2f3f993b
RS
2357 /* Store the symbol's current value into the alist entry
2358 it is currently set up for. This is so that, if the
2359 local is marked permanent, and we make it local again
2360 later in Fkill_all_local_variables, we don't lose the value. */
f3fbd155
KR
2361 XSETCDR (XCAR (tem),
2362 do_symval_forwarding (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue));
2f3f993b 2363 /* Switch to the symbol's default-value alist entry. */
f3fbd155 2364 XSETCAR (tem, tem);
2f3f993b 2365 /* Mark it as current for buffer B. */
f5c1dd0d 2366 XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer = buffer;
2f3f993b 2367 /* Store the current value into any forwarding in the symbol. */
3d871c85 2368 store_symval_forwarding (sym,
f5c1dd0d 2369 XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue,
9b3a7dad 2370 XCDR (tem), NULL);
2f3f993b
RS
2371 }
2372 }
2373}
1ab256cb 2374\f
2eec3b4e
RS
2375/* Find all the overlays in the current buffer that contain position POS.
2376 Return the number found, and store them in a vector in *VEC_PTR.
2377 Store in *LEN_PTR the size allocated for the vector.
52f8ec73
JB
2378 Store in *NEXT_PTR the next position after POS where an overlay starts,
2379 or ZV if there are no more overlays.
bbbe9545 2380 Store in *PREV_PTR the previous position before POS where an overlay ends,
413e06a4
RS
2381 or where an overlay starts which ends at or after POS;
2382 or BEGV if there are no such overlays.
239c932b 2383 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
2eec3b4e
RS
2384
2385 *VEC_PTR and *LEN_PTR should contain a valid vector and size
61d54cd5
RS
2386 when this function is called.
2387
2388 If EXTEND is non-zero, we make the vector bigger if necessary.
2389 If EXTEND is zero, we never extend the vector,
2390 and we store only as many overlays as will fit.
ac869cf7
MB
2391 But we still return the total number of overlays.
2392
2393 If CHANGE_REQ is true, then any position written into *PREV_PTR or
2394 *NEXT_PTR is guaranteed to be not equal to POS, unless it is the
2395 default (BEGV or ZV). */
2eec3b4e
RS
2396
2397int
ac869cf7 2398overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr, prev_ptr, change_req)
2eec3b4e 2399 int pos;
61d54cd5 2400 int extend;
2eec3b4e
RS
2401 Lisp_Object **vec_ptr;
2402 int *len_ptr;
2403 int *next_ptr;
239c932b 2404 int *prev_ptr;
ac869cf7 2405 int change_req;
1ab256cb 2406{
6af718a4 2407 Lisp_Object tail, overlay, start, end;
2eec3b4e
RS
2408 int idx = 0;
2409 int len = *len_ptr;
2410 Lisp_Object *vec = *vec_ptr;
2411 int next = ZV;
239c932b 2412 int prev = BEGV;
61d54cd5
RS
2413 int inhibit_storing = 0;
2414
2eec3b4e 2415 for (tail = current_buffer->overlays_before;
8fc0589a 2416 GC_CONSP (tail);
7539e11f 2417 tail = XCDR (tail))
2eec3b4e 2418 {
239c932b 2419 int startpos, endpos;
52f8ec73 2420
7539e11f 2421 overlay = XCAR (tail);
1ab256cb 2422
2eec3b4e
RS
2423 start = OVERLAY_START (overlay);
2424 end = OVERLAY_END (overlay);
239c932b
RS
2425 endpos = OVERLAY_POSITION (end);
2426 if (endpos < pos)
2427 {
2428 if (prev < endpos)
2429 prev = endpos;
2430 break;
2431 }
413e06a4
RS
2432 startpos = OVERLAY_POSITION (start);
2433 /* This one ends at or after POS
daa1c109 2434 so its start counts for PREV_PTR if it's before POS. */
413e06a4
RS
2435 if (prev < startpos && startpos < pos)
2436 prev = startpos;
239c932b
RS
2437 if (endpos == pos)
2438 continue;
2eec3b4e
RS
2439 if (startpos <= pos)
2440 {
2441 if (idx == len)
2442 {
61d54cd5
RS
2443 /* The supplied vector is full.
2444 Either make it bigger, or don't store any more in it. */
2445 if (extend)
2446 {
0552666b
GM
2447 /* Make it work with an initial len == 0. */
2448 len *= 2;
2449 if (len == 0)
2450 len = 4;
2451 *len_ptr = len;
61d54cd5
RS
2452 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
2453 *vec_ptr = vec;
2454 }
2455 else
2456 inhibit_storing = 1;
2eec3b4e 2457 }
61d54cd5
RS
2458
2459 if (!inhibit_storing)
2460 vec[idx] = overlay;
2461 /* Keep counting overlays even if we can't return them all. */
2462 idx++;
2eec3b4e
RS
2463 }
2464 else if (startpos < next)
2465 next = startpos;
2466 }
2467
2468 for (tail = current_buffer->overlays_after;
8fc0589a 2469 GC_CONSP (tail);
7539e11f 2470 tail = XCDR (tail))
1ab256cb 2471 {
239c932b 2472 int startpos, endpos;
52f8ec73 2473
7539e11f 2474 overlay = XCAR (tail);
2eec3b4e
RS
2475
2476 start = OVERLAY_START (overlay);
2477 end = OVERLAY_END (overlay);
2478 startpos = OVERLAY_POSITION (start);
52f8ec73 2479 if (pos < startpos)
2eec3b4e
RS
2480 {
2481 if (startpos < next)
2482 next = startpos;
2483 break;
2484 }
239c932b
RS
2485 endpos = OVERLAY_POSITION (end);
2486 if (pos < endpos)
2eec3b4e
RS
2487 {
2488 if (idx == len)
2489 {
61d54cd5
RS
2490 if (extend)
2491 {
2492 *len_ptr = len *= 2;
0552666b
GM
2493 if (len == 0)
2494 len = *len_ptr = 4;
61d54cd5
RS
2495 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
2496 *vec_ptr = vec;
2497 }
2498 else
2499 inhibit_storing = 1;
2eec3b4e 2500 }
61d54cd5
RS
2501
2502 if (!inhibit_storing)
2503 vec[idx] = overlay;
2504 idx++;
413e06a4
RS
2505
2506 if (startpos < pos && startpos > prev)
2507 prev = startpos;
2eec3b4e 2508 }
239c932b
RS
2509 else if (endpos < pos && endpos > prev)
2510 prev = endpos;
1d5f4c1d
MB
2511 else if (endpos == pos && startpos > prev
2512 && (!change_req || startpos < pos))
413e06a4 2513 prev = startpos;
1ab256cb
RM
2514 }
2515
239c932b
RS
2516 if (next_ptr)
2517 *next_ptr = next;
2518 if (prev_ptr)
2519 *prev_ptr = prev;
2eec3b4e
RS
2520 return idx;
2521}
74514898
RS
2522\f
2523/* Find all the overlays in the current buffer that overlap the range BEG-END
2a3eeee7
RS
2524 or are empty at BEG.
2525
74514898
RS
2526 Return the number found, and store them in a vector in *VEC_PTR.
2527 Store in *LEN_PTR the size allocated for the vector.
2528 Store in *NEXT_PTR the next position after POS where an overlay starts,
2529 or ZV if there are no more overlays.
2530 Store in *PREV_PTR the previous position before POS where an overlay ends,
2531 or BEGV if there are no previous overlays.
2532 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
2533
2534 *VEC_PTR and *LEN_PTR should contain a valid vector and size
2535 when this function is called.
2536
2537 If EXTEND is non-zero, we make the vector bigger if necessary.
2538 If EXTEND is zero, we never extend the vector,
2539 and we store only as many overlays as will fit.
2540 But we still return the total number of overlays. */
2541
2542int
2543overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr)
2544 int beg, end;
2545 int extend;
2546 Lisp_Object **vec_ptr;
2547 int *len_ptr;
2548 int *next_ptr;
2549 int *prev_ptr;
2550{
6af718a4 2551 Lisp_Object tail, overlay, ostart, oend;
74514898
RS
2552 int idx = 0;
2553 int len = *len_ptr;
2554 Lisp_Object *vec = *vec_ptr;
2555 int next = ZV;
2556 int prev = BEGV;
2557 int inhibit_storing = 0;
2558
2559 for (tail = current_buffer->overlays_before;
2560 GC_CONSP (tail);
7539e11f 2561 tail = XCDR (tail))
74514898
RS
2562 {
2563 int startpos, endpos;
2564
7539e11f 2565 overlay = XCAR (tail);
74514898
RS
2566
2567 ostart = OVERLAY_START (overlay);
2568 oend = OVERLAY_END (overlay);
2569 endpos = OVERLAY_POSITION (oend);
2570 if (endpos < beg)
2571 {
2572 if (prev < endpos)
2573 prev = endpos;
2574 break;
2575 }
2576 startpos = OVERLAY_POSITION (ostart);
2577 /* Count an interval if it either overlaps the range
2a3eeee7 2578 or is empty at the start of the range. */
74514898 2579 if ((beg < endpos && startpos < end)
2a3eeee7 2580 || (startpos == endpos && beg == endpos))
74514898
RS
2581 {
2582 if (idx == len)
2583 {
2584 /* The supplied vector is full.
2585 Either make it bigger, or don't store any more in it. */
2586 if (extend)
2587 {
2588 *len_ptr = len *= 2;
2589 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
2590 *vec_ptr = vec;
2591 }
2592 else
2593 inhibit_storing = 1;
2594 }
2595
2596 if (!inhibit_storing)
2597 vec[idx] = overlay;
2598 /* Keep counting overlays even if we can't return them all. */
2599 idx++;
2600 }
2601 else if (startpos < next)
2602 next = startpos;
2603 }
2604
2605 for (tail = current_buffer->overlays_after;
2606 GC_CONSP (tail);
7539e11f 2607 tail = XCDR (tail))
74514898
RS
2608 {
2609 int startpos, endpos;
2610
7539e11f 2611 overlay = XCAR (tail);
74514898
RS
2612
2613 ostart = OVERLAY_START (overlay);
2614 oend = OVERLAY_END (overlay);
2615 startpos = OVERLAY_POSITION (ostart);
2616 if (end < startpos)
2617 {
2618 if (startpos < next)
2619 next = startpos;
2620 break;
2621 }
2622 endpos = OVERLAY_POSITION (oend);
2a3eeee7
RS
2623 /* Count an interval if it either overlaps the range
2624 or is empty at the start of the range. */
74514898 2625 if ((beg < endpos && startpos < end)
2a3eeee7 2626 || (startpos == endpos && beg == endpos))
74514898
RS
2627 {
2628 if (idx == len)
2629 {
2630 if (extend)
2631 {
2632 *len_ptr = len *= 2;
2633 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
2634 *vec_ptr = vec;
2635 }
2636 else
2637 inhibit_storing = 1;
2638 }
2639
2640 if (!inhibit_storing)
2641 vec[idx] = overlay;
2642 idx++;
2643 }
2644 else if (endpos < beg && endpos > prev)
2645 prev = endpos;
2646 }
fc04fa47 2647
74514898
RS
2648 if (next_ptr)
2649 *next_ptr = next;
2650 if (prev_ptr)
2651 *prev_ptr = prev;
2652 return idx;
2653}
09a22085
GM
2654
2655
2656/* Return non-zero if there exists an overlay with a non-nil
2657 `mouse-face' property overlapping OVERLAY. */
2658
2659int
2660mouse_face_overlay_overlaps (overlay)
2661 Lisp_Object overlay;
2662{
2663 int start = OVERLAY_POSITION (OVERLAY_START (overlay));
2664 int end = OVERLAY_POSITION (OVERLAY_END (overlay));
bfd8410f 2665 int n, i, size;
09a22085
GM
2666 Lisp_Object *v, tem;
2667
bfd8410f
GM
2668 size = 10;
2669 v = (Lisp_Object *) alloca (size * sizeof *v);
2670 n = overlays_in (start, end, 0, &v, &size, NULL, NULL);
2671 if (n > size)
09a22085 2672 {
09a22085
GM
2673 v = (Lisp_Object *) alloca (n * sizeof *v);
2674 overlays_in (start, end, 0, &v, &n, NULL, NULL);
2675 }
2676
2677 for (i = 0; i < n; ++i)
2678 if (!EQ (v[i], overlay)
2679 && (tem = Foverlay_get (overlay, Qmouse_face),
2680 !NILP (tem)))
2681 break;
2682
2683 return i < n;
2684}
2685
2686
74514898 2687\f
fc04fa47
KH
2688/* Fast function to just test if we're at an overlay boundary. */
2689int
2690overlay_touches_p (pos)
2691 int pos;
2692{
2693 Lisp_Object tail, overlay;
2694
2695 for (tail = current_buffer->overlays_before; GC_CONSP (tail);
7539e11f 2696 tail = XCDR (tail))
fc04fa47
KH
2697 {
2698 int endpos;
2699
7539e11f 2700 overlay = XCAR (tail);
fc04fa47
KH
2701 if (!GC_OVERLAYP (overlay))
2702 abort ();
2703
2704 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2705 if (endpos < pos)
2706 break;
2707 if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos)
2708 return 1;
2709 }
2710
2711 for (tail = current_buffer->overlays_after; GC_CONSP (tail);
7539e11f 2712 tail = XCDR (tail))
fc04fa47
KH
2713 {
2714 int startpos;
2715
7539e11f 2716 overlay = XCAR (tail);
fc04fa47
KH
2717 if (!GC_OVERLAYP (overlay))
2718 abort ();
2719
2720 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2721 if (pos < startpos)
2722 break;
2723 if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
2724 return 1;
2725 }
2726 return 0;
2727}
2eec3b4e 2728\f
5985d248
KH
2729struct sortvec
2730{
2731 Lisp_Object overlay;
2732 int beg, end;
2733 int priority;
2734};
2735
2736static int
dfcf069d
AS
2737compare_overlays (v1, v2)
2738 const void *v1, *v2;
5985d248 2739{
dfcf069d
AS
2740 const struct sortvec *s1 = (const struct sortvec *) v1;
2741 const struct sortvec *s2 = (const struct sortvec *) v2;
5985d248
KH
2742 if (s1->priority != s2->priority)
2743 return s1->priority - s2->priority;
2744 if (s1->beg != s2->beg)
2745 return s1->beg - s2->beg;
2746 if (s1->end != s2->end)
2747 return s2->end - s1->end;
2748 return 0;
2749}
2750
2751/* Sort an array of overlays by priority. The array is modified in place.
2752 The return value is the new size; this may be smaller than the original
2753 size if some of the overlays were invalid or were window-specific. */
2754int
2755sort_overlays (overlay_vec, noverlays, w)
2756 Lisp_Object *overlay_vec;
2757 int noverlays;
2758 struct window *w;
2759{
2760 int i, j;
2761 struct sortvec *sortvec;
2762 sortvec = (struct sortvec *) alloca (noverlays * sizeof (struct sortvec));
2763
2764 /* Put the valid and relevant overlays into sortvec. */
2765
2766 for (i = 0, j = 0; i < noverlays; i++)
2767 {
0fa767e7 2768 Lisp_Object tem;
c99fc30f 2769 Lisp_Object overlay;
5985d248 2770
c99fc30f 2771 overlay = overlay_vec[i];
5985d248
KH
2772 if (OVERLAY_VALID (overlay)
2773 && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0
2774 && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0)
2775 {
0fa767e7
KH
2776 /* If we're interested in a specific window, then ignore
2777 overlays that are limited to some other window. */
2778 if (w)
5985d248 2779 {
0fa767e7
KH
2780 Lisp_Object window;
2781
2782 window = Foverlay_get (overlay, Qwindow);
a7a60ce9 2783 if (WINDOWP (window) && XWINDOW (window) != w)
0fa767e7 2784 continue;
5985d248 2785 }
0fa767e7
KH
2786
2787 /* This overlay is good and counts: put it into sortvec. */
2788 sortvec[j].overlay = overlay;
2789 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
2790 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
2791 tem = Foverlay_get (overlay, Qpriority);
2792 if (INTEGERP (tem))
2793 sortvec[j].priority = XINT (tem);
2794 else
2795 sortvec[j].priority = 0;
2796 j++;
5985d248
KH
2797 }
2798 }
2799 noverlays = j;
2800
2801 /* Sort the overlays into the proper order: increasing priority. */
2802
2803 if (noverlays > 1)
2804 qsort (sortvec, noverlays, sizeof (struct sortvec), compare_overlays);
2805
2806 for (i = 0; i < noverlays; i++)
2807 overlay_vec[i] = sortvec[i].overlay;
2808 return (noverlays);
2809}
2810\f
bbbe9545
KH
2811struct sortstr
2812{
cb26008f 2813 Lisp_Object string, string2;
bbbe9545
KH
2814 int size;
2815 int priority;
2816};
2817
e8185fa8
KH
2818struct sortstrlist
2819{
2820 struct sortstr *buf; /* An array that expands as needed; never freed. */
2821 int size; /* Allocated length of that array. */
2822 int used; /* How much of the array is currently in use. */
2823 int bytes; /* Total length of the strings in buf. */
2824};
2825
2826/* Buffers for storing information about the overlays touching a given
2827 position. These could be automatic variables in overlay_strings, but
2828 it's more efficient to hold onto the memory instead of repeatedly
2829 allocating and freeing it. */
2830static struct sortstrlist overlay_heads, overlay_tails;
9492daf2 2831static unsigned char *overlay_str_buf;
e8185fa8
KH
2832
2833/* Allocated length of overlay_str_buf. */
2834static int overlay_str_len;
2835
bbbe9545
KH
2836/* A comparison function suitable for passing to qsort. */
2837static int
2838cmp_for_strings (as1, as2)
2839 char *as1, *as2;
2840{
2841 struct sortstr *s1 = (struct sortstr *)as1;
2842 struct sortstr *s2 = (struct sortstr *)as2;
2843 if (s1->size != s2->size)
2844 return s2->size - s1->size;
2845 if (s1->priority != s2->priority)
2846 return s1->priority - s2->priority;
2847 return 0;
2848}
2849
e8185fa8 2850static void
cb26008f 2851record_overlay_string (ssl, str, str2, pri, size)
e8185fa8 2852 struct sortstrlist *ssl;
cb26008f 2853 Lisp_Object str, str2, pri;
e8185fa8
KH
2854 int size;
2855{
43d27a72
RS
2856 int nbytes;
2857
e8185fa8
KH
2858 if (ssl->used == ssl->size)
2859 {
2860 if (ssl->buf)
2861 ssl->size *= 2;
2862 else
2863 ssl->size = 5;
2864 ssl->buf = ((struct sortstr *)
2865 xrealloc (ssl->buf, ssl->size * sizeof (struct sortstr)));
2866 }
2867 ssl->buf[ssl->used].string = str;
cb26008f 2868 ssl->buf[ssl->used].string2 = str2;
e8185fa8
KH
2869 ssl->buf[ssl->used].size = size;
2870 ssl->buf[ssl->used].priority = (INTEGERP (pri) ? XINT (pri) : 0);
2871 ssl->used++;
43d27a72
RS
2872
2873 if (NILP (current_buffer->enable_multibyte_characters))
2874 nbytes = XSTRING (str)->size;
2875 else if (! STRING_MULTIBYTE (str))
2876 nbytes = count_size_as_multibyte (XSTRING (str)->data,
fc932ac6 2877 STRING_BYTES (XSTRING (str)));
43d27a72 2878 else
fc932ac6 2879 nbytes = STRING_BYTES (XSTRING (str));
43d27a72
RS
2880
2881 ssl->bytes += nbytes;
2882
cb26008f 2883 if (STRINGP (str2))
43d27a72
RS
2884 {
2885 if (NILP (current_buffer->enable_multibyte_characters))
2886 nbytes = XSTRING (str2)->size;
2887 else if (! STRING_MULTIBYTE (str2))
2888 nbytes = count_size_as_multibyte (XSTRING (str2)->data,
fc932ac6 2889 STRING_BYTES (XSTRING (str2)));
43d27a72 2890 else
fc932ac6 2891 nbytes = STRING_BYTES (XSTRING (str2));
43d27a72
RS
2892
2893 ssl->bytes += nbytes;
2894 }
e8185fa8 2895}
bbbe9545
KH
2896
2897/* Return the concatenation of the strings associated with overlays that
2898 begin or end at POS, ignoring overlays that are specific to a window
2899 other than W. The strings are concatenated in the appropriate order:
2900 shorter overlays nest inside longer ones, and higher priority inside
cb26008f
KH
2901 lower. Normally all of the after-strings come first, but zero-sized
2902 overlays have their after-strings ride along with the before-strings
2903 because it would look strange to print them inside-out.
2904
2905 Returns the string length, and stores the contents indirectly through
2906 PSTR, if that variable is non-null. The string may be overwritten by
2907 subsequent calls. */
6b5d3b89 2908
bbbe9545
KH
2909int
2910overlay_strings (pos, w, pstr)
2911 int pos;
2912 struct window *w;
6b5d3b89 2913 unsigned char **pstr;
bbbe9545 2914{
e8185fa8 2915 Lisp_Object ov, overlay, window, str;
bbbe9545 2916 int startpos, endpos;
43d27a72 2917 int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
bbbe9545 2918
e8185fa8
KH
2919 overlay_heads.used = overlay_heads.bytes = 0;
2920 overlay_tails.used = overlay_tails.bytes = 0;
7539e11f 2921 for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCDR (ov))
bbbe9545 2922 {
7539e11f 2923 overlay = XCAR (ov);
bbbe9545
KH
2924 if (!OVERLAYP (overlay))
2925 abort ();
2926
2927 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2928 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2929 if (endpos < pos)
2930 break;
2931 if (endpos != pos && startpos != pos)
2932 continue;
2933 window = Foverlay_get (overlay, Qwindow);
2934 if (WINDOWP (window) && XWINDOW (window) != w)
2935 continue;
e8185fa8
KH
2936 if (startpos == pos
2937 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
2938 record_overlay_string (&overlay_heads, str,
cb26008f
KH
2939 (startpos == endpos
2940 ? Foverlay_get (overlay, Qafter_string)
2941 : Qnil),
2942 Foverlay_get (overlay, Qpriority),
2943 endpos - startpos);
2944 else if (endpos == pos
2945 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
2946 record_overlay_string (&overlay_tails, str, Qnil,
e8185fa8
KH
2947 Foverlay_get (overlay, Qpriority),
2948 endpos - startpos);
bbbe9545 2949 }
7539e11f 2950 for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCDR (ov))
bbbe9545 2951 {
7539e11f 2952 overlay = XCAR (ov);
bbbe9545
KH
2953 if (!OVERLAYP (overlay))
2954 abort ();
2955
2956 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2957 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2958 if (startpos > pos)
2959 break;
e8185fa8
KH
2960 if (endpos != pos && startpos != pos)
2961 continue;
2962 window = Foverlay_get (overlay, Qwindow);
2963 if (WINDOWP (window) && XWINDOW (window) != w)
2964 continue;
e8185fa8
KH
2965 if (startpos == pos
2966 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
2967 record_overlay_string (&overlay_heads, str,
cb26008f
KH
2968 (startpos == endpos
2969 ? Foverlay_get (overlay, Qafter_string)
2970 : Qnil),
2971 Foverlay_get (overlay, Qpriority),
2972 endpos - startpos);
2973 else if (endpos == pos
2974 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
2975 record_overlay_string (&overlay_tails, str, Qnil,
e8185fa8
KH
2976 Foverlay_get (overlay, Qpriority),
2977 endpos - startpos);
bbbe9545 2978 }
e8185fa8
KH
2979 if (overlay_tails.used > 1)
2980 qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr),
2981 cmp_for_strings);
2982 if (overlay_heads.used > 1)
2983 qsort (overlay_heads.buf, overlay_heads.used, sizeof (struct sortstr),
2984 cmp_for_strings);
2985 if (overlay_heads.bytes || overlay_tails.bytes)
bbbe9545 2986 {
e8185fa8 2987 Lisp_Object tem;
bbbe9545 2988 int i;
9f4d7cde 2989 unsigned char *p;
e8185fa8 2990 int total = overlay_heads.bytes + overlay_tails.bytes;
bbbe9545
KH
2991
2992 if (total > overlay_str_len)
9f4d7cde
RS
2993 {
2994 overlay_str_len = total;
2995 overlay_str_buf = (unsigned char *)xrealloc (overlay_str_buf,
2996 total);
2997 }
bbbe9545 2998 p = overlay_str_buf;
e8185fa8 2999 for (i = overlay_tails.used; --i >= 0;)
bbbe9545 3000 {
43d27a72 3001 int nbytes;
e8185fa8 3002 tem = overlay_tails.buf[i].string;
fc932ac6
RS
3003 nbytes = copy_text (XSTRING (tem)->data, p,
3004 STRING_BYTES (XSTRING (tem)),
43d27a72
RS
3005 STRING_MULTIBYTE (tem), multibyte);
3006 p += nbytes;
bbbe9545 3007 }
e8185fa8 3008 for (i = 0; i < overlay_heads.used; ++i)
bbbe9545 3009 {
43d27a72 3010 int nbytes;
e8185fa8 3011 tem = overlay_heads.buf[i].string;
fc932ac6
RS
3012 nbytes = copy_text (XSTRING (tem)->data, p,
3013 STRING_BYTES (XSTRING (tem)),
43d27a72
RS
3014 STRING_MULTIBYTE (tem), multibyte);
3015 p += nbytes;
cb26008f
KH
3016 tem = overlay_heads.buf[i].string2;
3017 if (STRINGP (tem))
3018 {
43d27a72 3019 nbytes = copy_text (XSTRING (tem)->data, p,
fc932ac6 3020 STRING_BYTES (XSTRING (tem)),
43d27a72
RS
3021 STRING_MULTIBYTE (tem), multibyte);
3022 p += nbytes;
cb26008f 3023 }
bbbe9545 3024 }
cb26008f
KH
3025 if (p != overlay_str_buf + total)
3026 abort ();
bbbe9545
KH
3027 if (pstr)
3028 *pstr = overlay_str_buf;
e8185fa8 3029 return total;
bbbe9545 3030 }
e8185fa8 3031 return 0;
bbbe9545
KH
3032}
3033\f
5c4f68f1 3034/* Shift overlays in BUF's overlay lists, to center the lists at POS. */
1ab256cb 3035
2eec3b4e 3036void
5c4f68f1
JB
3037recenter_overlay_lists (buf, pos)
3038 struct buffer *buf;
2eec3b4e
RS
3039 int pos;
3040{
3041 Lisp_Object overlay, tail, next, prev, beg, end;
3042
3043 /* See if anything in overlays_before should move to overlays_after. */
3044
3045 /* We don't strictly need prev in this loop; it should always be nil.
3046 But we use it for symmetry and in case that should cease to be true
3047 with some future change. */
3048 prev = Qnil;
5c4f68f1 3049 for (tail = buf->overlays_before;
2eec3b4e
RS
3050 CONSP (tail);
3051 prev = tail, tail = next)
1ab256cb 3052 {
7539e11f
KR
3053 next = XCDR (tail);
3054 overlay = XCAR (tail);
2eec3b4e
RS
3055
3056 /* If the overlay is not valid, get rid of it. */
3057 if (!OVERLAY_VALID (overlay))
52f8ec73
JB
3058#if 1
3059 abort ();
3060#else
2eec3b4e
RS
3061 {
3062 /* Splice the cons cell TAIL out of overlays_before. */
3063 if (!NILP (prev))
7539e11f 3064 XCDR (prev) = next;
2eec3b4e 3065 else
5c4f68f1 3066 buf->overlays_before = next;
2eec3b4e
RS
3067 tail = prev;
3068 continue;
3069 }
52f8ec73 3070#endif
1ab256cb 3071
2eec3b4e
RS
3072 beg = OVERLAY_START (overlay);
3073 end = OVERLAY_END (overlay);
1ab256cb 3074
2eec3b4e 3075 if (OVERLAY_POSITION (end) > pos)
1ab256cb 3076 {
2eec3b4e
RS
3077 /* OVERLAY needs to be moved. */
3078 int where = OVERLAY_POSITION (beg);
3079 Lisp_Object other, other_prev;
3080
3081 /* Splice the cons cell TAIL out of overlays_before. */
3082 if (!NILP (prev))
f3fbd155 3083 XSETCDR (prev, next);
2eec3b4e 3084 else
5c4f68f1 3085 buf->overlays_before = next;
2eec3b4e
RS
3086
3087 /* Search thru overlays_after for where to put it. */
3088 other_prev = Qnil;
5c4f68f1 3089 for (other = buf->overlays_after;
2eec3b4e 3090 CONSP (other);
7539e11f 3091 other_prev = other, other = XCDR (other))
1ab256cb 3092 {
6af718a4 3093 Lisp_Object otherbeg, otheroverlay;
2eec3b4e 3094
7539e11f 3095 otheroverlay = XCAR (other);
2eec3b4e 3096 if (! OVERLAY_VALID (otheroverlay))
52f8ec73 3097 abort ();
2eec3b4e
RS
3098
3099 otherbeg = OVERLAY_START (otheroverlay);
3100 if (OVERLAY_POSITION (otherbeg) >= where)
3101 break;
1ab256cb 3102 }
2eec3b4e
RS
3103
3104 /* Add TAIL to overlays_after before OTHER. */
f3fbd155 3105 XSETCDR (tail, other);
2eec3b4e 3106 if (!NILP (other_prev))
f3fbd155 3107 XSETCDR (other_prev, tail);
1ab256cb 3108 else
5c4f68f1 3109 buf->overlays_after = tail;
2eec3b4e 3110 tail = prev;
1ab256cb 3111 }
2eec3b4e
RS
3112 else
3113 /* We've reached the things that should stay in overlays_before.
3114 All the rest of overlays_before must end even earlier,
3115 so stop now. */
3116 break;
3117 }
3118
3119 /* See if anything in overlays_after should be in overlays_before. */
3120 prev = Qnil;
5c4f68f1 3121 for (tail = buf->overlays_after;
2eec3b4e
RS
3122 CONSP (tail);
3123 prev = tail, tail = next)
3124 {
7539e11f
KR
3125 next = XCDR (tail);
3126 overlay = XCAR (tail);
2eec3b4e
RS
3127
3128 /* If the overlay is not valid, get rid of it. */
3129 if (!OVERLAY_VALID (overlay))
52f8ec73
JB
3130#if 1
3131 abort ();
3132#else
2eec3b4e
RS
3133 {
3134 /* Splice the cons cell TAIL out of overlays_after. */
3135 if (!NILP (prev))
7539e11f 3136 XCDR (prev) = next;
2eec3b4e 3137 else
5c4f68f1 3138 buf->overlays_after = next;
2eec3b4e
RS
3139 tail = prev;
3140 continue;
3141 }
52f8ec73 3142#endif
2eec3b4e
RS
3143
3144 beg = OVERLAY_START (overlay);
3145 end = OVERLAY_END (overlay);
3146
3147 /* Stop looking, when we know that nothing further
3148 can possibly end before POS. */
3149 if (OVERLAY_POSITION (beg) > pos)
3150 break;
3151
3152 if (OVERLAY_POSITION (end) <= pos)
3153 {
3154 /* OVERLAY needs to be moved. */
3155 int where = OVERLAY_POSITION (end);
3156 Lisp_Object other, other_prev;
3157
3158 /* Splice the cons cell TAIL out of overlays_after. */
3159 if (!NILP (prev))
f3fbd155 3160 XSETCDR (prev, next);
2eec3b4e 3161 else
5c4f68f1 3162 buf->overlays_after = next;
2eec3b4e
RS
3163
3164 /* Search thru overlays_before for where to put it. */
3165 other_prev = Qnil;
5c4f68f1 3166 for (other = buf->overlays_before;
2eec3b4e 3167 CONSP (other);
7539e11f 3168 other_prev = other, other = XCDR (other))
2eec3b4e
RS
3169 {
3170 Lisp_Object otherend, otheroverlay;
2eec3b4e 3171
7539e11f 3172 otheroverlay = XCAR (other);
2eec3b4e 3173 if (! OVERLAY_VALID (otheroverlay))
52f8ec73 3174 abort ();
2eec3b4e
RS
3175
3176 otherend = OVERLAY_END (otheroverlay);
3177 if (OVERLAY_POSITION (otherend) <= where)
3178 break;
3179 }
3180
3181 /* Add TAIL to overlays_before before OTHER. */
f3fbd155 3182 XSETCDR (tail, other);
2eec3b4e 3183 if (!NILP (other_prev))
f3fbd155 3184 XSETCDR (other_prev, tail);
2eec3b4e 3185 else
5c4f68f1 3186 buf->overlays_before = tail;
2eec3b4e
RS
3187 tail = prev;
3188 }
3189 }
3190
8d7a4592 3191 XSETFASTINT (buf->overlay_center, pos);
2eec3b4e 3192}
2b1bdf65 3193
423cdb46
KH
3194void
3195adjust_overlays_for_insert (pos, length)
3196 int pos;
3197 int length;
3198{
3199 /* After an insertion, the lists are still sorted properly,
3200 but we may need to update the value of the overlay center. */
3201 if (XFASTINT (current_buffer->overlay_center) >= pos)
3202 XSETFASTINT (current_buffer->overlay_center,
3203 XFASTINT (current_buffer->overlay_center) + length);
3204}
3205
3206void
3207adjust_overlays_for_delete (pos, length)
3208 int pos;
3209 int length;
3210{
3211 if (XFASTINT (current_buffer->overlay_center) < pos)
3212 /* The deletion was to our right. No change needed; the before- and
3213 after-lists are still consistent. */
3214 ;
3215 else if (XFASTINT (current_buffer->overlay_center) > pos + length)
3216 /* The deletion was to our left. We need to adjust the center value
3217 to account for the change in position, but the lists are consistent
3218 given the new value. */
3219 XSETFASTINT (current_buffer->overlay_center,
3220 XFASTINT (current_buffer->overlay_center) - length);
3221 else
3222 /* We're right in the middle. There might be things on the after-list
3223 that now belong on the before-list. Recentering will move them,
3224 and also update the center point. */
3225 recenter_overlay_lists (current_buffer, pos);
3226}
3227
2b1bdf65
KH
3228/* Fix up overlays that were garbled as a result of permuting markers
3229 in the range START through END. Any overlay with at least one
3230 endpoint in this range will need to be unlinked from the overlay
3231 list and reinserted in its proper place.
3232 Such an overlay might even have negative size at this point.
3233 If so, we'll reverse the endpoints. Can you think of anything
3234 better to do in this situation? */
3235void
3236fix_overlays_in_range (start, end)
3237 register int start, end;
3238{
6af718a4 3239 Lisp_Object overlay;
2b1bdf65
KH
3240 Lisp_Object before_list, after_list;
3241 Lisp_Object *ptail, *pbefore = &before_list, *pafter = &after_list;
3242 int startpos, endpos;
3243
3244 /* This algorithm shifts links around instead of consing and GCing.
3245 The loop invariant is that before_list (resp. after_list) is a
3246 well-formed list except that its last element, the one that
3247 *pbefore (resp. *pafter) points to, is still uninitialized.
3248 So it's not a bug that before_list isn't initialized, although
3249 it may look strange. */
3250 for (ptail = &current_buffer->overlays_before; CONSP (*ptail);)
3251 {
7539e11f 3252 overlay = XCAR (*ptail);
2b1bdf65
KH
3253 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3254 if (endpos < start)
3255 break;
3256 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3257 if (endpos < end
3258 || (startpos >= start && startpos < end))
3259 {
3260 /* If the overlay is backwards, fix that now. */
3261 if (startpos > endpos)
3262 {
3263 int tem;
2c99f3ea
RS
3264 Fset_marker (OVERLAY_START (overlay), make_number (endpos),
3265 Qnil);
3266 Fset_marker (OVERLAY_END (overlay), make_number (startpos),
3267 Qnil);
2b1bdf65
KH
3268 tem = startpos; startpos = endpos; endpos = tem;
3269 }
3270 /* Add it to the end of the wrong list. Later on,
3271 recenter_overlay_lists will move it to the right place. */
3272 if (endpos < XINT (current_buffer->overlay_center))
3273 {
3274 *pafter = *ptail;
7539e11f 3275 pafter = &XCDR (*ptail);
2b1bdf65
KH
3276 }
3277 else
3278 {
3279 *pbefore = *ptail;
7539e11f 3280 pbefore = &XCDR (*ptail);
2b1bdf65 3281 }
7539e11f 3282 *ptail = XCDR (*ptail);
2b1bdf65
KH
3283 }
3284 else
7539e11f 3285 ptail = &XCDR (*ptail);
2b1bdf65
KH
3286 }
3287 for (ptail = &current_buffer->overlays_after; CONSP (*ptail);)
3288 {
7539e11f 3289 overlay = XCAR (*ptail);
2b1bdf65
KH
3290 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3291 if (startpos >= end)
3292 break;
3293 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3294 if (startpos >= start
3295 || (endpos >= start && endpos < end))
3296 {
3297 if (startpos > endpos)
3298 {
3299 int tem;
2c99f3ea
RS
3300 Fset_marker (OVERLAY_START (overlay), make_number (endpos),
3301 Qnil);
3302 Fset_marker (OVERLAY_END (overlay), make_number (startpos),
3303 Qnil);
2b1bdf65
KH
3304 tem = startpos; startpos = endpos; endpos = tem;
3305 }
3306 if (endpos < XINT (current_buffer->overlay_center))
3307 {
3308 *pafter = *ptail;
7539e11f 3309 pafter = &XCDR (*ptail);
2b1bdf65
KH
3310 }
3311 else
3312 {
3313 *pbefore = *ptail;
7539e11f 3314 pbefore = &XCDR (*ptail);
2b1bdf65 3315 }
7539e11f 3316 *ptail = XCDR (*ptail);
2b1bdf65
KH
3317 }
3318 else
7539e11f 3319 ptail = &XCDR (*ptail);
2b1bdf65
KH
3320 }
3321
3322 /* Splice the constructed (wrong) lists into the buffer's lists,
3323 and let the recenter function make it sane again. */
3324 *pbefore = current_buffer->overlays_before;
3325 current_buffer->overlays_before = before_list;
3326 recenter_overlay_lists (current_buffer,
3327 XINT (current_buffer->overlay_center));
3328
3329 *pafter = current_buffer->overlays_after;
3330 current_buffer->overlays_after = after_list;
3331 recenter_overlay_lists (current_buffer,
3332 XINT (current_buffer->overlay_center));
3333}
3b06f880
KH
3334
3335/* We have two types of overlay: the one whose ending marker is
3336 after-insertion-marker (this is the usual case) and the one whose
3337 ending marker is before-insertion-marker. When `overlays_before'
3338 contains overlays of the latter type and the former type in this
3339 order and both overlays end at inserting position, inserting a text
3340 increases only the ending marker of the latter type, which results
3341 in incorrect ordering of `overlays_before'.
3342
3343 This function fixes ordering of overlays in the slot
3344 `overlays_before' of the buffer *BP. Before the insertion, `point'
3345 was at PREV, and now is at POS. */
3346
01136e9b 3347void
3b06f880
KH
3348fix_overlays_before (bp, prev, pos)
3349 struct buffer *bp;
3350 int prev, pos;
3351{
3352 Lisp_Object *tailp = &bp->overlays_before;
3353 Lisp_Object *right_place;
3354 int end;
3355
3356 /* After the insertion, the several overlays may be in incorrect
3357 order. The possibility is that, in the list `overlays_before',
3358 an overlay which ends at POS appears after an overlay which ends
3359 at PREV. Since POS is greater than PREV, we must fix the
3360 ordering of these overlays, by moving overlays ends at POS before
3361 the overlays ends at PREV. */
3362
3363 /* At first, find a place where disordered overlays should be linked
3364 in. It is where an overlay which end before POS exists. (i.e. an
3365 overlay whose ending marker is after-insertion-marker if disorder
3366 exists). */
3367 while (!NILP (*tailp)
7539e11f 3368 && ((end = OVERLAY_POSITION (OVERLAY_END (XCAR (*tailp))))
3b06f880 3369 >= pos))
7539e11f 3370 tailp = &XCDR (*tailp);
3b06f880
KH
3371
3372 /* If we don't find such an overlay,
3373 or the found one ends before PREV,
3374 or the found one is the last one in the list,
3375 we don't have to fix anything. */
3376 if (NILP (*tailp)
3377 || end < prev
7539e11f 3378 || NILP (XCDR (*tailp)))
3b06f880
KH
3379 return;
3380
3381 right_place = tailp;
7539e11f 3382 tailp = &XCDR (*tailp);
3b06f880
KH
3383
3384 /* Now, end position of overlays in the list *TAILP should be before
3385 or equal to PREV. In the loop, an overlay which ends at POS is
3386 moved ahead to the place pointed by RIGHT_PLACE. If we found an
3387 overlay which ends before PREV, the remaining overlays are in
3388 correct order. */
3389 while (!NILP (*tailp))
3390 {
7539e11f 3391 end = OVERLAY_POSITION (OVERLAY_END (XCAR (*tailp)));
3b06f880
KH
3392
3393 if (end == pos)
3394 { /* This overlay is disordered. */
3395 Lisp_Object found = *tailp;
3396
3397 /* Unlink the found overlay. */
7539e11f 3398 *tailp = XCDR (found);
3b06f880 3399 /* Move an overlay at RIGHT_PLACE to the next of the found one. */
7539e11f 3400 XCDR (found) = *right_place;
3b06f880
KH
3401 /* Link it into the right place. */
3402 *right_place = found;
3403 }
3404 else if (end == prev)
7539e11f 3405 tailp = &XCDR (*tailp);
3b06f880
KH
3406 else /* No more disordered overlay. */
3407 break;
3408 }
3409}
2eec3b4e 3410\f
52f8ec73 3411DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
7ee72033
MB
3412 doc: /* Return t if OBJECT is an overlay. */)
3413 (object)
52f8ec73
JB
3414 Lisp_Object object;
3415{
3416 return (OVERLAYP (object) ? Qt : Qnil);
3417}
3418
acac2700 3419DEFUN ("make-overlay", Fmake_overlay, Smake_overlay, 2, 5, 0,
7ee72033 3420 doc: /* Create a new overlay with range BEG to END in BUFFER.
018ba359
PJ
3421If omitted, BUFFER defaults to the current buffer.
3422BEG and END may be integers or markers.
3423The fourth arg FRONT-ADVANCE, if non-nil, makes the
3424front delimiter advance when text is inserted there.
3425The fifth arg REAR-ADVANCE, if non-nil, makes the
7ee72033
MB
3426rear delimiter advance when text is inserted there. */)
3427 (beg, end, buffer, front_advance, rear_advance)
5c4f68f1 3428 Lisp_Object beg, end, buffer;
acac2700 3429 Lisp_Object front_advance, rear_advance;
2eec3b4e
RS
3430{
3431 Lisp_Object overlay;
5c4f68f1 3432 struct buffer *b;
2eec3b4e 3433
5c4f68f1 3434 if (NILP (buffer))
67180c6a 3435 XSETBUFFER (buffer, current_buffer);
883047b9 3436 else
b7826503 3437 CHECK_BUFFER (buffer);
883047b9
JB
3438 if (MARKERP (beg)
3439 && ! EQ (Fmarker_buffer (beg), buffer))
3440 error ("Marker points into wrong buffer");
3441 if (MARKERP (end)
3442 && ! EQ (Fmarker_buffer (end), buffer))
3443 error ("Marker points into wrong buffer");
2eec3b4e 3444
b7826503
PJ
3445 CHECK_NUMBER_COERCE_MARKER (beg);
3446 CHECK_NUMBER_COERCE_MARKER (end);
5c4f68f1 3447
883047b9 3448 if (XINT (beg) > XINT (end))
5c4f68f1 3449 {
c99fc30f
KH
3450 Lisp_Object temp;
3451 temp = beg; beg = end; end = temp;
5c4f68f1 3452 }
883047b9
JB
3453
3454 b = XBUFFER (buffer);
3455
3456 beg = Fset_marker (Fmake_marker (), beg, buffer);
3457 end = Fset_marker (Fmake_marker (), end, buffer);
5c4f68f1 3458
acac2700
RS
3459 if (!NILP (front_advance))
3460 XMARKER (beg)->insertion_type = 1;
3461 if (!NILP (rear_advance))
3462 XMARKER (end)->insertion_type = 1;
597dd755 3463
48e2e3ba 3464 overlay = allocate_misc ();
89ca3e1b 3465 XMISCTYPE (overlay) = Lisp_Misc_Overlay;
48e2e3ba
KH
3466 XOVERLAY (overlay)->start = beg;
3467 XOVERLAY (overlay)->end = end;
3468 XOVERLAY (overlay)->plist = Qnil;
2eec3b4e
RS
3469
3470 /* Put the new overlay on the wrong list. */
3471 end = OVERLAY_END (overlay);
5c4f68f1
JB
3472 if (OVERLAY_POSITION (end) < XINT (b->overlay_center))
3473 b->overlays_after = Fcons (overlay, b->overlays_after);
2eec3b4e 3474 else
5c4f68f1 3475 b->overlays_before = Fcons (overlay, b->overlays_before);
2eec3b4e
RS
3476
3477 /* This puts it in the right list, and in the right order. */
5c4f68f1 3478 recenter_overlay_lists (b, XINT (b->overlay_center));
2eec3b4e 3479
b61982dd
JB
3480 /* We don't need to redisplay the region covered by the overlay, because
3481 the overlay has no properties at the moment. */
3482
2eec3b4e
RS
3483 return overlay;
3484}
876aa27c
RS
3485\f
3486/* Mark a section of BUF as needing redisplay because of overlays changes. */
3487
3488static void
3489modify_overlay (buf, start, end)
3490 struct buffer *buf;
3491 int start, end;
3492{
876aa27c
RS
3493 if (start > end)
3494 {
3495 int temp = start;
26f545d7
GM
3496 start = end;
3497 end = temp;
876aa27c
RS
3498 }
3499
481b5054
GM
3500 BUF_COMPUTE_UNCHANGED (buf, start, end);
3501
876aa27c
RS
3502 /* If this is a buffer not in the selected window,
3503 we must do other windows. */
3504 if (buf != XBUFFER (XWINDOW (selected_window)->buffer))
3505 windows_or_buffers_changed = 1;
876aa27c
RS
3506 /* If multiple windows show this buffer, we must do other windows. */
3507 else if (buffer_shared > 1)
3508 windows_or_buffers_changed = 1;
876aa27c 3509
d8b9150f 3510 ++BUF_OVERLAY_MODIFF (buf);
876aa27c 3511}
2eec3b4e 3512
018ba359 3513\f
2e34157c
RS
3514Lisp_Object Fdelete_overlay ();
3515
5c4f68f1 3516DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
7ee72033 3517 doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER.
018ba359
PJ
3518If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.
3519If BUFFER is omitted, and OVERLAY is in no buffer, put it in the current
7ee72033
MB
3520buffer. */)
3521 (overlay, beg, end, buffer)
5c4f68f1 3522 Lisp_Object overlay, beg, end, buffer;
2eec3b4e 3523{
0a4469c9
RS
3524 struct buffer *b, *ob;
3525 Lisp_Object obuffer;
3526 int count = specpdl_ptr - specpdl;
5c4f68f1 3527
b7826503 3528 CHECK_OVERLAY (overlay);
5c4f68f1
JB
3529 if (NILP (buffer))
3530 buffer = Fmarker_buffer (OVERLAY_START (overlay));
3ece337a 3531 if (NILP (buffer))
67180c6a 3532 XSETBUFFER (buffer, current_buffer);
b7826503 3533 CHECK_BUFFER (buffer);
883047b9
JB
3534
3535 if (MARKERP (beg)
3536 && ! EQ (Fmarker_buffer (beg), buffer))
3537 error ("Marker points into wrong buffer");
3538 if (MARKERP (end)
3539 && ! EQ (Fmarker_buffer (end), buffer))
3540 error ("Marker points into wrong buffer");
3541
b7826503
PJ
3542 CHECK_NUMBER_COERCE_MARKER (beg);
3543 CHECK_NUMBER_COERCE_MARKER (end);
b61982dd 3544
9d7608b7
KH
3545 if (XINT (beg) == XINT (end) && ! NILP (Foverlay_get (overlay, Qevaporate)))
3546 return Fdelete_overlay (overlay);
0a4469c9 3547
b61982dd
JB
3548 if (XINT (beg) > XINT (end))
3549 {
c99fc30f
KH
3550 Lisp_Object temp;
3551 temp = beg; beg = end; end = temp;
b61982dd
JB
3552 }
3553
9d7608b7
KH
3554 specbind (Qinhibit_quit, Qt);
3555
0a4469c9 3556 obuffer = Fmarker_buffer (OVERLAY_START (overlay));
5c4f68f1 3557 b = XBUFFER (buffer);
8801a864 3558 ob = BUFFERP (obuffer) ? XBUFFER (obuffer) : (struct buffer *) 0;
2eec3b4e 3559
c82ed728 3560 /* If the overlay has changed buffers, do a thorough redisplay. */
0a4469c9 3561 if (!EQ (buffer, obuffer))
50760c4a
RS
3562 {
3563 /* Redisplay where the overlay was. */
3564 if (!NILP (obuffer))
3565 {
2e34157c
RS
3566 int o_beg;
3567 int o_end;
50760c4a 3568
80509f2f
RS
3569 o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3570 o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
50760c4a 3571
2e34157c 3572 modify_overlay (ob, o_beg, o_end);
50760c4a
RS
3573 }
3574
3575 /* Redisplay where the overlay is going to be. */
876aa27c 3576 modify_overlay (b, XINT (beg), XINT (end));
50760c4a 3577 }
c82ed728
JB
3578 else
3579 /* Redisplay the area the overlay has just left, or just enclosed. */
3580 {
2e34157c 3581 int o_beg, o_end;
c82ed728 3582
80509f2f
RS
3583 o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3584 o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
c82ed728 3585
2e34157c
RS
3586 if (o_beg == XINT (beg))
3587 modify_overlay (b, o_end, XINT (end));
3588 else if (o_end == XINT (end))
3589 modify_overlay (b, o_beg, XINT (beg));
c82ed728
JB
3590 else
3591 {
2e34157c
RS
3592 if (XINT (beg) < o_beg) o_beg = XINT (beg);
3593 if (XINT (end) > o_end) o_end = XINT (end);
3594 modify_overlay (b, o_beg, o_end);
c82ed728
JB
3595 }
3596 }
b61982dd 3597
0a4469c9
RS
3598 if (!NILP (obuffer))
3599 {
3600 ob->overlays_before = Fdelq (overlay, ob->overlays_before);
3601 ob->overlays_after = Fdelq (overlay, ob->overlays_after);
3602 }
5c4f68f1
JB
3603
3604 Fset_marker (OVERLAY_START (overlay), beg, buffer);
3605 Fset_marker (OVERLAY_END (overlay), end, buffer);
2eec3b4e
RS
3606
3607 /* Put the overlay on the wrong list. */
3608 end = OVERLAY_END (overlay);
5c4f68f1
JB
3609 if (OVERLAY_POSITION (end) < XINT (b->overlay_center))
3610 b->overlays_after = Fcons (overlay, b->overlays_after);
2eec3b4e 3611 else
5c4f68f1 3612 b->overlays_before = Fcons (overlay, b->overlays_before);
2eec3b4e
RS
3613
3614 /* This puts it in the right list, and in the right order. */
5c4f68f1 3615 recenter_overlay_lists (b, XINT (b->overlay_center));
2eec3b4e 3616
0a4469c9 3617 return unbind_to (count, overlay);
2eec3b4e
RS
3618}
3619
3620DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
7ee72033
MB
3621 doc: /* Delete the overlay OVERLAY from its buffer. */)
3622 (overlay)
5c4f68f1 3623 Lisp_Object overlay;
2eec3b4e 3624{
0a4469c9 3625 Lisp_Object buffer;
5c4f68f1 3626 struct buffer *b;
0a4469c9 3627 int count = specpdl_ptr - specpdl;
5c4f68f1 3628
b7826503 3629 CHECK_OVERLAY (overlay);
52f8ec73 3630
0a4469c9
RS
3631 buffer = Fmarker_buffer (OVERLAY_START (overlay));
3632 if (NILP (buffer))
3633 return Qnil;
3634
3635 b = XBUFFER (buffer);
0a4469c9 3636 specbind (Qinhibit_quit, Qt);
26f545d7 3637
5c4f68f1 3638 b->overlays_before = Fdelq (overlay, b->overlays_before);
26f545d7 3639 b->overlays_after = Fdelq (overlay, b->overlays_after);
876aa27c 3640 modify_overlay (b,
8231a9aa
RS
3641 marker_position (OVERLAY_START (overlay)),
3642 marker_position (OVERLAY_END (overlay)));
3ece337a
JB
3643 Fset_marker (OVERLAY_START (overlay), Qnil, Qnil);
3644 Fset_marker (OVERLAY_END (overlay), Qnil, Qnil);
3645
e58c389d 3646 /* When deleting an overlay with before or after strings, turn off
26f545d7
GM
3647 display optimizations for the affected buffer, on the basis that
3648 these strings may contain newlines. This is easier to do than to
3649 check for that situation during redisplay. */
3650 if (!windows_or_buffers_changed
3651 && (!NILP (Foverlay_get (overlay, Qbefore_string))
3652 || !NILP (Foverlay_get (overlay, Qafter_string))))
3653 b->prevent_redisplay_optimizations_p = 1;
3654
0a4469c9 3655 return unbind_to (count, Qnil);
2eec3b4e
RS
3656}
3657\f
8ebafa8d
JB
3658/* Overlay dissection functions. */
3659
3660DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
7ee72033
MB
3661 doc: /* Return the position at which OVERLAY starts. */)
3662 (overlay)
8ebafa8d
JB
3663 Lisp_Object overlay;
3664{
b7826503 3665 CHECK_OVERLAY (overlay);
8ebafa8d
JB
3666
3667 return (Fmarker_position (OVERLAY_START (overlay)));
3668}
3669
3670DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
7ee72033
MB
3671 doc: /* Return the position at which OVERLAY ends. */)
3672 (overlay)
8ebafa8d
JB
3673 Lisp_Object overlay;
3674{
b7826503 3675 CHECK_OVERLAY (overlay);
8ebafa8d
JB
3676
3677 return (Fmarker_position (OVERLAY_END (overlay)));
3678}
3679
3680DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
7ee72033
MB
3681 doc: /* Return the buffer OVERLAY belongs to. */)
3682 (overlay)
8ebafa8d
JB
3683 Lisp_Object overlay;
3684{
b7826503 3685 CHECK_OVERLAY (overlay);
8ebafa8d
JB
3686
3687 return Fmarker_buffer (OVERLAY_START (overlay));
3688}
3689
3690DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
7ee72033 3691 doc: /* Return a list of the properties on OVERLAY.
018ba359 3692This is a copy of OVERLAY's plist; modifying its conses has no effect on
7ee72033
MB
3693OVERLAY. */)
3694 (overlay)
8ebafa8d
JB
3695 Lisp_Object overlay;
3696{
b7826503 3697 CHECK_OVERLAY (overlay);
8ebafa8d 3698
48e2e3ba 3699 return Fcopy_sequence (XOVERLAY (overlay)->plist);
8ebafa8d
JB
3700}
3701
3702\f
2eec3b4e 3703DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
7ee72033
MB
3704 doc: /* Return a list of the overlays that contain position POS. */)
3705 (pos)
2eec3b4e
RS
3706 Lisp_Object pos;
3707{
3708 int noverlays;
2eec3b4e
RS
3709 Lisp_Object *overlay_vec;
3710 int len;
3711 Lisp_Object result;
3712
b7826503 3713 CHECK_NUMBER_COERCE_MARKER (pos);
2eec3b4e
RS
3714
3715 len = 10;
a9800ae8 3716 /* We can't use alloca here because overlays_at can call xrealloc. */
2eec3b4e
RS
3717 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
3718
3719 /* Put all the overlays we want in a vector in overlay_vec.
3720 Store the length in len. */
2a77a7d7 3721 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
ac869cf7 3722 (int *) 0, (int *) 0, 0);
2eec3b4e
RS
3723
3724 /* Make a list of them all. */
3725 result = Flist (noverlays, overlay_vec);
3726
9ac0d9e0 3727 xfree (overlay_vec);
2eec3b4e
RS
3728 return result;
3729}
3730
74514898 3731DEFUN ("overlays-in", Foverlays_in, Soverlays_in, 2, 2, 0,
7ee72033 3732 doc: /* Return a list of the overlays that overlap the region BEG ... END.
018ba359
PJ
3733Overlap means that at least one character is contained within the overlay
3734and also contained within the specified region.
3735Empty overlays are included in the result if they are located at BEG
7ee72033
MB
3736or between BEG and END. */)
3737 (beg, end)
74514898
RS
3738 Lisp_Object beg, end;
3739{
3740 int noverlays;
3741 Lisp_Object *overlay_vec;
3742 int len;
3743 Lisp_Object result;
3744
b7826503
PJ
3745 CHECK_NUMBER_COERCE_MARKER (beg);
3746 CHECK_NUMBER_COERCE_MARKER (end);
74514898
RS
3747
3748 len = 10;
3749 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
3750
3751 /* Put all the overlays we want in a vector in overlay_vec.
3752 Store the length in len. */
3753 noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len,
3754 (int *) 0, (int *) 0);
3755
3756 /* Make a list of them all. */
3757 result = Flist (noverlays, overlay_vec);
3758
3759 xfree (overlay_vec);
3760 return result;
3761}
3762
2eec3b4e 3763DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change,
efc7e75f 3764 1, 1, 0,
7ee72033
MB
3765 doc: /* Return the next position after POS where an overlay starts or ends.
3766If there are no more overlay boundaries after POS, return (point-max). */)
3767 (pos)
2eec3b4e
RS
3768 Lisp_Object pos;
3769{
3770 int noverlays;
3771 int endpos;
3772 Lisp_Object *overlay_vec;
3773 int len;
2eec3b4e
RS
3774 int i;
3775
b7826503 3776 CHECK_NUMBER_COERCE_MARKER (pos);
2eec3b4e
RS
3777
3778 len = 10;
3779 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
3780
3781 /* Put all the overlays we want in a vector in overlay_vec.
3782 Store the length in len.
3783 endpos gets the position where the next overlay starts. */
2a77a7d7 3784 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
ac869cf7 3785 &endpos, (int *) 0, 1);
2eec3b4e
RS
3786
3787 /* If any of these overlays ends before endpos,
3788 use its ending point instead. */
3789 for (i = 0; i < noverlays; i++)
3790 {
3791 Lisp_Object oend;
3792 int oendpos;
3793
3794 oend = OVERLAY_END (overlay_vec[i]);
3795 oendpos = OVERLAY_POSITION (oend);
3796 if (oendpos < endpos)
3797 endpos = oendpos;
1ab256cb
RM
3798 }
3799
9ac0d9e0 3800 xfree (overlay_vec);
2eec3b4e
RS
3801 return make_number (endpos);
3802}
239c932b
RS
3803
3804DEFUN ("previous-overlay-change", Fprevious_overlay_change,
3805 Sprevious_overlay_change, 1, 1, 0,
7ee72033
MB
3806 doc: /* Return the previous position before POS where an overlay starts or ends.
3807If there are no more overlay boundaries before POS, return (point-min). */)
3808 (pos)
239c932b
RS
3809 Lisp_Object pos;
3810{
3811 int noverlays;
3812 int prevpos;
3813 Lisp_Object *overlay_vec;
3814 int len;
239c932b 3815
b7826503 3816 CHECK_NUMBER_COERCE_MARKER (pos);
239c932b 3817
624bbdc4
RS
3818 /* At beginning of buffer, we know the answer;
3819 avoid bug subtracting 1 below. */
3820 if (XINT (pos) == BEGV)
3821 return pos;
3822
017f0539
GM
3823 len = 10;
3824 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
3825
239c932b
RS
3826 /* Put all the overlays we want in a vector in overlay_vec.
3827 Store the length in len.
daa1c109 3828 prevpos gets the position of the previous change. */
2a77a7d7 3829 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
ac869cf7 3830 (int *) 0, &prevpos, 1);
239c932b 3831
239c932b
RS
3832 xfree (overlay_vec);
3833 return make_number (prevpos);
3834}
2eec3b4e
RS
3835\f
3836/* These functions are for debugging overlays. */
3837
3838DEFUN ("overlay-lists", Foverlay_lists, Soverlay_lists, 0, 0, 0,
7ee72033 3839 doc: /* Return a pair of lists giving all the overlays of the current buffer.
018ba359
PJ
3840The car has all the overlays before the overlay center;
3841the cdr has all the overlays after the overlay center.
3842Recentering overlays moves overlays between these lists.
3843The lists you get are copies, so that changing them has no effect.
7ee72033
MB
3844However, the overlays you get are the real objects that the buffer uses. */)
3845 ()
2eec3b4e
RS
3846{
3847 Lisp_Object before, after;
3848 before = current_buffer->overlays_before;
3849 if (CONSP (before))
3850 before = Fcopy_sequence (before);
3851 after = current_buffer->overlays_after;
3852 if (CONSP (after))
3853 after = Fcopy_sequence (after);
3854
3855 return Fcons (before, after);
3856}
3857
3858DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
7ee72033
MB
3859 doc: /* Recenter the overlays of the current buffer around position POS. */)
3860 (pos)
2eec3b4e
RS
3861 Lisp_Object pos;
3862{
b7826503 3863 CHECK_NUMBER_COERCE_MARKER (pos);
2eec3b4e 3864
5c4f68f1 3865 recenter_overlay_lists (current_buffer, XINT (pos));
2eec3b4e
RS
3866 return Qnil;
3867}
3868\f
3869DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0,
7ee72033
MB
3870 doc: /* Get the property of overlay OVERLAY with property name PROP. */)
3871 (overlay, prop)
2eec3b4e
RS
3872 Lisp_Object overlay, prop;
3873{
cab4777e 3874 Lisp_Object plist, fallback;
52f8ec73 3875
b7826503 3876 CHECK_OVERLAY (overlay);
52f8ec73 3877
cab4777e
RS
3878 fallback = Qnil;
3879
48e2e3ba 3880 for (plist = XOVERLAY (overlay)->plist;
7539e11f
KR
3881 CONSP (plist) && CONSP (XCDR (plist));
3882 plist = XCDR (XCDR (plist)))
2eec3b4e 3883 {
7539e11f
KR
3884 if (EQ (XCAR (plist), prop))
3885 return XCAR (XCDR (plist));
3886 else if (EQ (XCAR (plist), Qcategory))
cab4777e
RS
3887 {
3888 Lisp_Object tem;
3889 tem = Fcar (Fcdr (plist));
3890 if (SYMBOLP (tem))
3891 fallback = Fget (tem, prop);
3892 }
2eec3b4e 3893 }
52f8ec73 3894
cab4777e 3895 return fallback;
2eec3b4e
RS
3896}
3897
3898DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
7ee72033
MB
3899 doc: /* Set one property of overlay OVERLAY: give property PROP value VALUE. */)
3900 (overlay, prop, value)
2eec3b4e
RS
3901 Lisp_Object overlay, prop, value;
3902{
48e2e3ba 3903 Lisp_Object tail, buffer;
9d7608b7 3904 int changed;
2eec3b4e 3905
b7826503 3906 CHECK_OVERLAY (overlay);
b61982dd 3907
274a9425
RS
3908 buffer = Fmarker_buffer (OVERLAY_START (overlay));
3909
48e2e3ba 3910 for (tail = XOVERLAY (overlay)->plist;
7539e11f
KR
3911 CONSP (tail) && CONSP (XCDR (tail));
3912 tail = XCDR (XCDR (tail)))
3913 if (EQ (XCAR (tail), prop))
274a9425 3914 {
7539e11f 3915 changed = !EQ (XCAR (XCDR (tail)), value);
f3fbd155 3916 XSETCAR (XCDR (tail), value);
9d7608b7 3917 goto found;
274a9425 3918 }
9d7608b7
KH
3919 /* It wasn't in the list, so add it to the front. */
3920 changed = !NILP (value);
48e2e3ba
KH
3921 XOVERLAY (overlay)->plist
3922 = Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist));
9d7608b7
KH
3923 found:
3924 if (! NILP (buffer))
3925 {
3926 if (changed)
876aa27c 3927 modify_overlay (XBUFFER (buffer),
26f545d7
GM
3928 marker_position (OVERLAY_START (overlay)),
3929 marker_position (OVERLAY_END (overlay)));
9d7608b7
KH
3930 if (EQ (prop, Qevaporate) && ! NILP (value)
3931 && (OVERLAY_POSITION (OVERLAY_START (overlay))
3932 == OVERLAY_POSITION (OVERLAY_END (overlay))))
3933 Fdelete_overlay (overlay);
3934 }
2eec3b4e 3935 return value;
1ab256cb
RM
3936}
3937\f
9115729e
KH
3938/* Subroutine of report_overlay_modification. */
3939
3940/* Lisp vector holding overlay hook functions to call.
3941 Vector elements come in pairs.
3942 Each even-index element is a list of hook functions.
3943 The following odd-index element is the overlay they came from.
3944
3945 Before the buffer change, we fill in this vector
3946 as we call overlay hook functions.
3947 After the buffer change, we get the functions to call from this vector.
3948 This way we always call the same functions before and after the change. */
3949static Lisp_Object last_overlay_modification_hooks;
3950
3951/* Number of elements actually used in last_overlay_modification_hooks. */
3952static int last_overlay_modification_hooks_used;
3953
3954/* Add one functionlist/overlay pair
3955 to the end of last_overlay_modification_hooks. */
3956
3957static void
3958add_overlay_mod_hooklist (functionlist, overlay)
3959 Lisp_Object functionlist, overlay;
3960{
3961 int oldsize = XVECTOR (last_overlay_modification_hooks)->size;
3962
3963 if (last_overlay_modification_hooks_used == oldsize)
3964 {
3965 Lisp_Object old;
3966 old = last_overlay_modification_hooks;
3967 last_overlay_modification_hooks
3968 = Fmake_vector (make_number (oldsize * 2), Qnil);
0b1f1b09
RS
3969 bcopy (XVECTOR (old)->contents,
3970 XVECTOR (last_overlay_modification_hooks)->contents,
9115729e
KH
3971 sizeof (Lisp_Object) * oldsize);
3972 }
3973 XVECTOR (last_overlay_modification_hooks)->contents[last_overlay_modification_hooks_used++] = functionlist;
3974 XVECTOR (last_overlay_modification_hooks)->contents[last_overlay_modification_hooks_used++] = overlay;
3975}
3976\f
173f2a64
RS
3977/* Run the modification-hooks of overlays that include
3978 any part of the text in START to END.
9115729e
KH
3979 If this change is an insertion, also
3980 run the insert-before-hooks of overlay starting at END,
930a9140
RS
3981 and the insert-after-hooks of overlay ending at START.
3982
3983 This is called both before and after the modification.
3984 AFTER is nonzero when we call after the modification.
3985
9115729e
KH
3986 ARG1, ARG2, ARG3 are arguments to pass to the hook functions.
3987 When AFTER is nonzero, they are the start position,
3988 the position after the inserted new text,
3989 and the length of deleted or replaced old text. */
173f2a64
RS
3990
3991void
930a9140 3992report_overlay_modification (start, end, after, arg1, arg2, arg3)
173f2a64 3993 Lisp_Object start, end;
930a9140
RS
3994 int after;
3995 Lisp_Object arg1, arg2, arg3;
173f2a64
RS
3996{
3997 Lisp_Object prop, overlay, tail;
9115729e
KH
3998 /* 1 if this change is an insertion. */
3999 int insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end));
55b48893 4000 int tail_copied;
930a9140 4001 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
55b48893
RS
4002
4003 overlay = Qnil;
4004 tail = Qnil;
930a9140 4005 GCPRO5 (overlay, tail, arg1, arg2, arg3);
173f2a64 4006
9115729e
KH
4007 if (after)
4008 {
4009 /* Call the functions recorded in last_overlay_modification_hooks
4010 rather than scanning the overlays again.
4011 First copy the vector contents, in case some of these hooks
4012 do subsequent modification of the buffer. */
4013 int size = last_overlay_modification_hooks_used;
4014 Lisp_Object *copy = (Lisp_Object *) alloca (size * sizeof (Lisp_Object));
4015 int i;
4016
4017 bcopy (XVECTOR (last_overlay_modification_hooks)->contents,
4018 copy, size * sizeof (Lisp_Object));
4019 gcpro1.var = copy;
4020 gcpro1.nvars = size;
4021
4022 for (i = 0; i < size;)
4023 {
4024 Lisp_Object prop, overlay;
4025 prop = copy[i++];
4026 overlay = copy[i++];
4027 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
4028 }
4029 UNGCPRO;
4030 return;
4031 }
4032
4033 /* We are being called before a change.
4034 Scan the overlays to find the functions to call. */
4035 last_overlay_modification_hooks_used = 0;
55b48893 4036 tail_copied = 0;
173f2a64
RS
4037 for (tail = current_buffer->overlays_before;
4038 CONSP (tail);
7539e11f 4039 tail = XCDR (tail))
173f2a64
RS
4040 {
4041 int startpos, endpos;
be8b1c6b 4042 Lisp_Object ostart, oend;
173f2a64 4043
7539e11f 4044 overlay = XCAR (tail);
173f2a64
RS
4045
4046 ostart = OVERLAY_START (overlay);
4047 oend = OVERLAY_END (overlay);
4048 endpos = OVERLAY_POSITION (oend);
4049 if (XFASTINT (start) > endpos)
4050 break;
4051 startpos = OVERLAY_POSITION (ostart);
9115729e
KH
4052 if (insertion && (XFASTINT (start) == startpos
4053 || XFASTINT (end) == startpos))
173f2a64
RS
4054 {
4055 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
5fb5aa33
RS
4056 if (!NILP (prop))
4057 {
4058 /* Copy TAIL in case the hook recenters the overlay lists. */
55b48893
RS
4059 if (!tail_copied)
4060 tail = Fcopy_sequence (tail);
4061 tail_copied = 1;
930a9140 4062 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 4063 }
173f2a64 4064 }
9115729e
KH
4065 if (insertion && (XFASTINT (start) == endpos
4066 || XFASTINT (end) == endpos))
173f2a64
RS
4067 {
4068 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
5fb5aa33
RS
4069 if (!NILP (prop))
4070 {
55b48893
RS
4071 if (!tail_copied)
4072 tail = Fcopy_sequence (tail);
4073 tail_copied = 1;
930a9140 4074 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 4075 }
173f2a64 4076 }
3bd13e92
KH
4077 /* Test for intersecting intervals. This does the right thing
4078 for both insertion and deletion. */
4079 if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
173f2a64
RS
4080 {
4081 prop = Foverlay_get (overlay, Qmodification_hooks);
5fb5aa33
RS
4082 if (!NILP (prop))
4083 {
55b48893
RS
4084 if (!tail_copied)
4085 tail = Fcopy_sequence (tail);
4086 tail_copied = 1;
930a9140 4087 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 4088 }
173f2a64
RS
4089 }
4090 }
4091
55b48893 4092 tail_copied = 0;
173f2a64
RS
4093 for (tail = current_buffer->overlays_after;
4094 CONSP (tail);
7539e11f 4095 tail = XCDR (tail))
173f2a64
RS
4096 {
4097 int startpos, endpos;
be8b1c6b 4098 Lisp_Object ostart, oend;
173f2a64 4099
7539e11f 4100 overlay = XCAR (tail);
173f2a64
RS
4101
4102 ostart = OVERLAY_START (overlay);
4103 oend = OVERLAY_END (overlay);
4104 startpos = OVERLAY_POSITION (ostart);
cdf0b096 4105 endpos = OVERLAY_POSITION (oend);
173f2a64
RS
4106 if (XFASTINT (end) < startpos)
4107 break;
9115729e
KH
4108 if (insertion && (XFASTINT (start) == startpos
4109 || XFASTINT (end) == startpos))
173f2a64
RS
4110 {
4111 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
5fb5aa33
RS
4112 if (!NILP (prop))
4113 {
55b48893
RS
4114 if (!tail_copied)
4115 tail = Fcopy_sequence (tail);
4116 tail_copied = 1;
930a9140 4117 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 4118 }
173f2a64 4119 }
9115729e
KH
4120 if (insertion && (XFASTINT (start) == endpos
4121 || XFASTINT (end) == endpos))
173f2a64
RS
4122 {
4123 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
5fb5aa33
RS
4124 if (!NILP (prop))
4125 {
55b48893
RS
4126 if (!tail_copied)
4127 tail = Fcopy_sequence (tail);
4128 tail_copied = 1;
930a9140 4129 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 4130 }
173f2a64 4131 }
3bd13e92
KH
4132 /* Test for intersecting intervals. This does the right thing
4133 for both insertion and deletion. */
4134 if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
173f2a64
RS
4135 {
4136 prop = Foverlay_get (overlay, Qmodification_hooks);
5fb5aa33
RS
4137 if (!NILP (prop))
4138 {
55b48893
RS
4139 if (!tail_copied)
4140 tail = Fcopy_sequence (tail);
4141 tail_copied = 1;
930a9140 4142 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
5fb5aa33 4143 }
173f2a64
RS
4144 }
4145 }
55b48893
RS
4146
4147 UNGCPRO;
173f2a64
RS
4148}
4149
4150static void
930a9140
RS
4151call_overlay_mod_hooks (list, overlay, after, arg1, arg2, arg3)
4152 Lisp_Object list, overlay;
4153 int after;
4154 Lisp_Object arg1, arg2, arg3;
173f2a64 4155{
930a9140 4156 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9115729e 4157
930a9140 4158 GCPRO4 (list, arg1, arg2, arg3);
9115729e
KH
4159 if (! after)
4160 add_overlay_mod_hooklist (list, overlay);
4161
173f2a64
RS
4162 while (!NILP (list))
4163 {
930a9140
RS
4164 if (NILP (arg3))
4165 call4 (Fcar (list), overlay, after ? Qt : Qnil, arg1, arg2);
4166 else
4167 call5 (Fcar (list), overlay, after ? Qt : Qnil, arg1, arg2, arg3);
173f2a64
RS
4168 list = Fcdr (list);
4169 }
4170 UNGCPRO;
4171}
9d7608b7
KH
4172
4173/* Delete any zero-sized overlays at position POS, if the `evaporate'
4174 property is set. */
4175void
4176evaporate_overlays (pos)
4177 int pos;
4178{
4179 Lisp_Object tail, overlay, hit_list;
4180
4181 hit_list = Qnil;
4182 if (pos <= XFASTINT (current_buffer->overlay_center))
4183 for (tail = current_buffer->overlays_before; CONSP (tail);
7539e11f 4184 tail = XCDR (tail))
9d7608b7
KH
4185 {
4186 int endpos;
7539e11f 4187 overlay = XCAR (tail);
9d7608b7
KH
4188 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
4189 if (endpos < pos)
4190 break;
4191 if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos
c3935f9d 4192 && ! NILP (Foverlay_get (overlay, Qevaporate)))
9d7608b7
KH
4193 hit_list = Fcons (overlay, hit_list);
4194 }
4195 else
4196 for (tail = current_buffer->overlays_after; CONSP (tail);
7539e11f 4197 tail = XCDR (tail))
9d7608b7
KH
4198 {
4199 int startpos;
7539e11f 4200 overlay = XCAR (tail);
9d7608b7
KH
4201 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
4202 if (startpos > pos)
4203 break;
4204 if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
c3935f9d 4205 && ! NILP (Foverlay_get (overlay, Qevaporate)))
9d7608b7
KH
4206 hit_list = Fcons (overlay, hit_list);
4207 }
7539e11f
KR
4208 for (; CONSP (hit_list); hit_list = XCDR (hit_list))
4209 Fdelete_overlay (XCAR (hit_list));
9d7608b7 4210}
173f2a64 4211\f
54dfdeb0 4212/* Somebody has tried to store a value with an unacceptable type
1bf08baf
KH
4213 in the slot with offset OFFSET. */
4214
0fa3ba92 4215void
54dfdeb0
KH
4216buffer_slot_type_mismatch (offset)
4217 int offset;
0fa3ba92 4218{
54dfdeb0 4219 Lisp_Object sym;
0fa3ba92 4220 char *type_name;
7c02e886 4221
7313acd0 4222 switch (XINT (PER_BUFFER_TYPE (offset)))
0fa3ba92 4223 {
7c02e886
GM
4224 case Lisp_Int:
4225 type_name = "integers";
4226 break;
4227
4228 case Lisp_String:
4229 type_name = "strings";
4230 break;
4231
4232 case Lisp_Symbol:
4233 type_name = "symbols";
4234 break;
4235
0fa3ba92
JB
4236 default:
4237 abort ();
4238 }
4239
7313acd0 4240 sym = PER_BUFFER_SYMBOL (offset);
1bf08baf 4241 error ("Only %s should be stored in the buffer-local variable %s",
54dfdeb0 4242 type_name, XSYMBOL (sym)->name->data);
0fa3ba92 4243}
7c02e886 4244
0fa3ba92 4245\f
b86af064
GM
4246/***********************************************************************
4247 Allocation with mmap
4248 ***********************************************************************/
4249
4250#ifdef USE_MMAP_FOR_BUFFERS
4251
4252#include <sys/types.h>
4253#include <sys/mman.h>
4254
4255#ifndef MAP_ANON
4256#ifdef MAP_ANONYMOUS
4257#define MAP_ANON MAP_ANONYMOUS
4258#else
4259#define MAP_ANON 0
4260#endif
4261#endif
4262
09dfdf85
GM
4263#ifndef MAP_FAILED
4264#define MAP_FAILED ((void *) -1)
4265#endif
4266
b86af064
GM
4267#include <stdio.h>
4268#include <errno.h>
4269
4270#if MAP_ANON == 0
4271#include <fcntl.h>
4272#endif
4273
b86af064
GM
4274
4275/* Memory is allocated in regions which are mapped using mmap(2).
4276 The current implementation lets the system select mapped
4277 addresses; we're not using MAP_FIXED in general, except when
4278 trying to enlarge regions.
4279
4280 Each mapped region starts with a mmap_region structure, the user
4281 area starts after that structure, aligned to MEM_ALIGN.
4282
4283 +-----------------------+
4284 | struct mmap_info + |
4285 | padding |
4286 +-----------------------+
4287 | user data |
4288 | |
4289 | |
4290 +-----------------------+ */
4291
4292struct mmap_region
4293{
4294 /* User-specified size. */
4295 size_t nbytes_specified;
4296
4297 /* Number of bytes mapped */
4298 size_t nbytes_mapped;
4299
4300 /* Pointer to the location holding the address of the memory
4301 allocated with the mmap'd block. The variable actually points
4302 after this structure. */
4303 POINTER_TYPE **var;
4304
4305 /* Next and previous in list of all mmap'd regions. */
4306 struct mmap_region *next, *prev;
4307};
4308
4309/* Doubly-linked list of mmap'd regions. */
4310
4311static struct mmap_region *mmap_regions;
4312
4313/* File descriptor for mmap. If we don't have anonymous mapping,
4314 /dev/zero will be opened on it. */
4315
4316static int mmap_fd;
4317
4318/* Temporary storage for mmap_set_vars, see there. */
4319
4320static struct mmap_region *mmap_regions_1;
4321static int mmap_fd_1;
4322
4323/* Page size on this system. */
4324
4325static int mmap_page_size;
4326
4327/* 1 means mmap has been intialized. */
4328
4329static int mmap_initialized_p;
4330
4331/* Value is X rounded up to the next multiple of N. */
4332
4333#define ROUND(X, N) (((X) + (N) - 1) / (N) * (N))
4334
4335/* Size of mmap_region structure plus padding. */
4336
4337#define MMAP_REGION_STRUCT_SIZE \
4338 ROUND (sizeof (struct mmap_region), MEM_ALIGN)
4339
4340/* Given a pointer P to the start of the user-visible part of a mapped
4341 region, return a pointer to the start of the region. */
4342
4343#define MMAP_REGION(P) \
4344 ((struct mmap_region *) ((char *) (P) - MMAP_REGION_STRUCT_SIZE))
4345
4346/* Given a pointer P to the start of a mapped region, return a pointer
4347 to the start of the user-visible part of the region. */
4348
4349#define MMAP_USER_AREA(P) \
4350 ((POINTER_TYPE *) ((char *) (P) + MMAP_REGION_STRUCT_SIZE))
4351
4352#define MEM_ALIGN sizeof (double)
4353
cab1603f
DL
4354/* Predicate returning true if part of the address range [START ..
4355 END[ is currently mapped. Used to prevent overwriting an existing
4356 memory mapping.
4357
4358 Default is to conservativly assume the address range is occupied by
4359 something else. This can be overridden by system configuration
4360 files if system-specific means to determine this exists. */
4361
4362#ifndef MMAP_ALLOCATED_P
4363#define MMAP_ALLOCATED_P(start, end) 1
4364#endif
4365
b86af064
GM
4366/* Function prototypes. */
4367
4368static int mmap_free_1 P_ ((struct mmap_region *));
4369static int mmap_enlarge P_ ((struct mmap_region *, int));
4370static struct mmap_region *mmap_find P_ ((POINTER_TYPE *, POINTER_TYPE *));
4371static POINTER_TYPE *mmap_alloc P_ ((POINTER_TYPE **, size_t));
4372static POINTER_TYPE *mmap_realloc P_ ((POINTER_TYPE **, size_t));
4373static void mmap_free P_ ((POINTER_TYPE **ptr));
4374static void mmap_init P_ ((void));
4375
4376
4377/* Return a region overlapping address range START...END, or null if
4378 none. END is not including, i.e. the last byte in the range
4379 is at END - 1. */
4380
4381static struct mmap_region *
4382mmap_find (start, end)
4383 POINTER_TYPE *start, *end;
4384{
4385 struct mmap_region *r;
4386 char *s = (char *) start, *e = (char *) end;
4387
4388 for (r = mmap_regions; r; r = r->next)
4389 {
4390 char *rstart = (char *) r;
4391 char *rend = rstart + r->nbytes_mapped;
4392
4393 if (/* First byte of range, i.e. START, in this region? */
4394 (s >= rstart && s < rend)
4395 /* Last byte of range, i.e. END - 1, in this region? */
4396 || (e > rstart && e <= rend)
4397 /* First byte of this region in the range? */
4398 || (rstart >= s && rstart < e)
4399 /* Last byte of this region in the range? */
4400 || (rend > s && rend <= e))
4401 break;
4402 }
4403
4404 return r;
4405}
4406
4407
4408/* Unmap a region. P is a pointer to the start of the user-araa of
4409 the region. Value is non-zero if successful. */
4410
4411static int
4412mmap_free_1 (r)
4413 struct mmap_region *r;
4414{
4415 if (r->next)
4416 r->next->prev = r->prev;
4417 if (r->prev)
4418 r->prev->next = r->next;
4419 else
4420 mmap_regions = r->next;
4421
1a15cca0 4422 if (munmap ((POINTER_TYPE *) r, r->nbytes_mapped) == -1)
b86af064
GM
4423 {
4424 fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
4425 return 0;
4426 }
4427
4428 return 1;
4429}
4430
4431
4432/* Enlarge region R by NPAGES pages. NPAGES < 0 means shrink R.
4433 Value is non-zero if successful. */
4434
4435static int
4436mmap_enlarge (r, npages)
4437 struct mmap_region *r;
4438 int npages;
4439{
4440 char *region_end = (char *) r + r->nbytes_mapped;
4441 size_t nbytes;
4442 int success = 0;
4443
4444 if (npages < 0)
4445 {
4446 /* Unmap pages at the end of the region. */
4447 nbytes = - npages * mmap_page_size;
4448 if (munmap (region_end - nbytes, nbytes) == -1)
4449 fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
4450 else
4451 {
4452 r->nbytes_mapped -= nbytes;
4453 success = 1;
4454 }
4455 }
4456 else if (npages > 0)
4457 {
b86af064
GM
4458 nbytes = npages * mmap_page_size;
4459
4460 /* Try to map additional pages at the end of the region. We
4461 cannot do this if the address range is already occupied by
4462 something else because mmap deletes any previous mapping.
4463 I'm not sure this is worth doing, let's see. */
cab1603f 4464 if (!MMAP_ALLOCATED_P (region_end, region_end + nbytes))
b86af064
GM
4465 {
4466 POINTER_TYPE *p;
4467
4468 p = mmap (region_end, nbytes, PROT_READ | PROT_WRITE,
4469 MAP_ANON | MAP_PRIVATE | MAP_FIXED, mmap_fd, 0);
4470 if (p == MAP_FAILED)
edaa9aed 4471 ; /* fprintf (stderr, "mmap: %s\n", emacs_strerror (errno)); */
b86af064
GM
4472 else if (p != (POINTER_TYPE *) region_end)
4473 {
4474 /* Kernels are free to choose a different address. In
4475 that case, unmap what we've mapped above; we have
4476 no use for it. */
4477 if (munmap (p, nbytes) == -1)
4478 fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
4479 }
4480 else
4481 {
4482 r->nbytes_mapped += nbytes;
4483 success = 1;
4484 }
4485 }
4486 }
4487
4488 return success;
4489}
4490
4491
4492/* Set or reset variables holding references to mapped regions. If
4493 RESTORE_P is zero, set all variables to null. If RESTORE_P is
4494 non-zero, set all variables to the start of the user-areas
4495 of mapped regions.
4496
4497 This function is called from Fdump_emacs to ensure that the dumped
4498 Emacs doesn't contain references to memory that won't be mapped
4499 when Emacs starts. */
4500
4501void
4502mmap_set_vars (restore_p)
4503 int restore_p;
4504{
4505 struct mmap_region *r;
4506
4507 if (restore_p)
4508 {
4509 mmap_regions = mmap_regions_1;
4510 mmap_fd = mmap_fd_1;
4511 for (r = mmap_regions; r; r = r->next)
4512 *r->var = MMAP_USER_AREA (r);
4513 }
4514 else
4515 {
4516 for (r = mmap_regions; r; r = r->next)
4517 *r->var = NULL;
4518 mmap_regions_1 = mmap_regions;
4519 mmap_regions = NULL;
4520 mmap_fd_1 = mmap_fd;
4521 mmap_fd = -1;
4522 }
4523}
4524
4525
4526/* Allocate a block of storage large enough to hold NBYTES bytes of
4527 data. A pointer to the data is returned in *VAR. VAR is thus the
4528 address of some variable which will use the data area.
4529
4530 The allocation of 0 bytes is valid.
4531
4532 If we can't allocate the necessary memory, set *VAR to null, and
4533 return null. */
4534
4535static POINTER_TYPE *
4536mmap_alloc (var, nbytes)
4537 POINTER_TYPE **var;
4538 size_t nbytes;
4539{
4540 void *p;
4541 size_t map;
4542
4543 mmap_init ();
4544
4545 map = ROUND (nbytes + MMAP_REGION_STRUCT_SIZE, mmap_page_size);
4546 p = mmap (NULL, map, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
4547 mmap_fd, 0);
4548
4549 if (p == MAP_FAILED)
4550 {
4551 if (errno != ENOMEM)
4552 fprintf (stderr, "mmap: %s\n", emacs_strerror (errno));
4553 p = NULL;
4554 }
4555 else
4556 {
4557 struct mmap_region *r = (struct mmap_region *) p;
4558
4559 r->nbytes_specified = nbytes;
4560 r->nbytes_mapped = map;
4561 r->var = var;
4562 r->prev = NULL;
4563 r->next = mmap_regions;
4564 if (r->next)
4565 r->next->prev = r;
4566 mmap_regions = r;
4567
4568 p = MMAP_USER_AREA (p);
4569 }
4570
4571 return *var = p;
4572}
4573
4574
4575/* Given a pointer at address VAR to data allocated with mmap_alloc,
4576 resize it to size NBYTES. Change *VAR to reflect the new block,
4577 and return this value. If more memory cannot be allocated, then
4578 leave *VAR unchanged, and return null. */
4579
4580static POINTER_TYPE *
4581mmap_realloc (var, nbytes)
4582 POINTER_TYPE **var;
4583 size_t nbytes;
4584{
4585 POINTER_TYPE *result;
4586
4587 mmap_init ();
4588
4589 if (*var == NULL)
4590 result = mmap_alloc (var, nbytes);
4591 else if (nbytes == 0)
4592 {
4593 mmap_free (var);
4594 result = mmap_alloc (var, nbytes);
4595 }
4596 else
4597 {
4598 struct mmap_region *r = MMAP_REGION (*var);
4599 size_t room = r->nbytes_mapped - MMAP_REGION_STRUCT_SIZE;
4600
4601 if (room < nbytes)
4602 {
4603 /* Must enlarge. */
4604 POINTER_TYPE *old_ptr = *var;
4605
4606 /* Try to map additional pages at the end of the region.
4607 If that fails, allocate a new region, copy data
4608 from the old region, then free it. */
4609 if (mmap_enlarge (r, (ROUND (nbytes - room, mmap_page_size)
4610 / mmap_page_size)))
4611 {
4612 r->nbytes_specified = nbytes;
4613 *var = result = old_ptr;
4614 }
4615 else if (mmap_alloc (var, nbytes))
4616 {
4617 bcopy (old_ptr, *var, r->nbytes_specified);
4618 mmap_free_1 (MMAP_REGION (old_ptr));
4619 result = *var;
4620 r = MMAP_REGION (result);
4621 r->nbytes_specified = nbytes;
4622 }
4623 else
4624 {
4625 *var = old_ptr;
4626 result = NULL;
4627 }
4628 }
4629 else if (room - nbytes >= mmap_page_size)
4630 {
4631 /* Shrinking by at least a page. Let's give some
4632 memory back to the system. */
4633 mmap_enlarge (r, - (room - nbytes) / mmap_page_size);
4634 result = *var;
4635 r->nbytes_specified = nbytes;
4636 }
4637 else
4638 {
4639 /* Leave it alone. */
4640 result = *var;
4641 r->nbytes_specified = nbytes;
4642 }
4643 }
4644
4645 return result;
4646}
4647
4648
4649/* Free a block of relocatable storage whose data is pointed to by
4650 PTR. Store 0 in *PTR to show there's no block allocated. */
4651
4652static void
4653mmap_free (var)
4654 POINTER_TYPE **var;
4655{
4656 mmap_init ();
4657
4658 if (*var)
4659 {
4660 mmap_free_1 (MMAP_REGION (*var));
4661 *var = NULL;
4662 }
4663}
4664
4665
4666/* Perform necessary intializations for the use of mmap. */
4667
4668static void
4669mmap_init ()
4670{
4671#if MAP_ANON == 0
4672 /* The value of mmap_fd is initially 0 in temacs, and -1
4673 in a dumped Emacs. */
4674 if (mmap_fd <= 0)
4675 {
4676 /* No anonymous mmap -- we need the file descriptor. */
4677 mmap_fd = open ("/dev/zero", O_RDONLY);
4678 if (mmap_fd == -1)
4679 fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
4680 }
4681#endif /* MAP_ANON == 0 */
4682
4683 if (mmap_initialized_p)
4684 return;
4685 mmap_initialized_p = 1;
4686
4687#if MAP_ANON != 0
4688 mmap_fd = -1;
4689#endif
4690
4691 mmap_page_size = getpagesize ();
4692}
4693
4694#endif /* USE_MMAP_FOR_BUFFERS */
4695
4696
4697\f
4698/***********************************************************************
4699 Buffer-text Allocation
4700 ***********************************************************************/
4701
4702#ifdef REL_ALLOC
4703extern POINTER_TYPE *r_alloc P_ ((POINTER_TYPE **, size_t));
4704extern POINTER_TYPE *r_re_alloc P_ ((POINTER_TYPE **, size_t));
4705extern void r_alloc_free P_ ((POINTER_TYPE **ptr));
4706#endif /* REL_ALLOC */
4707
4708
4709/* Allocate NBYTES bytes for buffer B's text buffer. */
4710
4711static void
4712alloc_buffer_text (b, nbytes)
4713 struct buffer *b;
4714 size_t nbytes;
4715{
4716 POINTER_TYPE *p;
4717
4718 BLOCK_INPUT;
4719#if defined USE_MMAP_FOR_BUFFERS
4720 p = mmap_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
4721#elif defined REL_ALLOC
4722 p = r_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
4723#else
815add84 4724 p = xmalloc (nbytes);
b86af064
GM
4725#endif
4726
4727 if (p == NULL)
4728 {
4729 UNBLOCK_INPUT;
4730 memory_full ();
4731 }
4732
4733 b->text->beg = (unsigned char *) p;
4734 UNBLOCK_INPUT;
4735}
4736
4737/* Enlarge buffer B's text buffer by DELTA bytes. DELTA < 0 means
4738 shrink it. */
4739
4740void
4741enlarge_buffer_text (b, delta)
4742 struct buffer *b;
4743 int delta;
4744{
4745 POINTER_TYPE *p;
4746 size_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
4747 + delta);
4748 BLOCK_INPUT;
4749#if defined USE_MMAP_FOR_BUFFERS
4750 p = mmap_realloc ((POINTER_TYPE **) &b->text->beg, nbytes);
4751#elif defined REL_ALLOC
4752 p = r_re_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
4753#else
4754 p = xrealloc (b->text->beg, nbytes);
4755#endif
4756
4757 if (p == NULL)
4758 {
4759 UNBLOCK_INPUT;
4760 memory_full ();
4761 }
4762
4763 BUF_BEG_ADDR (b) = (unsigned char *) p;
4764 UNBLOCK_INPUT;
4765}
4766
4767
4768/* Free buffer B's text buffer. */
4769
4770static void
4771free_buffer_text (b)
4772 struct buffer *b;
4773{
4774 BLOCK_INPUT;
4775
4776#if defined USE_MMAP_FOR_BUFFERS
4777 mmap_free ((POINTER_TYPE **) &b->text->beg);
4778#elif defined REL_ALLOC
4779 r_alloc_free ((POINTER_TYPE **) &b->text->beg);
4780#else
4781 xfree (b->text->beg);
4782#endif
4783
4784 BUF_BEG_ADDR (b) = NULL;
4785 UNBLOCK_INPUT;
4786}
4787
4788
4789\f
4790/***********************************************************************
4791 Initialization
4792 ***********************************************************************/
4793
dfcf069d 4794void
1ab256cb
RM
4795init_buffer_once ()
4796{
7c02e886
GM
4797 int idx;
4798
4799 bzero (buffer_permanent_local_flags, sizeof buffer_permanent_local_flags);
13de9290 4800
1ab256cb
RM
4801 /* Make sure all markable slots in buffer_defaults
4802 are initialized reasonably, so mark_buffer won't choke. */
4803 reset_buffer (&buffer_defaults);
13de9290 4804 reset_buffer_local_variables (&buffer_defaults, 1);
1ab256cb 4805 reset_buffer (&buffer_local_symbols);
13de9290 4806 reset_buffer_local_variables (&buffer_local_symbols, 1);
336cd056
RS
4807 /* Prevent GC from getting confused. */
4808 buffer_defaults.text = &buffer_defaults.own_text;
4809 buffer_local_symbols.text = &buffer_local_symbols.own_text;
336cd056
RS
4810 BUF_INTERVALS (&buffer_defaults) = 0;
4811 BUF_INTERVALS (&buffer_local_symbols) = 0;
67180c6a
KH
4812 XSETBUFFER (Vbuffer_defaults, &buffer_defaults);
4813 XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols);
1ab256cb
RM
4814
4815 /* Set up the default values of various buffer slots. */
4816 /* Must do these before making the first buffer! */
4817
f532dca0 4818 /* real setup is done in bindings.el */
1ab256cb 4819 buffer_defaults.mode_line_format = build_string ("%-");
045dee35 4820 buffer_defaults.header_line_format = Qnil;
1ab256cb
RM
4821 buffer_defaults.abbrev_mode = Qnil;
4822 buffer_defaults.overwrite_mode = Qnil;
4823 buffer_defaults.case_fold_search = Qt;
4824 buffer_defaults.auto_fill_function = Qnil;
4825 buffer_defaults.selective_display = Qnil;
4826#ifndef old
4827 buffer_defaults.selective_display_ellipses = Qt;
4828#endif
4829 buffer_defaults.abbrev_table = Qnil;
4830 buffer_defaults.display_table = Qnil;
1ab256cb 4831 buffer_defaults.undo_list = Qnil;
c48f61ef 4832 buffer_defaults.mark_active = Qnil;
be9aafdd 4833 buffer_defaults.file_format = Qnil;
2eec3b4e
RS
4834 buffer_defaults.overlays_before = Qnil;
4835 buffer_defaults.overlays_after = Qnil;
bbbe9545 4836 XSETFASTINT (buffer_defaults.overlay_center, BEG);
1ab256cb 4837
8d7a4592 4838 XSETFASTINT (buffer_defaults.tab_width, 8);
1ab256cb
RM
4839 buffer_defaults.truncate_lines = Qnil;
4840 buffer_defaults.ctl_arrow = Qt;
3b06f880 4841 buffer_defaults.direction_reversed = Qnil;
bb2ec976 4842 buffer_defaults.cursor_type = Qt;
a3bbced0 4843 buffer_defaults.extra_line_spacing = Qnil;
1ab256cb 4844
f7975d07 4845#ifdef DOS_NT
0776cb1b 4846 buffer_defaults.buffer_file_type = Qnil; /* TEXT */
54ad07d3 4847#endif
a1a17b61 4848 buffer_defaults.enable_multibyte_characters = Qt;
c71b5d9b 4849 buffer_defaults.buffer_file_coding_system = Qnil;
8d7a4592
KH
4850 XSETFASTINT (buffer_defaults.fill_column, 70);
4851 XSETFASTINT (buffer_defaults.left_margin, 0);
28e969dd 4852 buffer_defaults.cache_long_line_scans = Qnil;
f6ed2e84 4853 buffer_defaults.file_truename = Qnil;
7962a441 4854 XSETFASTINT (buffer_defaults.display_count, 0);
0552666b
GM
4855 buffer_defaults.indicate_empty_lines = Qnil;
4856 buffer_defaults.scroll_up_aggressively = Qnil;
4857 buffer_defaults.scroll_down_aggressively = Qnil;
3fd364db 4858 buffer_defaults.display_time = Qnil;
1ab256cb
RM
4859
4860 /* Assign the local-flags to the slots that have default values.
4861 The local flag is a bit that is used in the buffer
4862 to say that it has its own local value for the slot.
4863 The local flag bits are in the local_var_flags slot of the buffer. */
4864
4865 /* Nothing can work if this isn't true */
4d2f1389 4866 if (sizeof (EMACS_INT) != sizeof (Lisp_Object)) abort ();
1ab256cb
RM
4867
4868 /* 0 means not a lisp var, -1 means always local, else mask */
4869 bzero (&buffer_local_flags, sizeof buffer_local_flags);
aab80822
KH
4870 XSETINT (buffer_local_flags.filename, -1);
4871 XSETINT (buffer_local_flags.directory, -1);
4872 XSETINT (buffer_local_flags.backed_up, -1);
4873 XSETINT (buffer_local_flags.save_length, -1);
4874 XSETINT (buffer_local_flags.auto_save_file_name, -1);
4875 XSETINT (buffer_local_flags.read_only, -1);
4876 XSETINT (buffer_local_flags.major_mode, -1);
4877 XSETINT (buffer_local_flags.mode_name, -1);
4878 XSETINT (buffer_local_flags.undo_list, -1);
4879 XSETINT (buffer_local_flags.mark_active, -1);
943e065b 4880 XSETINT (buffer_local_flags.point_before_scroll, -1);
f6ed2e84 4881 XSETINT (buffer_local_flags.file_truename, -1);
3cb719bd 4882 XSETINT (buffer_local_flags.invisibility_spec, -1);
55ac8536 4883 XSETINT (buffer_local_flags.file_format, -1);
7962a441 4884 XSETINT (buffer_local_flags.display_count, -1);
3fd364db 4885 XSETINT (buffer_local_flags.display_time, -1);
1bf08baf 4886 XSETINT (buffer_local_flags.enable_multibyte_characters, -1);
8d7a4592 4887
7c02e886
GM
4888 idx = 1;
4889 XSETFASTINT (buffer_local_flags.mode_line_format, idx); ++idx;
4890 XSETFASTINT (buffer_local_flags.abbrev_mode, idx); ++idx;
4891 XSETFASTINT (buffer_local_flags.overwrite_mode, idx); ++idx;
4892 XSETFASTINT (buffer_local_flags.case_fold_search, idx); ++idx;
4893 XSETFASTINT (buffer_local_flags.auto_fill_function, idx); ++idx;
4894 XSETFASTINT (buffer_local_flags.selective_display, idx); ++idx;
1ab256cb 4895#ifndef old
7c02e886 4896 XSETFASTINT (buffer_local_flags.selective_display_ellipses, idx); ++idx;
1ab256cb 4897#endif
7c02e886
GM
4898 XSETFASTINT (buffer_local_flags.tab_width, idx); ++idx;
4899 XSETFASTINT (buffer_local_flags.truncate_lines, idx); ++idx;
4900 XSETFASTINT (buffer_local_flags.ctl_arrow, idx); ++idx;
4901 XSETFASTINT (buffer_local_flags.fill_column, idx); ++idx;
4902 XSETFASTINT (buffer_local_flags.left_margin, idx); ++idx;
4903 XSETFASTINT (buffer_local_flags.abbrev_table, idx); ++idx;
4904 XSETFASTINT (buffer_local_flags.display_table, idx); ++idx;
f7975d07 4905#ifdef DOS_NT
7c02e886 4906 XSETFASTINT (buffer_local_flags.buffer_file_type, idx);
13de9290 4907 /* Make this one a permanent local. */
7c02e886 4908 buffer_permanent_local_flags[idx++] = 1;
54ad07d3 4909#endif
7c02e886
GM
4910 XSETFASTINT (buffer_local_flags.syntax_table, idx); ++idx;
4911 XSETFASTINT (buffer_local_flags.cache_long_line_scans, idx); ++idx;
4912 XSETFASTINT (buffer_local_flags.category_table, idx); ++idx;
4913 XSETFASTINT (buffer_local_flags.direction_reversed, idx); ++idx;
4914 XSETFASTINT (buffer_local_flags.buffer_file_coding_system, idx);
a1a17b61 4915 /* Make this one a permanent local. */
7c02e886
GM
4916 buffer_permanent_local_flags[idx++] = 1;
4917 XSETFASTINT (buffer_local_flags.left_margin_width, idx); ++idx;
4918 XSETFASTINT (buffer_local_flags.right_margin_width, idx); ++idx;
4919 XSETFASTINT (buffer_local_flags.indicate_empty_lines, idx); ++idx;
4920 XSETFASTINT (buffer_local_flags.scroll_up_aggressively, idx); ++idx;
4921 XSETFASTINT (buffer_local_flags.scroll_down_aggressively, idx); ++idx;
4922 XSETFASTINT (buffer_local_flags.header_line_format, idx); ++idx;
bd96bd79 4923 XSETFASTINT (buffer_local_flags.cursor_type, idx); ++idx;
a3bbced0 4924 XSETFASTINT (buffer_local_flags.extra_line_spacing, idx); ++idx;
7c02e886
GM
4925
4926 /* Need more room? */
7313acd0 4927 if (idx >= MAX_PER_BUFFER_VARS)
7c02e886 4928 abort ();
7313acd0 4929 last_per_buffer_idx = idx;
c71b5d9b 4930
1ab256cb
RM
4931 Vbuffer_alist = Qnil;
4932 current_buffer = 0;
4933 all_buffers = 0;
4934
4935 QSFundamental = build_string ("Fundamental");
4936
4937 Qfundamental_mode = intern ("fundamental-mode");
4938 buffer_defaults.major_mode = Qfundamental_mode;
4939
4940 Qmode_class = intern ("mode-class");
4941
4942 Qprotected_field = intern ("protected-field");
4943
4944 Qpermanent_local = intern ("permanent-local");
4945
4946 Qkill_buffer_hook = intern ("kill-buffer-hook");
4947
4948 Vprin1_to_string_buffer = Fget_buffer_create (build_string (" prin1"));
000f8083 4949
1ab256cb
RM
4950 /* super-magic invisible buffer */
4951 Vbuffer_alist = Qnil;
4952
ffd56f97 4953 Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
7775635d
KH
4954
4955 inhibit_modification_hooks = 0;
1ab256cb
RM
4956}
4957
dfcf069d 4958void
1ab256cb
RM
4959init_buffer ()
4960{
93c27ef1 4961 char buf[MAXPATHLEN + 1];
2381d133
JB
4962 char *pwd;
4963 struct stat dotstat, pwdstat;
136351b7 4964 Lisp_Object temp;
f7975d07 4965 int rc;
1ab256cb 4966
b86af064 4967#ifdef USE_MMAP_FOR_BUFFERS
93c27ef1
GM
4968 {
4969 /* When using the ralloc implementation based on mmap(2), buffer
4970 text pointers will have been set to null in the dumped Emacs.
4971 Map new memory. */
4972 struct buffer *b;
4973
93c27ef1
GM
4974 for (b = all_buffers; b; b = b->next)
4975 if (b->text->beg == NULL)
b86af064 4976 enlarge_buffer_text (b, 0);
93c27ef1 4977 }
b86af064 4978#endif /* USE_MMAP_FOR_BUFFERS */
93c27ef1 4979
1ab256cb 4980 Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
3d871c85
RS
4981 if (NILP (buffer_defaults.enable_multibyte_characters))
4982 Fset_buffer_multibyte (Qnil);
2381d133 4983
cab1603f
DL
4984 /* If PWD is accurate, use it instead of calling getwd. PWD is
4985 sometimes a nicer name, and using it may avoid a fatal error if a
4986 parent directory is searchable but not readable. */
309f2a6e
RS
4987 if ((pwd = getenv ("PWD")) != 0
4988 && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
2381d133
JB
4989 && stat (pwd, &pwdstat) == 0
4990 && stat (".", &dotstat) == 0
4991 && dotstat.st_ino == pwdstat.st_ino
4992 && dotstat.st_dev == pwdstat.st_dev
4993 && strlen (pwd) < MAXPATHLEN)
4994 strcpy (buf, pwd);
6335beb0
RS
4995#ifdef HAVE_GETCWD
4996 else if (getcwd (buf, MAXPATHLEN+1) == 0)
9dde47f5 4997 fatal ("`getcwd' failed: %s\n", strerror (errno));
6335beb0 4998#else
2381d133 4999 else if (getwd (buf) == 0)
cf1e6391 5000 fatal ("`getwd' failed: %s\n", buf);
6335beb0 5001#endif
1ab256cb
RM
5002
5003#ifndef VMS
5004 /* Maybe this should really use some standard subroutine
5005 whose definition is filename syntax dependent. */
f7975d07
RS
5006 rc = strlen (buf);
5007 if (!(IS_DIRECTORY_SEP (buf[rc - 1])))
5008 {
5009 buf[rc] = DIRECTORY_SEP;
5010 buf[rc + 1] = '\0';
5011 }
1ab256cb 5012#endif /* not VMS */
0995fa35 5013
1ab256cb 5014 current_buffer->directory = build_string (buf);
136351b7 5015
0995fa35
RS
5016 /* Add /: to the front of the name
5017 if it would otherwise be treated as magic. */
5018 temp = Ffind_file_name_handler (current_buffer->directory, Qt);
81ab2e07
KH
5019 if (! NILP (temp)
5020 /* If the default dir is just /, TEMP is non-nil
5021 because of the ange-ftp completion handler.
5022 However, it is not necessary to turn / into /:/.
5023 So avoid doing that. */
5024 && strcmp ("/", XSTRING (current_buffer->directory)->data))
0995fa35
RS
5025 current_buffer->directory
5026 = concat2 (build_string ("/:"), current_buffer->directory);
5027
136351b7
RS
5028 temp = get_minibuffer (0);
5029 XBUFFER (temp)->directory = current_buffer->directory;
1ab256cb
RM
5030}
5031
5032/* initialize the buffer routines */
dfcf069d 5033void
1ab256cb
RM
5034syms_of_buffer ()
5035{
9115729e
KH
5036 staticpro (&last_overlay_modification_hooks);
5037 last_overlay_modification_hooks
5038 = Fmake_vector (make_number (10), Qnil);
5039
1ab256cb
RM
5040 staticpro (&Vbuffer_defaults);
5041 staticpro (&Vbuffer_local_symbols);
5042 staticpro (&Qfundamental_mode);
5043 staticpro (&Qmode_class);
5044 staticpro (&QSFundamental);
5045 staticpro (&Vbuffer_alist);
5046 staticpro (&Qprotected_field);
5047 staticpro (&Qpermanent_local);
5048 staticpro (&Qkill_buffer_hook);
22378665 5049 Qoverlayp = intern ("overlayp");
52f8ec73 5050 staticpro (&Qoverlayp);
9d7608b7
KH
5051 Qevaporate = intern ("evaporate");
5052 staticpro (&Qevaporate);
294d215f 5053 Qmodification_hooks = intern ("modification-hooks");
22378665 5054 staticpro (&Qmodification_hooks);
294d215f 5055 Qinsert_in_front_hooks = intern ("insert-in-front-hooks");
22378665 5056 staticpro (&Qinsert_in_front_hooks);
294d215f 5057 Qinsert_behind_hooks = intern ("insert-behind-hooks");
22378665 5058 staticpro (&Qinsert_behind_hooks);
5fe0b67e 5059 Qget_file_buffer = intern ("get-file-buffer");
22378665 5060 staticpro (&Qget_file_buffer);
5985d248
KH
5061 Qpriority = intern ("priority");
5062 staticpro (&Qpriority);
5063 Qwindow = intern ("window");
5064 staticpro (&Qwindow);
bbbe9545
KH
5065 Qbefore_string = intern ("before-string");
5066 staticpro (&Qbefore_string);
5067 Qafter_string = intern ("after-string");
5068 staticpro (&Qafter_string);
22378665
RS
5069 Qfirst_change_hook = intern ("first-change-hook");
5070 staticpro (&Qfirst_change_hook);
5071 Qbefore_change_functions = intern ("before-change-functions");
5072 staticpro (&Qbefore_change_functions);
5073 Qafter_change_functions = intern ("after-change-functions");
5074 staticpro (&Qafter_change_functions);
1ab256cb
RM
5075
5076 Fput (Qprotected_field, Qerror_conditions,
5077 Fcons (Qprotected_field, Fcons (Qerror, Qnil)));
5078 Fput (Qprotected_field, Qerror_message,
5079 build_string ("Attempt to modify a protected field"));
5080
5081 /* All these use DEFVAR_LISP_NOPRO because the slots in
5082 buffer_defaults will all be marked via Vbuffer_defaults. */
5083
5084 DEFVAR_LISP_NOPRO ("default-mode-line-format",
7ee72033
MB
5085 &buffer_defaults.mode_line_format,
5086 doc: /* Default value of `mode-line-format' for buffers that don't override it.
018ba359 5087This is the same as (default-value 'mode-line-format). */);
1ab256cb 5088
045dee35 5089 DEFVAR_LISP_NOPRO ("default-header-line-format",
7ee72033
MB
5090 &buffer_defaults.header_line_format,
5091 doc: /* Default value of `header-line-format' for buffers that don't override it.
018ba359 5092This is the same as (default-value 'header-line-format). */);
0552666b 5093
7ee72033
MB
5094 DEFVAR_LISP_NOPRO ("default-cursor-type", &buffer_defaults.cursor_type,
5095 doc: /* Default value of `cursor-type' for buffers that don't override it.
018ba359 5096This is the same as (default-value 'cursor-type). */);
bd96bd79 5097
a3bbced0 5098 DEFVAR_LISP_NOPRO ("default-line-spacing",
7ee72033
MB
5099 &buffer_defaults.extra_line_spacing,
5100 doc: /* Default value of `line-spacing' for buffers that don't override it.
018ba359 5101This is the same as (default-value 'line-spacing). */);
a3bbced0 5102
1ab256cb 5103 DEFVAR_LISP_NOPRO ("default-abbrev-mode",
efc7e75f 5104 &buffer_defaults.abbrev_mode,
7ee72033 5105 doc: /* Default value of `abbrev-mode' for buffers that do not override it.
018ba359 5106This is the same as (default-value 'abbrev-mode). */);
1ab256cb
RM
5107
5108 DEFVAR_LISP_NOPRO ("default-ctl-arrow",
efc7e75f 5109 &buffer_defaults.ctl_arrow,
7ee72033 5110 doc: /* Default value of `ctl-arrow' for buffers that do not override it.
018ba359 5111This is the same as (default-value 'ctl-arrow). */);
1ab256cb 5112
3b06f880 5113 DEFVAR_LISP_NOPRO ("default-direction-reversed",
efc7e75f 5114 &buffer_defaults.direction_reversed,
7ee72033 5115 doc: /* Default value of `direction_reversed' for buffers that do not override it.
018ba359 5116This is the same as (default-value 'direction-reversed). */);
3b06f880 5117
a1a17b61 5118 DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters",
efc7e75f 5119 &buffer_defaults.enable_multibyte_characters,
7ee72033 5120 doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it.
018ba359 5121This is the same as (default-value 'enable-multibyte-characters). */);
a1a17b61 5122
c71b5d9b 5123 DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system",
efc7e75f 5124 &buffer_defaults.buffer_file_coding_system,
7ee72033 5125 doc: /* Default value of `buffer-file-coding-system' for buffers not overriding it.
018ba359 5126This is the same as (default-value 'buffer-file-coding-system). */);
c71b5d9b 5127
1ab256cb 5128 DEFVAR_LISP_NOPRO ("default-truncate-lines",
efc7e75f
PJ
5129 &buffer_defaults.truncate_lines,
5130 doc: /* Default value of `truncate-lines' for buffers that do not override it.
018ba359 5131This is the same as (default-value 'truncate-lines). */);
1ab256cb
RM
5132
5133 DEFVAR_LISP_NOPRO ("default-fill-column",
efc7e75f
PJ
5134 &buffer_defaults.fill_column,
5135 doc: /* Default value of `fill-column' for buffers that do not override it.
018ba359 5136This is the same as (default-value 'fill-column). */);
1ab256cb
RM
5137
5138 DEFVAR_LISP_NOPRO ("default-left-margin",
efc7e75f
PJ
5139 &buffer_defaults.left_margin,
5140 doc: /* Default value of `left-margin' for buffers that do not override it.
018ba359 5141This is the same as (default-value 'left-margin). */);
1ab256cb
RM
5142
5143 DEFVAR_LISP_NOPRO ("default-tab-width",
7ee72033
MB
5144 &buffer_defaults.tab_width,
5145 doc: /* Default value of `tab-width' for buffers that do not override it.
018ba359 5146This is the same as (default-value 'tab-width). */);
1ab256cb
RM
5147
5148 DEFVAR_LISP_NOPRO ("default-case-fold-search",
efc7e75f
PJ
5149 &buffer_defaults.case_fold_search,
5150 doc: /* Default value of `case-fold-search' for buffers that don't override it.
018ba359 5151This is the same as (default-value 'case-fold-search). */);
1ab256cb 5152
f7975d07 5153#ifdef DOS_NT
54ad07d3 5154 DEFVAR_LISP_NOPRO ("default-buffer-file-type",
7ee72033 5155 &buffer_defaults.buffer_file_type,
efc7e75f 5156 doc: /* Default file type for buffers that do not override it.
018ba359
PJ
5157This is the same as (default-value 'buffer-file-type).
5158The file type is nil for text, t for binary. */);
54ad07d3
RS
5159#endif
5160
0552666b 5161 DEFVAR_LISP_NOPRO ("default-left-margin-width",
efc7e75f
PJ
5162 &buffer_defaults.left_margin_width,
5163 doc: /* Default value of `left-margin-width' for buffers that don't override it.
018ba359 5164This is the same as (default-value 'left-margin-width). */);
0552666b
GM
5165
5166 DEFVAR_LISP_NOPRO ("default-right-margin-width",
efc7e75f
PJ
5167 &buffer_defaults.right_margin_width,
5168 doc: /* Default value of `right_margin_width' for buffers that don't override it.
018ba359 5169This is the same as (default-value 'right-margin-width). */);
0552666b
GM
5170
5171 DEFVAR_LISP_NOPRO ("default-indicate-empty-lines",
efc7e75f
PJ
5172 &buffer_defaults.indicate_empty_lines,
5173 doc: /* Default value of `indicate-empty-lines' for buffers that don't override it.
018ba359 5174This is the same as (default-value 'indicate-empty-lines). */);
0552666b
GM
5175
5176 DEFVAR_LISP_NOPRO ("default-scroll-up-aggressively",
efc7e75f 5177 &buffer_defaults.scroll_up_aggressively,
7614d762
RS
5178 doc: /* Default value of `scroll-up-aggressively'.
5179This value applies in buffers that don't have their own local values.
5180This variable is an alias for (default-value 'scroll-up-aggressively). */);
0552666b
GM
5181
5182 DEFVAR_LISP_NOPRO ("default-scroll-down-aggressively",
efc7e75f 5183 &buffer_defaults.scroll_down_aggressively,
7614d762
RS
5184 doc: /* Default value of `scroll-down-aggressively'.
5185This value applies in buffers that don't have their own local values.
5186This variable is an alias for (default-value 'scroll-down-aggressively). */);
0552666b 5187
045dee35 5188 DEFVAR_PER_BUFFER ("header-line-format",
018ba359 5189 &current_buffer->header_line_format,
7ee72033 5190 Qnil,
7614d762
RS
5191 doc: /* Analogous to `mode-line-format', but controls the header line.
5192The header line appears, optionally, at the top of a window;
5193the mode line appears at the bottom. */);
0552666b 5194
1ab256cb 5195 DEFVAR_PER_BUFFER ("mode-line-format", &current_buffer->mode_line_format,
efc7e75f
PJ
5196 Qnil,
5197 doc: /* Template for displaying mode line for current buffer.
018ba359
PJ
5198Each buffer has its own value of this variable.
5199Value may be nil, a string, a symbol or a list or cons cell.
5200A value of nil means don't display a mode line.
5201For a symbol, its value is used (but it is ignored if t or nil).
5202 A string appearing directly as the value of a symbol is processed verbatim
5203 in that the %-constructs below are not recognized.
5204For a list of the form `(:eval FORM)', FORM is evaluated and the result
5205 is used as a mode line element.
5206For a list whose car is a symbol, the symbol's value is taken,
5207 and if that is non-nil, the cadr of the list is processed recursively.
5208 Otherwise, the caddr of the list (if there is one) is processed.
5209For a list whose car is a string or list, each element is processed
5210 recursively and the results are effectively concatenated.
5211For a list whose car is an integer, the cdr of the list is processed
5212 and padded (if the number is positive) or truncated (if negative)
5213 to the width specified by that number.
5214A string is printed verbatim in the mode line except for %-constructs:
5215 (%-constructs are allowed when the string is the entire mode-line-format
5216 or when it is found in a cons-cell or a list)
5217 %b -- print buffer name. %f -- print visited file name.
5218 %F -- print frame name.
5219 %* -- print %, * or hyphen. %+ -- print *, % or hyphen.
5220 %& is like %*, but ignore read-only-ness.
5221 % means buffer is read-only and * means it is modified.
5222 For a modified read-only buffer, %* gives % and %+ gives *.
5223 %s -- print process status. %l -- print the current line number.
5224 %c -- print the current column number (this makes editing slower).
5225 To make the column number update correctly in all cases,
5226 `column-number-mode' must be non-nil.
5227 %p -- print percent of buffer above top of window, or Top, Bot or All.
5228 %P -- print percent of buffer above bottom of window, perhaps plus Top,
5229 or print Bottom or All.
5230 %m -- print the mode name.
5231 %n -- print Narrow if appropriate.
5232 %z -- print mnemonics of buffer, terminal, and keyboard coding systems.
5233 %Z -- like %z, but including the end-of-line format.
5234 %[ -- print one [ for each recursive editing level. %] similar.
5235 %% -- print %. %- -- print infinitely many dashes.
5236Decimal digits after the % specify field width to which to pad. */);
5237
7ee72033 5238 DEFVAR_LISP_NOPRO ("default-major-mode", &buffer_defaults.major_mode,
efc7e75f 5239 doc: /* *Major mode for new buffers. Defaults to `fundamental-mode'.
018ba359 5240nil here means use current buffer's major mode. */);
1ab256cb
RM
5241
5242 DEFVAR_PER_BUFFER ("major-mode", &current_buffer->major_mode,
7ee72033 5243 make_number (Lisp_Symbol),
efc7e75f 5244 doc: /* Symbol for current buffer's major mode. */);
1ab256cb
RM
5245
5246 DEFVAR_PER_BUFFER ("mode-name", &current_buffer->mode_name,
cab1603f 5247 Qnil,
efc7e75f 5248 doc: /* Pretty name of current buffer's major mode (a string). */);
1ab256cb 5249
7ee72033 5250 DEFVAR_PER_BUFFER ("abbrev-mode", &current_buffer->abbrev_mode, Qnil,
efc7e75f 5251 doc: /* Non-nil turns on automatic expansion of abbrevs as they are inserted. */);
1ab256cb
RM
5252
5253 DEFVAR_PER_BUFFER ("case-fold-search", &current_buffer->case_fold_search,
7ee72033 5254 Qnil,
efc7e75f 5255 doc: /* *Non-nil if searches and matches should ignore case. */);
1ab256cb
RM
5256
5257 DEFVAR_PER_BUFFER ("fill-column", &current_buffer->fill_column,
7ee72033 5258 make_number (Lisp_Int),
efc7e75f 5259 doc: /* *Column beyond which automatic line-wrapping should happen. */);
1ab256cb
RM
5260
5261 DEFVAR_PER_BUFFER ("left-margin", &current_buffer->left_margin,
7ee72033 5262 make_number (Lisp_Int),
efc7e75f 5263 doc: /* *Column for the default indent-line-function to indent to.
018ba359 5264Linefeed indents to this column in Fundamental mode. */);
1ab256cb
RM
5265
5266 DEFVAR_PER_BUFFER ("tab-width", &current_buffer->tab_width,
7ee72033 5267 make_number (Lisp_Int),
efc7e75f 5268 doc: /* *Distance between tab stops (for display of tab characters), in columns. */);
1ab256cb 5269
7ee72033 5270 DEFVAR_PER_BUFFER ("ctl-arrow", &current_buffer->ctl_arrow, Qnil,
efc7e75f 5271 doc: /* *Non-nil means display control chars with uparrow.
018ba359
PJ
5272A value of nil means use backslash and octal digits.
5273This variable does not apply to characters whose display is specified
5274in the current display table (if there is one). */);
1ab256cb 5275
3b06f880 5276 DEFVAR_PER_BUFFER ("enable-multibyte-characters",
1bf08baf 5277 &current_buffer->enable_multibyte_characters,
7ee72033 5278 make_number (-1),
efc7e75f 5279 doc: /* Non-nil means the buffer contents are regarded as multi-byte characters.
018ba359
PJ
5280Otherwise they are regarded as unibyte. This affects the display,
5281file I/O and the behavior of various editing commands.
5282
5283This variable is buffer-local but you cannot set it directly;
5284use the function `set-buffer-multibyte' to change a buffer's representation.
5285Changing its default value with `setq-default' is supported.
5286See also variable `default-enable-multibyte-characters' and Info node
5287`(elisp)Text Representations'. */);
3b06f880 5288
c71b5d9b 5289 DEFVAR_PER_BUFFER ("buffer-file-coding-system",
7ee72033 5290 &current_buffer->buffer_file_coding_system, Qnil,
efc7e75f 5291 doc: /* Coding system to be used for encoding the buffer contents on saving.
018ba359
PJ
5292This variable applies to saving the buffer, and also to `write-region'
5293and other functions that use `write-region'.
5294It does not apply to sending output to subprocesses, however.
5295
5296If this is nil, the buffer is saved without any code conversion
5297unless some coding system is specified in `file-coding-system-alist'
5298for the buffer file.
5299
cab1603f
DL
5300If the text to be saved cannot be encoded as specified by this variable,
5301an alternative encoding is selected by `select-safe-coding-system', which see.
5302
018ba359
PJ
5303The variable `coding-system-for-write', if non-nil, overrides this variable.
5304
5305This variable is never applied to a way of decoding a file while reading it. */);
c71b5d9b 5306
3b06f880 5307 DEFVAR_PER_BUFFER ("direction-reversed", &current_buffer->direction_reversed,
7ee72033 5308 Qnil,
efc7e75f 5309 doc: /* *Non-nil means lines in the buffer are displayed right to left. */);
3b06f880 5310
7ee72033 5311 DEFVAR_PER_BUFFER ("truncate-lines", &current_buffer->truncate_lines, Qnil,
7614d762
RS
5312 doc: /* *Non-nil means do not display continuation lines.
5313Instead, give each line of text just one screen line.
018ba359
PJ
5314
5315Note that this is overridden by the variable
5316`truncate-partial-width-windows' if that variable is non-nil
5317and this buffer is not full-frame width. */);
1ab256cb 5318
f7975d07 5319#ifdef DOS_NT
54ad07d3 5320 DEFVAR_PER_BUFFER ("buffer-file-type", &current_buffer->buffer_file_type,
7ee72033 5321 Qnil,
efc7e75f 5322 doc: /* Non-nil if the visited file is a binary file.
018ba359
PJ
5323This variable is meaningful on MS-DOG and Windows NT.
5324On those systems, it is automatically local in every buffer.
5325On other systems, this variable is normally always nil. */);
54ad07d3
RS
5326#endif
5327
1ab256cb 5328 DEFVAR_PER_BUFFER ("default-directory", &current_buffer->directory,
7ee72033 5329 make_number (Lisp_String),
efc7e75f 5330 doc: /* Name of default directory of current buffer. Should end with slash.
018ba359 5331To interactively change the default directory, use command `cd'. */);
1ab256cb
RM
5332
5333 DEFVAR_PER_BUFFER ("auto-fill-function", &current_buffer->auto_fill_function,
7ee72033 5334 Qnil,
efc7e75f 5335 doc: /* Function called (if non-nil) to perform auto-fill.
018ba359
PJ
5336It is called after self-inserting any character specified in
5337the `auto-fill-chars' table.
5338NOTE: This variable is not a hook;
5339its value may not be a list of functions. */);
1ab256cb
RM
5340
5341 DEFVAR_PER_BUFFER ("buffer-file-name", &current_buffer->filename,
7ee72033 5342 make_number (Lisp_String),
efc7e75f 5343 doc: /* Name of file visited in current buffer, or nil if not visiting a file. */);
1ab256cb 5344
f6ed2e84 5345 DEFVAR_PER_BUFFER ("buffer-file-truename", &current_buffer->file_truename,
7ee72033 5346 make_number (Lisp_String),
efc7e75f 5347 doc: /* Abbreviated truename of file visited in current buffer, or nil if none.
018ba359
PJ
5348The truename of a file is calculated by `file-truename'
5349and then abbreviated with `abbreviate-file-name'. */);
f6ed2e84 5350
1ab256cb 5351 DEFVAR_PER_BUFFER ("buffer-auto-save-file-name",
3f5fcd47 5352 &current_buffer->auto_save_file_name,
7ee72033 5353 make_number (Lisp_String),
7614d762
RS
5354 doc: /* Name of file for auto-saving current buffer.
5355If it is nil, that means don't auto-save this buffer. */);
1ab256cb 5356
7ee72033 5357 DEFVAR_PER_BUFFER ("buffer-read-only", &current_buffer->read_only, Qnil,
efc7e75f 5358 doc: /* Non-nil if this buffer is read-only. */);
1ab256cb 5359
7ee72033 5360 DEFVAR_PER_BUFFER ("buffer-backed-up", &current_buffer->backed_up, Qnil,
efc7e75f 5361 doc: /* Non-nil if this buffer's file has been backed up.
018ba359 5362Backing up is done before the first time the file is saved. */);
1ab256cb
RM
5363
5364 DEFVAR_PER_BUFFER ("buffer-saved-size", &current_buffer->save_length,
7ee72033 5365 make_number (Lisp_Int),
efc7e75f 5366 doc: /* Length of current buffer when last read in, saved or auto-saved.
018ba359 53670 initially. */);
1ab256cb
RM
5368
5369 DEFVAR_PER_BUFFER ("selective-display", &current_buffer->selective_display,
7ee72033 5370 Qnil,
7614d762
RS
5371 doc: /* Non-nil enables selective display.
5372An Integer N as value means display only lines
5373that start with less than n columns of space.
5374A value of t means that the character ^M makes itself and
5375all the rest of the line invisible; also, when saving the buffer
5376in a file, save the ^M as a newline. */);
1ab256cb
RM
5377
5378#ifndef old
5379 DEFVAR_PER_BUFFER ("selective-display-ellipses",
5380 &current_buffer->selective_display_ellipses,
7ee72033 5381 Qnil,
3f676284 5382 doc: /* Non-nil means display ... on previous line when a line is invisible. */);
1ab256cb
RM
5383#endif
5384
7ee72033 5385 DEFVAR_PER_BUFFER ("overwrite-mode", &current_buffer->overwrite_mode, Qnil,
efc7e75f 5386 doc: /* Non-nil if self-insertion should replace existing text.
018ba359
PJ
5387The value should be one of `overwrite-mode-textual',
5388`overwrite-mode-binary', or nil.
5389If it is `overwrite-mode-textual', self-insertion still
5390inserts at the end of a line, and inserts when point is before a tab,
5391until the tab is filled in.
5392If `overwrite-mode-binary', self-insertion replaces newlines and tabs too. */);
5393
54939090 5394 DEFVAR_PER_BUFFER ("buffer-display-table", &current_buffer->display_table,
7ee72033 5395 Qnil,
efc7e75f 5396 doc: /* Display table that controls display of the contents of current buffer.
018ba359
PJ
5397
5398If this variable is nil, the value of `standard-display-table' is used.
5399Each window can have its own, overriding display table, see
5400`set-window-display-table' and `window-display-table'.
5401
5402The display table is a char-table created with `make-display-table'.
5403A char-table is an array indexed by character codes. Normal array
5404primitives `aref' and `aset' can be used to access elements of a char-table.
5405
5406Each of the char-table elements control how to display the corresponding
5407text character: the element at index C in the table says how to display
5408the character whose code is C. Each element should be a vector of
5409characters or nil. nil means display the character in the default fashion;
5410otherwise, the characters from the vector are delivered to the screen
5411instead of the original character.
5412
5413For example, (aset buffer-display-table ?X ?Y) will cause Emacs to display
5414a capital Y instead of each X character.
5415
5416In addition, a char-table has six extra slots to control the display of:
5417
5418 the end of a truncated screen line (extra-slot 0, a single character);
5419 the end of a continued line (extra-slot 1, a single character);
5420 the escape character used to display character codes in octal
5421 (extra-slot 2, a single character);
5422 the character used as an arrow for control characters (extra-slot 3,
5423 a single character);
5424 the decoration indicating the presence of invisible lines (extra-slot 4,
5425 a vector of characters);
5426 the character used to draw the border between side-by-side windows
5427 (extra-slot 5, a single character).
5428
5429See also the functions `display-table-slot' and `set-display-table-slot'. */);
1ab256cb 5430
0552666b 5431 DEFVAR_PER_BUFFER ("left-margin-width", &current_buffer->left_margin_width,
7ee72033 5432 Qnil,
efc7e75f 5433 doc: /* *Width of left marginal area for display of a buffer.
018ba359 5434A value of nil means no marginal area. */);
0552666b
GM
5435
5436 DEFVAR_PER_BUFFER ("right-margin-width", &current_buffer->right_margin_width,
7ee72033 5437 Qnil,
efc7e75f 5438 doc: /* *Width of right marginal area for display of a buffer.
018ba359 5439A value of nil means no marginal area. */);
0552666b
GM
5440
5441 DEFVAR_PER_BUFFER ("indicate-empty-lines",
7ee72033 5442 &current_buffer->indicate_empty_lines, Qnil,
efc7e75f 5443 doc: /* *Visually indicate empty lines after the buffer end.
018ba359
PJ
5444If non-nil, a bitmap is displayed in the left fringe of a window on
5445window-systems. */);
0552666b
GM
5446
5447 DEFVAR_PER_BUFFER ("scroll-up-aggressively",
7ee72033 5448 &current_buffer->scroll_up_aggressively, Qnil,
efc7e75f 5449 doc: /* *If a number, scroll display up aggressively.
6524d955 5450If scrolling a window because point is below the window end, choose
018ba359 5451a new window start so that point ends up that fraction of the window's
6524d955 5452height from the bottom of the window. */);
0552666b
GM
5453
5454 DEFVAR_PER_BUFFER ("scroll-down-aggressively",
7ee72033 5455 &current_buffer->scroll_down_aggressively, Qnil,
efc7e75f 5456 doc: /* *If a number, scroll display down aggressively.
6524d955 5457If scrolling a window because point is above the window start, choose
018ba359 5458a new window start so that point ends up that fraction of the window's
6524d955 5459height from the top of the window. */);
0552666b 5460
1ab256cb
RM
5461/*DEFVAR_LISP ("debug-check-symbol", &Vcheck_symbol,
5462 "Don't ask.");
5463*/
1ab256cb 5464
7ee72033
MB
5465 DEFVAR_LISP ("before-change-functions", &Vbefore_change_functions,
5466 doc: /* List of functions to call before each text change.
018ba359
PJ
5467Two arguments are passed to each function: the positions of
5468the beginning and end of the range of old text to be changed.
5469\(For an insertion, the beginning and end are at the same place.)
5470No information is given about the length of the text after the change.
5471
5472Buffer changes made while executing the `before-change-functions'
5473don't call any before-change or after-change functions.
5474That's because these variables are temporarily set to nil.
5475As a result, a hook function cannot straightforwardly alter the value of
5476these variables. See the Emacs Lisp manual for a way of
5477accomplishing an equivalent result by using other variables.
5478
5479If an unhandled error happens in running these functions,
5480the variable's value remains nil. That prevents the error
5481from happening repeatedly and making Emacs nonfunctional. */);
5f079267
RS
5482 Vbefore_change_functions = Qnil;
5483
7ee72033 5484 DEFVAR_LISP ("after-change-functions", &Vafter_change_functions,
cab1603f 5485 doc: /* List of functions to call after each text change.
018ba359
PJ
5486Three arguments are passed to each function: the positions of
5487the beginning and end of the range of changed text,
5488and the length in bytes of the pre-change text replaced by that range.
5489\(For an insertion, the pre-change length is zero;
5490for a deletion, that length is the number of bytes deleted,
5491and the post-change beginning and end are at the same place.)
5492
5493Buffer changes made while executing the `after-change-functions'
5494don't call any before-change or after-change functions.
5495That's because these variables are temporarily set to nil.
5496As a result, a hook function cannot straightforwardly alter the value of
5497these variables. See the Emacs Lisp manual for a way of
5498accomplishing an equivalent result by using other variables.
5499
5500If an unhandled error happens in running these functions,
5501the variable's value remains nil. That prevents the error
5502from happening repeatedly and making Emacs nonfunctional. */);
5f079267
RS
5503 Vafter_change_functions = Qnil;
5504
7ee72033 5505 DEFVAR_LISP ("first-change-hook", &Vfirst_change_hook,
efc7e75f 5506 doc: /* A list of functions to call before changing a buffer which is unmodified.
018ba359 5507The functions are run using the `run-hooks' function. */);
dbc4e1c1 5508 Vfirst_change_hook = Qnil;
1ab256cb 5509
7ee72033
MB
5510 DEFVAR_PER_BUFFER ("buffer-undo-list", &current_buffer->undo_list, Qnil,
5511 doc: /* List of undo entries in current buffer.
018ba359
PJ
5512Recent changes come first; older changes follow newer.
5513
5514An entry (BEG . END) represents an insertion which begins at
5515position BEG and ends at position END.
5516
5517An entry (TEXT . POSITION) represents the deletion of the string TEXT
5518from (abs POSITION). If POSITION is positive, point was at the front
5519of the text being deleted; if negative, point was at the end.
5520
5521An entry (t HIGH . LOW) indicates that the buffer previously had
5522\"unmodified\" status. HIGH and LOW are the high and low 16-bit portions
5523of the visited file's modification time, as of that time. If the
5524modification time of the most recent save is different, this entry is
5525obsolete.
5526
5527An entry (nil PROPERTY VALUE BEG . END) indicates that a text property
5528was modified between BEG and END. PROPERTY is the property name,
5529and VALUE is the old value.
5530
5531An entry (MARKER . DISTANCE) indicates that the marker MARKER
5532was adjusted in position by the offset DISTANCE (an integer).
5533
5534An entry of the form POSITION indicates that point was at the buffer
5535location given by the integer. Undoing an entry of this form places
5536point at POSITION.
5537
5538nil marks undo boundaries. The undo command treats the changes
5539between two undo boundaries as a single step to be undone.
5540
5541If the value of the variable is t, undo information is not recorded. */);
5542
7ee72033
MB
5543 DEFVAR_PER_BUFFER ("mark-active", &current_buffer->mark_active, Qnil,
5544 doc: /* Non-nil means the mark and region are currently active in this buffer. */);
018ba359 5545
7ee72033
MB
5546 DEFVAR_PER_BUFFER ("cache-long-line-scans", &current_buffer->cache_long_line_scans, Qnil,
5547 doc: /* Non-nil means that Emacs should use caches to handle long lines more quickly.
018ba359
PJ
5548
5549Normally, the line-motion functions work by scanning the buffer for
5550newlines. Columnar operations (like move-to-column and
5551compute-motion) also work by scanning the buffer, summing character
5552widths as they go. This works well for ordinary text, but if the
5553buffer's lines are very long (say, more than 500 characters), these
5554motion functions will take longer to execute. Emacs may also take
5555longer to update the display.
5556
5557If cache-long-line-scans is non-nil, these motion functions cache the
5558results of their scans, and consult the cache to avoid rescanning
5559regions of the buffer until the text is modified. The caches are most
5560beneficial when they prevent the most searching---that is, when the
5561buffer contains long lines and large regions of characters with the
5562same, fixed screen width.
5563
5564When cache-long-line-scans is non-nil, processing short lines will
5565become slightly slower (because of the overhead of consulting the
5566cache), and the caches will use memory roughly proportional to the
5567number of newlines and characters whose screen width varies.
5568
5569The caches require no explicit maintenance; their accuracy is
5570maintained internally by the Emacs primitives. Enabling or disabling
5571the cache should not affect the behavior of any of the motion
5572functions; it should only affect their performance. */);
5573
7ee72033
MB
5574 DEFVAR_PER_BUFFER ("point-before-scroll", &current_buffer->point_before_scroll, Qnil,
5575 doc: /* Value of point before the last series of scroll operations, or nil. */);
018ba359 5576
7ee72033
MB
5577 DEFVAR_PER_BUFFER ("buffer-file-format", &current_buffer->file_format, Qnil,
5578 doc: /* List of formats to use when saving this buffer.
018ba359
PJ
5579Formats are defined by `format-alist'. This variable is
5580set when a file is visited. Automatically local in all buffers. */);
be9aafdd 5581
3cb719bd 5582 DEFVAR_PER_BUFFER ("buffer-invisibility-spec",
7ee72033
MB
5583 &current_buffer->invisibility_spec, Qnil,
5584 doc: /* Invisibility spec of this buffer.
018ba359
PJ
5585The default is t, which means that text is invisible
5586if it has a non-nil `invisible' property.
5587If the value is a list, a text character is invisible if its `invisible'
5588property is an element in that list.
5589If an element is a cons cell of the form (PROP . ELLIPSIS),
5590then characters with property value PROP are invisible,
5591and they have an ellipsis as well if ELLIPSIS is non-nil. */);
3cb719bd 5592
7962a441 5593 DEFVAR_PER_BUFFER ("buffer-display-count",
7ee72033
MB
5594 &current_buffer->display_count, Qnil,
5595 doc: /* A number incremented each time this buffer is displayed in a window.
018ba359 5596The function `set-window-buffer' increments it. */);
3fd364db
RS
5597
5598 DEFVAR_PER_BUFFER ("buffer-display-time",
7ee72033
MB
5599 &current_buffer->display_time, Qnil,
5600 doc: /* Time stamp updated each time this buffer is displayed in a window.
018ba359
PJ
5601The function `set-window-buffer' updates this variable
5602to the value obtained by calling `current-time'.
5603If the buffer has never been shown in a window, the value is nil. */);
5604
7ee72033
MB
5605 DEFVAR_LISP ("transient-mark-mode", &Vtransient_mark_mode,
5606 doc: /* *Non-nil means deactivate the mark when the buffer contents change.
018ba359
PJ
5607Non-nil also enables highlighting of the region whenever the mark is active.
5608The variable `highlight-nonselected-windows' controls whether to highlight
5609all windows or just the selected window. */);
c48f61ef
RS
5610 Vtransient_mark_mode = Qnil;
5611
7ee72033
MB
5612 DEFVAR_LISP ("inhibit-read-only", &Vinhibit_read_only,
5613 doc: /* *Non-nil means disregard read-only status of buffers or characters.
018ba359
PJ
5614If the value is t, disregard `buffer-read-only' and all `read-only'
5615text properties. If the value is a list, disregard `buffer-read-only'
5616and disregard a `read-only' text property if the property value
5617is a member of the list. */);
a96b68f1
RS
5618 Vinhibit_read_only = Qnil;
5619
7ee72033
MB
5620 DEFVAR_PER_BUFFER ("cursor-type", &current_buffer->cursor_type, Qnil,
5621 doc: /* Cursor to use in window displaying this buffer.
018ba359
PJ
5622Values are interpreted as follows:
5623
5624 t use the cursor specified for the frame
5625 nil don't display a cursor
5626 `bar' display a bar cursor with default width
5627 (bar . WIDTH) display a bar cursor with width WIDTH
5628 others display a box cursor. */);
bb2ec976 5629
a3bbced0 5630 DEFVAR_PER_BUFFER ("line-spacing",
7ee72033
MB
5631 &current_buffer->extra_line_spacing, Qnil,
5632 doc: /* Additional space to put between lines when displaying a buffer.
018ba359 5633The space is measured in pixels, and put below lines on window systems. */);
a3bbced0 5634
7ee72033 5635 DEFVAR_LISP ("kill-buffer-query-functions", &Vkill_buffer_query_functions,
efc7e75f 5636 doc: /* List of functions called with no args to query before killing a buffer. */);
dcdffbf6
RS
5637 Vkill_buffer_query_functions = Qnil;
5638
0dc88e60 5639 defsubr (&Sbuffer_live_p);
1ab256cb
RM
5640 defsubr (&Sbuffer_list);
5641 defsubr (&Sget_buffer);
5642 defsubr (&Sget_file_buffer);
5643 defsubr (&Sget_buffer_create);
336cd056 5644 defsubr (&Smake_indirect_buffer);
01050cb5 5645 defsubr (&Sgenerate_new_buffer_name);
1ab256cb
RM
5646 defsubr (&Sbuffer_name);
5647/*defsubr (&Sbuffer_number);*/
5648 defsubr (&Sbuffer_file_name);
336cd056 5649 defsubr (&Sbuffer_base_buffer);
79aa712d 5650 defsubr (&Sbuffer_local_value);
1ab256cb
RM
5651 defsubr (&Sbuffer_local_variables);
5652 defsubr (&Sbuffer_modified_p);
5653 defsubr (&Sset_buffer_modified_p);
5654 defsubr (&Sbuffer_modified_tick);
5655 defsubr (&Srename_buffer);
5656 defsubr (&Sother_buffer);
5657 defsubr (&Sbuffer_disable_undo);
5658 defsubr (&Sbuffer_enable_undo);
5659 defsubr (&Skill_buffer);
a9ee7a59 5660 defsubr (&Sset_buffer_major_mode);
1ab256cb
RM
5661 defsubr (&Sswitch_to_buffer);
5662 defsubr (&Spop_to_buffer);
5663 defsubr (&Scurrent_buffer);
5664 defsubr (&Sset_buffer);
5665 defsubr (&Sbarf_if_buffer_read_only);
5666 defsubr (&Sbury_buffer);
3ac81adb
RS
5667 defsubr (&Serase_buffer);
5668 defsubr (&Sset_buffer_multibyte);
1ab256cb 5669 defsubr (&Skill_all_local_variables);
2eec3b4e 5670
52f8ec73 5671 defsubr (&Soverlayp);
2eec3b4e
RS
5672 defsubr (&Smake_overlay);
5673 defsubr (&Sdelete_overlay);
5674 defsubr (&Smove_overlay);
8ebafa8d
JB
5675 defsubr (&Soverlay_start);
5676 defsubr (&Soverlay_end);
5677 defsubr (&Soverlay_buffer);
5678 defsubr (&Soverlay_properties);
2eec3b4e 5679 defsubr (&Soverlays_at);
74514898 5680 defsubr (&Soverlays_in);
2eec3b4e 5681 defsubr (&Snext_overlay_change);
239c932b 5682 defsubr (&Sprevious_overlay_change);
2eec3b4e
RS
5683 defsubr (&Soverlay_recenter);
5684 defsubr (&Soverlay_lists);
5685 defsubr (&Soverlay_get);
5686 defsubr (&Soverlay_put);
a8c21b48 5687 defsubr (&Srestore_buffer_modified_p);
1ab256cb
RM
5688}
5689
dfcf069d 5690void
1ab256cb
RM
5691keys_of_buffer ()
5692{
5693 initial_define_key (control_x_map, 'b', "switch-to-buffer");
5694 initial_define_key (control_x_map, 'k', "kill-buffer");
4158c17d
RM
5695
5696 /* This must not be in syms_of_buffer, because Qdisabled is not
5697 initialized when that function gets called. */
5698 Fput (intern ("erase-buffer"), Qdisabled, Qt);
1ab256cb 5699}