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