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