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