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