Fix int/EMACS_INT in bidi.c.
[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
d3da34e0 2095advance_to_char_boundary (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. */
a9bcded1
KH
2108 int orig_byte_pos = byte_pos;
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;
458c8af4 2276 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 {
a9bcded1
KH
2308 int pos, stop;
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 {
a9bcded1
KH
2372 int pt = PT;
2373 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
KH
2388 {
2389 int new_gpt = GPT_BYTE - (GPT_ADDR - p);
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 {
2473 int pt_byte = advance_to_char_boundary (PT_BYTE);
2474 int pt;
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;
2645 int next = ZV;
239c932b 2646 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 {
239c932b 2651 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 {
239c932b 2702 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
d3da34e0
JB
2776overlays_in (int beg, int end, int extend, Lisp_Object **vec_ptr, int *len_ptr,
2777 int *next_ptr, int *prev_ptr)
74514898 2778{
2410d73a
SM
2779 Lisp_Object overlay, ostart, oend;
2780 struct Lisp_Overlay *tail;
74514898
RS
2781 int idx = 0;
2782 int len = *len_ptr;
2783 Lisp_Object *vec = *vec_ptr;
2784 int next = ZV;
2785 int prev = BEGV;
2786 int inhibit_storing = 0;
7723e095 2787 int end_is_Z = end == Z;
74514898 2788
2410d73a 2789 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
74514898
RS
2790 {
2791 int startpos, endpos;
2792
2410d73a 2793 XSETMISC (overlay, tail);
74514898
RS
2794
2795 ostart = OVERLAY_START (overlay);
2796 oend = OVERLAY_END (overlay);
2797 endpos = OVERLAY_POSITION (oend);
2798 if (endpos < beg)
2799 {
2800 if (prev < endpos)
2801 prev = endpos;
2802 break;
2803 }
2804 startpos = OVERLAY_POSITION (ostart);
7723e095
MR
2805 /* Count an interval if it overlaps the range, is empty at the
2806 start of the range, or is empty at END provided END denotes the
2807 end of the buffer. */
74514898 2808 if ((beg < endpos && startpos < end)
7723e095
MR
2809 || (startpos == endpos
2810 && (beg == endpos || (end_is_Z && endpos == end))))
74514898
RS
2811 {
2812 if (idx == len)
2813 {
2814 /* The supplied vector is full.
2815 Either make it bigger, or don't store any more in it. */
2816 if (extend)
2817 {
4b0e44fc
RS
2818 /* Make it work with an initial len == 0. */
2819 len *= 2;
2820 if (len == 0)
2821 len = 4;
2822 *len_ptr = len;
74514898
RS
2823 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
2824 *vec_ptr = vec;
2825 }
2826 else
2827 inhibit_storing = 1;
2828 }
2829
2830 if (!inhibit_storing)
2831 vec[idx] = overlay;
2832 /* Keep counting overlays even if we can't return them all. */
2833 idx++;
2834 }
2835 else if (startpos < next)
2836 next = startpos;
2837 }
2838
2410d73a 2839 for (tail = current_buffer->overlays_after; tail; tail = tail->next)
74514898
RS
2840 {
2841 int startpos, endpos;
2842
2410d73a 2843 XSETMISC (overlay, tail);
74514898
RS
2844
2845 ostart = OVERLAY_START (overlay);
2846 oend = OVERLAY_END (overlay);
2847 startpos = OVERLAY_POSITION (ostart);
2848 if (end < startpos)
2849 {
2850 if (startpos < next)
2851 next = startpos;
2852 break;
2853 }
2854 endpos = OVERLAY_POSITION (oend);
7723e095
MR
2855 /* Count an interval if it overlaps the range, is empty at the
2856 start of the range, or is empty at END provided END denotes the
2857 end of the buffer. */
74514898 2858 if ((beg < endpos && startpos < end)
7723e095
MR
2859 || (startpos == endpos
2860 && (beg == endpos || (end_is_Z && endpos == end))))
74514898
RS
2861 {
2862 if (idx == len)
2863 {
2864 if (extend)
2865 {
4b0e44fc
RS
2866 /* Make it work with an initial len == 0. */
2867 len *= 2;
2868 if (len == 0)
2869 len = 4;
2870 *len_ptr = len;
74514898
RS
2871 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
2872 *vec_ptr = vec;
2873 }
2874 else
2875 inhibit_storing = 1;
2876 }
2877
2878 if (!inhibit_storing)
2879 vec[idx] = overlay;
2880 idx++;
2881 }
2882 else if (endpos < beg && endpos > prev)
2883 prev = endpos;
2884 }
fc04fa47 2885
74514898
RS
2886 if (next_ptr)
2887 *next_ptr = next;
2888 if (prev_ptr)
2889 *prev_ptr = prev;
2890 return idx;
2891}
09a22085
GM
2892
2893
2894/* Return non-zero if there exists an overlay with a non-nil
2895 `mouse-face' property overlapping OVERLAY. */
2896
2897int
d3da34e0 2898mouse_face_overlay_overlaps (Lisp_Object overlay)
09a22085
GM
2899{
2900 int start = OVERLAY_POSITION (OVERLAY_START (overlay));
2901 int end = OVERLAY_POSITION (OVERLAY_END (overlay));
bfd8410f 2902 int n, i, size;
09a22085 2903 Lisp_Object *v, tem;
177c0ea7 2904
bfd8410f
GM
2905 size = 10;
2906 v = (Lisp_Object *) alloca (size * sizeof *v);
2907 n = overlays_in (start, end, 0, &v, &size, NULL, NULL);
2908 if (n > size)
09a22085 2909 {
09a22085
GM
2910 v = (Lisp_Object *) alloca (n * sizeof *v);
2911 overlays_in (start, end, 0, &v, &n, NULL, NULL);
2912 }
2913
2914 for (i = 0; i < n; ++i)
2915 if (!EQ (v[i], overlay)
2916 && (tem = Foverlay_get (overlay, Qmouse_face),
2917 !NILP (tem)))
2918 break;
2919
2920 return i < n;
2921}
2922
2923
74514898 2924\f
fc04fa47
KH
2925/* Fast function to just test if we're at an overlay boundary. */
2926int
d3da34e0 2927overlay_touches_p (int pos)
fc04fa47 2928{
2410d73a
SM
2929 Lisp_Object overlay;
2930 struct Lisp_Overlay *tail;
fc04fa47 2931
2410d73a 2932 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
fc04fa47
KH
2933 {
2934 int endpos;
2935
2410d73a 2936 XSETMISC (overlay ,tail);
8e50cc2d 2937 if (!OVERLAYP (overlay))
fc04fa47
KH
2938 abort ();
2939
2940 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
2941 if (endpos < pos)
2942 break;
2943 if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos)
2944 return 1;
2945 }
2946
2410d73a 2947 for (tail = current_buffer->overlays_after; tail; tail = tail->next)
fc04fa47
KH
2948 {
2949 int startpos;
2950
2410d73a 2951 XSETMISC (overlay, tail);
8e50cc2d 2952 if (!OVERLAYP (overlay))
fc04fa47
KH
2953 abort ();
2954
2955 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
2956 if (pos < startpos)
2957 break;
2958 if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
2959 return 1;
2960 }
2961 return 0;
2962}
2eec3b4e 2963\f
5985d248
KH
2964struct sortvec
2965{
2966 Lisp_Object overlay;
2967 int beg, end;
2968 int priority;
2969};
2970
2971static int
d3da34e0 2972compare_overlays (const void *v1, const void *v2)
5985d248 2973{
dfcf069d
AS
2974 const struct sortvec *s1 = (const struct sortvec *) v1;
2975 const struct sortvec *s2 = (const struct sortvec *) v2;
5985d248
KH
2976 if (s1->priority != s2->priority)
2977 return s1->priority - s2->priority;
2978 if (s1->beg != s2->beg)
2979 return s1->beg - s2->beg;
2980 if (s1->end != s2->end)
2981 return s2->end - s1->end;
2982 return 0;
2983}
2984
2985/* Sort an array of overlays by priority. The array is modified in place.
2986 The return value is the new size; this may be smaller than the original
2987 size if some of the overlays were invalid or were window-specific. */
2988int
d3da34e0 2989sort_overlays (Lisp_Object *overlay_vec, int noverlays, struct window *w)
5985d248
KH
2990{
2991 int i, j;
2992 struct sortvec *sortvec;
2993 sortvec = (struct sortvec *) alloca (noverlays * sizeof (struct sortvec));
2994
2995 /* Put the valid and relevant overlays into sortvec. */
2996
2997 for (i = 0, j = 0; i < noverlays; i++)
2998 {
0fa767e7 2999 Lisp_Object tem;
c99fc30f 3000 Lisp_Object overlay;
5985d248 3001
c99fc30f 3002 overlay = overlay_vec[i];
5985d248
KH
3003 if (OVERLAY_VALID (overlay)
3004 && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0
3005 && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0)
3006 {
0fa767e7
KH
3007 /* If we're interested in a specific window, then ignore
3008 overlays that are limited to some other window. */
3009 if (w)
5985d248 3010 {
0fa767e7
KH
3011 Lisp_Object window;
3012
3013 window = Foverlay_get (overlay, Qwindow);
a7a60ce9 3014 if (WINDOWP (window) && XWINDOW (window) != w)
0fa767e7 3015 continue;
5985d248 3016 }
0fa767e7
KH
3017
3018 /* This overlay is good and counts: put it into sortvec. */
3019 sortvec[j].overlay = overlay;
3020 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3021 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
3022 tem = Foverlay_get (overlay, Qpriority);
3023 if (INTEGERP (tem))
3024 sortvec[j].priority = XINT (tem);
3025 else
3026 sortvec[j].priority = 0;
3027 j++;
5985d248
KH
3028 }
3029 }
3030 noverlays = j;
3031
3032 /* Sort the overlays into the proper order: increasing priority. */
3033
3034 if (noverlays > 1)
3035 qsort (sortvec, noverlays, sizeof (struct sortvec), compare_overlays);
3036
3037 for (i = 0; i < noverlays; i++)
3038 overlay_vec[i] = sortvec[i].overlay;
3039 return (noverlays);
3040}
3041\f
bbbe9545
KH
3042struct sortstr
3043{
cb26008f 3044 Lisp_Object string, string2;
bbbe9545
KH
3045 int size;
3046 int priority;
3047};
3048
e8185fa8
KH
3049struct sortstrlist
3050{
3051 struct sortstr *buf; /* An array that expands as needed; never freed. */
3052 int size; /* Allocated length of that array. */
3053 int used; /* How much of the array is currently in use. */
3054 int bytes; /* Total length of the strings in buf. */
3055};
3056
3057/* Buffers for storing information about the overlays touching a given
3058 position. These could be automatic variables in overlay_strings, but
3059 it's more efficient to hold onto the memory instead of repeatedly
3060 allocating and freeing it. */
3061static struct sortstrlist overlay_heads, overlay_tails;
9492daf2 3062static unsigned char *overlay_str_buf;
e8185fa8
KH
3063
3064/* Allocated length of overlay_str_buf. */
3065static int overlay_str_len;
3066
bbbe9545
KH
3067/* A comparison function suitable for passing to qsort. */
3068static int
d3da34e0 3069cmp_for_strings (const void *as1, const void *as2)
bbbe9545
KH
3070{
3071 struct sortstr *s1 = (struct sortstr *)as1;
3072 struct sortstr *s2 = (struct sortstr *)as2;
3073 if (s1->size != s2->size)
3074 return s2->size - s1->size;
3075 if (s1->priority != s2->priority)
3076 return s1->priority - s2->priority;
3077 return 0;
3078}
3079
e8185fa8 3080static void
d3da34e0 3081record_overlay_string (struct sortstrlist *ssl, Lisp_Object str, Lisp_Object str2, Lisp_Object pri, int size)
e8185fa8 3082{
43d27a72
RS
3083 int nbytes;
3084
e8185fa8
KH
3085 if (ssl->used == ssl->size)
3086 {
3087 if (ssl->buf)
3088 ssl->size *= 2;
3089 else
3090 ssl->size = 5;
3091 ssl->buf = ((struct sortstr *)
3092 xrealloc (ssl->buf, ssl->size * sizeof (struct sortstr)));
3093 }
3094 ssl->buf[ssl->used].string = str;
cb26008f 3095 ssl->buf[ssl->used].string2 = str2;
e8185fa8
KH
3096 ssl->buf[ssl->used].size = size;
3097 ssl->buf[ssl->used].priority = (INTEGERP (pri) ? XINT (pri) : 0);
3098 ssl->used++;
43d27a72
RS
3099
3100 if (NILP (current_buffer->enable_multibyte_characters))
d5db4077 3101 nbytes = SCHARS (str);
43d27a72 3102 else if (! STRING_MULTIBYTE (str))
d5db4077
KR
3103 nbytes = count_size_as_multibyte (SDATA (str),
3104 SBYTES (str));
43d27a72 3105 else
d5db4077 3106 nbytes = SBYTES (str);
43d27a72
RS
3107
3108 ssl->bytes += nbytes;
3109
cb26008f 3110 if (STRINGP (str2))
43d27a72
RS
3111 {
3112 if (NILP (current_buffer->enable_multibyte_characters))
d5db4077 3113 nbytes = SCHARS (str2);
43d27a72 3114 else if (! STRING_MULTIBYTE (str2))
d5db4077
KR
3115 nbytes = count_size_as_multibyte (SDATA (str2),
3116 SBYTES (str2));
43d27a72 3117 else
d5db4077 3118 nbytes = SBYTES (str2);
43d27a72
RS
3119
3120 ssl->bytes += nbytes;
3121 }
e8185fa8 3122}
bbbe9545
KH
3123
3124/* Return the concatenation of the strings associated with overlays that
3125 begin or end at POS, ignoring overlays that are specific to a window
3126 other than W. The strings are concatenated in the appropriate order:
3127 shorter overlays nest inside longer ones, and higher priority inside
cb26008f
KH
3128 lower. Normally all of the after-strings come first, but zero-sized
3129 overlays have their after-strings ride along with the before-strings
3130 because it would look strange to print them inside-out.
3131
3132 Returns the string length, and stores the contents indirectly through
3133 PSTR, if that variable is non-null. The string may be overwritten by
3134 subsequent calls. */
6b5d3b89 3135
bbbe9545 3136int
d3da34e0 3137overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr)
bbbe9545 3138{
2410d73a
SM
3139 Lisp_Object overlay, window, str;
3140 struct Lisp_Overlay *ov;
bbbe9545 3141 int startpos, endpos;
43d27a72 3142 int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
bbbe9545 3143
e8185fa8
KH
3144 overlay_heads.used = overlay_heads.bytes = 0;
3145 overlay_tails.used = overlay_tails.bytes = 0;
2410d73a 3146 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
bbbe9545 3147 {
2410d73a 3148 XSETMISC (overlay, ov);
c2d5b10f 3149 eassert (OVERLAYP (overlay));
bbbe9545
KH
3150
3151 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3152 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3153 if (endpos < pos)
3154 break;
3155 if (endpos != pos && startpos != pos)
3156 continue;
3157 window = Foverlay_get (overlay, Qwindow);
3158 if (WINDOWP (window) && XWINDOW (window) != w)
3159 continue;
e8185fa8
KH
3160 if (startpos == pos
3161 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3162 record_overlay_string (&overlay_heads, str,
cb26008f
KH
3163 (startpos == endpos
3164 ? Foverlay_get (overlay, Qafter_string)
3165 : Qnil),
3166 Foverlay_get (overlay, Qpriority),
3167 endpos - startpos);
3168 else if (endpos == pos
3169 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
3170 record_overlay_string (&overlay_tails, str, Qnil,
e8185fa8
KH
3171 Foverlay_get (overlay, Qpriority),
3172 endpos - startpos);
bbbe9545 3173 }
2410d73a 3174 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
bbbe9545 3175 {
2410d73a
SM
3176 XSETMISC (overlay, ov);
3177 eassert (OVERLAYP (overlay));
bbbe9545
KH
3178
3179 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3180 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3181 if (startpos > pos)
3182 break;
e8185fa8
KH
3183 if (endpos != pos && startpos != pos)
3184 continue;
3185 window = Foverlay_get (overlay, Qwindow);
3186 if (WINDOWP (window) && XWINDOW (window) != w)
3187 continue;
e8185fa8
KH
3188 if (startpos == pos
3189 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3190 record_overlay_string (&overlay_heads, str,
cb26008f
KH
3191 (startpos == endpos
3192 ? Foverlay_get (overlay, Qafter_string)
3193 : Qnil),
3194 Foverlay_get (overlay, Qpriority),
3195 endpos - startpos);
3196 else if (endpos == pos
3197 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
3198 record_overlay_string (&overlay_tails, str, Qnil,
e8185fa8
KH
3199 Foverlay_get (overlay, Qpriority),
3200 endpos - startpos);
bbbe9545 3201 }
e8185fa8
KH
3202 if (overlay_tails.used > 1)
3203 qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr),
3204 cmp_for_strings);
3205 if (overlay_heads.used > 1)
3206 qsort (overlay_heads.buf, overlay_heads.used, sizeof (struct sortstr),
3207 cmp_for_strings);
3208 if (overlay_heads.bytes || overlay_tails.bytes)
bbbe9545 3209 {
e8185fa8 3210 Lisp_Object tem;
bbbe9545 3211 int i;
9f4d7cde 3212 unsigned char *p;
e8185fa8 3213 int total = overlay_heads.bytes + overlay_tails.bytes;
bbbe9545
KH
3214
3215 if (total > overlay_str_len)
9f4d7cde
RS
3216 {
3217 overlay_str_len = total;
3218 overlay_str_buf = (unsigned char *)xrealloc (overlay_str_buf,
3219 total);
3220 }
bbbe9545 3221 p = overlay_str_buf;
e8185fa8 3222 for (i = overlay_tails.used; --i >= 0;)
bbbe9545 3223 {
43d27a72 3224 int nbytes;
e8185fa8 3225 tem = overlay_tails.buf[i].string;
d5db4077
KR
3226 nbytes = copy_text (SDATA (tem), p,
3227 SBYTES (tem),
43d27a72
RS
3228 STRING_MULTIBYTE (tem), multibyte);
3229 p += nbytes;
bbbe9545 3230 }
e8185fa8 3231 for (i = 0; i < overlay_heads.used; ++i)
bbbe9545 3232 {
43d27a72 3233 int nbytes;
e8185fa8 3234 tem = overlay_heads.buf[i].string;
d5db4077
KR
3235 nbytes = copy_text (SDATA (tem), p,
3236 SBYTES (tem),
43d27a72
RS
3237 STRING_MULTIBYTE (tem), multibyte);
3238 p += nbytes;
cb26008f
KH
3239 tem = overlay_heads.buf[i].string2;
3240 if (STRINGP (tem))
3241 {
d5db4077
KR
3242 nbytes = copy_text (SDATA (tem), p,
3243 SBYTES (tem),
43d27a72
RS
3244 STRING_MULTIBYTE (tem), multibyte);
3245 p += nbytes;
cb26008f 3246 }
bbbe9545 3247 }
cb26008f
KH
3248 if (p != overlay_str_buf + total)
3249 abort ();
bbbe9545
KH
3250 if (pstr)
3251 *pstr = overlay_str_buf;
e8185fa8 3252 return total;
bbbe9545 3253 }
e8185fa8 3254 return 0;
bbbe9545
KH
3255}
3256\f
5c4f68f1 3257/* Shift overlays in BUF's overlay lists, to center the lists at POS. */
1ab256cb 3258
2eec3b4e 3259void
d3da34e0 3260recenter_overlay_lists (struct buffer *buf, EMACS_INT pos)
2eec3b4e 3261{
2410d73a
SM
3262 Lisp_Object overlay, beg, end;
3263 struct Lisp_Overlay *prev, *tail, *next;
2eec3b4e
RS
3264
3265 /* See if anything in overlays_before should move to overlays_after. */
3266
3267 /* We don't strictly need prev in this loop; it should always be nil.
3268 But we use it for symmetry and in case that should cease to be true
3269 with some future change. */
2410d73a
SM
3270 prev = NULL;
3271 for (tail = buf->overlays_before; tail; prev = tail, tail = next)
1ab256cb 3272 {
2410d73a
SM
3273 next = tail->next;
3274 XSETMISC (overlay, tail);
2eec3b4e
RS
3275
3276 /* If the overlay is not valid, get rid of it. */
3277 if (!OVERLAY_VALID (overlay))
52f8ec73
JB
3278#if 1
3279 abort ();
3280#else
2eec3b4e
RS
3281 {
3282 /* Splice the cons cell TAIL out of overlays_before. */
3283 if (!NILP (prev))
7539e11f 3284 XCDR (prev) = next;
2eec3b4e 3285 else
5c4f68f1 3286 buf->overlays_before = next;
2eec3b4e
RS
3287 tail = prev;
3288 continue;
3289 }
52f8ec73 3290#endif
1ab256cb 3291
2eec3b4e
RS
3292 beg = OVERLAY_START (overlay);
3293 end = OVERLAY_END (overlay);
1ab256cb 3294
2eec3b4e 3295 if (OVERLAY_POSITION (end) > pos)
1ab256cb 3296 {
2eec3b4e
RS
3297 /* OVERLAY needs to be moved. */
3298 int where = OVERLAY_POSITION (beg);
2410d73a 3299 struct Lisp_Overlay *other, *other_prev;
2eec3b4e
RS
3300
3301 /* Splice the cons cell TAIL out of overlays_before. */
2410d73a
SM
3302 if (prev)
3303 prev->next = next;
2eec3b4e 3304 else
5c4f68f1 3305 buf->overlays_before = next;
2eec3b4e
RS
3306
3307 /* Search thru overlays_after for where to put it. */
2410d73a
SM
3308 other_prev = NULL;
3309 for (other = buf->overlays_after; other;
3310 other_prev = other, other = other->next)
1ab256cb 3311 {
6af718a4 3312 Lisp_Object otherbeg, otheroverlay;
2eec3b4e 3313
2410d73a
SM
3314 XSETMISC (otheroverlay, other);
3315 eassert (OVERLAY_VALID (otheroverlay));
2eec3b4e
RS
3316
3317 otherbeg = OVERLAY_START (otheroverlay);
3318 if (OVERLAY_POSITION (otherbeg) >= where)
3319 break;
1ab256cb 3320 }
2eec3b4e
RS
3321
3322 /* Add TAIL to overlays_after before OTHER. */
2410d73a
SM
3323 tail->next = other;
3324 if (other_prev)
3325 other_prev->next = tail;
1ab256cb 3326 else
5c4f68f1 3327 buf->overlays_after = tail;
2eec3b4e 3328 tail = prev;
1ab256cb 3329 }
2eec3b4e
RS
3330 else
3331 /* We've reached the things that should stay in overlays_before.
3332 All the rest of overlays_before must end even earlier,
3333 so stop now. */
3334 break;
3335 }
3336
3337 /* See if anything in overlays_after should be in overlays_before. */
2410d73a
SM
3338 prev = NULL;
3339 for (tail = buf->overlays_after; tail; prev = tail, tail = next)
2eec3b4e 3340 {
2410d73a
SM
3341 next = tail->next;
3342 XSETMISC (overlay, tail);
2eec3b4e
RS
3343
3344 /* If the overlay is not valid, get rid of it. */
3345 if (!OVERLAY_VALID (overlay))
52f8ec73
JB
3346#if 1
3347 abort ();
3348#else
2eec3b4e
RS
3349 {
3350 /* Splice the cons cell TAIL out of overlays_after. */
3351 if (!NILP (prev))
7539e11f 3352 XCDR (prev) = next;
2eec3b4e 3353 else
5c4f68f1 3354 buf->overlays_after = next;
2eec3b4e
RS
3355 tail = prev;
3356 continue;
3357 }
52f8ec73 3358#endif
2eec3b4e
RS
3359
3360 beg = OVERLAY_START (overlay);
3361 end = OVERLAY_END (overlay);
3362
3363 /* Stop looking, when we know that nothing further
3364 can possibly end before POS. */
3365 if (OVERLAY_POSITION (beg) > pos)
3366 break;
3367
3368 if (OVERLAY_POSITION (end) <= pos)
3369 {
3370 /* OVERLAY needs to be moved. */
3371 int where = OVERLAY_POSITION (end);
2410d73a 3372 struct Lisp_Overlay *other, *other_prev;
2eec3b4e
RS
3373
3374 /* Splice the cons cell TAIL out of overlays_after. */
2410d73a
SM
3375 if (prev)
3376 prev->next = next;
2eec3b4e 3377 else
5c4f68f1 3378 buf->overlays_after = next;
2eec3b4e
RS
3379
3380 /* Search thru overlays_before for where to put it. */
2410d73a
SM
3381 other_prev = NULL;
3382 for (other = buf->overlays_before; other;
3383 other_prev = other, other = other->next)
2eec3b4e
RS
3384 {
3385 Lisp_Object otherend, otheroverlay;
2eec3b4e 3386
2410d73a
SM
3387 XSETMISC (otheroverlay, other);
3388 eassert (OVERLAY_VALID (otheroverlay));
2eec3b4e
RS
3389
3390 otherend = OVERLAY_END (otheroverlay);
3391 if (OVERLAY_POSITION (otherend) <= where)
3392 break;
3393 }
3394
3395 /* Add TAIL to overlays_before before OTHER. */
2410d73a
SM
3396 tail->next = other;
3397 if (other_prev)
3398 other_prev->next = tail;
2eec3b4e 3399 else
5c4f68f1 3400 buf->overlays_before = tail;
2eec3b4e
RS
3401 tail = prev;
3402 }
3403 }
3404
c2d5b10f 3405 buf->overlay_center = pos;
2eec3b4e 3406}
2b1bdf65 3407
423cdb46 3408void
d3da34e0 3409adjust_overlays_for_insert (EMACS_INT pos, EMACS_INT length)
423cdb46
KH
3410{
3411 /* After an insertion, the lists are still sorted properly,
3412 but we may need to update the value of the overlay center. */
c2d5b10f
SM
3413 if (current_buffer->overlay_center >= pos)
3414 current_buffer->overlay_center += length;
423cdb46
KH
3415}
3416
3417void
d3da34e0 3418adjust_overlays_for_delete (EMACS_INT pos, EMACS_INT length)
423cdb46 3419{
c2d5b10f 3420 if (current_buffer->overlay_center < pos)
423cdb46
KH
3421 /* The deletion was to our right. No change needed; the before- and
3422 after-lists are still consistent. */
3423 ;
c2d5b10f 3424 else if (current_buffer->overlay_center > pos + length)
423cdb46
KH
3425 /* The deletion was to our left. We need to adjust the center value
3426 to account for the change in position, but the lists are consistent
3427 given the new value. */
c2d5b10f 3428 current_buffer->overlay_center -= length;
423cdb46
KH
3429 else
3430 /* We're right in the middle. There might be things on the after-list
3431 that now belong on the before-list. Recentering will move them,
3432 and also update the center point. */
3433 recenter_overlay_lists (current_buffer, pos);
3434}
3435
2b1bdf65
KH
3436/* Fix up overlays that were garbled as a result of permuting markers
3437 in the range START through END. Any overlay with at least one
3438 endpoint in this range will need to be unlinked from the overlay
3439 list and reinserted in its proper place.
3440 Such an overlay might even have negative size at this point.
6b61353c 3441 If so, we'll make the overlay empty. */
2b1bdf65 3442void
d3da34e0 3443fix_start_end_in_overlays (register int start, register int end)
2b1bdf65 3444{
6af718a4 3445 Lisp_Object overlay;
2410d73a 3446 struct Lisp_Overlay *before_list, *after_list;
1138e742
KR
3447 /* These are either nil, indicating that before_list or after_list
3448 should be assigned, or the cons cell the cdr of which should be
3449 assigned. */
2410d73a 3450 struct Lisp_Overlay *beforep = NULL, *afterp = NULL;
1138e742
KR
3451 /* 'Parent', likewise, indicates a cons cell or
3452 current_buffer->overlays_before or overlays_after, depending
3453 which loop we're in. */
2410d73a 3454 struct Lisp_Overlay *tail, *parent;
2b1bdf65
KH
3455 int startpos, endpos;
3456
3457 /* This algorithm shifts links around instead of consing and GCing.
3458 The loop invariant is that before_list (resp. after_list) is a
1138e742
KR
3459 well-formed list except that its last element, the CDR of beforep
3460 (resp. afterp) if beforep (afterp) isn't nil or before_list
3461 (after_list) if it is, is still uninitialized. So it's not a bug
3462 that before_list isn't initialized, although it may look
3463 strange. */
2410d73a 3464 for (parent = NULL, tail = current_buffer->overlays_before; tail;)
2b1bdf65 3465 {
2410d73a 3466 XSETMISC (overlay, tail);
6b61353c 3467
2b1bdf65 3468 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
6b61353c
KH
3469 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3470
3471 /* If the overlay is backwards, make it empty. */
3472 if (endpos < startpos)
3473 {
3474 startpos = endpos;
3475 Fset_marker (OVERLAY_START (overlay), make_number (startpos),
3476 Qnil);
3477 }
3478
2b1bdf65
KH
3479 if (endpos < start)
3480 break;
60ebfdf3 3481
2b1bdf65
KH
3482 if (endpos < end
3483 || (startpos >= start && startpos < end))
3484 {
2b1bdf65
KH
3485 /* Add it to the end of the wrong list. Later on,
3486 recenter_overlay_lists will move it to the right place. */
c2d5b10f 3487 if (endpos < current_buffer->overlay_center)
2b1bdf65 3488 {
2410d73a 3489 if (!afterp)
1138e742
KR
3490 after_list = tail;
3491 else
2410d73a 3492 afterp->next = tail;
1138e742 3493 afterp = tail;
2b1bdf65
KH
3494 }
3495 else
3496 {
2410d73a 3497 if (!beforep)
1138e742
KR
3498 before_list = tail;
3499 else
2410d73a 3500 beforep->next = tail;
1138e742 3501 beforep = tail;
2b1bdf65 3502 }
2410d73a
SM
3503 if (!parent)
3504 current_buffer->overlays_before = tail->next;
1138e742 3505 else
2410d73a
SM
3506 parent->next = tail->next;
3507 tail = tail->next;
2b1bdf65
KH
3508 }
3509 else
2410d73a 3510 parent = tail, tail = parent->next;
2b1bdf65 3511 }
2410d73a 3512 for (parent = NULL, tail = current_buffer->overlays_after; tail;)
2b1bdf65 3513 {
2410d73a 3514 XSETMISC (overlay, tail);
6b61353c 3515
2b1bdf65 3516 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
6b61353c
KH
3517 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3518
3519 /* If the overlay is backwards, make it empty. */
3520 if (endpos < startpos)
3521 {
3522 startpos = endpos;
3523 Fset_marker (OVERLAY_START (overlay), make_number (startpos),
60ebfdf3 3524 Qnil);
6b61353c
KH
3525 }
3526
2b1bdf65
KH
3527 if (startpos >= end)
3528 break;
6b61353c 3529
2b1bdf65
KH
3530 if (startpos >= start
3531 || (endpos >= start && endpos < end))
3532 {
c2d5b10f 3533 if (endpos < current_buffer->overlay_center)
2b1bdf65 3534 {
2410d73a 3535 if (!afterp)
1138e742
KR
3536 after_list = tail;
3537 else
2410d73a 3538 afterp->next = tail;
1138e742 3539 afterp = tail;
2b1bdf65
KH
3540 }
3541 else
3542 {
2410d73a 3543 if (!beforep)
1138e742
KR
3544 before_list = tail;
3545 else
2410d73a 3546 beforep->next = tail;
1138e742 3547 beforep = tail;
2b1bdf65 3548 }
2410d73a
SM
3549 if (!parent)
3550 current_buffer->overlays_after = tail->next;
1138e742 3551 else
2410d73a
SM
3552 parent->next = tail->next;
3553 tail = tail->next;
2b1bdf65
KH
3554 }
3555 else
2410d73a 3556 parent = tail, tail = parent->next;
2b1bdf65
KH
3557 }
3558
3559 /* Splice the constructed (wrong) lists into the buffer's lists,
3560 and let the recenter function make it sane again. */
2410d73a 3561 if (beforep)
1138e742 3562 {
2410d73a 3563 beforep->next = current_buffer->overlays_before;
1138e742
KR
3564 current_buffer->overlays_before = before_list;
3565 }
c2d5b10f 3566 recenter_overlay_lists (current_buffer, current_buffer->overlay_center);
2b1bdf65 3567
2410d73a 3568 if (afterp)
1138e742 3569 {
2410d73a 3570 afterp->next = current_buffer->overlays_after;
1138e742
KR
3571 current_buffer->overlays_after = after_list;
3572 }
c2d5b10f 3573 recenter_overlay_lists (current_buffer, current_buffer->overlay_center);
2b1bdf65 3574}
3b06f880
KH
3575
3576/* We have two types of overlay: the one whose ending marker is
3577 after-insertion-marker (this is the usual case) and the one whose
3578 ending marker is before-insertion-marker. When `overlays_before'
3579 contains overlays of the latter type and the former type in this
3580 order and both overlays end at inserting position, inserting a text
3581 increases only the ending marker of the latter type, which results
3582 in incorrect ordering of `overlays_before'.
3583
3584 This function fixes ordering of overlays in the slot
3585 `overlays_before' of the buffer *BP. Before the insertion, `point'
3586 was at PREV, and now is at POS. */
3587
01136e9b 3588void
d3da34e0 3589fix_overlays_before (struct buffer *bp, EMACS_INT prev, EMACS_INT pos)
3b06f880 3590{
2410d73a
SM
3591 /* If parent is nil, replace overlays_before; otherwise, parent->next. */
3592 struct Lisp_Overlay *tail = bp->overlays_before, *parent = NULL, *right_pair;
3593 Lisp_Object tem;
c2d5b10f 3594 EMACS_INT end;
3b06f880
KH
3595
3596 /* After the insertion, the several overlays may be in incorrect
3597 order. The possibility is that, in the list `overlays_before',
3598 an overlay which ends at POS appears after an overlay which ends
3599 at PREV. Since POS is greater than PREV, we must fix the
3600 ordering of these overlays, by moving overlays ends at POS before
3601 the overlays ends at PREV. */
3602
3603 /* At first, find a place where disordered overlays should be linked
3604 in. It is where an overlay which end before POS exists. (i.e. an
3605 overlay whose ending marker is after-insertion-marker if disorder
3606 exists). */
2410d73a
SM
3607 while (tail
3608 && (XSETMISC (tem, tail),
3609 (end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos))
1138e742
KR
3610 {
3611 parent = tail;
2410d73a 3612 tail = tail->next;
1138e742 3613 }
3b06f880
KH
3614
3615 /* If we don't find such an overlay,
3616 or the found one ends before PREV,
3617 or the found one is the last one in the list,
3618 we don't have to fix anything. */
f93ad4cf 3619 if (!tail || end < prev || !tail->next)
3b06f880
KH
3620 return;
3621
1138e742
KR
3622 right_pair = parent;
3623 parent = tail;
2410d73a 3624 tail = tail->next;
3b06f880 3625
1138e742 3626 /* Now, end position of overlays in the list TAIL should be before
3b06f880 3627 or equal to PREV. In the loop, an overlay which ends at POS is
1138e742
KR
3628 moved ahead to the place indicated by the CDR of RIGHT_PAIR. If
3629 we found an overlay which ends before PREV, the remaining
3630 overlays are in correct order. */
2410d73a 3631 while (tail)
3b06f880 3632 {
2410d73a
SM
3633 XSETMISC (tem, tail);
3634 end = OVERLAY_POSITION (OVERLAY_END (tem));
3b06f880
KH
3635
3636 if (end == pos)
3637 { /* This overlay is disordered. */
2410d73a 3638 struct Lisp_Overlay *found = tail;
3b06f880
KH
3639
3640 /* Unlink the found overlay. */
2410d73a
SM
3641 tail = found->next;
3642 parent->next = tail;
1138e742
KR
3643 /* Move an overlay at RIGHT_PLACE to the next of the found one,
3644 and link it into the right place. */
2410d73a 3645 if (!right_pair)
1138e742 3646 {
2410d73a 3647 found->next = bp->overlays_before;
1138e742
KR
3648 bp->overlays_before = found;
3649 }
3650 else
3651 {
2410d73a
SM
3652 found->next = right_pair->next;
3653 right_pair->next = found;
1138e742 3654 }
3b06f880
KH
3655 }
3656 else if (end == prev)
1138e742
KR
3657 {
3658 parent = tail;
2410d73a 3659 tail = tail->next;
1138e742 3660 }
3b06f880
KH
3661 else /* No more disordered overlay. */
3662 break;
3663 }
3664}
2eec3b4e 3665\f
52f8ec73 3666DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
7ee72033 3667 doc: /* Return t if OBJECT is an overlay. */)
5842a27b 3668 (Lisp_Object object)
52f8ec73
JB
3669{
3670 return (OVERLAYP (object) ? Qt : Qnil);
3671}
3672
acac2700 3673DEFUN ("make-overlay", Fmake_overlay, Smake_overlay, 2, 5, 0,
7ee72033 3674 doc: /* Create a new overlay with range BEG to END in BUFFER.
018ba359
PJ
3675If omitted, BUFFER defaults to the current buffer.
3676BEG and END may be integers or markers.
a625ee20
RS
3677The fourth arg FRONT-ADVANCE, if non-nil, makes the marker
3678for the front of the overlay advance when text is inserted there
63af6055 3679\(which means the text *is not* included in the overlay).
a625ee20
RS
3680The fifth arg REAR-ADVANCE, if non-nil, makes the marker
3681for the rear of the overlay advance when text is inserted there
63af6055 3682\(which means the text *is* included in the overlay). */)
5842a27b 3683 (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer, Lisp_Object front_advance, Lisp_Object rear_advance)
2eec3b4e
RS
3684{
3685 Lisp_Object overlay;
5c4f68f1 3686 struct buffer *b;
2eec3b4e 3687
5c4f68f1 3688 if (NILP (buffer))
67180c6a 3689 XSETBUFFER (buffer, current_buffer);
883047b9 3690 else
b7826503 3691 CHECK_BUFFER (buffer);
883047b9
JB
3692 if (MARKERP (beg)
3693 && ! EQ (Fmarker_buffer (beg), buffer))
3694 error ("Marker points into wrong buffer");
3695 if (MARKERP (end)
3696 && ! EQ (Fmarker_buffer (end), buffer))
3697 error ("Marker points into wrong buffer");
2eec3b4e 3698
b7826503
PJ
3699 CHECK_NUMBER_COERCE_MARKER (beg);
3700 CHECK_NUMBER_COERCE_MARKER (end);
5c4f68f1 3701
883047b9 3702 if (XINT (beg) > XINT (end))
5c4f68f1 3703 {
c99fc30f
KH
3704 Lisp_Object temp;
3705 temp = beg; beg = end; end = temp;
5c4f68f1 3706 }
883047b9
JB
3707
3708 b = XBUFFER (buffer);
3709
3710 beg = Fset_marker (Fmake_marker (), beg, buffer);
3711 end = Fset_marker (Fmake_marker (), end, buffer);
5c4f68f1 3712
acac2700
RS
3713 if (!NILP (front_advance))
3714 XMARKER (beg)->insertion_type = 1;
3715 if (!NILP (rear_advance))
3716 XMARKER (end)->insertion_type = 1;
597dd755 3717
48e2e3ba 3718 overlay = allocate_misc ();
89ca3e1b 3719 XMISCTYPE (overlay) = Lisp_Misc_Overlay;
48e2e3ba
KH
3720 XOVERLAY (overlay)->start = beg;
3721 XOVERLAY (overlay)->end = end;
3722 XOVERLAY (overlay)->plist = Qnil;
2410d73a 3723 XOVERLAY (overlay)->next = NULL;
2eec3b4e 3724
177c0ea7 3725 /* Put the new overlay on the wrong list. */
2eec3b4e 3726 end = OVERLAY_END (overlay);
c2d5b10f 3727 if (OVERLAY_POSITION (end) < b->overlay_center)
2410d73a
SM
3728 {
3729 if (b->overlays_after)
3730 XOVERLAY (overlay)->next = b->overlays_after;
3731 b->overlays_after = XOVERLAY (overlay);
3732 }
2eec3b4e 3733 else
2410d73a
SM
3734 {
3735 if (b->overlays_before)
3736 XOVERLAY (overlay)->next = b->overlays_before;
3737 b->overlays_before = XOVERLAY (overlay);
3738 }
2eec3b4e
RS
3739
3740 /* This puts it in the right list, and in the right order. */
c2d5b10f 3741 recenter_overlay_lists (b, b->overlay_center);
2eec3b4e 3742
b61982dd
JB
3743 /* We don't need to redisplay the region covered by the overlay, because
3744 the overlay has no properties at the moment. */
3745
2eec3b4e
RS
3746 return overlay;
3747}
876aa27c
RS
3748\f
3749/* Mark a section of BUF as needing redisplay because of overlays changes. */
3750
3751static void
d3da34e0 3752modify_overlay (struct buffer *buf, EMACS_INT start, EMACS_INT end)
876aa27c 3753{
876aa27c
RS
3754 if (start > end)
3755 {
3756 int temp = start;
26f545d7
GM
3757 start = end;
3758 end = temp;
876aa27c
RS
3759 }
3760
481b5054 3761 BUF_COMPUTE_UNCHANGED (buf, start, end);
177c0ea7 3762
876aa27c
RS
3763 /* If this is a buffer not in the selected window,
3764 we must do other windows. */
3765 if (buf != XBUFFER (XWINDOW (selected_window)->buffer))
3766 windows_or_buffers_changed = 1;
876aa27c
RS
3767 /* If multiple windows show this buffer, we must do other windows. */
3768 else if (buffer_shared > 1)
3769 windows_or_buffers_changed = 1;
18700091
KS
3770 /* If we modify an overlay at the end of the buffer, we cannot
3771 be sure that window end is still valid. */
3772 else if (end >= ZV && start <= ZV)
3773 windows_or_buffers_changed = 1;
876aa27c 3774
d8b9150f 3775 ++BUF_OVERLAY_MODIFF (buf);
876aa27c 3776}
2eec3b4e 3777
018ba359 3778\f
d3da34e0 3779Lisp_Object Fdelete_overlay (Lisp_Object overlay);
2e34157c 3780
2410d73a 3781static struct Lisp_Overlay *
d3da34e0 3782unchain_overlay (struct Lisp_Overlay *list, struct Lisp_Overlay *overlay)
2410d73a
SM
3783{
3784 struct Lisp_Overlay *tmp, *prev;
3785 for (tmp = list, prev = NULL; tmp; prev = tmp, tmp = tmp->next)
3786 if (tmp == overlay)
3787 {
3788 if (prev)
3789 prev->next = tmp->next;
3790 else
3791 list = tmp->next;
3792 overlay->next = NULL;
3793 break;
3794 }
3795 return list;
3796}
3797
5c4f68f1 3798DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
7ee72033 3799 doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER.
018ba359
PJ
3800If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.
3801If BUFFER is omitted, and OVERLAY is in no buffer, put it in the current
7ee72033 3802buffer. */)
5842a27b 3803 (Lisp_Object overlay, Lisp_Object beg, Lisp_Object end, Lisp_Object buffer)
2eec3b4e 3804{
0a4469c9
RS
3805 struct buffer *b, *ob;
3806 Lisp_Object obuffer;
aed13378 3807 int count = SPECPDL_INDEX ();
5c4f68f1 3808
b7826503 3809 CHECK_OVERLAY (overlay);
5c4f68f1
JB
3810 if (NILP (buffer))
3811 buffer = Fmarker_buffer (OVERLAY_START (overlay));
3ece337a 3812 if (NILP (buffer))
67180c6a 3813 XSETBUFFER (buffer, current_buffer);
b7826503 3814 CHECK_BUFFER (buffer);
883047b9
JB
3815
3816 if (MARKERP (beg)
3817 && ! EQ (Fmarker_buffer (beg), buffer))
3818 error ("Marker points into wrong buffer");
3819 if (MARKERP (end)
3820 && ! EQ (Fmarker_buffer (end), buffer))
3821 error ("Marker points into wrong buffer");
3822
b7826503
PJ
3823 CHECK_NUMBER_COERCE_MARKER (beg);
3824 CHECK_NUMBER_COERCE_MARKER (end);
b61982dd 3825
9d7608b7
KH
3826 if (XINT (beg) == XINT (end) && ! NILP (Foverlay_get (overlay, Qevaporate)))
3827 return Fdelete_overlay (overlay);
0a4469c9 3828
b61982dd
JB
3829 if (XINT (beg) > XINT (end))
3830 {
c99fc30f
KH
3831 Lisp_Object temp;
3832 temp = beg; beg = end; end = temp;
b61982dd
JB
3833 }
3834
9d7608b7
KH
3835 specbind (Qinhibit_quit, Qt);
3836
0a4469c9 3837 obuffer = Fmarker_buffer (OVERLAY_START (overlay));
5c4f68f1 3838 b = XBUFFER (buffer);
8801a864 3839 ob = BUFFERP (obuffer) ? XBUFFER (obuffer) : (struct buffer *) 0;
2eec3b4e 3840
c82ed728 3841 /* If the overlay has changed buffers, do a thorough redisplay. */
0a4469c9 3842 if (!EQ (buffer, obuffer))
50760c4a
RS
3843 {
3844 /* Redisplay where the overlay was. */
3845 if (!NILP (obuffer))
3846 {
2e34157c
RS
3847 int o_beg;
3848 int o_end;
50760c4a 3849
80509f2f
RS
3850 o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3851 o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
50760c4a 3852
2e34157c 3853 modify_overlay (ob, o_beg, o_end);
50760c4a
RS
3854 }
3855
3856 /* Redisplay where the overlay is going to be. */
876aa27c 3857 modify_overlay (b, XINT (beg), XINT (end));
50760c4a 3858 }
c82ed728
JB
3859 else
3860 /* Redisplay the area the overlay has just left, or just enclosed. */
3861 {
2e34157c 3862 int o_beg, o_end;
c82ed728 3863
80509f2f
RS
3864 o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3865 o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
c82ed728 3866
2e34157c
RS
3867 if (o_beg == XINT (beg))
3868 modify_overlay (b, o_end, XINT (end));
3869 else if (o_end == XINT (end))
3870 modify_overlay (b, o_beg, XINT (beg));
c82ed728
JB
3871 else
3872 {
2e34157c
RS
3873 if (XINT (beg) < o_beg) o_beg = XINT (beg);
3874 if (XINT (end) > o_end) o_end = XINT (end);
3875 modify_overlay (b, o_beg, o_end);
c82ed728
JB
3876 }
3877 }
b61982dd 3878
0a4469c9
RS
3879 if (!NILP (obuffer))
3880 {
2410d73a
SM
3881 ob->overlays_before
3882 = unchain_overlay (ob->overlays_before, XOVERLAY (overlay));
3883 ob->overlays_after
3884 = unchain_overlay (ob->overlays_after, XOVERLAY (overlay));
3885 eassert (XOVERLAY (overlay)->next == NULL);
0a4469c9 3886 }
5c4f68f1
JB
3887
3888 Fset_marker (OVERLAY_START (overlay), beg, buffer);
3889 Fset_marker (OVERLAY_END (overlay), end, buffer);
2eec3b4e 3890
177c0ea7 3891 /* Put the overlay on the wrong list. */
2eec3b4e 3892 end = OVERLAY_END (overlay);
c2d5b10f 3893 if (OVERLAY_POSITION (end) < b->overlay_center)
2410d73a 3894 {
8f924df7
KH
3895 XOVERLAY (overlay)->next = b->overlays_after;
3896 b->overlays_after = XOVERLAY (overlay);
2410d73a 3897 }
2eec3b4e 3898 else
2410d73a 3899 {
8f924df7
KH
3900 XOVERLAY (overlay)->next = b->overlays_before;
3901 b->overlays_before = XOVERLAY (overlay);
2410d73a 3902 }
2eec3b4e
RS
3903
3904 /* This puts it in the right list, and in the right order. */
c2d5b10f 3905 recenter_overlay_lists (b, b->overlay_center);
2eec3b4e 3906
0a4469c9 3907 return unbind_to (count, overlay);
2eec3b4e
RS
3908}
3909
3910DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
7ee72033 3911 doc: /* Delete the overlay OVERLAY from its buffer. */)
5842a27b 3912 (Lisp_Object overlay)
2eec3b4e 3913{
0a4469c9 3914 Lisp_Object buffer;
5c4f68f1 3915 struct buffer *b;
aed13378 3916 int count = SPECPDL_INDEX ();
5c4f68f1 3917
b7826503 3918 CHECK_OVERLAY (overlay);
52f8ec73 3919
0a4469c9
RS
3920 buffer = Fmarker_buffer (OVERLAY_START (overlay));
3921 if (NILP (buffer))
3922 return Qnil;
3923
3924 b = XBUFFER (buffer);
0a4469c9 3925 specbind (Qinhibit_quit, Qt);
177c0ea7 3926
2410d73a
SM
3927 b->overlays_before = unchain_overlay (b->overlays_before,XOVERLAY (overlay));
3928 b->overlays_after = unchain_overlay (b->overlays_after, XOVERLAY (overlay));
3929 eassert (XOVERLAY (overlay)->next == NULL);
876aa27c 3930 modify_overlay (b,
8231a9aa
RS
3931 marker_position (OVERLAY_START (overlay)),
3932 marker_position (OVERLAY_END (overlay)));
3ece337a
JB
3933 Fset_marker (OVERLAY_START (overlay), Qnil, Qnil);
3934 Fset_marker (OVERLAY_END (overlay), Qnil, Qnil);
3935
e58c389d 3936 /* When deleting an overlay with before or after strings, turn off
26f545d7
GM
3937 display optimizations for the affected buffer, on the basis that
3938 these strings may contain newlines. This is easier to do than to
3939 check for that situation during redisplay. */
3940 if (!windows_or_buffers_changed
3941 && (!NILP (Foverlay_get (overlay, Qbefore_string))
3942 || !NILP (Foverlay_get (overlay, Qafter_string))))
3943 b->prevent_redisplay_optimizations_p = 1;
3944
0a4469c9 3945 return unbind_to (count, Qnil);
2eec3b4e
RS
3946}
3947\f
8ebafa8d
JB
3948/* Overlay dissection functions. */
3949
3950DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
7ee72033 3951 doc: /* Return the position at which OVERLAY starts. */)
5842a27b 3952 (Lisp_Object overlay)
8ebafa8d 3953{
b7826503 3954 CHECK_OVERLAY (overlay);
8ebafa8d
JB
3955
3956 return (Fmarker_position (OVERLAY_START (overlay)));
3957}
3958
3959DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
7ee72033 3960 doc: /* Return the position at which OVERLAY ends. */)
5842a27b 3961 (Lisp_Object overlay)
8ebafa8d 3962{
b7826503 3963 CHECK_OVERLAY (overlay);
8ebafa8d
JB
3964
3965 return (Fmarker_position (OVERLAY_END (overlay)));
3966}
3967
3968DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
563f7128
LK
3969 doc: /* Return the buffer OVERLAY belongs to.
3970Return nil if OVERLAY has been deleted. */)
5842a27b 3971 (Lisp_Object overlay)
8ebafa8d 3972{
b7826503 3973 CHECK_OVERLAY (overlay);
8ebafa8d
JB
3974
3975 return Fmarker_buffer (OVERLAY_START (overlay));
3976}
3977
3978DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
7ee72033 3979 doc: /* Return a list of the properties on OVERLAY.
018ba359 3980This is a copy of OVERLAY's plist; modifying its conses has no effect on
7ee72033 3981OVERLAY. */)
5842a27b 3982 (Lisp_Object overlay)
8ebafa8d 3983{
b7826503 3984 CHECK_OVERLAY (overlay);
8ebafa8d 3985
48e2e3ba 3986 return Fcopy_sequence (XOVERLAY (overlay)->plist);
8ebafa8d
JB
3987}
3988
3989\f
2eec3b4e 3990DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
aabc29c8 3991 doc: /* Return a list of the overlays that contain the character at POS. */)
5842a27b 3992 (Lisp_Object pos)
2eec3b4e
RS
3993{
3994 int noverlays;
2eec3b4e
RS
3995 Lisp_Object *overlay_vec;
3996 int len;
3997 Lisp_Object result;
3998
b7826503 3999 CHECK_NUMBER_COERCE_MARKER (pos);
2eec3b4e
RS
4000
4001 len = 10;
a9800ae8 4002 /* We can't use alloca here because overlays_at can call xrealloc. */
2eec3b4e
RS
4003 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
4004
4005 /* Put all the overlays we want in a vector in overlay_vec.
4006 Store the length in len. */
2a77a7d7 4007 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
0f8b27ea 4008 (EMACS_INT *) 0, (EMACS_INT *) 0, 0);
2eec3b4e
RS
4009
4010 /* Make a list of them all. */
4011 result = Flist (noverlays, overlay_vec);
4012
9ac0d9e0 4013 xfree (overlay_vec);
2eec3b4e
RS
4014 return result;
4015}
4016
74514898 4017DEFUN ("overlays-in", Foverlays_in, Soverlays_in, 2, 2, 0,
7ee72033 4018 doc: /* Return a list of the overlays that overlap the region BEG ... END.
018ba359
PJ
4019Overlap means that at least one character is contained within the overlay
4020and also contained within the specified region.
7723e095
MR
4021Empty overlays are included in the result if they are located at BEG,
4022between BEG and END, or at END provided END denotes the position at the
4023end of the buffer. */)
5842a27b 4024 (Lisp_Object beg, Lisp_Object end)
74514898
RS
4025{
4026 int noverlays;
4027 Lisp_Object *overlay_vec;
4028 int len;
4029 Lisp_Object result;
4030
b7826503
PJ
4031 CHECK_NUMBER_COERCE_MARKER (beg);
4032 CHECK_NUMBER_COERCE_MARKER (end);
74514898
RS
4033
4034 len = 10;
4035 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
4036
4037 /* Put all the overlays we want in a vector in overlay_vec.
4038 Store the length in len. */
4039 noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len,
4040 (int *) 0, (int *) 0);
4041
4042 /* Make a list of them all. */
4043 result = Flist (noverlays, overlay_vec);
4044
4045 xfree (overlay_vec);
4046 return result;
4047}
4048
2eec3b4e 4049DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change,
efc7e75f 4050 1, 1, 0,
7ee72033 4051 doc: /* Return the next position after POS where an overlay starts or ends.
624d2678
RS
4052If there are no overlay boundaries from POS to (point-max),
4053the value is (point-max). */)
5842a27b 4054 (Lisp_Object pos)
2eec3b4e
RS
4055{
4056 int noverlays;
0f8b27ea 4057 EMACS_INT endpos;
2eec3b4e
RS
4058 Lisp_Object *overlay_vec;
4059 int len;
2eec3b4e
RS
4060 int i;
4061
b7826503 4062 CHECK_NUMBER_COERCE_MARKER (pos);
2eec3b4e
RS
4063
4064 len = 10;
4065 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
4066
4067 /* Put all the overlays we want in a vector in overlay_vec.
4068 Store the length in len.
4069 endpos gets the position where the next overlay starts. */
2a77a7d7 4070 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
0f8b27ea 4071 &endpos, (EMACS_INT *) 0, 1);
2eec3b4e
RS
4072
4073 /* If any of these overlays ends before endpos,
4074 use its ending point instead. */
4075 for (i = 0; i < noverlays; i++)
4076 {
4077 Lisp_Object oend;
0f8b27ea 4078 EMACS_INT oendpos;
2eec3b4e
RS
4079
4080 oend = OVERLAY_END (overlay_vec[i]);
4081 oendpos = OVERLAY_POSITION (oend);
4082 if (oendpos < endpos)
4083 endpos = oendpos;
1ab256cb
RM
4084 }
4085
9ac0d9e0 4086 xfree (overlay_vec);
2eec3b4e
RS
4087 return make_number (endpos);
4088}
239c932b
RS
4089
4090DEFUN ("previous-overlay-change", Fprevious_overlay_change,
4091 Sprevious_overlay_change, 1, 1, 0,
7ee72033 4092 doc: /* Return the previous position before POS where an overlay starts or ends.
624d2678
RS
4093If there are no overlay boundaries from (point-min) to POS,
4094the value is (point-min). */)
5842a27b 4095 (Lisp_Object pos)
239c932b
RS
4096{
4097 int noverlays;
0f8b27ea 4098 EMACS_INT prevpos;
239c932b
RS
4099 Lisp_Object *overlay_vec;
4100 int len;
239c932b 4101
b7826503 4102 CHECK_NUMBER_COERCE_MARKER (pos);
239c932b 4103
624bbdc4
RS
4104 /* At beginning of buffer, we know the answer;
4105 avoid bug subtracting 1 below. */
4106 if (XINT (pos) == BEGV)
4107 return pos;
4108
017f0539
GM
4109 len = 10;
4110 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
4111
239c932b
RS
4112 /* Put all the overlays we want in a vector in overlay_vec.
4113 Store the length in len.
daa1c109 4114 prevpos gets the position of the previous change. */
2a77a7d7 4115 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
0f8b27ea 4116 (EMACS_INT *) 0, &prevpos, 1);
239c932b 4117
239c932b
RS
4118 xfree (overlay_vec);
4119 return make_number (prevpos);
4120}
2eec3b4e
RS
4121\f
4122/* These functions are for debugging overlays. */
4123
4124DEFUN ("overlay-lists", Foverlay_lists, Soverlay_lists, 0, 0, 0,
7ee72033 4125 doc: /* Return a pair of lists giving all the overlays of the current buffer.
018ba359
PJ
4126The car has all the overlays before the overlay center;
4127the cdr has all the overlays after the overlay center.
4128Recentering overlays moves overlays between these lists.
4129The lists you get are copies, so that changing them has no effect.
7ee72033 4130However, the overlays you get are the real objects that the buffer uses. */)
5842a27b 4131 (void)
2eec3b4e 4132{
2410d73a
SM
4133 struct Lisp_Overlay *ol;
4134 Lisp_Object before = Qnil, after = Qnil, tmp;
4135 for (ol = current_buffer->overlays_before; ol; ol = ol->next)
4136 {
4137 XSETMISC (tmp, ol);
4138 before = Fcons (tmp, before);
4139 }
4140 for (ol = current_buffer->overlays_after; ol; ol = ol->next)
4141 {
4142 XSETMISC (tmp, ol);
4143 after = Fcons (tmp, after);
4144 }
4145 return Fcons (Fnreverse (before), Fnreverse (after));
2eec3b4e
RS
4146}
4147
4148DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
c87426c5
RS
4149 doc: /* Recenter the overlays of the current buffer around position POS.
4150That makes overlay lookup faster for positions near POS (but perhaps slower
4151for positions far away from POS). */)
5842a27b 4152 (Lisp_Object pos)
2eec3b4e 4153{
b7826503 4154 CHECK_NUMBER_COERCE_MARKER (pos);
2eec3b4e 4155
5c4f68f1 4156 recenter_overlay_lists (current_buffer, XINT (pos));
2eec3b4e
RS
4157 return Qnil;
4158}
4159\f
4160DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0,
7ee72033 4161 doc: /* Get the property of overlay OVERLAY with property name PROP. */)
5842a27b 4162 (Lisp_Object overlay, Lisp_Object prop)
2eec3b4e 4163{
b7826503 4164 CHECK_OVERLAY (overlay);
9a593927 4165 return lookup_char_property (XOVERLAY (overlay)->plist, prop, 0);
2eec3b4e
RS
4166}
4167
4168DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
7ee72033 4169 doc: /* Set one property of overlay OVERLAY: give property PROP value VALUE. */)
5842a27b 4170 (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value)
2eec3b4e 4171{
48e2e3ba 4172 Lisp_Object tail, buffer;
9d7608b7 4173 int changed;
2eec3b4e 4174
b7826503 4175 CHECK_OVERLAY (overlay);
b61982dd 4176
274a9425
RS
4177 buffer = Fmarker_buffer (OVERLAY_START (overlay));
4178
48e2e3ba 4179 for (tail = XOVERLAY (overlay)->plist;
7539e11f
KR
4180 CONSP (tail) && CONSP (XCDR (tail));
4181 tail = XCDR (XCDR (tail)))
4182 if (EQ (XCAR (tail), prop))
274a9425 4183 {
7539e11f 4184 changed = !EQ (XCAR (XCDR (tail)), value);
f3fbd155 4185 XSETCAR (XCDR (tail), value);
9d7608b7 4186 goto found;
274a9425 4187 }
9d7608b7
KH
4188 /* It wasn't in the list, so add it to the front. */
4189 changed = !NILP (value);
48e2e3ba
KH
4190 XOVERLAY (overlay)->plist
4191 = Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist));
9d7608b7
KH
4192 found:
4193 if (! NILP (buffer))
4194 {
4195 if (changed)
876aa27c 4196 modify_overlay (XBUFFER (buffer),
26f545d7
GM
4197 marker_position (OVERLAY_START (overlay)),
4198 marker_position (OVERLAY_END (overlay)));
9d7608b7
KH
4199 if (EQ (prop, Qevaporate) && ! NILP (value)
4200 && (OVERLAY_POSITION (OVERLAY_START (overlay))
4201 == OVERLAY_POSITION (OVERLAY_END (overlay))))
4202 Fdelete_overlay (overlay);
4203 }
7d63db98 4204
2eec3b4e 4205 return value;
1ab256cb
RM
4206}
4207\f
9115729e
KH
4208/* Subroutine of report_overlay_modification. */
4209
4210/* Lisp vector holding overlay hook functions to call.
4211 Vector elements come in pairs.
4212 Each even-index element is a list of hook functions.
4213 The following odd-index element is the overlay they came from.
4214
4215 Before the buffer change, we fill in this vector
4216 as we call overlay hook functions.
4217 After the buffer change, we get the functions to call from this vector.
4218 This way we always call the same functions before and after the change. */
4219static Lisp_Object last_overlay_modification_hooks;
4220
4221/* Number of elements actually used in last_overlay_modification_hooks. */
4222static int last_overlay_modification_hooks_used;
4223
4224/* Add one functionlist/overlay pair
4225 to the end of last_overlay_modification_hooks. */
4226
4227static void
d3da34e0 4228add_overlay_mod_hooklist (Lisp_Object functionlist, Lisp_Object overlay)
9115729e
KH
4229{
4230 int oldsize = XVECTOR (last_overlay_modification_hooks)->size;
4231
4232 if (last_overlay_modification_hooks_used == oldsize)
409f2919 4233 last_overlay_modification_hooks = larger_vector
de0280a2 4234 (last_overlay_modification_hooks, oldsize * 2, Qnil);
3ae565b3
SM
4235 ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
4236 functionlist); last_overlay_modification_hooks_used++;
4237 ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
4238 overlay); last_overlay_modification_hooks_used++;
9115729e
KH
4239}
4240\f
173f2a64
RS
4241/* Run the modification-hooks of overlays that include
4242 any part of the text in START to END.
9115729e
KH
4243 If this change is an insertion, also
4244 run the insert-before-hooks of overlay starting at END,
930a9140
RS
4245 and the insert-after-hooks of overlay ending at START.
4246
4247 This is called both before and after the modification.
4248 AFTER is nonzero when we call after the modification.
4249
9115729e
KH
4250 ARG1, ARG2, ARG3 are arguments to pass to the hook functions.
4251 When AFTER is nonzero, they are the start position,
4252 the position after the inserted new text,
4253 and the length of deleted or replaced old text. */
173f2a64
RS
4254
4255void
d3da34e0
JB
4256report_overlay_modification (Lisp_Object start, Lisp_Object end, int after,
4257 Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
173f2a64 4258{
2410d73a
SM
4259 Lisp_Object prop, overlay;
4260 struct Lisp_Overlay *tail;
9115729e
KH
4261 /* 1 if this change is an insertion. */
4262 int insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end));
a615c6dc 4263 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
55b48893
RS
4264
4265 overlay = Qnil;
2410d73a 4266 tail = NULL;
9115729e 4267
27c6b98e
SM
4268 /* We used to run the functions as soon as we found them and only register
4269 them in last_overlay_modification_hooks for the purpose of the `after'
4270 case. But running elisp code as we traverse the list of overlays is
4271 painful because the list can be modified by the elisp code so we had to
4272 copy at several places. We now simply do a read-only traversal that
4273 only collects the functions to run and we run them afterwards. It's
4274 simpler, especially since all the code was already there. -stef */
4275
a615c6dc 4276 if (!after)
173f2a64 4277 {
a615c6dc
SM
4278 /* We are being called before a change.
4279 Scan the overlays to find the functions to call. */
4280 last_overlay_modification_hooks_used = 0;
2410d73a 4281 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
173f2a64 4282 {
a615c6dc
SM
4283 int startpos, endpos;
4284 Lisp_Object ostart, oend;
4285
2410d73a 4286 XSETMISC (overlay, tail);
a615c6dc
SM
4287
4288 ostart = OVERLAY_START (overlay);
4289 oend = OVERLAY_END (overlay);
4290 endpos = OVERLAY_POSITION (oend);
4291 if (XFASTINT (start) > endpos)
4292 break;
4293 startpos = OVERLAY_POSITION (ostart);
4294 if (insertion && (XFASTINT (start) == startpos
4295 || XFASTINT (end) == startpos))
5fb5aa33 4296 {
a615c6dc
SM
4297 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4298 if (!NILP (prop))
4299 add_overlay_mod_hooklist (prop, overlay);
5fb5aa33 4300 }
a615c6dc
SM
4301 if (insertion && (XFASTINT (start) == endpos
4302 || XFASTINT (end) == endpos))
5fb5aa33 4303 {
a615c6dc
SM
4304 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4305 if (!NILP (prop))
4306 add_overlay_mod_hooklist (prop, overlay);
5fb5aa33 4307 }
a615c6dc
SM
4308 /* Test for intersecting intervals. This does the right thing
4309 for both insertion and deletion. */
4310 if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
5fb5aa33 4311 {
a615c6dc
SM
4312 prop = Foverlay_get (overlay, Qmodification_hooks);
4313 if (!NILP (prop))
4314 add_overlay_mod_hooklist (prop, overlay);
5fb5aa33 4315 }
173f2a64 4316 }
60ebfdf3 4317
2410d73a 4318 for (tail = current_buffer->overlays_after; tail; tail = tail->next)
173f2a64 4319 {
a615c6dc
SM
4320 int startpos, endpos;
4321 Lisp_Object ostart, oend;
4322
2410d73a 4323 XSETMISC (overlay, tail);
a615c6dc
SM
4324
4325 ostart = OVERLAY_START (overlay);
4326 oend = OVERLAY_END (overlay);
4327 startpos = OVERLAY_POSITION (ostart);
4328 endpos = OVERLAY_POSITION (oend);
4329 if (XFASTINT (end) < startpos)
4330 break;
4331 if (insertion && (XFASTINT (start) == startpos
4332 || XFASTINT (end) == startpos))
5fb5aa33 4333 {
a615c6dc
SM
4334 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4335 if (!NILP (prop))
4336 add_overlay_mod_hooklist (prop, overlay);
5fb5aa33 4337 }
a615c6dc
SM
4338 if (insertion && (XFASTINT (start) == endpos
4339 || XFASTINT (end) == endpos))
5fb5aa33 4340 {
a615c6dc
SM
4341 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4342 if (!NILP (prop))
4343 add_overlay_mod_hooklist (prop, overlay);
5fb5aa33 4344 }
a615c6dc
SM
4345 /* Test for intersecting intervals. This does the right thing
4346 for both insertion and deletion. */
4347 if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
5fb5aa33 4348 {
a615c6dc
SM
4349 prop = Foverlay_get (overlay, Qmodification_hooks);
4350 if (!NILP (prop))
4351 add_overlay_mod_hooklist (prop, overlay);
5fb5aa33 4352 }
173f2a64
RS
4353 }
4354 }
55b48893 4355
a615c6dc
SM
4356 GCPRO4 (overlay, arg1, arg2, arg3);
4357 {
4358 /* Call the functions recorded in last_overlay_modification_hooks.
4359 First copy the vector contents, in case some of these hooks
4360 do subsequent modification of the buffer. */
4361 int size = last_overlay_modification_hooks_used;
4362 Lisp_Object *copy = (Lisp_Object *) alloca (size * sizeof (Lisp_Object));
4363 int i;
4364
72af86bd
AS
4365 memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
4366 size * sizeof (Lisp_Object));
a615c6dc
SM
4367 gcpro1.var = copy;
4368 gcpro1.nvars = size;
4369
4370 for (i = 0; i < size;)
4371 {
4372 Lisp_Object prop, overlay;
4373 prop = copy[i++];
4374 overlay = copy[i++];
4375 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
4376 }
4377 }
55b48893 4378 UNGCPRO;
173f2a64
RS
4379}
4380
4381static void
d3da34e0
JB
4382call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, int after,
4383 Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
173f2a64 4384{
930a9140 4385 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9115729e 4386
930a9140 4387 GCPRO4 (list, arg1, arg2, arg3);
9115729e 4388
6d70a280 4389 while (CONSP (list))
173f2a64 4390 {
930a9140 4391 if (NILP (arg3))
6d70a280 4392 call4 (XCAR (list), overlay, after ? Qt : Qnil, arg1, arg2);
930a9140 4393 else
6d70a280
SM
4394 call5 (XCAR (list), overlay, after ? Qt : Qnil, arg1, arg2, arg3);
4395 list = XCDR (list);
173f2a64
RS
4396 }
4397 UNGCPRO;
4398}
9d7608b7
KH
4399
4400/* Delete any zero-sized overlays at position POS, if the `evaporate'
4401 property is set. */
4402void
d3da34e0 4403evaporate_overlays (EMACS_INT pos)
9d7608b7 4404{
2410d73a
SM
4405 Lisp_Object overlay, hit_list;
4406 struct Lisp_Overlay *tail;
9d7608b7
KH
4407
4408 hit_list = Qnil;
c2d5b10f 4409 if (pos <= current_buffer->overlay_center)
2410d73a 4410 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
9d7608b7
KH
4411 {
4412 int endpos;
2410d73a 4413 XSETMISC (overlay, tail);
9d7608b7
KH
4414 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
4415 if (endpos < pos)
4416 break;
4417 if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos
c3935f9d 4418 && ! NILP (Foverlay_get (overlay, Qevaporate)))
9d7608b7
KH
4419 hit_list = Fcons (overlay, hit_list);
4420 }
4421 else
2410d73a 4422 for (tail = current_buffer->overlays_after; tail; tail = tail->next)
9d7608b7
KH
4423 {
4424 int startpos;
2410d73a 4425 XSETMISC (overlay, tail);
9d7608b7
KH
4426 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
4427 if (startpos > pos)
4428 break;
4429 if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
c3935f9d 4430 && ! NILP (Foverlay_get (overlay, Qevaporate)))
9d7608b7
KH
4431 hit_list = Fcons (overlay, hit_list);
4432 }
7539e11f
KR
4433 for (; CONSP (hit_list); hit_list = XCDR (hit_list))
4434 Fdelete_overlay (XCAR (hit_list));
9d7608b7 4435}
173f2a64 4436\f
54dfdeb0 4437/* Somebody has tried to store a value with an unacceptable type
1bf08baf
KH
4438 in the slot with offset OFFSET. */
4439
0fa3ba92 4440void
d3da34e0 4441buffer_slot_type_mismatch (Lisp_Object newval, int type)
0fa3ba92 4442{
ad97b375 4443 Lisp_Object predicate;
177c0ea7 4444
64e16c3c 4445 switch (type)
0fa3ba92 4446 {
2de9f71c 4447 case_Lisp_Int: predicate = Qintegerp; break;
ad97b375
SM
4448 case Lisp_String: predicate = Qstringp; break;
4449 case Lisp_Symbol: predicate = Qsymbolp; break;
4450 default: abort ();
0fa3ba92
JB
4451 }
4452
ad97b375 4453 wrong_type_argument (predicate, newval);
0fa3ba92 4454}
7c02e886 4455
0fa3ba92 4456\f
b86af064
GM
4457/***********************************************************************
4458 Allocation with mmap
4459 ***********************************************************************/
4460
4461#ifdef USE_MMAP_FOR_BUFFERS
4462
4463#include <sys/types.h>
4464#include <sys/mman.h>
4465
4466#ifndef MAP_ANON
4467#ifdef MAP_ANONYMOUS
4468#define MAP_ANON MAP_ANONYMOUS
4469#else
4470#define MAP_ANON 0
4471#endif
4472#endif
4473
09dfdf85
GM
4474#ifndef MAP_FAILED
4475#define MAP_FAILED ((void *) -1)
4476#endif
4477
b86af064 4478#include <stdio.h>
b86af064
GM
4479
4480#if MAP_ANON == 0
4481#include <fcntl.h>
4482#endif
4483
4484#include "coding.h"
4485
4486
4487/* Memory is allocated in regions which are mapped using mmap(2).
4488 The current implementation lets the system select mapped
4489 addresses; we're not using MAP_FIXED in general, except when
4490 trying to enlarge regions.
4491
4492 Each mapped region starts with a mmap_region structure, the user
4493 area starts after that structure, aligned to MEM_ALIGN.
4494
4495 +-----------------------+
4496 | struct mmap_info + |
4497 | padding |
4498 +-----------------------+
4499 | user data |
4500 | |
4501 | |
4502 +-----------------------+ */
4503
4504struct mmap_region
4505{
4506 /* User-specified size. */
4507 size_t nbytes_specified;
177c0ea7 4508
b86af064
GM
4509 /* Number of bytes mapped */
4510 size_t nbytes_mapped;
4511
4512 /* Pointer to the location holding the address of the memory
4513 allocated with the mmap'd block. The variable actually points
4514 after this structure. */
4515 POINTER_TYPE **var;
4516
4517 /* Next and previous in list of all mmap'd regions. */
4518 struct mmap_region *next, *prev;
4519};
4520
4521/* Doubly-linked list of mmap'd regions. */
4522
4523static struct mmap_region *mmap_regions;
4524
4525/* File descriptor for mmap. If we don't have anonymous mapping,
4526 /dev/zero will be opened on it. */
4527
4528static int mmap_fd;
4529
4530/* Temporary storage for mmap_set_vars, see there. */
4531
4532static struct mmap_region *mmap_regions_1;
4533static int mmap_fd_1;
4534
4535/* Page size on this system. */
4536
4537static int mmap_page_size;
4538
4539/* 1 means mmap has been intialized. */
4540
4541static int mmap_initialized_p;
4542
4543/* Value is X rounded up to the next multiple of N. */
4544
4545#define ROUND(X, N) (((X) + (N) - 1) / (N) * (N))
4546
4547/* Size of mmap_region structure plus padding. */
4548
4549#define MMAP_REGION_STRUCT_SIZE \
4550 ROUND (sizeof (struct mmap_region), MEM_ALIGN)
4551
4552/* Given a pointer P to the start of the user-visible part of a mapped
4553 region, return a pointer to the start of the region. */
4554
4555#define MMAP_REGION(P) \
4556 ((struct mmap_region *) ((char *) (P) - MMAP_REGION_STRUCT_SIZE))
4557
4558/* Given a pointer P to the start of a mapped region, return a pointer
4559 to the start of the user-visible part of the region. */
4560
4561#define MMAP_USER_AREA(P) \
4562 ((POINTER_TYPE *) ((char *) (P) + MMAP_REGION_STRUCT_SIZE))
4563
4564#define MEM_ALIGN sizeof (double)
4565
7273faa1
DL
4566/* Predicate returning true if part of the address range [START .. END]
4567 is currently mapped. Used to prevent overwriting an existing
08327b22
GM
4568 memory mapping.
4569
4570 Default is to conservativly assume the address range is occupied by
4571 something else. This can be overridden by system configuration
4572 files if system-specific means to determine this exists. */
4573
4574#ifndef MMAP_ALLOCATED_P
4575#define MMAP_ALLOCATED_P(start, end) 1
4576#endif
4577
b86af064
GM
4578/* Function prototypes. */
4579
f57e2426
J
4580static int mmap_free_1 (struct mmap_region *);
4581static int mmap_enlarge (struct mmap_region *, int);
4582static struct mmap_region *mmap_find (POINTER_TYPE *, POINTER_TYPE *);
4583static POINTER_TYPE *mmap_alloc (POINTER_TYPE **, size_t);
4584static POINTER_TYPE *mmap_realloc (POINTER_TYPE **, size_t);
4585static void mmap_free (POINTER_TYPE **ptr);
4586static void mmap_init (void);
b86af064
GM
4587
4588
4589/* Return a region overlapping address range START...END, or null if
4590 none. END is not including, i.e. the last byte in the range
4591 is at END - 1. */
4592
4593static struct mmap_region *
4594mmap_find (start, end)
4595 POINTER_TYPE *start, *end;
4596{
4597 struct mmap_region *r;
4598 char *s = (char *) start, *e = (char *) end;
177c0ea7 4599
b86af064
GM
4600 for (r = mmap_regions; r; r = r->next)
4601 {
4602 char *rstart = (char *) r;
4603 char *rend = rstart + r->nbytes_mapped;
4604
4605 if (/* First byte of range, i.e. START, in this region? */
4606 (s >= rstart && s < rend)
4607 /* Last byte of range, i.e. END - 1, in this region? */
4608 || (e > rstart && e <= rend)
4609 /* First byte of this region in the range? */
4610 || (rstart >= s && rstart < e)
4611 /* Last byte of this region in the range? */
4612 || (rend > s && rend <= e))
4613 break;
4614 }
4615
4616 return r;
4617}
4618
4619
4620/* Unmap a region. P is a pointer to the start of the user-araa of
4621 the region. Value is non-zero if successful. */
4622
4623static int
4624mmap_free_1 (r)
4625 struct mmap_region *r;
4626{
4627 if (r->next)
4628 r->next->prev = r->prev;
4629 if (r->prev)
4630 r->prev->next = r->next;
4631 else
4632 mmap_regions = r->next;
177c0ea7 4633
1a15cca0 4634 if (munmap ((POINTER_TYPE *) r, r->nbytes_mapped) == -1)
b86af064
GM
4635 {
4636 fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
4637 return 0;
4638 }
4639
4640 return 1;
4641}
4642
4643
4644/* Enlarge region R by NPAGES pages. NPAGES < 0 means shrink R.
4645 Value is non-zero if successful. */
4646
4647static int
4648mmap_enlarge (r, npages)
4649 struct mmap_region *r;
4650 int npages;
4651{
4652 char *region_end = (char *) r + r->nbytes_mapped;
4653 size_t nbytes;
4654 int success = 0;
4655
4656 if (npages < 0)
4657 {
4658 /* Unmap pages at the end of the region. */
4659 nbytes = - npages * mmap_page_size;
4660 if (munmap (region_end - nbytes, nbytes) == -1)
4661 fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
4662 else
4663 {
4664 r->nbytes_mapped -= nbytes;
4665 success = 1;
4666 }
4667 }
4668 else if (npages > 0)
4669 {
b86af064 4670 nbytes = npages * mmap_page_size;
177c0ea7 4671
b86af064
GM
4672 /* Try to map additional pages at the end of the region. We
4673 cannot do this if the address range is already occupied by
4674 something else because mmap deletes any previous mapping.
4675 I'm not sure this is worth doing, let's see. */
08327b22 4676 if (!MMAP_ALLOCATED_P (region_end, region_end + nbytes))
b86af064
GM
4677 {
4678 POINTER_TYPE *p;
177c0ea7 4679
b86af064
GM
4680 p = mmap (region_end, nbytes, PROT_READ | PROT_WRITE,
4681 MAP_ANON | MAP_PRIVATE | MAP_FIXED, mmap_fd, 0);
4682 if (p == MAP_FAILED)
edaa9aed 4683 ; /* fprintf (stderr, "mmap: %s\n", emacs_strerror (errno)); */
b86af064
GM
4684 else if (p != (POINTER_TYPE *) region_end)
4685 {
4686 /* Kernels are free to choose a different address. In
4687 that case, unmap what we've mapped above; we have
4688 no use for it. */
4689 if (munmap (p, nbytes) == -1)
4690 fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
4691 }
4692 else
4693 {
4694 r->nbytes_mapped += nbytes;
4695 success = 1;
4696 }
4697 }
4698 }
4699
4700 return success;
4701}
4702
4703
4704/* Set or reset variables holding references to mapped regions. If
4705 RESTORE_P is zero, set all variables to null. If RESTORE_P is
4706 non-zero, set all variables to the start of the user-areas
4707 of mapped regions.
4708
4709 This function is called from Fdump_emacs to ensure that the dumped
4710 Emacs doesn't contain references to memory that won't be mapped
4711 when Emacs starts. */
4712
4713void
4714mmap_set_vars (restore_p)
4715 int restore_p;
4716{
4717 struct mmap_region *r;
4718
4719 if (restore_p)
4720 {
4721 mmap_regions = mmap_regions_1;
4722 mmap_fd = mmap_fd_1;
4723 for (r = mmap_regions; r; r = r->next)
4724 *r->var = MMAP_USER_AREA (r);
4725 }
4726 else
4727 {
4728 for (r = mmap_regions; r; r = r->next)
4729 *r->var = NULL;
4730 mmap_regions_1 = mmap_regions;
4731 mmap_regions = NULL;
4732 mmap_fd_1 = mmap_fd;
4733 mmap_fd = -1;
4734 }
4735}
4736
4737
4738/* Allocate a block of storage large enough to hold NBYTES bytes of
4739 data. A pointer to the data is returned in *VAR. VAR is thus the
4740 address of some variable which will use the data area.
4741
4742 The allocation of 0 bytes is valid.
4743
4744 If we can't allocate the necessary memory, set *VAR to null, and
4745 return null. */
4746
4747static POINTER_TYPE *
4748mmap_alloc (var, nbytes)
4749 POINTER_TYPE **var;
4750 size_t nbytes;
4751{
4752 void *p;
4753 size_t map;
4754
4755 mmap_init ();
4756
4757 map = ROUND (nbytes + MMAP_REGION_STRUCT_SIZE, mmap_page_size);
4758 p = mmap (NULL, map, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
4759 mmap_fd, 0);
177c0ea7 4760
b86af064
GM
4761 if (p == MAP_FAILED)
4762 {
4763 if (errno != ENOMEM)
4764 fprintf (stderr, "mmap: %s\n", emacs_strerror (errno));
4765 p = NULL;
4766 }
4767 else
4768 {
4769 struct mmap_region *r = (struct mmap_region *) p;
177c0ea7 4770
b86af064
GM
4771 r->nbytes_specified = nbytes;
4772 r->nbytes_mapped = map;
4773 r->var = var;
4774 r->prev = NULL;
4775 r->next = mmap_regions;
4776 if (r->next)
4777 r->next->prev = r;
4778 mmap_regions = r;
177c0ea7 4779
b86af064
GM
4780 p = MMAP_USER_AREA (p);
4781 }
177c0ea7 4782
b86af064
GM
4783 return *var = p;
4784}
4785
4786
4787/* Given a pointer at address VAR to data allocated with mmap_alloc,
4788 resize it to size NBYTES. Change *VAR to reflect the new block,
4789 and return this value. If more memory cannot be allocated, then
4790 leave *VAR unchanged, and return null. */
4791
4792static POINTER_TYPE *
4793mmap_realloc (var, nbytes)
4794 POINTER_TYPE **var;
4795 size_t nbytes;
4796{
4797 POINTER_TYPE *result;
177c0ea7 4798
b86af064
GM
4799 mmap_init ();
4800
4801 if (*var == NULL)
4802 result = mmap_alloc (var, nbytes);
177c0ea7 4803 else if (nbytes == 0)
b86af064
GM
4804 {
4805 mmap_free (var);
4806 result = mmap_alloc (var, nbytes);
4807 }
4808 else
4809 {
4810 struct mmap_region *r = MMAP_REGION (*var);
4811 size_t room = r->nbytes_mapped - MMAP_REGION_STRUCT_SIZE;
177c0ea7 4812
b86af064
GM
4813 if (room < nbytes)
4814 {
4815 /* Must enlarge. */
4816 POINTER_TYPE *old_ptr = *var;
4817
4818 /* Try to map additional pages at the end of the region.
4819 If that fails, allocate a new region, copy data
4820 from the old region, then free it. */
4821 if (mmap_enlarge (r, (ROUND (nbytes - room, mmap_page_size)
4822 / mmap_page_size)))
4823 {
4824 r->nbytes_specified = nbytes;
4825 *var = result = old_ptr;
4826 }
4827 else if (mmap_alloc (var, nbytes))
4828 {
72af86bd 4829 memcpy (*var, old_ptr, r->nbytes_specified);
b86af064
GM
4830 mmap_free_1 (MMAP_REGION (old_ptr));
4831 result = *var;
4832 r = MMAP_REGION (result);
4833 r->nbytes_specified = nbytes;
4834 }
4835 else
4836 {
4837 *var = old_ptr;
4838 result = NULL;
4839 }
4840 }
4841 else if (room - nbytes >= mmap_page_size)
4842 {
4843 /* Shrinking by at least a page. Let's give some
6bcdeb8c
KR
4844 memory back to the system.
4845
4846 The extra parens are to make the division happens first,
4847 on positive values, so we know it will round towards
4848 zero. */
bb63c5c9 4849 mmap_enlarge (r, - ((room - nbytes) / mmap_page_size));
b86af064
GM
4850 result = *var;
4851 r->nbytes_specified = nbytes;
4852 }
4853 else
4854 {
4855 /* Leave it alone. */
4856 result = *var;
4857 r->nbytes_specified = nbytes;
4858 }
4859 }
4860
4861 return result;
4862}
4863
4864
4865/* Free a block of relocatable storage whose data is pointed to by
4866 PTR. Store 0 in *PTR to show there's no block allocated. */
4867
4868static void
4869mmap_free (var)
4870 POINTER_TYPE **var;
4871{
4872 mmap_init ();
177c0ea7 4873
b86af064
GM
4874 if (*var)
4875 {
4876 mmap_free_1 (MMAP_REGION (*var));
4877 *var = NULL;
4878 }
4879}
4880
4881
4882/* Perform necessary intializations for the use of mmap. */
4883
4884static void
4885mmap_init ()
4886{
4887#if MAP_ANON == 0
4888 /* The value of mmap_fd is initially 0 in temacs, and -1
4889 in a dumped Emacs. */
4890 if (mmap_fd <= 0)
4891 {
4892 /* No anonymous mmap -- we need the file descriptor. */
4893 mmap_fd = open ("/dev/zero", O_RDONLY);
4894 if (mmap_fd == -1)
4895 fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
4896 }
4897#endif /* MAP_ANON == 0 */
4898
4899 if (mmap_initialized_p)
4900 return;
4901 mmap_initialized_p = 1;
177c0ea7 4902
b86af064
GM
4903#if MAP_ANON != 0
4904 mmap_fd = -1;
4905#endif
177c0ea7 4906
b86af064
GM
4907 mmap_page_size = getpagesize ();
4908}
4909
4910#endif /* USE_MMAP_FOR_BUFFERS */
4911
4912
4913\f
4914/***********************************************************************
4915 Buffer-text Allocation
4916 ***********************************************************************/
4917
4918#ifdef REL_ALLOC
f57e2426
J
4919extern POINTER_TYPE *r_alloc (POINTER_TYPE **, size_t);
4920extern POINTER_TYPE *r_re_alloc (POINTER_TYPE **, size_t);
4921extern void r_alloc_free (POINTER_TYPE **ptr);
b86af064
GM
4922#endif /* REL_ALLOC */
4923
4924
4925/* Allocate NBYTES bytes for buffer B's text buffer. */
4926
4927static void
d3da34e0 4928alloc_buffer_text (struct buffer *b, size_t nbytes)
b86af064
GM
4929{
4930 POINTER_TYPE *p;
177c0ea7 4931
b86af064
GM
4932 BLOCK_INPUT;
4933#if defined USE_MMAP_FOR_BUFFERS
4934 p = mmap_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
4935#elif defined REL_ALLOC
4936 p = r_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
4937#else
815add84 4938 p = xmalloc (nbytes);
b86af064 4939#endif
177c0ea7 4940
b86af064
GM
4941 if (p == NULL)
4942 {
4943 UNBLOCK_INPUT;
4944 memory_full ();
4945 }
4946
4947 b->text->beg = (unsigned char *) p;
4948 UNBLOCK_INPUT;
4949}
4950
4951/* Enlarge buffer B's text buffer by DELTA bytes. DELTA < 0 means
4952 shrink it. */
4953
4954void
5371d722 4955enlarge_buffer_text (struct buffer *b, EMACS_INT delta)
b86af064
GM
4956{
4957 POINTER_TYPE *p;
4958 size_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
4959 + delta);
4960 BLOCK_INPUT;
4961#if defined USE_MMAP_FOR_BUFFERS
4962 p = mmap_realloc ((POINTER_TYPE **) &b->text->beg, nbytes);
4963#elif defined REL_ALLOC
4964 p = r_re_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
4965#else
4966 p = xrealloc (b->text->beg, nbytes);
4967#endif
177c0ea7 4968
b86af064
GM
4969 if (p == NULL)
4970 {
4971 UNBLOCK_INPUT;
4972 memory_full ();
4973 }
4974
4975 BUF_BEG_ADDR (b) = (unsigned char *) p;
4976 UNBLOCK_INPUT;
4977}
4978
4979
4980/* Free buffer B's text buffer. */
4981
4982static void
d3da34e0 4983free_buffer_text (struct buffer *b)
b86af064
GM
4984{
4985 BLOCK_INPUT;
4986
4987#if defined USE_MMAP_FOR_BUFFERS
4988 mmap_free ((POINTER_TYPE **) &b->text->beg);
4989#elif defined REL_ALLOC
4990 r_alloc_free ((POINTER_TYPE **) &b->text->beg);
4991#else
4992 xfree (b->text->beg);
4993#endif
177c0ea7 4994
b86af064
GM
4995 BUF_BEG_ADDR (b) = NULL;
4996 UNBLOCK_INPUT;
4997}
4998
4999
5000\f
5001/***********************************************************************
5002 Initialization
5003 ***********************************************************************/
5004
dfcf069d 5005void
d3da34e0 5006init_buffer_once (void)
1ab256cb 5007{
7c02e886
GM
5008 int idx;
5009
72af86bd 5010 memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags);
13de9290 5011
1ab256cb
RM
5012 /* Make sure all markable slots in buffer_defaults
5013 are initialized reasonably, so mark_buffer won't choke. */
5014 reset_buffer (&buffer_defaults);
ce5b453a 5015 eassert (EQ (buffer_defaults.name, make_number (0)));
13de9290 5016 reset_buffer_local_variables (&buffer_defaults, 1);
ce5b453a 5017 eassert (EQ (buffer_local_symbols.name, make_number (0)));
1ab256cb 5018 reset_buffer (&buffer_local_symbols);
13de9290 5019 reset_buffer_local_variables (&buffer_local_symbols, 1);
336cd056
RS
5020 /* Prevent GC from getting confused. */
5021 buffer_defaults.text = &buffer_defaults.own_text;
5022 buffer_local_symbols.text = &buffer_local_symbols.own_text;
336cd056
RS
5023 BUF_INTERVALS (&buffer_defaults) = 0;
5024 BUF_INTERVALS (&buffer_local_symbols) = 0;
cf00e751 5025 XSETPVECTYPE (&buffer_defaults, PVEC_BUFFER);
67180c6a 5026 XSETBUFFER (Vbuffer_defaults, &buffer_defaults);
cf00e751 5027 XSETPVECTYPE (&buffer_local_symbols, PVEC_BUFFER);
67180c6a 5028 XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols);
1ab256cb
RM
5029
5030 /* Set up the default values of various buffer slots. */
5031 /* Must do these before making the first buffer! */
5032
f532dca0 5033 /* real setup is done in bindings.el */
d67b4f80 5034 buffer_defaults.mode_line_format = make_pure_c_string ("%-");
045dee35 5035 buffer_defaults.header_line_format = Qnil;
1ab256cb
RM
5036 buffer_defaults.abbrev_mode = Qnil;
5037 buffer_defaults.overwrite_mode = Qnil;
5038 buffer_defaults.case_fold_search = Qt;
5039 buffer_defaults.auto_fill_function = Qnil;
5040 buffer_defaults.selective_display = Qnil;
5041#ifndef old
5042 buffer_defaults.selective_display_ellipses = Qt;
5043#endif
5044 buffer_defaults.abbrev_table = Qnil;
5045 buffer_defaults.display_table = Qnil;
1ab256cb 5046 buffer_defaults.undo_list = Qnil;
c48f61ef 5047 buffer_defaults.mark_active = Qnil;
be9aafdd 5048 buffer_defaults.file_format = Qnil;
71ed49fa 5049 buffer_defaults.auto_save_file_format = Qt;
2410d73a
SM
5050 buffer_defaults.overlays_before = NULL;
5051 buffer_defaults.overlays_after = NULL;
c2d5b10f 5052 buffer_defaults.overlay_center = BEG;
1ab256cb 5053
8d7a4592 5054 XSETFASTINT (buffer_defaults.tab_width, 8);
1ab256cb 5055 buffer_defaults.truncate_lines = Qnil;
0858cd02 5056 buffer_defaults.word_wrap = Qnil;
1ab256cb 5057 buffer_defaults.ctl_arrow = Qt;
f44e260c 5058 buffer_defaults.bidi_display_reordering = Qnil;
6c0cf218 5059 buffer_defaults.bidi_paragraph_direction = Qnil;
bb2ec976 5060 buffer_defaults.cursor_type = Qt;
a3bbced0 5061 buffer_defaults.extra_line_spacing = Qnil;
187ccf49 5062 buffer_defaults.cursor_in_non_selected_windows = Qt;
1ab256cb 5063
f7975d07 5064#ifdef DOS_NT
0776cb1b 5065 buffer_defaults.buffer_file_type = Qnil; /* TEXT */
54ad07d3 5066#endif
a1a17b61 5067 buffer_defaults.enable_multibyte_characters = Qt;
c71b5d9b 5068 buffer_defaults.buffer_file_coding_system = Qnil;
8d7a4592
KH
5069 XSETFASTINT (buffer_defaults.fill_column, 70);
5070 XSETFASTINT (buffer_defaults.left_margin, 0);
28e969dd 5071 buffer_defaults.cache_long_line_scans = Qnil;
f6ed2e84 5072 buffer_defaults.file_truename = Qnil;
7962a441 5073 XSETFASTINT (buffer_defaults.display_count, 0);
2ad8731a
KS
5074 XSETFASTINT (buffer_defaults.left_margin_cols, 0);
5075 XSETFASTINT (buffer_defaults.right_margin_cols, 0);
5076 buffer_defaults.left_fringe_width = Qnil;
5077 buffer_defaults.right_fringe_width = Qnil;
5078 buffer_defaults.fringes_outside_margins = Qnil;
5079 buffer_defaults.scroll_bar_width = Qnil;
5080 buffer_defaults.vertical_scroll_bar_type = Qt;
0552666b 5081 buffer_defaults.indicate_empty_lines = Qnil;
6b61353c 5082 buffer_defaults.indicate_buffer_boundaries = Qnil;
c6a46372
KS
5083 buffer_defaults.fringe_indicator_alist = Qnil;
5084 buffer_defaults.fringe_cursor_alist = Qnil;
0552666b
GM
5085 buffer_defaults.scroll_up_aggressively = Qnil;
5086 buffer_defaults.scroll_down_aggressively = Qnil;
3fd364db 5087 buffer_defaults.display_time = Qnil;
1ab256cb
RM
5088
5089 /* Assign the local-flags to the slots that have default values.
5090 The local flag is a bit that is used in the buffer
5091 to say that it has its own local value for the slot.
5092 The local flag bits are in the local_var_flags slot of the buffer. */
5093
5094 /* Nothing can work if this isn't true */
4d2f1389 5095 if (sizeof (EMACS_INT) != sizeof (Lisp_Object)) abort ();
1ab256cb
RM
5096
5097 /* 0 means not a lisp var, -1 means always local, else mask */
72af86bd 5098 memset (&buffer_local_flags, 0, sizeof buffer_local_flags);
aab80822
KH
5099 XSETINT (buffer_local_flags.filename, -1);
5100 XSETINT (buffer_local_flags.directory, -1);
5101 XSETINT (buffer_local_flags.backed_up, -1);
5102 XSETINT (buffer_local_flags.save_length, -1);
5103 XSETINT (buffer_local_flags.auto_save_file_name, -1);
5104 XSETINT (buffer_local_flags.read_only, -1);
5105 XSETINT (buffer_local_flags.major_mode, -1);
5106 XSETINT (buffer_local_flags.mode_name, -1);
5107 XSETINT (buffer_local_flags.undo_list, -1);
5108 XSETINT (buffer_local_flags.mark_active, -1);
943e065b 5109 XSETINT (buffer_local_flags.point_before_scroll, -1);
f6ed2e84 5110 XSETINT (buffer_local_flags.file_truename, -1);
3cb719bd 5111 XSETINT (buffer_local_flags.invisibility_spec, -1);
55ac8536 5112 XSETINT (buffer_local_flags.file_format, -1);
71ed49fa 5113 XSETINT (buffer_local_flags.auto_save_file_format, -1);
7962a441 5114 XSETINT (buffer_local_flags.display_count, -1);
3fd364db 5115 XSETINT (buffer_local_flags.display_time, -1);
1bf08baf 5116 XSETINT (buffer_local_flags.enable_multibyte_characters, -1);
8d7a4592 5117
7c02e886
GM
5118 idx = 1;
5119 XSETFASTINT (buffer_local_flags.mode_line_format, idx); ++idx;
5120 XSETFASTINT (buffer_local_flags.abbrev_mode, idx); ++idx;
5121 XSETFASTINT (buffer_local_flags.overwrite_mode, idx); ++idx;
5122 XSETFASTINT (buffer_local_flags.case_fold_search, idx); ++idx;
5123 XSETFASTINT (buffer_local_flags.auto_fill_function, idx); ++idx;
5124 XSETFASTINT (buffer_local_flags.selective_display, idx); ++idx;
1ab256cb 5125#ifndef old
7c02e886 5126 XSETFASTINT (buffer_local_flags.selective_display_ellipses, idx); ++idx;
1ab256cb 5127#endif
7c02e886
GM
5128 XSETFASTINT (buffer_local_flags.tab_width, idx); ++idx;
5129 XSETFASTINT (buffer_local_flags.truncate_lines, idx); ++idx;
0858cd02 5130 XSETFASTINT (buffer_local_flags.word_wrap, idx); ++idx;
7c02e886
GM
5131 XSETFASTINT (buffer_local_flags.ctl_arrow, idx); ++idx;
5132 XSETFASTINT (buffer_local_flags.fill_column, idx); ++idx;
5133 XSETFASTINT (buffer_local_flags.left_margin, idx); ++idx;
5134 XSETFASTINT (buffer_local_flags.abbrev_table, idx); ++idx;
5135 XSETFASTINT (buffer_local_flags.display_table, idx); ++idx;
f7975d07 5136#ifdef DOS_NT
7c02e886 5137 XSETFASTINT (buffer_local_flags.buffer_file_type, idx);
13de9290 5138 /* Make this one a permanent local. */
7c02e886 5139 buffer_permanent_local_flags[idx++] = 1;
54ad07d3 5140#endif
7c02e886
GM
5141 XSETFASTINT (buffer_local_flags.syntax_table, idx); ++idx;
5142 XSETFASTINT (buffer_local_flags.cache_long_line_scans, idx); ++idx;
5143 XSETFASTINT (buffer_local_flags.category_table, idx); ++idx;
f44e260c 5144 XSETFASTINT (buffer_local_flags.bidi_display_reordering, idx); ++idx;
6c0cf218 5145 XSETFASTINT (buffer_local_flags.bidi_paragraph_direction, idx); ++idx;
177c0ea7 5146 XSETFASTINT (buffer_local_flags.buffer_file_coding_system, idx);
a1a17b61 5147 /* Make this one a permanent local. */
7c02e886 5148 buffer_permanent_local_flags[idx++] = 1;
2ad8731a
KS
5149 XSETFASTINT (buffer_local_flags.left_margin_cols, idx); ++idx;
5150 XSETFASTINT (buffer_local_flags.right_margin_cols, idx); ++idx;
5151 XSETFASTINT (buffer_local_flags.left_fringe_width, idx); ++idx;
5152 XSETFASTINT (buffer_local_flags.right_fringe_width, idx); ++idx;
5153 XSETFASTINT (buffer_local_flags.fringes_outside_margins, idx); ++idx;
5154 XSETFASTINT (buffer_local_flags.scroll_bar_width, idx); ++idx;
5155 XSETFASTINT (buffer_local_flags.vertical_scroll_bar_type, idx); ++idx;
7c02e886 5156 XSETFASTINT (buffer_local_flags.indicate_empty_lines, idx); ++idx;
6b61353c 5157 XSETFASTINT (buffer_local_flags.indicate_buffer_boundaries, idx); ++idx;
c6a46372
KS
5158 XSETFASTINT (buffer_local_flags.fringe_indicator_alist, idx); ++idx;
5159 XSETFASTINT (buffer_local_flags.fringe_cursor_alist, idx); ++idx;
7c02e886
GM
5160 XSETFASTINT (buffer_local_flags.scroll_up_aggressively, idx); ++idx;
5161 XSETFASTINT (buffer_local_flags.scroll_down_aggressively, idx); ++idx;
5162 XSETFASTINT (buffer_local_flags.header_line_format, idx); ++idx;
bd96bd79 5163 XSETFASTINT (buffer_local_flags.cursor_type, idx); ++idx;
a3bbced0 5164 XSETFASTINT (buffer_local_flags.extra_line_spacing, idx); ++idx;
0124c5bd 5165 XSETFASTINT (buffer_local_flags.cursor_in_non_selected_windows, idx); ++idx;
7c02e886
GM
5166
5167 /* Need more room? */
7313acd0 5168 if (idx >= MAX_PER_BUFFER_VARS)
7c02e886 5169 abort ();
7313acd0 5170 last_per_buffer_idx = idx;
177c0ea7 5171
1ab256cb
RM
5172 Vbuffer_alist = Qnil;
5173 current_buffer = 0;
5174 all_buffers = 0;
5175
f4265f6c 5176 QSFundamental = make_pure_c_string ("Fundamental");
1ab256cb 5177
d67b4f80 5178 Qfundamental_mode = intern_c_string ("fundamental-mode");
1ab256cb
RM
5179 buffer_defaults.major_mode = Qfundamental_mode;
5180
d67b4f80 5181 Qmode_class = intern_c_string ("mode-class");
1ab256cb 5182
d67b4f80 5183 Qprotected_field = intern_c_string ("protected-field");
1ab256cb 5184
d67b4f80 5185 Qpermanent_local = intern_c_string ("permanent-local");
1ab256cb 5186
d67b4f80 5187 Qkill_buffer_hook = intern_c_string ("kill-buffer-hook");
fd6cfe11 5188 Fput (Qkill_buffer_hook, Qpermanent_local, Qt);
1ab256cb 5189
d67b4f80 5190 Qucs_set_table_for_input = intern_c_string ("ucs-set-table-for-input");
48265e61 5191
1ab256cb 5192 /* super-magic invisible buffer */
d67b4f80 5193 Vprin1_to_string_buffer = Fget_buffer_create (make_pure_c_string (" prin1"));
1ab256cb
RM
5194 Vbuffer_alist = Qnil;
5195
d67b4f80 5196 Fset_buffer (Fget_buffer_create (make_pure_c_string ("*scratch*")));
7775635d
KH
5197
5198 inhibit_modification_hooks = 0;
1ab256cb
RM
5199}
5200
dfcf069d 5201void
d3da34e0 5202init_buffer (void)
1ab256cb 5203{
2381d133 5204 char *pwd;
136351b7 5205 Lisp_Object temp;
b639c9be 5206 int len;
1ab256cb 5207
b86af064 5208#ifdef USE_MMAP_FOR_BUFFERS
93c27ef1
GM
5209 {
5210 /* When using the ralloc implementation based on mmap(2), buffer
5211 text pointers will have been set to null in the dumped Emacs.
5212 Map new memory. */
5213 struct buffer *b;
177c0ea7 5214
93c27ef1
GM
5215 for (b = all_buffers; b; b = b->next)
5216 if (b->text->beg == NULL)
b86af064 5217 enlarge_buffer_text (b, 0);
93c27ef1 5218 }
b86af064 5219#endif /* USE_MMAP_FOR_BUFFERS */
177c0ea7 5220
1ab256cb 5221 Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
3d871c85
RS
5222 if (NILP (buffer_defaults.enable_multibyte_characters))
5223 Fset_buffer_multibyte (Qnil);
2381d133 5224
01537133 5225 pwd = get_current_dir_name ();
a17b5ed1 5226
156bdb41 5227 if (!pwd)
a17b5ed1 5228 fatal ("`get_current_dir_name' failed: %s\n", strerror (errno));
1ab256cb 5229
1ab256cb
RM
5230 /* Maybe this should really use some standard subroutine
5231 whose definition is filename syntax dependent. */
b639c9be
RF
5232 len = strlen (pwd);
5233 if (!(IS_DIRECTORY_SEP (pwd[len - 1])))
f7975d07 5234 {
156bdb41 5235 /* Grow buffer to add directory separator and '\0'. */
8b146312
AS
5236 pwd = (char *) realloc (pwd, len + 2);
5237 if (!pwd)
5238 fatal ("`get_current_dir_name' failed: %s\n", strerror (errno));
b639c9be
RF
5239 pwd[len] = DIRECTORY_SEP;
5240 pwd[len + 1] = '\0';
f7975d07 5241 }
0995fa35 5242
01537133 5243 current_buffer->directory = make_unibyte_string (pwd, strlen (pwd));
dcd74c5f 5244 if (! NILP (buffer_defaults.enable_multibyte_characters))
f9962371 5245 /* At this moment, we still don't know how to decode the
156bdb41 5246 directory name. So, we keep the bytes in multibyte form so
dcd74c5f
KH
5247 that ENCODE_FILE correctly gets the original bytes. */
5248 current_buffer->directory
5249 = string_to_multibyte (current_buffer->directory);
136351b7 5250
0995fa35
RS
5251 /* Add /: to the front of the name
5252 if it would otherwise be treated as magic. */
5253 temp = Ffind_file_name_handler (current_buffer->directory, Qt);
81ab2e07
KH
5254 if (! NILP (temp)
5255 /* If the default dir is just /, TEMP is non-nil
5256 because of the ange-ftp completion handler.
5257 However, it is not necessary to turn / into /:/.
5258 So avoid doing that. */
d5db4077 5259 && strcmp ("/", SDATA (current_buffer->directory)))
0995fa35
RS
5260 current_buffer->directory
5261 = concat2 (build_string ("/:"), current_buffer->directory);
5262
136351b7
RS
5263 temp = get_minibuffer (0);
5264 XBUFFER (temp)->directory = current_buffer->directory;
01537133
EZ
5265
5266 free (pwd);
1ab256cb
RM
5267}
5268
d6aa1876
SM
5269/* Similar to defvar_lisp but define a variable whose value is the Lisp
5270 Object stored in the current buffer. address is the address of the slot
5271 in the buffer that is current now. */
5272
5273/* TYPE is nil for a general Lisp variable.
ce5b453a 5274 An integer specifies a type; then only Lisp values
d6aa1876 5275 with that type code are allowed (except that nil is allowed too).
ce5b453a 5276 LNAME is the Lisp-level variable name.
d6aa1876
SM
5277 VNAME is the name of the buffer slot.
5278 DOC is a dummy where you write the doc string as a comment. */
ce5b453a
SM
5279#define DEFVAR_PER_BUFFER(lname, vname, type, doc) \
5280 do { \
5281 static struct Lisp_Buffer_Objfwd bo_fwd; \
5282 defvar_per_buffer (&bo_fwd, lname, vname, type, 0); \
5283 } while (0)
d6aa1876
SM
5284
5285static void
8ea90aa3 5286defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
d3da34e0 5287 Lisp_Object *address, Lisp_Object type, char *doc)
d6aa1876 5288{
ce5b453a 5289 struct Lisp_Symbol *sym;
d6aa1876
SM
5290 int offset;
5291
ce5b453a 5292 sym = XSYMBOL (intern (namestring));
d6aa1876
SM
5293 offset = (char *)address - (char *)current_buffer;
5294
ce5b453a
SM
5295 bo_fwd->type = Lisp_Fwd_Buffer_Obj;
5296 bo_fwd->offset = offset;
5297 bo_fwd->slottype = type;
5298 sym->redirect = SYMBOL_FORWARDED;
5299 {
5300 /* I tried to do the job without a cast, but it seems impossible.
5301 union Lisp_Fwd *fwd; &(fwd->u_buffer_objfwd) = bo_fwd; */
5302 SET_SYMBOL_FWD (sym, (union Lisp_Fwd *)bo_fwd);
5303 }
5304 XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym);
d6aa1876
SM
5305
5306 if (PER_BUFFER_IDX (offset) == 0)
5307 /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
5308 slot of buffer_local_flags */
5309 abort ();
5310}
5311
5312
1ab256cb 5313/* initialize the buffer routines */
dfcf069d 5314void
d3da34e0 5315syms_of_buffer (void)
1ab256cb 5316{
9115729e
KH
5317 staticpro (&last_overlay_modification_hooks);
5318 last_overlay_modification_hooks
5319 = Fmake_vector (make_number (10), Qnil);
5320
1ab256cb
RM
5321 staticpro (&Vbuffer_defaults);
5322 staticpro (&Vbuffer_local_symbols);
5323 staticpro (&Qfundamental_mode);
5324 staticpro (&Qmode_class);
5325 staticpro (&QSFundamental);
5326 staticpro (&Vbuffer_alist);
5327 staticpro (&Qprotected_field);
5328 staticpro (&Qpermanent_local);
d67b4f80 5329 Qpermanent_local_hook = intern_c_string ("permanent-local-hook");
2f7a359d 5330 staticpro (&Qpermanent_local_hook);
1ab256cb 5331 staticpro (&Qkill_buffer_hook);
d67b4f80 5332 Qoverlayp = intern_c_string ("overlayp");
52f8ec73 5333 staticpro (&Qoverlayp);
d67b4f80 5334 Qevaporate = intern_c_string ("evaporate");
9d7608b7 5335 staticpro (&Qevaporate);
d67b4f80 5336 Qmodification_hooks = intern_c_string ("modification-hooks");
22378665 5337 staticpro (&Qmodification_hooks);
d67b4f80 5338 Qinsert_in_front_hooks = intern_c_string ("insert-in-front-hooks");
22378665 5339 staticpro (&Qinsert_in_front_hooks);
d67b4f80 5340 Qinsert_behind_hooks = intern_c_string ("insert-behind-hooks");
22378665 5341 staticpro (&Qinsert_behind_hooks);
d67b4f80 5342 Qget_file_buffer = intern_c_string ("get-file-buffer");
22378665 5343 staticpro (&Qget_file_buffer);
d67b4f80 5344 Qpriority = intern_c_string ("priority");
5985d248 5345 staticpro (&Qpriority);
d67b4f80 5346 Qbefore_string = intern_c_string ("before-string");
bbbe9545 5347 staticpro (&Qbefore_string);
d67b4f80 5348 Qafter_string = intern_c_string ("after-string");
bbbe9545 5349 staticpro (&Qafter_string);
d67b4f80 5350 Qfirst_change_hook = intern_c_string ("first-change-hook");
22378665 5351 staticpro (&Qfirst_change_hook);
d67b4f80 5352 Qbefore_change_functions = intern_c_string ("before-change-functions");
22378665 5353 staticpro (&Qbefore_change_functions);
d67b4f80 5354 Qafter_change_functions = intern_c_string ("after-change-functions");
22378665 5355 staticpro (&Qafter_change_functions);
2f7a359d 5356 /* The next one is initialized in init_buffer_once. */
48265e61 5357 staticpro (&Qucs_set_table_for_input);
1ab256cb 5358
d67b4f80 5359 Qkill_buffer_query_functions = intern_c_string ("kill-buffer-query-functions");
5b20caf0
RS
5360 staticpro (&Qkill_buffer_query_functions);
5361
1ab256cb 5362 Fput (Qprotected_field, Qerror_conditions,
d67b4f80 5363 pure_cons (Qprotected_field, pure_cons (Qerror, Qnil)));
1ab256cb 5364 Fput (Qprotected_field, Qerror_message,
d67b4f80 5365 make_pure_c_string ("Attempt to modify a protected field"));
1ab256cb
RM
5366
5367 /* All these use DEFVAR_LISP_NOPRO because the slots in
5368 buffer_defaults will all be marked via Vbuffer_defaults. */
5369
5370 DEFVAR_LISP_NOPRO ("default-mode-line-format",
7ee72033
MB
5371 &buffer_defaults.mode_line_format,
5372 doc: /* Default value of `mode-line-format' for buffers that don't override it.
018ba359 5373This is the same as (default-value 'mode-line-format). */);
1ab256cb 5374
045dee35 5375 DEFVAR_LISP_NOPRO ("default-header-line-format",
7ee72033
MB
5376 &buffer_defaults.header_line_format,
5377 doc: /* Default value of `header-line-format' for buffers that don't override it.
018ba359 5378This is the same as (default-value 'header-line-format). */);
0552666b 5379
7ee72033
MB
5380 DEFVAR_LISP_NOPRO ("default-cursor-type", &buffer_defaults.cursor_type,
5381 doc: /* Default value of `cursor-type' for buffers that don't override it.
018ba359 5382This is the same as (default-value 'cursor-type). */);
bd96bd79 5383
a3bbced0 5384 DEFVAR_LISP_NOPRO ("default-line-spacing",
7ee72033
MB
5385 &buffer_defaults.extra_line_spacing,
5386 doc: /* Default value of `line-spacing' for buffers that don't override it.
018ba359 5387This is the same as (default-value 'line-spacing). */);
a3bbced0 5388
187ccf49
KS
5389 DEFVAR_LISP_NOPRO ("default-cursor-in-non-selected-windows",
5390 &buffer_defaults.cursor_in_non_selected_windows,
5391 doc: /* Default value of `cursor-in-non-selected-windows'.
5392This is the same as (default-value 'cursor-in-non-selected-windows). */);
5393
1ab256cb 5394 DEFVAR_LISP_NOPRO ("default-abbrev-mode",
efc7e75f 5395 &buffer_defaults.abbrev_mode,
7ee72033 5396 doc: /* Default value of `abbrev-mode' for buffers that do not override it.
018ba359 5397This is the same as (default-value 'abbrev-mode). */);
1ab256cb
RM
5398
5399 DEFVAR_LISP_NOPRO ("default-ctl-arrow",
efc7e75f 5400 &buffer_defaults.ctl_arrow,
7ee72033 5401 doc: /* Default value of `ctl-arrow' for buffers that do not override it.
018ba359 5402This is the same as (default-value 'ctl-arrow). */);
1ab256cb 5403
5e2ad10b
JB
5404 DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters",
5405 &buffer_defaults.enable_multibyte_characters,
5406 doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it.
018ba359 5407This is the same as (default-value 'enable-multibyte-characters). */);
177c0ea7 5408
5e2ad10b
JB
5409 DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system",
5410 &buffer_defaults.buffer_file_coding_system,
5411 doc: /* Default value of `buffer-file-coding-system' for buffers not overriding it.
018ba359 5412This is the same as (default-value 'buffer-file-coding-system). */);
177c0ea7 5413
1ab256cb 5414 DEFVAR_LISP_NOPRO ("default-truncate-lines",
efc7e75f
PJ
5415 &buffer_defaults.truncate_lines,
5416 doc: /* Default value of `truncate-lines' for buffers that do not override it.
018ba359 5417This is the same as (default-value 'truncate-lines). */);
1ab256cb
RM
5418
5419 DEFVAR_LISP_NOPRO ("default-fill-column",
efc7e75f
PJ
5420 &buffer_defaults.fill_column,
5421 doc: /* Default value of `fill-column' for buffers that do not override it.
018ba359 5422This is the same as (default-value 'fill-column). */);
1ab256cb
RM
5423
5424 DEFVAR_LISP_NOPRO ("default-left-margin",
efc7e75f
PJ
5425 &buffer_defaults.left_margin,
5426 doc: /* Default value of `left-margin' for buffers that do not override it.
018ba359 5427This is the same as (default-value 'left-margin). */);
1ab256cb
RM
5428
5429 DEFVAR_LISP_NOPRO ("default-tab-width",
bc0ede35 5430 &buffer_defaults.tab_width,
23625946 5431 doc: /* Default value of `tab-width' for buffers that do not override it.
018ba359 5432This is the same as (default-value 'tab-width). */);
1ab256cb
RM
5433
5434 DEFVAR_LISP_NOPRO ("default-case-fold-search",
efc7e75f
PJ
5435 &buffer_defaults.case_fold_search,
5436 doc: /* Default value of `case-fold-search' for buffers that don't override it.
018ba359 5437This is the same as (default-value 'case-fold-search). */);
1ab256cb 5438
f7975d07 5439#ifdef DOS_NT
177c0ea7 5440 DEFVAR_LISP_NOPRO ("default-buffer-file-type",
7ee72033 5441 &buffer_defaults.buffer_file_type,
efc7e75f 5442 doc: /* Default file type for buffers that do not override it.
018ba359
PJ
5443This is the same as (default-value 'buffer-file-type).
5444The file type is nil for text, t for binary. */);
54ad07d3
RS
5445#endif
5446
0552666b 5447 DEFVAR_LISP_NOPRO ("default-left-margin-width",
2ad8731a 5448 &buffer_defaults.left_margin_cols,
efc7e75f 5449 doc: /* Default value of `left-margin-width' for buffers that don't override it.
018ba359 5450This is the same as (default-value 'left-margin-width). */);
0552666b
GM
5451
5452 DEFVAR_LISP_NOPRO ("default-right-margin-width",
2ad8731a
KS
5453 &buffer_defaults.right_margin_cols,
5454 doc: /* Default value of `right-margin-width' for buffers that don't override it.
018ba359 5455This is the same as (default-value 'right-margin-width). */);
177c0ea7 5456
2ad8731a
KS
5457 DEFVAR_LISP_NOPRO ("default-left-fringe-width",
5458 &buffer_defaults.left_fringe_width,
5459 doc: /* Default value of `left-fringe-width' for buffers that don't override it.
5460This is the same as (default-value 'left-fringe-width). */);
5461
5462 DEFVAR_LISP_NOPRO ("default-right-fringe-width",
5463 &buffer_defaults.right_fringe_width,
5464 doc: /* Default value of `right-fringe-width' for buffers that don't override it.
5465This is the same as (default-value 'right-fringe-width). */);
5466
5467 DEFVAR_LISP_NOPRO ("default-fringes-outside-margins",
5468 &buffer_defaults.fringes_outside_margins,
5469 doc: /* Default value of `fringes-outside-margins' for buffers that don't override it.
5470This is the same as (default-value 'fringes-outside-margins). */);
5471
5472 DEFVAR_LISP_NOPRO ("default-scroll-bar-width",
5473 &buffer_defaults.scroll_bar_width,
5474 doc: /* Default value of `scroll-bar-width' for buffers that don't override it.
5475This is the same as (default-value 'scroll-bar-width). */);
5476
5477 DEFVAR_LISP_NOPRO ("default-vertical-scroll-bar",
5478 &buffer_defaults.vertical_scroll_bar_type,
5479 doc: /* Default value of `vertical-scroll-bar' for buffers that don't override it.
5480This is the same as (default-value 'vertical-scroll-bar). */);
5481
0552666b 5482 DEFVAR_LISP_NOPRO ("default-indicate-empty-lines",
efc7e75f
PJ
5483 &buffer_defaults.indicate_empty_lines,
5484 doc: /* Default value of `indicate-empty-lines' for buffers that don't override it.
018ba359 5485This is the same as (default-value 'indicate-empty-lines). */);
177c0ea7 5486
6b61353c
KH
5487 DEFVAR_LISP_NOPRO ("default-indicate-buffer-boundaries",
5488 &buffer_defaults.indicate_buffer_boundaries,
5489 doc: /* Default value of `indicate-buffer-boundaries' for buffers that don't override it.
5490This is the same as (default-value 'indicate-buffer-boundaries). */);
5491
c6a46372
KS
5492 DEFVAR_LISP_NOPRO ("default-fringe-indicator-alist",
5493 &buffer_defaults.fringe_indicator_alist,
5494 doc: /* Default value of `fringe-indicator-alist' for buffers that don't override it.
5495This is the same as (default-value 'fringe-indicator-alist'). */);
5496
5497 DEFVAR_LISP_NOPRO ("default-fringe-cursor-alist",
5498 &buffer_defaults.fringe_cursor_alist,
5499 doc: /* Default value of `fringe-cursor-alist' for buffers that don't override it.
5500This is the same as (default-value 'fringe-cursor-alist'). */);
5501
0552666b 5502 DEFVAR_LISP_NOPRO ("default-scroll-up-aggressively",
efc7e75f 5503 &buffer_defaults.scroll_up_aggressively,
7614d762
RS
5504 doc: /* Default value of `scroll-up-aggressively'.
5505This value applies in buffers that don't have their own local values.
fc961256 5506This is the same as (default-value 'scroll-up-aggressively). */);
177c0ea7 5507
0552666b 5508 DEFVAR_LISP_NOPRO ("default-scroll-down-aggressively",
efc7e75f 5509 &buffer_defaults.scroll_down_aggressively,
7614d762
RS
5510 doc: /* Default value of `scroll-down-aggressively'.
5511This value applies in buffers that don't have their own local values.
fc961256 5512This is the same as (default-value 'scroll-down-aggressively). */);
177c0ea7 5513
045dee35 5514 DEFVAR_PER_BUFFER ("header-line-format",
018ba359 5515 &current_buffer->header_line_format,
7ee72033 5516 Qnil,
7614d762
RS
5517 doc: /* Analogous to `mode-line-format', but controls the header line.
5518The header line appears, optionally, at the top of a window;
5519the mode line appears at the bottom. */);
177c0ea7 5520
1ab256cb 5521 DEFVAR_PER_BUFFER ("mode-line-format", &current_buffer->mode_line_format,
efc7e75f
PJ
5522 Qnil,
5523 doc: /* Template for displaying mode line for current buffer.
018ba359
PJ
5524Each buffer has its own value of this variable.
5525Value may be nil, a string, a symbol or a list or cons cell.
5526A value of nil means don't display a mode line.
5527For a symbol, its value is used (but it is ignored if t or nil).
5528 A string appearing directly as the value of a symbol is processed verbatim
5529 in that the %-constructs below are not recognized.
ed463255 5530 Note that unless the symbol is marked as a `risky-local-variable', all
177c0ea7 5531 properties in any strings, as well as all :eval and :propertize forms
ed463255 5532 in the value of that symbol will be ignored.
018ba359 5533For a list of the form `(:eval FORM)', FORM is evaluated and the result
9c3eecf3
RS
5534 is used as a mode line element. Be careful--FORM should not load any files,
5535 because that can cause an infinite recursion.
ed463255
KS
5536For a list of the form `(:propertize ELT PROPS...)', ELT is displayed
5537 with the specified properties PROPS applied.
018ba359
PJ
5538For a list whose car is a symbol, the symbol's value is taken,
5539 and if that is non-nil, the cadr of the list is processed recursively.
5540 Otherwise, the caddr of the list (if there is one) is processed.
5541For a list whose car is a string or list, each element is processed
5542 recursively and the results are effectively concatenated.
5543For a list whose car is an integer, the cdr of the list is processed
5544 and padded (if the number is positive) or truncated (if negative)
5545 to the width specified by that number.
5546A string is printed verbatim in the mode line except for %-constructs:
5547 (%-constructs are allowed when the string is the entire mode-line-format
5548 or when it is found in a cons-cell or a list)
5549 %b -- print buffer name. %f -- print visited file name.
5550 %F -- print frame name.
5551 %* -- print %, * or hyphen. %+ -- print *, % or hyphen.
5552 %& is like %*, but ignore read-only-ness.
5553 % means buffer is read-only and * means it is modified.
5554 For a modified read-only buffer, %* gives % and %+ gives *.
5555 %s -- print process status. %l -- print the current line number.
5556 %c -- print the current column number (this makes editing slower).
5557 To make the column number update correctly in all cases,
5558 `column-number-mode' must be non-nil.
6b61353c
KH
5559 %i -- print the size of the buffer.
5560 %I -- like %i, but use k, M, G, etc., to abbreviate.
018ba359
PJ
5561 %p -- print percent of buffer above top of window, or Top, Bot or All.
5562 %P -- print percent of buffer above bottom of window, perhaps plus Top,
5563 or print Bottom or All.
018ba359 5564 %n -- print Narrow if appropriate.
dafbe726 5565 %t -- visited file is text or binary (if OS supports this distinction).
47419860 5566 %z -- print mnemonics of keyboard, terminal, and buffer coding systems.
018ba359 5567 %Z -- like %z, but including the end-of-line format.
dafbe726 5568 %e -- print error message about full memory.
f7165034
NR
5569 %@ -- print @ or hyphen. @ means that default-directory is on a
5570 remote machine.
018ba359
PJ
5571 %[ -- print one [ for each recursive editing level. %] similar.
5572 %% -- print %. %- -- print infinitely many dashes.
5573Decimal digits after the % specify field width to which to pad. */);
5574
7ee72033 5575 DEFVAR_LISP_NOPRO ("default-major-mode", &buffer_defaults.major_mode,
5a021dd0 5576 doc: /* *Value of `major-mode' for new buffers. */);
1ab256cb
RM
5577
5578 DEFVAR_PER_BUFFER ("major-mode", &current_buffer->major_mode,
7ee72033 5579 make_number (Lisp_Symbol),
5a021dd0
GM
5580 doc: /* Symbol for current buffer's major mode.
5581The default value (normally `fundamental-mode') affects new buffers.
5582A value of nil means to use the current buffer's major mode, provided
5583it is not marked as "special".
5584
5585When a mode is used by default, `find-file' switches to it before it
5586reads the contents into the buffer and before it finishes setting up
5587the buffer. Thus, the mode and its hooks should not expect certain
5588variables such as `buffer-read-only' and `buffer-file-coding-system'
5589to be set up. */);
1ab256cb
RM
5590
5591 DEFVAR_PER_BUFFER ("mode-name", &current_buffer->mode_name,
c01d0677 5592 Qnil,
64a7c220 5593 doc: /* Pretty name of current buffer's major mode.
7cb70974
EZ
5594Usually a string, but can use any of the constructs for `mode-line-format',
5595which see.
5596Format with `format-mode-line' to produce a string value. */);
1ab256cb 5597
d6aa1876
SM
5598 DEFVAR_PER_BUFFER ("local-abbrev-table", &current_buffer->abbrev_table, Qnil,
5599 doc: /* Local (mode-specific) abbrev table of current buffer. */);
5600
7ee72033 5601 DEFVAR_PER_BUFFER ("abbrev-mode", &current_buffer->abbrev_mode, Qnil,
efc7e75f 5602 doc: /* Non-nil turns on automatic expansion of abbrevs as they are inserted. */);
1ab256cb
RM
5603
5604 DEFVAR_PER_BUFFER ("case-fold-search", &current_buffer->case_fold_search,
7ee72033 5605 Qnil,
efc7e75f 5606 doc: /* *Non-nil if searches and matches should ignore case. */);
1ab256cb
RM
5607
5608 DEFVAR_PER_BUFFER ("fill-column", &current_buffer->fill_column,
2de9f71c 5609 make_number (LISP_INT_TAG),
1ac5826d 5610 doc: /* *Column beyond which automatic line-wrapping should happen.
f1ccb329 5611Interactively, you can set the buffer local value using \\[set-fill-column]. */);
1ab256cb
RM
5612
5613 DEFVAR_PER_BUFFER ("left-margin", &current_buffer->left_margin,
2de9f71c 5614 make_number (LISP_INT_TAG),
fc961256 5615 doc: /* *Column for the default `indent-line-function' to indent to.
018ba359 5616Linefeed indents to this column in Fundamental mode. */);
1ab256cb
RM
5617
5618 DEFVAR_PER_BUFFER ("tab-width", &current_buffer->tab_width,
2de9f71c 5619 make_number (LISP_INT_TAG),
efc7e75f 5620 doc: /* *Distance between tab stops (for display of tab characters), in columns. */);
1ab256cb 5621
7ee72033 5622 DEFVAR_PER_BUFFER ("ctl-arrow", &current_buffer->ctl_arrow, Qnil,
efc7e75f 5623 doc: /* *Non-nil means display control chars with uparrow.
018ba359
PJ
5624A value of nil means use backslash and octal digits.
5625This variable does not apply to characters whose display is specified
5626in the current display table (if there is one). */);
1ab256cb 5627
3b06f880 5628 DEFVAR_PER_BUFFER ("enable-multibyte-characters",
1bf08baf 5629 &current_buffer->enable_multibyte_characters,
a9b9a780 5630 Qnil,
efc7e75f 5631 doc: /* Non-nil means the buffer contents are regarded as multi-byte characters.
018ba359
PJ
5632Otherwise they are regarded as unibyte. This affects the display,
5633file I/O and the behavior of various editing commands.
5634
5635This variable is buffer-local but you cannot set it directly;
5636use the function `set-buffer-multibyte' to change a buffer's representation.
5637Changing its default value with `setq-default' is supported.
5638See also variable `default-enable-multibyte-characters' and Info node
5639`(elisp)Text Representations'. */);
d67b4f80 5640 XSYMBOL (intern_c_string ("enable-multibyte-characters"))->constant = 1;
3b06f880 5641
c71b5d9b 5642 DEFVAR_PER_BUFFER ("buffer-file-coding-system",
7ee72033 5643 &current_buffer->buffer_file_coding_system, Qnil,
efc7e75f 5644 doc: /* Coding system to be used for encoding the buffer contents on saving.
018ba359
PJ
5645This variable applies to saving the buffer, and also to `write-region'
5646and other functions that use `write-region'.
5647It does not apply to sending output to subprocesses, however.
5648
5649If this is nil, the buffer is saved without any code conversion
5650unless some coding system is specified in `file-coding-system-alist'
5651for the buffer file.
5652
31a6cb06
EZ
5653If the text to be saved cannot be encoded as specified by this variable,
5654an alternative encoding is selected by `select-safe-coding-system', which see.
5655
018ba359
PJ
5656The variable `coding-system-for-write', if non-nil, overrides this variable.
5657
5658This variable is never applied to a way of decoding a file while reading it. */);
c71b5d9b 5659
f44e260c
EZ
5660 DEFVAR_PER_BUFFER ("bidi-display-reordering",
5661 &current_buffer->bidi_display_reordering, Qnil,
938efb77 5662 doc: /* Non-nil means reorder bidirectional text for display in the visual order. */);
3b06f880 5663
6c0cf218
EZ
5664 DEFVAR_PER_BUFFER ("bidi-paragraph-direction",
5665 &current_buffer->bidi_paragraph_direction, Qnil,
b44d9321 5666 doc: /* *If non-nil, forces directionality of text paragraphs in the buffer.
b4bf28b7 5667
b44d9321
EZ
5668If this is nil (the default), the direction of each paragraph is
5669determined by the first strong directional character of its text.
5670The values of `right-to-left' and `left-to-right' override that.
5671Any other value is treated as nil.
b4bf28b7 5672
b44d9321
EZ
5673This variable has no effect unless the buffer's value of
5674\`bidi-display-reordering' is non-nil. */);
5675
b7b65b15 5676 DEFVAR_PER_BUFFER ("truncate-lines", &current_buffer->truncate_lines, Qnil,
7614d762
RS
5677 doc: /* *Non-nil means do not display continuation lines.
5678Instead, give each line of text just one screen line.
018ba359
PJ
5679
5680Note that this is overridden by the variable
5681`truncate-partial-width-windows' if that variable is non-nil
5682and this buffer is not full-frame width. */);
1ab256cb 5683
0858cd02
CY
5684 DEFVAR_PER_BUFFER ("word-wrap", &current_buffer->word_wrap, Qnil,
5685 doc: /* *Non-nil means to use word-wrapping for continuation lines.
5686When word-wrapping is on, continuation lines are wrapped at the space
5687or tab character nearest to the right window edge.
5688If nil, continuation lines are wrapped at the right screen edge.
5689
5690This variable has no effect if long lines are truncated (see
eb577e27
GM
5691`truncate-lines' and `truncate-partial-width-windows'). If you use
5692word-wrapping, you might want to reduce the value of
5693`truncate-partial-width-windows', since wrapping can make text readable
5694in narrower windows. */);
0858cd02 5695
f7975d07 5696#ifdef DOS_NT
54ad07d3 5697 DEFVAR_PER_BUFFER ("buffer-file-type", &current_buffer->buffer_file_type,
7ee72033 5698 Qnil,
efc7e75f 5699 doc: /* Non-nil if the visited file is a binary file.
018ba359
PJ
5700This variable is meaningful on MS-DOG and Windows NT.
5701On those systems, it is automatically local in every buffer.
5702On other systems, this variable is normally always nil. */);
54ad07d3
RS
5703#endif
5704
1ab256cb 5705 DEFVAR_PER_BUFFER ("default-directory", &current_buffer->directory,
7ee72033 5706 make_number (Lisp_String),
efc7e75f 5707 doc: /* Name of default directory of current buffer. Should end with slash.
018ba359 5708To interactively change the default directory, use command `cd'. */);
1ab256cb
RM
5709
5710 DEFVAR_PER_BUFFER ("auto-fill-function", &current_buffer->auto_fill_function,
7ee72033 5711 Qnil,
efc7e75f 5712 doc: /* Function called (if non-nil) to perform auto-fill.
018ba359
PJ
5713It is called after self-inserting any character specified in
5714the `auto-fill-chars' table.
5715NOTE: This variable is not a hook;
5716its value may not be a list of functions. */);
1ab256cb
RM
5717
5718 DEFVAR_PER_BUFFER ("buffer-file-name", &current_buffer->filename,
7ee72033 5719 make_number (Lisp_String),
efc7e75f 5720 doc: /* Name of file visited in current buffer, or nil if not visiting a file. */);
1ab256cb 5721
f6ed2e84 5722 DEFVAR_PER_BUFFER ("buffer-file-truename", &current_buffer->file_truename,
7ee72033 5723 make_number (Lisp_String),
efc7e75f 5724 doc: /* Abbreviated truename of file visited in current buffer, or nil if none.
018ba359
PJ
5725The truename of a file is calculated by `file-truename'
5726and then abbreviated with `abbreviate-file-name'. */);
f6ed2e84 5727
1ab256cb 5728 DEFVAR_PER_BUFFER ("buffer-auto-save-file-name",
3f5fcd47 5729 &current_buffer->auto_save_file_name,
7ee72033 5730 make_number (Lisp_String),
7614d762
RS
5731 doc: /* Name of file for auto-saving current buffer.
5732If it is nil, that means don't auto-save this buffer. */);
1ab256cb 5733
7ee72033 5734 DEFVAR_PER_BUFFER ("buffer-read-only", &current_buffer->read_only, Qnil,
efc7e75f 5735 doc: /* Non-nil if this buffer is read-only. */);
1ab256cb 5736
7ee72033 5737 DEFVAR_PER_BUFFER ("buffer-backed-up", &current_buffer->backed_up, Qnil,
efc7e75f 5738 doc: /* Non-nil if this buffer's file has been backed up.
018ba359 5739Backing up is done before the first time the file is saved. */);
1ab256cb
RM
5740
5741 DEFVAR_PER_BUFFER ("buffer-saved-size", &current_buffer->save_length,
2de9f71c 5742 make_number (LISP_INT_TAG),
efc7e75f 5743 doc: /* Length of current buffer when last read in, saved or auto-saved.
4be941e3
RS
57440 initially.
5745-1 means auto-saving turned off until next real save.
5746
5747If you set this to -2, that means don't turn off auto-saving in this buffer
5748if its text size shrinks. If you use `buffer-swap-text' on a buffer,
5749you probably should set this to -2 in that buffer. */);
1ab256cb
RM
5750
5751 DEFVAR_PER_BUFFER ("selective-display", &current_buffer->selective_display,
7ee72033 5752 Qnil,
7614d762 5753 doc: /* Non-nil enables selective display.
a66f285a
JB
5754An integer N as value means display only lines
5755that start with less than N columns of space.
7614d762
RS
5756A value of t means that the character ^M makes itself and
5757all the rest of the line invisible; also, when saving the buffer
5758in a file, save the ^M as a newline. */);
1ab256cb
RM
5759
5760#ifndef old
5761 DEFVAR_PER_BUFFER ("selective-display-ellipses",
d765e3a3 5762 &current_buffer->selective_display_ellipses,
7ee72033 5763 Qnil,
3f676284 5764 doc: /* Non-nil means display ... on previous line when a line is invisible. */);
1ab256cb
RM
5765#endif
5766
7ee72033 5767 DEFVAR_PER_BUFFER ("overwrite-mode", &current_buffer->overwrite_mode, Qnil,
efc7e75f 5768 doc: /* Non-nil if self-insertion should replace existing text.
018ba359
PJ
5769The value should be one of `overwrite-mode-textual',
5770`overwrite-mode-binary', or nil.
5771If it is `overwrite-mode-textual', self-insertion still
5772inserts at the end of a line, and inserts when point is before a tab,
5773until the tab is filled in.
5774If `overwrite-mode-binary', self-insertion replaces newlines and tabs too. */);
5775
54939090 5776 DEFVAR_PER_BUFFER ("buffer-display-table", &current_buffer->display_table,
7ee72033 5777 Qnil,
efc7e75f 5778 doc: /* Display table that controls display of the contents of current buffer.
018ba359
PJ
5779
5780If this variable is nil, the value of `standard-display-table' is used.
5781Each window can have its own, overriding display table, see
5782`set-window-display-table' and `window-display-table'.
5783
5784The display table is a char-table created with `make-display-table'.
5785A char-table is an array indexed by character codes. Normal array
5786primitives `aref' and `aset' can be used to access elements of a char-table.
5787
5788Each of the char-table elements control how to display the corresponding
5789text character: the element at index C in the table says how to display
5790the character whose code is C. Each element should be a vector of
426a9163
JB
5791characters or nil. The value nil means display the character in the
5792default fashion; otherwise, the characters from the vector are delivered
5793to the screen instead of the original character.
018ba359 5794
5fd11dc8 5795For example, (aset buffer-display-table ?X [?Y]) tells Emacs
adbb3b05 5796to display a capital Y instead of each X character.
018ba359
PJ
5797
5798In addition, a char-table has six extra slots to control the display of:
5799
5800 the end of a truncated screen line (extra-slot 0, a single character);
5801 the end of a continued line (extra-slot 1, a single character);
5802 the escape character used to display character codes in octal
5803 (extra-slot 2, a single character);
5804 the character used as an arrow for control characters (extra-slot 3,
5805 a single character);
5806 the decoration indicating the presence of invisible lines (extra-slot 4,
5807 a vector of characters);
5808 the character used to draw the border between side-by-side windows
5809 (extra-slot 5, a single character).
5810
5811See also the functions `display-table-slot' and `set-display-table-slot'. */);
1ab256cb 5812
2ad8731a 5813 DEFVAR_PER_BUFFER ("left-margin-width", &current_buffer->left_margin_cols,
7ee72033 5814 Qnil,
efc7e75f 5815 doc: /* *Width of left marginal area for display of a buffer.
018ba359 5816A value of nil means no marginal area. */);
177c0ea7 5817
2ad8731a 5818 DEFVAR_PER_BUFFER ("right-margin-width", &current_buffer->right_margin_cols,
7ee72033 5819 Qnil,
efc7e75f 5820 doc: /* *Width of right marginal area for display of a buffer.
018ba359 5821A value of nil means no marginal area. */);
177c0ea7 5822
2ad8731a
KS
5823 DEFVAR_PER_BUFFER ("left-fringe-width", &current_buffer->left_fringe_width,
5824 Qnil,
5825 doc: /* *Width of this buffer's left fringe (in pixels).
5826A value of 0 means no left fringe is shown in this buffer's window.
5827A value of nil means to use the left fringe width from the window's frame. */);
5828
5829 DEFVAR_PER_BUFFER ("right-fringe-width", &current_buffer->right_fringe_width,
5830 Qnil,
5831 doc: /* *Width of this buffer's right fringe (in pixels).
5832A value of 0 means no right fringe is shown in this buffer's window.
5833A value of nil means to use the right fringe width from the window's frame. */);
5834
5835 DEFVAR_PER_BUFFER ("fringes-outside-margins", &current_buffer->fringes_outside_margins,
5836 Qnil,
5837 doc: /* *Non-nil means to display fringes outside display margins.
5838A value of nil means to display fringes between margins and buffer text. */);
5839
5840 DEFVAR_PER_BUFFER ("scroll-bar-width", &current_buffer->scroll_bar_width,
5841 Qnil,
5842 doc: /* *Width of this buffer's scroll bars in pixels.
5843A value of nil means to use the scroll bar width from the window's frame. */);
5844
5845 DEFVAR_PER_BUFFER ("vertical-scroll-bar", &current_buffer->vertical_scroll_bar_type,
5846 Qnil,
5847 doc: /* *Position of this buffer's vertical scroll bar.
7c6b2007 5848The value takes effect whenever you tell a window to display this buffer;
188577ce 5849for instance, with `set-window-buffer' or when `display-buffer' displays it.
7c6b2007 5850
fc2c8887
RS
5851A value of `left' or `right' means put the vertical scroll bar at that side
5852of the window; a value of nil means don't show any vertical scroll bars.
5853A value of t (the default) means do whatever the window's frame specifies. */);
2ad8731a 5854
0552666b 5855 DEFVAR_PER_BUFFER ("indicate-empty-lines",
7ee72033 5856 &current_buffer->indicate_empty_lines, Qnil,
efc7e75f 5857 doc: /* *Visually indicate empty lines after the buffer end.
018ba359
PJ
5858If non-nil, a bitmap is displayed in the left fringe of a window on
5859window-systems. */);
177c0ea7 5860
6b61353c
KH
5861 DEFVAR_PER_BUFFER ("indicate-buffer-boundaries",
5862 &current_buffer->indicate_buffer_boundaries, Qnil,
5863 doc: /* *Visually indicate buffer boundaries and scrolling.
5864If non-nil, the first and last line of the buffer are marked in the fringe
5865of a window on window-systems with angle bitmaps, or if the window can be
5866scrolled, the top and bottom line of the window are marked with up and down
5867arrow bitmaps.
b2229037
KS
5868
5869If value is a symbol `left' or `right', both angle and arrow bitmaps
79e3497d 5870are displayed in the left or right fringe, resp. Any other value
845a78b4 5871that doesn't look like an alist means display the angle bitmaps in
79e3497d 5872the left fringe but no arrows.
b2229037 5873
79e3497d
RS
5874You can exercise more precise control by using an alist as the
5875value. Each alist element (INDICATOR . POSITION) specifies
5876where to show one of the indicators. INDICATOR is one of `top',
b2229037
KS
5877`bottom', `up', `down', or t, which specifies the default position,
5878and POSITION is one of `left', `right', or nil, meaning do not show
5879this indicator.
5880
5881For example, ((top . left) (t . right)) places the top angle bitmap in
5882left fringe, the bottom angle bitmap in right fringe, and both arrow
6b61353c 5883bitmaps in right fringe. To show just the angle bitmaps in the left
b2229037 5884fringe, but no arrow bitmaps, use ((top . left) (bottom . left)). */);
6b61353c 5885
c6a46372
KS
5886 DEFVAR_PER_BUFFER ("fringe-indicator-alist",
5887 &current_buffer->fringe_indicator_alist, Qnil,
5888 doc: /* *Mapping from logical to physical fringe indicator bitmaps.
5889The value is an alist where each element (INDICATOR . BITMAPS)
5890specifies the fringe bitmaps used to display a specific logical
5891fringe indicator.
5892
5893INDICATOR specifies the logical indicator type which is one of the
5894following symbols: `truncation' , `continuation', `overlay-arrow',
14fb5704 5895`top', `bottom', `top-bottom', `up', `down', empty-line', or `unknown'.
c6a46372 5896
14fb5704 5897BITMAPS is a list of symbols (LEFT RIGHT [LEFT1 RIGHT1]) which specifies
c6a46372
KS
5898the actual bitmap shown in the left or right fringe for the logical
5899indicator. LEFT and RIGHT are the bitmaps shown in the left and/or
5900right fringe for the specific indicator. The LEFT1 or RIGHT1 bitmaps
14fb5704
JB
5901are used only for the `bottom' and `top-bottom' indicators when the
5902last (only) line has no final newline. BITMAPS may also be a single
c6a46372
KS
5903symbol which is used in both left and right fringes. */);
5904
5905 DEFVAR_PER_BUFFER ("fringe-cursor-alist",
5906 &current_buffer->fringe_cursor_alist, Qnil,
5907 doc: /* *Mapping from logical to physical fringe cursor bitmaps.
5908The value is an alist where each element (CURSOR . BITMAP)
5909specifies the fringe bitmaps used to display a specific logical
5910cursor type in the fringe.
5911
5912CURSOR specifies the logical cursor type which is one of the following
5913symbols: `box' , `hollow', `bar', `hbar', or `hollow-small'. The last
5914one is used to show a hollow cursor on narrow lines display lines
5915where the normal hollow cursor will not fit.
5916
5917BITMAP is the corresponding fringe bitmap shown for the logical
5918cursor type. */);
5919
0552666b 5920 DEFVAR_PER_BUFFER ("scroll-up-aggressively",
7ee72033 5921 &current_buffer->scroll_up_aggressively, Qnil,
4e0692c1
RS
5922 doc: /* How far to scroll windows upward.
5923If you move point off the bottom, the window scrolls automatically.
426a9163 5924This variable controls how far it scrolls. The value nil, the default,
4e0692c1
RS
5925means scroll to center point. A fraction means scroll to put point
5926that fraction of the window's height from the bottom of the window.
d765e3a3
JB
5927When the value is 0.0, point goes at the bottom line, which in the
5928simple case that you moved off with C-f means scrolling just one line.
59291.0 means point goes at the top, so that in that simple case, the
5930window scrolls by a full window height. Meaningful values are
175e9712 5931between 0.0 and 1.0, inclusive. */);
177c0ea7 5932
0552666b 5933 DEFVAR_PER_BUFFER ("scroll-down-aggressively",
7ee72033 5934 &current_buffer->scroll_down_aggressively, Qnil,
4e0692c1
RS
5935 doc: /* How far to scroll windows downward.
5936If you move point off the top, the window scrolls automatically.
426a9163 5937This variable controls how far it scrolls. The value nil, the default,
4e0692c1
RS
5938means scroll to center point. A fraction means scroll to put point
5939that fraction of the window's height from the top of the window.
d765e3a3
JB
5940When the value is 0.0, point goes at the top line, which in the
5941simple case that you moved off with C-b means scrolling just one line.
59421.0 means point goes at the bottom, so that in that simple case, the
5943window scrolls by a full window height. Meaningful values are
175e9712 5944between 0.0 and 1.0, inclusive. */);
177c0ea7 5945
1ab256cb
RM
5946/*DEFVAR_LISP ("debug-check-symbol", &Vcheck_symbol,
5947 "Don't ask.");
5948*/
1ab256cb 5949
7ee72033
MB
5950 DEFVAR_LISP ("before-change-functions", &Vbefore_change_functions,
5951 doc: /* List of functions to call before each text change.
018ba359
PJ
5952Two arguments are passed to each function: the positions of
5953the beginning and end of the range of old text to be changed.
5954\(For an insertion, the beginning and end are at the same place.)
5955No information is given about the length of the text after the change.
5956
5957Buffer changes made while executing the `before-change-functions'
5958don't call any before-change or after-change functions.
5959That's because these variables are temporarily set to nil.
d765e3a3
JB
5960As a result, a hook function cannot straightforwardly alter the
5961value of these variables. See the Emacs Lisp manual for a way of
018ba359
PJ
5962accomplishing an equivalent result by using other variables.
5963
5964If an unhandled error happens in running these functions,
5965the variable's value remains nil. That prevents the error
5966from happening repeatedly and making Emacs nonfunctional. */);
5f079267
RS
5967 Vbefore_change_functions = Qnil;
5968
7ee72033 5969 DEFVAR_LISP ("after-change-functions", &Vafter_change_functions,
eacdfade 5970 doc: /* List of functions to call after each text change.
018ba359
PJ
5971Three arguments are passed to each function: the positions of
5972the beginning and end of the range of changed text,
5973and the length in bytes of the pre-change text replaced by that range.
5974\(For an insertion, the pre-change length is zero;
5975for a deletion, that length is the number of bytes deleted,
5976and the post-change beginning and end are at the same place.)
5977
5978Buffer changes made while executing the `after-change-functions'
5979don't call any before-change or after-change functions.
5980That's because these variables are temporarily set to nil.
d765e3a3
JB
5981As a result, a hook function cannot straightforwardly alter the
5982value of these variables. See the Emacs Lisp manual for a way of
018ba359
PJ
5983accomplishing an equivalent result by using other variables.
5984
5985If an unhandled error happens in running these functions,
5986the variable's value remains nil. That prevents the error
5987from happening repeatedly and making Emacs nonfunctional. */);
5f079267
RS
5988 Vafter_change_functions = Qnil;
5989
7ee72033 5990 DEFVAR_LISP ("first-change-hook", &Vfirst_change_hook,
efc7e75f 5991 doc: /* A list of functions to call before changing a buffer which is unmodified.
018ba359 5992The functions are run using the `run-hooks' function. */);
dbc4e1c1 5993 Vfirst_change_hook = Qnil;
1ab256cb 5994
7ee72033
MB
5995 DEFVAR_PER_BUFFER ("buffer-undo-list", &current_buffer->undo_list, Qnil,
5996 doc: /* List of undo entries in current buffer.
018ba359
PJ
5997Recent changes come first; older changes follow newer.
5998
5999An entry (BEG . END) represents an insertion which begins at
6000position BEG and ends at position END.
6001
6002An entry (TEXT . POSITION) represents the deletion of the string TEXT
6003from (abs POSITION). If POSITION is positive, point was at the front
6004of the text being deleted; if negative, point was at the end.
6005
6006An entry (t HIGH . LOW) indicates that the buffer previously had
6007\"unmodified\" status. HIGH and LOW are the high and low 16-bit portions
6008of the visited file's modification time, as of that time. If the
6009modification time of the most recent save is different, this entry is
6010obsolete.
6011
6012An entry (nil PROPERTY VALUE BEG . END) indicates that a text property
6013was modified between BEG and END. PROPERTY is the property name,
6014and VALUE is the old value.
6015
7405f386
KS
6016An entry (apply FUN-NAME . ARGS) means undo the change with
6017\(apply FUN-NAME ARGS).
6018
6019An entry (apply DELTA BEG END FUN-NAME . ARGS) supports selective undo
6020in the active region. BEG and END is the range affected by this entry
6021and DELTA is the number of bytes added or deleted in that range by
6022this change.
c6c7dc03 6023
018ba359
PJ
6024An entry (MARKER . DISTANCE) indicates that the marker MARKER
6025was adjusted in position by the offset DISTANCE (an integer).
6026
6027An entry of the form POSITION indicates that point was at the buffer
6028location given by the integer. Undoing an entry of this form places
6029point at POSITION.
6030
b4c4f2f4
JB
6031Entries with value `nil' mark undo boundaries. The undo command treats
6032the changes between two undo boundaries as a single step to be undone.
018ba359
PJ
6033
6034If the value of the variable is t, undo information is not recorded. */);
6035
7ee72033
MB
6036 DEFVAR_PER_BUFFER ("mark-active", &current_buffer->mark_active, Qnil,
6037 doc: /* Non-nil means the mark and region are currently active in this buffer. */);
018ba359 6038
7ee72033
MB
6039 DEFVAR_PER_BUFFER ("cache-long-line-scans", &current_buffer->cache_long_line_scans, Qnil,
6040 doc: /* Non-nil means that Emacs should use caches to handle long lines more quickly.
018ba359
PJ
6041
6042Normally, the line-motion functions work by scanning the buffer for
5629f29b
DK
6043newlines. Columnar operations (like `move-to-column' and
6044`compute-motion') also work by scanning the buffer, summing character
018ba359
PJ
6045widths as they go. This works well for ordinary text, but if the
6046buffer's lines are very long (say, more than 500 characters), these
6047motion functions will take longer to execute. Emacs may also take
6048longer to update the display.
6049
5629f29b 6050If `cache-long-line-scans' is non-nil, these motion functions cache the
018ba359
PJ
6051results of their scans, and consult the cache to avoid rescanning
6052regions of the buffer until the text is modified. The caches are most
6053beneficial when they prevent the most searching---that is, when the
6054buffer contains long lines and large regions of characters with the
6055same, fixed screen width.
6056
5629f29b 6057When `cache-long-line-scans' is non-nil, processing short lines will
018ba359
PJ
6058become slightly slower (because of the overhead of consulting the
6059cache), and the caches will use memory roughly proportional to the
6060number of newlines and characters whose screen width varies.
6061
6062The caches require no explicit maintenance; their accuracy is
6063maintained internally by the Emacs primitives. Enabling or disabling
6064the cache should not affect the behavior of any of the motion
6065functions; it should only affect their performance. */);
6066
7ee72033
MB
6067 DEFVAR_PER_BUFFER ("point-before-scroll", &current_buffer->point_before_scroll, Qnil,
6068 doc: /* Value of point before the last series of scroll operations, or nil. */);
018ba359 6069
7ee72033
MB
6070 DEFVAR_PER_BUFFER ("buffer-file-format", &current_buffer->file_format, Qnil,
6071 doc: /* List of formats to use when saving this buffer.
018ba359 6072Formats are defined by `format-alist'. This variable is
a9b9a780 6073set when a file is visited. */);
be9aafdd 6074
71ed49fa
LT
6075 DEFVAR_PER_BUFFER ("buffer-auto-save-file-format",
6076 &current_buffer->auto_save_file_format, Qnil,
6077 doc: /* *Format in which to write auto-save files.
6078Should be a list of symbols naming formats that are defined in `format-alist'.
6079If it is t, which is the default, auto-save files are written in the
6080same format as a regular save would use. */);
6081
3cb719bd 6082 DEFVAR_PER_BUFFER ("buffer-invisibility-spec",
7ee72033
MB
6083 &current_buffer->invisibility_spec, Qnil,
6084 doc: /* Invisibility spec of this buffer.
018ba359
PJ
6085The default is t, which means that text is invisible
6086if it has a non-nil `invisible' property.
6087If the value is a list, a text character is invisible if its `invisible'
b49dd850 6088property is an element in that list (or is a list with members in common).
018ba359
PJ
6089If an element is a cons cell of the form (PROP . ELLIPSIS),
6090then characters with property value PROP are invisible,
6091and they have an ellipsis as well if ELLIPSIS is non-nil. */);
3cb719bd 6092
7962a441 6093 DEFVAR_PER_BUFFER ("buffer-display-count",
7ee72033
MB
6094 &current_buffer->display_count, Qnil,
6095 doc: /* A number incremented each time this buffer is displayed in a window.
018ba359 6096The function `set-window-buffer' increments it. */);
3fd364db
RS
6097
6098 DEFVAR_PER_BUFFER ("buffer-display-time",
7ee72033
MB
6099 &current_buffer->display_time, Qnil,
6100 doc: /* Time stamp updated each time this buffer is displayed in a window.
018ba359
PJ
6101The function `set-window-buffer' updates this variable
6102to the value obtained by calling `current-time'.
6103If the buffer has never been shown in a window, the value is nil. */);
6104
7ee72033 6105 DEFVAR_LISP ("transient-mark-mode", &Vtransient_mark_mode,
526c9df9 6106 doc: /* */);
c48f61ef 6107 Vtransient_mark_mode = Qnil;
526c9df9
CY
6108 /* The docstring is in simple.el. If we put it here, it would be
6109 overwritten when transient-mark-mode is defined using
6110 define-minor-mode. */
c48f61ef 6111
7ee72033
MB
6112 DEFVAR_LISP ("inhibit-read-only", &Vinhibit_read_only,
6113 doc: /* *Non-nil means disregard read-only status of buffers or characters.
018ba359
PJ
6114If the value is t, disregard `buffer-read-only' and all `read-only'
6115text properties. If the value is a list, disregard `buffer-read-only'
6116and disregard a `read-only' text property if the property value
6117is a member of the list. */);
a96b68f1
RS
6118 Vinhibit_read_only = Qnil;
6119
7ee72033 6120 DEFVAR_PER_BUFFER ("cursor-type", &current_buffer->cursor_type, Qnil,
f6e22881 6121 doc: /* Cursor to use when this buffer is in the selected window.
018ba359
PJ
6122Values are interpreted as follows:
6123
b8dc613f
JB
6124 t use the cursor specified for the frame
6125 nil don't display a cursor
6126 box display a filled box cursor
6127 hollow display a hollow box cursor
6128 bar display a vertical bar cursor with default width
6129 (bar . WIDTH) display a vertical bar cursor with width WIDTH
6130 hbar display a horizontal bar cursor with default height
b4234f4c 6131 (hbar . HEIGHT) display a horizontal bar cursor with height HEIGHT
b8dc613f 6132 ANYTHING ELSE display a hollow box cursor
cd8d5236 6133
e08b1705
MR
6134When the buffer is displayed in a non-selected window, the
6135cursor's appearance is instead controlled by the variable
6136`cursor-in-non-selected-windows'. */);
bb2ec976 6137
a3bbced0 6138 DEFVAR_PER_BUFFER ("line-spacing",
7ee72033
MB
6139 &current_buffer->extra_line_spacing, Qnil,
6140 doc: /* Additional space to put between lines when displaying a buffer.
3ba010e5
EZ
6141The space is measured in pixels, and put below lines on graphic displays,
6142see `display-graphic-p'.
60ebfdf3 6143If value is a floating point number, it specifies the spacing relative
fc961256 6144to the default frame line height. A value of nil means add no extra space. */);
a3bbced0 6145
0124c5bd 6146 DEFVAR_PER_BUFFER ("cursor-in-non-selected-windows",
187ccf49 6147 &current_buffer->cursor_in_non_selected_windows, Qnil,
f6e22881 6148 doc: /* *Cursor type to display in non-selected windows.
fc961256 6149The value t means to use hollow box cursor. See `cursor-type' for other values. */);
0124c5bd 6150
7ee72033 6151 DEFVAR_LISP ("kill-buffer-query-functions", &Vkill_buffer_query_functions,
f6e22881
JB
6152 doc: /* List of functions called with no args to query before killing a buffer.
6153The buffer being killed will be current while the functions are running.
6154If any of them returns nil, the buffer is not killed. */);
dcdffbf6
RS
6155 Vkill_buffer_query_functions = Qnil;
6156
43ed3b8d
CY
6157 DEFVAR_LISP ("change-major-mode-hook", &Vchange_major_mode_hook,
6158 doc: /* Normal hook run before changing the major mode of a buffer.
6159The function `kill-all-local-variables' runs this before doing anything else. */);
6160 Vchange_major_mode_hook = Qnil;
d67b4f80 6161 Qchange_major_mode_hook = intern_c_string ("change-major-mode-hook");
43ed3b8d
CY
6162 staticpro (&Qchange_major_mode_hook);
6163
0dc88e60 6164 defsubr (&Sbuffer_live_p);
1ab256cb
RM
6165 defsubr (&Sbuffer_list);
6166 defsubr (&Sget_buffer);
6167 defsubr (&Sget_file_buffer);
6168 defsubr (&Sget_buffer_create);
336cd056 6169 defsubr (&Smake_indirect_buffer);
01050cb5 6170 defsubr (&Sgenerate_new_buffer_name);
1ab256cb
RM
6171 defsubr (&Sbuffer_name);
6172/*defsubr (&Sbuffer_number);*/
6173 defsubr (&Sbuffer_file_name);
336cd056 6174 defsubr (&Sbuffer_base_buffer);
79aa712d 6175 defsubr (&Sbuffer_local_value);
1ab256cb
RM
6176 defsubr (&Sbuffer_local_variables);
6177 defsubr (&Sbuffer_modified_p);
6178 defsubr (&Sset_buffer_modified_p);
6179 defsubr (&Sbuffer_modified_tick);
3e145152 6180 defsubr (&Sbuffer_chars_modified_tick);
1ab256cb
RM
6181 defsubr (&Srename_buffer);
6182 defsubr (&Sother_buffer);
1ab256cb
RM
6183 defsubr (&Sbuffer_enable_undo);
6184 defsubr (&Skill_buffer);
a9ee7a59 6185 defsubr (&Sset_buffer_major_mode);
1ab256cb 6186 defsubr (&Sswitch_to_buffer);
1ab256cb
RM
6187 defsubr (&Scurrent_buffer);
6188 defsubr (&Sset_buffer);
6189 defsubr (&Sbarf_if_buffer_read_only);
6190 defsubr (&Sbury_buffer);
3ac81adb 6191 defsubr (&Serase_buffer);
13cda5f9 6192 defsubr (&Sbuffer_swap_text);
3ac81adb 6193 defsubr (&Sset_buffer_multibyte);
1ab256cb 6194 defsubr (&Skill_all_local_variables);
2eec3b4e 6195
52f8ec73 6196 defsubr (&Soverlayp);
2eec3b4e
RS
6197 defsubr (&Smake_overlay);
6198 defsubr (&Sdelete_overlay);
6199 defsubr (&Smove_overlay);
8ebafa8d
JB
6200 defsubr (&Soverlay_start);
6201 defsubr (&Soverlay_end);
6202 defsubr (&Soverlay_buffer);
6203 defsubr (&Soverlay_properties);
2eec3b4e 6204 defsubr (&Soverlays_at);
74514898 6205 defsubr (&Soverlays_in);
2eec3b4e 6206 defsubr (&Snext_overlay_change);
239c932b 6207 defsubr (&Sprevious_overlay_change);
2eec3b4e
RS
6208 defsubr (&Soverlay_recenter);
6209 defsubr (&Soverlay_lists);
6210 defsubr (&Soverlay_get);
6211 defsubr (&Soverlay_put);
a8c21b48 6212 defsubr (&Srestore_buffer_modified_p);
1ab256cb
RM
6213}
6214
dfcf069d 6215void
d3da34e0 6216keys_of_buffer (void)
1ab256cb
RM
6217{
6218 initial_define_key (control_x_map, 'b', "switch-to-buffer");
6219 initial_define_key (control_x_map, 'k', "kill-buffer");
4158c17d
RM
6220
6221 /* This must not be in syms_of_buffer, because Qdisabled is not
6222 initialized when that function gets called. */
d67b4f80 6223 Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt);
1ab256cb 6224}
6b61353c
KH
6225
6226/* arch-tag: e48569bf-69a9-4b65-a23b-8e68769436e1
6227 (do not change this comment) */