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