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