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