(x_display_cursor, process_expose_from_menu): Block input.
[bpt/emacs.git] / src / buffer.c
CommitLineData
1ab256cb 1/* Buffer manipulation primitives for GNU Emacs.
4158c17d 2 Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994
c922bc55 3 Free Software Foundation, Inc.
1ab256cb
RM
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
c922bc55 9the Free Software Foundation; either version 2, or (at your option)
1ab256cb
RM
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21
2381d133
JB
22#include <sys/types.h>
23#include <sys/stat.h>
1ab256cb
RM
24#include <sys/param.h>
25
26#ifndef MAXPATHLEN
27/* in 4.1, param.h fails to define this. */
28#define MAXPATHLEN 1024
29#endif /* not MAXPATHLEN */
30
18160b98 31#include <config.h>
1ab256cb 32#include "lisp.h"
21cf4cf8 33#include "intervals.h"
1ab256cb
RM
34#include "window.h"
35#include "commands.h"
36#include "buffer.h"
1ab256cb 37#include "indent.h"
d014bf88 38#include "blockinput.h"
1ab256cb
RM
39
40struct buffer *current_buffer; /* the current buffer */
41
42/* First buffer in chain of all buffers (in reverse order of creation).
43 Threaded through ->next. */
44
45struct buffer *all_buffers;
46
47/* This structure holds the default values of the buffer-local variables
48 defined with DEFVAR_PER_BUFFER, that have special slots in each buffer.
49 The default value occupies the same slot in this structure
50 as an individual buffer's value occupies in that buffer.
51 Setting the default value also goes through the alist of buffers
52 and stores into each buffer that does not say it has a local value. */
53
54struct buffer buffer_defaults;
55
56/* A Lisp_Object pointer to the above, used for staticpro */
57
58static Lisp_Object Vbuffer_defaults;
59
60/* This structure marks which slots in a buffer have corresponding
61 default values in buffer_defaults.
62 Each such slot has a nonzero value in this structure.
63 The value has only one nonzero bit.
64
65 When a buffer has its own local value for a slot,
66 the bit for that slot (found in the same slot in this structure)
67 is turned on in the buffer's local_var_flags slot.
68
69 If a slot in this structure is -1, then even though there may
70 be a DEFVAR_PER_BUFFER for the slot, there is no default value for it;
71 and the corresponding slot in buffer_defaults is not used.
72
73 If a slot is -2, then there is no DEFVAR_PER_BUFFER for it,
74 but there is a default value which is copied into each buffer.
75
76 If a slot in this structure is negative, then even though there may
77 be a DEFVAR_PER_BUFFER for the slot, there is no default value for it;
78 and the corresponding slot in buffer_defaults is not used.
79
80 If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is
81 zero, that is a bug */
82
83struct buffer buffer_local_flags;
84
85/* This structure holds the names of symbols whose values may be
86 buffer-local. It is indexed and accessed in the same way as the above. */
87
88struct buffer buffer_local_symbols;
89/* A Lisp_Object pointer to the above, used for staticpro */
90static Lisp_Object Vbuffer_local_symbols;
91
0fa3ba92
JB
92/* This structure holds the required types for the values in the
93 buffer-local slots. If a slot contains Qnil, then the
94 corresponding buffer slot may contain a value of any type. If a
95 slot contains an integer, then prospective values' tags must be
96 equal to that integer. When a tag does not match, the function
97 buffer_slot_type_mismatch will signal an error. */
98struct buffer buffer_local_types;
99
1ab256cb 100Lisp_Object Fset_buffer ();
01050cb5 101void set_buffer_internal ();
173f2a64 102static void call_overlay_mod_hooks ();
1ab256cb
RM
103
104/* Alist of all buffer names vs the buffers. */
105/* This used to be a variable, but is no longer,
106 to prevent lossage due to user rplac'ing this alist or its elements. */
107Lisp_Object Vbuffer_alist;
108
109/* Functions to call before and after each text change. */
110Lisp_Object Vbefore_change_function;
111Lisp_Object Vafter_change_function;
112
c48f61ef
RS
113Lisp_Object Vtransient_mark_mode;
114
a96b68f1
RS
115/* t means ignore all read-only text properties.
116 A list means ignore such a property if its value is a member of the list.
117 Any non-nil value means ignore buffer-read-only. */
118Lisp_Object Vinhibit_read_only;
119
dbc4e1c1
JB
120/* List of functions to call before changing an unmodified buffer. */
121Lisp_Object Vfirst_change_hook;
122Lisp_Object Qfirst_change_hook;
1ab256cb
RM
123
124Lisp_Object Qfundamental_mode, Qmode_class, Qpermanent_local;
125
126Lisp_Object Qprotected_field;
127
128Lisp_Object QSFundamental; /* A string "Fundamental" */
129
130Lisp_Object Qkill_buffer_hook;
131
5fe0b67e
RS
132Lisp_Object Qget_file_buffer;
133
52f8ec73
JB
134Lisp_Object Qoverlayp;
135
5985d248
KH
136Lisp_Object Qpriority, Qwindow;
137
294d215f
RS
138Lisp_Object Qmodification_hooks;
139Lisp_Object Qinsert_in_front_hooks;
140Lisp_Object Qinsert_behind_hooks;
141
1ab256cb
RM
142/* For debugging; temporary. See set_buffer_internal. */
143/* Lisp_Object Qlisp_mode, Vcheck_symbol; */
144
54ad07d3
RS
145#ifdef MSDOS
146Lisp_Object Qbuffer_file_type;
147#endif
148
1ab256cb
RM
149nsberror (spec)
150 Lisp_Object spec;
151{
152 if (XTYPE (spec) == Lisp_String)
153 error ("No buffer named %s", XSTRING (spec)->data);
154 error ("Invalid buffer argument");
155}
156\f
157DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 0, 0,
158 "Return a list of all existing live buffers.")
159 ()
160{
161 return Fmapcar (Qcdr, Vbuffer_alist);
162}
163
164DEFUN ("get-buffer", Fget_buffer, Sget_buffer, 1, 1, 0,
165 "Return the buffer named NAME (a string).\n\
166If there is no live buffer named NAME, return nil.\n\
167NAME may also be a buffer; if so, the value is that buffer.")
168 (name)
169 register Lisp_Object name;
170{
171 if (XTYPE (name) == Lisp_Buffer)
172 return name;
173 CHECK_STRING (name, 0);
174
175 return Fcdr (Fassoc (name, Vbuffer_alist));
176}
177
178DEFUN ("get-file-buffer", Fget_file_buffer, Sget_file_buffer, 1, 1, 0,
179 "Return the buffer visiting file FILENAME (a string).\n\
180If there is no such live buffer, return nil.")
181 (filename)
182 register Lisp_Object filename;
183{
184 register Lisp_Object tail, buf, tem;
5fe0b67e
RS
185 Lisp_Object handler;
186
1ab256cb
RM
187 CHECK_STRING (filename, 0);
188 filename = Fexpand_file_name (filename, Qnil);
189
5fe0b67e
RS
190 /* If the file name has special constructs in it,
191 call the corresponding file handler. */
192 handler = Ffind_file_name_handler (filename);
193 if (!NILP (handler))
194 return call2 (handler, Qget_file_buffer, filename);
195
1ab256cb
RM
196 for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
197 {
198 buf = Fcdr (XCONS (tail)->car);
199 if (XTYPE (buf) != Lisp_Buffer) continue;
200 if (XTYPE (XBUFFER (buf)->filename) != Lisp_String) continue;
201 tem = Fstring_equal (XBUFFER (buf)->filename, filename);
265a9e55 202 if (!NILP (tem))
1ab256cb
RM
203 return buf;
204 }
205 return Qnil;
206}
207
208/* Incremented for each buffer created, to assign the buffer number. */
209int buffer_count;
210
211DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 1, 0,
212 "Return the buffer named NAME, or create such a buffer and return it.\n\
213A new buffer is created if there is no live buffer named NAME.\n\
b44895bc 214If NAME starts with a space, the new buffer does not keep undo information.\n\
1ab256cb
RM
215If NAME is a buffer instead of a string, then it is the value returned.\n\
216The value is never nil.")
217 (name)
218 register Lisp_Object name;
219{
220 register Lisp_Object buf, function, tem;
221 int count = specpdl_ptr - specpdl;
222 register struct buffer *b;
223
224 buf = Fget_buffer (name);
265a9e55 225 if (!NILP (buf))
1ab256cb
RM
226 return buf;
227
9ac0d9e0 228 b = (struct buffer *) xmalloc (sizeof (struct buffer));
1ab256cb
RM
229
230 BUF_GAP_SIZE (b) = 20;
9ac0d9e0 231 BLOCK_INPUT;
1ab256cb 232 BUFFER_ALLOC (BUF_BEG_ADDR (b), BUF_GAP_SIZE (b));
9ac0d9e0 233 UNBLOCK_INPUT;
1ab256cb
RM
234 if (! BUF_BEG_ADDR (b))
235 memory_full ();
236
237 BUF_PT (b) = 1;
238 BUF_GPT (b) = 1;
239 BUF_BEGV (b) = 1;
240 BUF_ZV (b) = 1;
241 BUF_Z (b) = 1;
242 BUF_MODIFF (b) = 1;
243
244 /* Put this on the chain of all buffers including killed ones. */
245 b->next = all_buffers;
246 all_buffers = b;
247
248 b->mark = Fmake_marker ();
249 /*b->number = make_number (++buffer_count);*/
250 b->name = name;
251 if (XSTRING (name)->data[0] != ' ')
252 b->undo_list = Qnil;
253 else
254 b->undo_list = Qt;
255
256 reset_buffer (b);
257
258 /* Put this in the alist of all live buffers. */
259 XSET (buf, Lisp_Buffer, b);
260 Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil));
261
262 b->mark = Fmake_marker ();
263 b->markers = Qnil;
264 b->name = name;
265
266 function = buffer_defaults.major_mode;
265a9e55 267 if (NILP (function))
1ab256cb
RM
268 {
269 tem = Fget (current_buffer->major_mode, Qmode_class);
270 if (EQ (tem, Qnil))
271 function = current_buffer->major_mode;
272 }
273
265a9e55 274 if (NILP (function) || EQ (function, Qfundamental_mode))
1ab256cb
RM
275 return buf;
276
277 /* To select a nonfundamental mode,
278 select the buffer temporarily and then call the mode function. */
279
280 record_unwind_protect (save_excursion_restore, save_excursion_save ());
281
282 Fset_buffer (buf);
283 call0 (function);
284
285 return unbind_to (count, buf);
286}
287
288/* Reinitialize everything about a buffer except its name and contents. */
289
290void
291reset_buffer (b)
292 register struct buffer *b;
293{
294 b->filename = Qnil;
295 b->directory = (current_buffer) ? current_buffer->directory : Qnil;
296 b->modtime = 0;
297 b->save_modified = 1;
291026b5 298 XFASTINT (b->save_length) = 0;
1ab256cb
RM
299 b->last_window_start = 1;
300 b->backed_up = Qnil;
301 b->auto_save_modified = 0;
302 b->auto_save_file_name = Qnil;
303 b->read_only = Qnil;
2eec3b4e
RS
304 b->overlays_before = Qnil;
305 b->overlays_after = Qnil;
306 XFASTINT (b->overlay_center) = 1;
dfda7a7f 307 b->mark_active = Qnil;
33f7013e
JA
308
309 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
310 INITIALIZE_INTERVAL (b, NULL_INTERVAL);
311
1ab256cb
RM
312 reset_buffer_local_variables(b);
313}
314
c48f61ef 315reset_buffer_local_variables (b)
1ab256cb
RM
316 register struct buffer *b;
317{
318 register int offset;
319
320 /* Reset the major mode to Fundamental, together with all the
321 things that depend on the major mode.
322 default-major-mode is handled at a higher level.
323 We ignore it here. */
324 b->major_mode = Qfundamental_mode;
325 b->keymap = Qnil;
326 b->abbrev_table = Vfundamental_mode_abbrev_table;
327 b->mode_name = QSFundamental;
328 b->minor_modes = Qnil;
329 b->downcase_table = Vascii_downcase_table;
330 b->upcase_table = Vascii_upcase_table;
331 b->case_canon_table = Vascii_downcase_table;
332 b->case_eqv_table = Vascii_upcase_table;
333#if 0
334 b->sort_table = XSTRING (Vascii_sort_table);
335 b->folding_sort_table = XSTRING (Vascii_folding_sort_table);
336#endif /* 0 */
337
338 /* Reset all per-buffer variables to their defaults. */
339 b->local_var_alist = Qnil;
340 b->local_var_flags = 0;
341
342 /* For each slot that has a default value,
343 copy that into the slot. */
344
345 for (offset = (char *)&buffer_local_flags.name - (char *)&buffer_local_flags;
346 offset < sizeof (struct buffer);
347 offset += sizeof (Lisp_Object)) /* sizeof int == sizeof Lisp_Object */
348 if (*(int *)(offset + (char *) &buffer_local_flags) > 0
349 || *(int *)(offset + (char *) &buffer_local_flags) == -2)
350 *(Lisp_Object *)(offset + (char *)b) =
351 *(Lisp_Object *)(offset + (char *)&buffer_defaults);
352}
353
01050cb5
RM
354/* We split this away from generate-new-buffer, because rename-buffer
355 and set-visited-file-name ought to be able to use this to really
356 rename the buffer properly. */
357
358DEFUN ("generate-new-buffer-name", Fgenerate_new_buffer_name, Sgenerate_new_buffer_name,
c273e647 359 1, 2, 0,
01050cb5
RM
360 "Return a string that is the name of no existing buffer based on NAME.\n\
361If there is no live buffer named NAME, then return NAME.\n\
1ab256cb 362Otherwise modify name by appending `<NUMBER>', incrementing NUMBER\n\
c273e647 363until an unused name is found, and then return that name.\n\
03bdd54c 364Optional second argument IGNORE specifies a name that is okay to use\n\
c273e647 365\(if it is in the sequence to be tried)\n\
e8b3a22d 366even if a buffer with that name exists.")
c273e647
RS
367 (name, ignore)
368 register Lisp_Object name, ignore;
1ab256cb
RM
369{
370 register Lisp_Object gentemp, tem;
371 int count;
372 char number[10];
373
374 CHECK_STRING (name, 0);
375
376 tem = Fget_buffer (name);
265a9e55 377 if (NILP (tem))
01050cb5 378 return name;
1ab256cb
RM
379
380 count = 1;
381 while (1)
382 {
383 sprintf (number, "<%d>", ++count);
384 gentemp = concat2 (name, build_string (number));
638e4fc3 385 tem = Fstring_equal (gentemp, ignore);
c273e647
RS
386 if (!NILP (tem))
387 return gentemp;
1ab256cb 388 tem = Fget_buffer (gentemp);
265a9e55 389 if (NILP (tem))
01050cb5 390 return gentemp;
1ab256cb
RM
391 }
392}
393
394\f
395DEFUN ("buffer-name", Fbuffer_name, Sbuffer_name, 0, 1, 0,
396 "Return the name of BUFFER, as a string.\n\
01050cb5 397With no argument or nil as argument, return the name of the current buffer.")
1ab256cb
RM
398 (buffer)
399 register Lisp_Object buffer;
400{
265a9e55 401 if (NILP (buffer))
1ab256cb
RM
402 return current_buffer->name;
403 CHECK_BUFFER (buffer, 0);
404 return XBUFFER (buffer)->name;
405}
406
407DEFUN ("buffer-file-name", Fbuffer_file_name, Sbuffer_file_name, 0, 1, 0,
408 "Return name of file BUFFER is visiting, or nil if none.\n\
409No argument or nil as argument means use the current buffer.")
410 (buffer)
411 register Lisp_Object buffer;
412{
265a9e55 413 if (NILP (buffer))
1ab256cb
RM
414 return current_buffer->filename;
415 CHECK_BUFFER (buffer, 0);
416 return XBUFFER (buffer)->filename;
417}
418
419DEFUN ("buffer-local-variables", Fbuffer_local_variables,
420 Sbuffer_local_variables, 0, 1, 0,
421 "Return an alist of variables that are buffer-local in BUFFER.\n\
553defa4
RS
422Most elements look like (SYMBOL . VALUE), describing one variable.\n\
423For a symbol that is locally unbound, just the symbol appears in the value.\n\
1ab256cb
RM
424Note that storing new VALUEs in these elements doesn't change the variables.\n\
425No argument or nil as argument means use current buffer as BUFFER.")
426 (buffer)
427 register Lisp_Object buffer;
428{
429 register struct buffer *buf;
553defa4 430 register Lisp_Object result;
1ab256cb 431
265a9e55 432 if (NILP (buffer))
1ab256cb
RM
433 buf = current_buffer;
434 else
435 {
436 CHECK_BUFFER (buffer, 0);
437 buf = XBUFFER (buffer);
438 }
439
553defa4
RS
440 result = Qnil;
441
1ab256cb
RM
442 {
443 /* Reference each variable in the alist in our current buffer.
444 If inquiring about the current buffer, this gets the current values,
445 so store them into the alist so the alist is up to date.
446 If inquiring about some other buffer, this swaps out any values
447 for that buffer, making the alist up to date automatically. */
553defa4
RS
448 register Lisp_Object tail;
449 for (tail = buf->local_var_alist; CONSP (tail); tail = XCONS (tail)->cdr)
1ab256cb 450 {
553defa4
RS
451 Lisp_Object val, elt;
452
453 elt = XCONS (tail)->car;
454
1ab256cb 455 if (buf == current_buffer)
553defa4
RS
456 val = find_symbol_value (XCONS (elt)->car);
457 else
458 val = XCONS (elt)->cdr;
459
460 /* If symbol is unbound, put just the symbol in the list. */
461 if (EQ (val, Qunbound))
462 result = Fcons (XCONS (elt)->car, result);
463 /* Otherwise, put (symbol . value) in the list. */
464 else
465 result = Fcons (Fcons (XCONS (elt)->car, val), result);
1ab256cb
RM
466 }
467 }
468
1ab256cb
RM
469 /* Add on all the variables stored in special slots. */
470 {
471 register int offset, mask;
472
473 for (offset = (char *)&buffer_local_symbols.name - (char *)&buffer_local_symbols;
474 offset < sizeof (struct buffer);
475 offset += (sizeof (int))) /* sizeof int == sizeof Lisp_Object */
476 {
477 mask = *(int *)(offset + (char *) &buffer_local_flags);
478 if (mask == -1 || (buf->local_var_flags & mask))
479 if (XTYPE (*(Lisp_Object *)(offset + (char *)&buffer_local_symbols))
480 == Lisp_Symbol)
553defa4
RS
481 result = Fcons (Fcons (*(Lisp_Object *)(offset + (char *)&buffer_local_symbols),
482 *(Lisp_Object *)(offset + (char *)buf)),
483 result);
1ab256cb
RM
484 }
485 }
553defa4
RS
486
487 return result;
1ab256cb
RM
488}
489
490\f
491DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p,
492 0, 1, 0,
493 "Return t if BUFFER was modified since its file was last read or saved.\n\
494No argument or nil as argument means use current buffer as BUFFER.")
495 (buffer)
496 register Lisp_Object buffer;
497{
498 register struct buffer *buf;
265a9e55 499 if (NILP (buffer))
1ab256cb
RM
500 buf = current_buffer;
501 else
502 {
503 CHECK_BUFFER (buffer, 0);
504 buf = XBUFFER (buffer);
505 }
506
507 return buf->save_modified < BUF_MODIFF (buf) ? Qt : Qnil;
508}
509
510DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p,
511 1, 1, 0,
512 "Mark current buffer as modified or unmodified according to FLAG.\n\
513A non-nil FLAG means mark the buffer modified.")
514 (flag)
515 register Lisp_Object flag;
516{
517 register int already;
518 register Lisp_Object fn;
519
520#ifdef CLASH_DETECTION
521 /* If buffer becoming modified, lock the file.
522 If buffer becoming unmodified, unlock the file. */
523
524 fn = current_buffer->filename;
265a9e55 525 if (!NILP (fn))
1ab256cb
RM
526 {
527 already = current_buffer->save_modified < MODIFF;
265a9e55 528 if (!already && !NILP (flag))
1ab256cb 529 lock_file (fn);
265a9e55 530 else if (already && NILP (flag))
1ab256cb
RM
531 unlock_file (fn);
532 }
533#endif /* CLASH_DETECTION */
534
265a9e55 535 current_buffer->save_modified = NILP (flag) ? MODIFF : 0;
1ab256cb
RM
536 update_mode_lines++;
537 return flag;
538}
539
540DEFUN ("buffer-modified-tick", Fbuffer_modified_tick, Sbuffer_modified_tick,
541 0, 1, 0,
542 "Return BUFFER's tick counter, incremented for each change in text.\n\
543Each buffer has a tick counter which is incremented each time the text in\n\
544that buffer is changed. It wraps around occasionally.\n\
545No argument or nil as argument means use current buffer as BUFFER.")
546 (buffer)
547 register Lisp_Object buffer;
548{
549 register struct buffer *buf;
265a9e55 550 if (NILP (buffer))
1ab256cb
RM
551 buf = current_buffer;
552 else
553 {
554 CHECK_BUFFER (buffer, 0);
555 buf = XBUFFER (buffer);
556 }
557
558 return make_number (BUF_MODIFF (buf));
559}
560\f
01050cb5 561DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2,
4c7e5f09 562 "sRename buffer (to new name): \nP",
1ab256cb 563 "Change current buffer's name to NEWNAME (a string).\n\
3bd779aa 564If second arg UNIQUE is nil or omitted, it is an error if a\n\
01050cb5 565buffer named NEWNAME already exists.\n\
3bd779aa 566If UNIQUE is non-nil, come up with a new name using\n\
01050cb5 567`generate-new-buffer-name'.\n\
3bd779aa
RS
568Interactively, you can set UNIQUE with a prefix argument.\n\
569We return the name we actually gave the buffer.\n\
1ab256cb 570This does not change the name of the visited file (if any).")
3bd779aa
RS
571 (name, unique)
572 register Lisp_Object name, unique;
1ab256cb
RM
573{
574 register Lisp_Object tem, buf;
575
576 CHECK_STRING (name, 0);
577 tem = Fget_buffer (name);
c059b5ea
RM
578 /* Don't short-circuit if UNIQUE is t. That is a useful way to rename
579 the buffer automatically so you can create another with the original name.
580 It makes UNIQUE equivalent to
581 (rename-buffer (generate-new-buffer-name NAME)). */
582 if (NILP (unique) && XBUFFER (tem) == current_buffer)
01050cb5 583 return current_buffer->name;
265a9e55 584 if (!NILP (tem))
01050cb5 585 {
3bd779aa 586 if (!NILP (unique))
c273e647 587 name = Fgenerate_new_buffer_name (name, current_buffer->name);
01050cb5
RM
588 else
589 error ("Buffer name \"%s\" is in use", XSTRING (name)->data);
590 }
1ab256cb
RM
591
592 current_buffer->name = name;
76f590d7
JB
593
594 /* Catch redisplay's attention. Unless we do this, the mode lines for
595 any windows displaying current_buffer will stay unchanged. */
596 update_mode_lines++;
597
1ab256cb
RM
598 XSET (buf, Lisp_Buffer, current_buffer);
599 Fsetcar (Frassq (buf, Vbuffer_alist), name);
265a9e55 600 if (NILP (current_buffer->filename) && !NILP (current_buffer->auto_save_file_name))
1ab256cb 601 call0 (intern ("rename-auto-save-file"));
01050cb5 602 return name;
1ab256cb
RM
603}
604
a0ebb746 605DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 2, 0,
1ab256cb 606 "Return most recently selected buffer other than BUFFER.\n\
a0ebb746
JB
607Buffers not visible in windows are preferred to visible buffers,\n\
608unless optional second argument VISIBLE-OK is non-nil.\n\
1ab256cb
RM
609If no other buffer exists, the buffer `*scratch*' is returned.\n\
610If BUFFER is omitted or nil, some interesting buffer is returned.")
a0ebb746
JB
611 (buffer, visible_ok)
612 register Lisp_Object buffer, visible_ok;
1ab256cb
RM
613{
614 register Lisp_Object tail, buf, notsogood, tem;
615 notsogood = Qnil;
616
265a9e55 617 for (tail = Vbuffer_alist; !NILP (tail); tail = Fcdr (tail))
1ab256cb
RM
618 {
619 buf = Fcdr (Fcar (tail));
620 if (EQ (buf, buffer))
621 continue;
622 if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
623 continue;
a0ebb746 624 if (NILP (visible_ok))
db732e5a 625 tem = Fget_buffer_window (buf, Qt);
a0ebb746
JB
626 else
627 tem = Qnil;
265a9e55 628 if (NILP (tem))
1ab256cb 629 return buf;
265a9e55 630 if (NILP (notsogood))
1ab256cb
RM
631 notsogood = buf;
632 }
265a9e55 633 if (!NILP (notsogood))
1ab256cb
RM
634 return notsogood;
635 return Fget_buffer_create (build_string ("*scratch*"));
636}
637\f
5b8bcf48 638DEFUN ("buffer-disable-undo", Fbuffer_disable_undo, Sbuffer_disable_undo, 0, 1,
1ab256cb 6390,
5b8bcf48
RS
640 "Make BUFFER stop keeping undo information.\n\
641No argument or nil as argument means do this for the current buffer.")
ffd56f97
JB
642 (buffer)
643 register Lisp_Object buffer;
1ab256cb 644{
ffd56f97
JB
645 Lisp_Object real_buffer;
646
647 if (NILP (buffer))
648 XSET (real_buffer, Lisp_Buffer, current_buffer);
649 else
650 {
651 real_buffer = Fget_buffer (buffer);
652 if (NILP (real_buffer))
653 nsberror (buffer);
654 }
655
656 XBUFFER (real_buffer)->undo_list = Qt;
657
1ab256cb
RM
658 return Qnil;
659}
660
661DEFUN ("buffer-enable-undo", Fbuffer_enable_undo, Sbuffer_enable_undo,
662 0, 1, "",
663 "Start keeping undo information for buffer BUFFER.\n\
664No argument or nil as argument means do this for the current buffer.")
ffd56f97
JB
665 (buffer)
666 register Lisp_Object buffer;
1ab256cb 667{
ffd56f97 668 Lisp_Object real_buffer;
1ab256cb 669
ffd56f97
JB
670 if (NILP (buffer))
671 XSET (real_buffer, Lisp_Buffer, current_buffer);
1ab256cb
RM
672 else
673 {
ffd56f97
JB
674 real_buffer = Fget_buffer (buffer);
675 if (NILP (real_buffer))
676 nsberror (buffer);
1ab256cb
RM
677 }
678
ffd56f97
JB
679 if (EQ (XBUFFER (real_buffer)->undo_list, Qt))
680 XBUFFER (real_buffer)->undo_list = Qnil;
1ab256cb
RM
681
682 return Qnil;
683}
684
685/*
686 DEFVAR_LISP ("kill-buffer-hook", no_cell, "\
687Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\
688The buffer being killed will be current while the hook is running.\n\
689See `kill-buffer'."
690 */
691DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 1, 1, "bKill buffer: ",
692 "Kill the buffer BUFFER.\n\
693The argument may be a buffer or may be the name of a buffer.\n\
694An argument of nil means kill the current buffer.\n\n\
695Value is t if the buffer is actually killed, nil if user says no.\n\n\
696The value of `kill-buffer-hook' (which may be local to that buffer),\n\
697if not void, is a list of functions to be called, with no arguments,\n\
698before the buffer is actually killed. The buffer to be killed is current\n\
699when the hook functions are called.\n\n\
700Any processes that have this buffer as the `process-buffer' are killed\n\
701with `delete-process'.")
702 (bufname)
703 Lisp_Object bufname;
704{
705 Lisp_Object buf;
706 register struct buffer *b;
707 register Lisp_Object tem;
708 register struct Lisp_Marker *m;
709 struct gcpro gcpro1, gcpro2;
710
265a9e55 711 if (NILP (bufname))
1ab256cb
RM
712 buf = Fcurrent_buffer ();
713 else
714 buf = Fget_buffer (bufname);
265a9e55 715 if (NILP (buf))
1ab256cb
RM
716 nsberror (bufname);
717
718 b = XBUFFER (buf);
719
720 /* Query if the buffer is still modified. */
265a9e55 721 if (INTERACTIVE && !NILP (b->filename)
1ab256cb
RM
722 && BUF_MODIFF (b) > b->save_modified)
723 {
724 GCPRO2 (buf, bufname);
725 tem = do_yes_or_no_p (format1 ("Buffer %s modified; kill anyway? ",
726 XSTRING (b->name)->data));
727 UNGCPRO;
265a9e55 728 if (NILP (tem))
1ab256cb
RM
729 return Qnil;
730 }
731
732 /* Run kill-buffer hook with the buffer to be killed the current buffer. */
733 {
734 register Lisp_Object val;
735 int count = specpdl_ptr - specpdl;
736
737 record_unwind_protect (save_excursion_restore, save_excursion_save ());
738 set_buffer_internal (b);
739 call1 (Vrun_hooks, Qkill_buffer_hook);
740 unbind_to (count, Qnil);
741 }
742
743 /* We have no more questions to ask. Verify that it is valid
744 to kill the buffer. This must be done after the questions
745 since anything can happen within do_yes_or_no_p. */
746
747 /* Don't kill the minibuffer now current. */
748 if (EQ (buf, XWINDOW (minibuf_window)->buffer))
749 return Qnil;
750
265a9e55 751 if (NILP (b->name))
1ab256cb
RM
752 return Qnil;
753
754 /* Make this buffer not be current.
755 In the process, notice if this is the sole visible buffer
756 and give up if so. */
757 if (b == current_buffer)
758 {
172a9c1f 759 tem = Fother_buffer (buf, Qnil);
1ab256cb
RM
760 Fset_buffer (tem);
761 if (b == current_buffer)
762 return Qnil;
763 }
764
765 /* Now there is no question: we can kill the buffer. */
766
767#ifdef CLASH_DETECTION
768 /* Unlock this buffer's file, if it is locked. */
769 unlock_buffer (b);
770#endif /* CLASH_DETECTION */
771
1ab256cb 772 kill_buffer_processes (buf);
1ab256cb
RM
773
774 tem = Vinhibit_quit;
775 Vinhibit_quit = Qt;
776 Vbuffer_alist = Fdelq (Frassq (buf, Vbuffer_alist), Vbuffer_alist);
777 Freplace_buffer_in_windows (buf);
778 Vinhibit_quit = tem;
779
780 /* Delete any auto-save file. */
781 if (XTYPE (b->auto_save_file_name) == Lisp_String)
782 {
783 Lisp_Object tem;
784 tem = Fsymbol_value (intern ("delete-auto-save-files"));
265a9e55 785 if (! NILP (tem))
1ab256cb
RM
786 unlink (XSTRING (b->auto_save_file_name)->data);
787 }
788
789 /* Unchain all markers of this buffer
790 and leave them pointing nowhere. */
791 for (tem = b->markers; !EQ (tem, Qnil); )
792 {
793 m = XMARKER (tem);
794 m->buffer = 0;
795 tem = m->chain;
796 m->chain = Qnil;
797 }
798 b->markers = Qnil;
799
33f7013e
JA
800 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
801 INITIALIZE_INTERVAL (b, NULL_INTERVAL);
802 /* Perhaps we should explicitly free the interval tree here... */
803
1ab256cb 804 b->name = Qnil;
9ac0d9e0 805 BLOCK_INPUT;
1ab256cb 806 BUFFER_FREE (BUF_BEG_ADDR (b));
9ac0d9e0 807 UNBLOCK_INPUT;
1ab256cb
RM
808 b->undo_list = Qnil;
809
810 return Qt;
811}
812\f
36a8c287
JB
813/* Move the assoc for buffer BUF to the front of buffer-alist. Since
814 we do this each time BUF is selected visibly, the more recently
815 selected buffers are always closer to the front of the list. This
816 means that other_buffer is more likely to choose a relevant buffer. */
1ab256cb
RM
817
818record_buffer (buf)
819 Lisp_Object buf;
820{
821 register Lisp_Object link, prev;
822
823 prev = Qnil;
824 for (link = Vbuffer_alist; CONSP (link); link = XCONS (link)->cdr)
825 {
826 if (EQ (XCONS (XCONS (link)->car)->cdr, buf))
827 break;
828 prev = link;
829 }
830
36a8c287
JB
831 /* Effectively do Vbuffer_alist = Fdelq (link, Vbuffer_alist);
832 we cannot use Fdelq itself here because it allows quitting. */
1ab256cb 833
265a9e55 834 if (NILP (prev))
1ab256cb
RM
835 Vbuffer_alist = XCONS (Vbuffer_alist)->cdr;
836 else
837 XCONS (prev)->cdr = XCONS (XCONS (prev)->cdr)->cdr;
838
839 XCONS(link)->cdr = Vbuffer_alist;
840 Vbuffer_alist = link;
841}
842
843DEFUN ("switch-to-buffer", Fswitch_to_buffer, Sswitch_to_buffer, 1, 2, "BSwitch to buffer: ",
844 "Select buffer BUFFER in the current window.\n\
845BUFFER may be a buffer or a buffer name.\n\
846Optional second arg NORECORD non-nil means\n\
847do not put this buffer at the front of the list of recently selected ones.\n\
848\n\
849WARNING: This is NOT the way to work on another buffer temporarily\n\
850within a Lisp program! Use `set-buffer' instead. That avoids messing with\n\
851the window-buffer correspondences.")
852 (bufname, norecord)
853 Lisp_Object bufname, norecord;
854{
855 register Lisp_Object buf;
856 Lisp_Object tem;
857
858 if (EQ (minibuf_window, selected_window))
859 error ("Cannot switch buffers in minibuffer window");
860 tem = Fwindow_dedicated_p (selected_window);
265a9e55 861 if (!NILP (tem))
1ab256cb
RM
862 error ("Cannot switch buffers in a dedicated window");
863
265a9e55 864 if (NILP (bufname))
172a9c1f 865 buf = Fother_buffer (Fcurrent_buffer (), Qnil);
1ab256cb
RM
866 else
867 buf = Fget_buffer_create (bufname);
868 Fset_buffer (buf);
265a9e55 869 if (NILP (norecord))
1ab256cb
RM
870 record_buffer (buf);
871
872 Fset_window_buffer (EQ (selected_window, minibuf_window)
5fcd022d
JB
873 ? Fnext_window (minibuf_window, Qnil, Qnil)
874 : selected_window,
1ab256cb
RM
875 buf);
876
e8b3a22d 877 return buf;
1ab256cb
RM
878}
879
880DEFUN ("pop-to-buffer", Fpop_to_buffer, Spop_to_buffer, 1, 2, 0,
881 "Select buffer BUFFER in some window, preferably a different one.\n\
882If BUFFER is nil, then some other buffer is chosen.\n\
883If `pop-up-windows' is non-nil, windows can be split to do this.\n\
884If optional second arg OTHER-WINDOW is non-nil, insist on finding another\n\
885window even if BUFFER is already visible in the selected window.")
886 (bufname, other)
887 Lisp_Object bufname, other;
888{
889 register Lisp_Object buf;
265a9e55 890 if (NILP (bufname))
172a9c1f 891 buf = Fother_buffer (Fcurrent_buffer (), Qnil);
1ab256cb
RM
892 else
893 buf = Fget_buffer_create (bufname);
894 Fset_buffer (buf);
895 record_buffer (buf);
896 Fselect_window (Fdisplay_buffer (buf, other));
e8b3a22d 897 return buf;
1ab256cb
RM
898}
899
900DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
901 "Return the current buffer as a Lisp object.")
902 ()
903{
904 register Lisp_Object buf;
905 XSET (buf, Lisp_Buffer, current_buffer);
906 return buf;
907}
908\f
909/* Set the current buffer to b */
910
911void
912set_buffer_internal (b)
913 register struct buffer *b;
914{
915 register struct buffer *old_buf;
916 register Lisp_Object tail, valcontents;
917 enum Lisp_Type tem;
918
919 if (current_buffer == b)
920 return;
921
922 windows_or_buffers_changed = 1;
923 old_buf = current_buffer;
924 current_buffer = b;
925 last_known_column_point = -1; /* invalidate indentation cache */
926
927 /* Look down buffer's list of local Lisp variables
928 to find and update any that forward into C variables. */
929
265a9e55 930 for (tail = b->local_var_alist; !NILP (tail); tail = XCONS (tail)->cdr)
1ab256cb
RM
931 {
932 valcontents = XSYMBOL (XCONS (XCONS (tail)->car)->car)->value;
933 if ((XTYPE (valcontents) == Lisp_Buffer_Local_Value
934 || XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value)
935 && (tem = XTYPE (XCONS (valcontents)->car),
936 (tem == Lisp_Boolfwd || tem == Lisp_Intfwd
937 || tem == Lisp_Objfwd)))
938 /* Just reference the variable
939 to cause it to become set for this buffer. */
940 Fsymbol_value (XCONS (XCONS (tail)->car)->car);
941 }
942
943 /* Do the same with any others that were local to the previous buffer */
944
945 if (old_buf)
265a9e55 946 for (tail = old_buf->local_var_alist; !NILP (tail); tail = XCONS (tail)->cdr)
1ab256cb
RM
947 {
948 valcontents = XSYMBOL (XCONS (XCONS (tail)->car)->car)->value;
949 if ((XTYPE (valcontents) == Lisp_Buffer_Local_Value
950 || XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value)
951 && (tem = XTYPE (XCONS (valcontents)->car),
952 (tem == Lisp_Boolfwd || tem == Lisp_Intfwd
953 || tem == Lisp_Objfwd)))
954 /* Just reference the variable
955 to cause it to become set for this buffer. */
956 Fsymbol_value (XCONS (XCONS (tail)->car)->car);
957 }
958}
959
960DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0,
961 "Make the buffer BUFFER current for editing operations.\n\
962BUFFER may be a buffer or the name of an existing buffer.\n\
963See also `save-excursion' when you want to make a buffer current temporarily.\n\
964This function does not display the buffer, so its effect ends\n\
965when the current command terminates.\n\
966Use `switch-to-buffer' or `pop-to-buffer' to switch buffers permanently.")
967 (bufname)
968 register Lisp_Object bufname;
969{
970 register Lisp_Object buffer;
971 buffer = Fget_buffer (bufname);
265a9e55 972 if (NILP (buffer))
1ab256cb 973 nsberror (bufname);
265a9e55 974 if (NILP (XBUFFER (buffer)->name))
1ab256cb
RM
975 error ("Selecting deleted buffer");
976 set_buffer_internal (XBUFFER (buffer));
977 return buffer;
978}
979\f
980DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
981 Sbarf_if_buffer_read_only, 0, 0, 0,
982 "Signal a `buffer-read-only' error if the current buffer is read-only.")
983 ()
984{
a96b68f1
RS
985 if (!NILP (current_buffer->read_only)
986 && NILP (Vinhibit_read_only))
1ab256cb
RM
987 Fsignal (Qbuffer_read_only, (Fcons (Fcurrent_buffer (), Qnil)));
988 return Qnil;
989}
990
991DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "",
992 "Put BUFFER at the end of the list of all buffers.\n\
993There it is the least likely candidate for `other-buffer' to return;\n\
528415e7 994thus, the least likely buffer for \\[switch-to-buffer] to select by default.\n\
a5611885
JB
995If BUFFER is nil or omitted, bury the current buffer.\n\
996Also, if BUFFER is nil or omitted, remove the current buffer from the\n\
997selected window if it is displayed there.")
1ab256cb
RM
998 (buf)
999 register Lisp_Object buf;
1000{
b271272a 1001 /* Figure out what buffer we're going to bury. */
265a9e55 1002 if (NILP (buf))
a5611885
JB
1003 {
1004 XSET (buf, Lisp_Buffer, current_buffer);
1005
1006 /* If we're burying the current buffer, unshow it. */
5fcd022d 1007 Fswitch_to_buffer (Fother_buffer (buf, Qnil), Qnil);
a5611885 1008 }
1ab256cb
RM
1009 else
1010 {
1011 Lisp_Object buf1;
1012
1013 buf1 = Fget_buffer (buf);
265a9e55 1014 if (NILP (buf1))
1ab256cb
RM
1015 nsberror (buf);
1016 buf = buf1;
b271272a
JB
1017 }
1018
a5611885 1019 /* Move buf to the end of the buffer list. */
b271272a
JB
1020 {
1021 register Lisp_Object aelt, link;
1022
1023 aelt = Frassq (buf, Vbuffer_alist);
1024 link = Fmemq (aelt, Vbuffer_alist);
1025 Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
1026 XCONS (link)->cdr = Qnil;
1027 Vbuffer_alist = nconc2 (Vbuffer_alist, link);
1028 }
1ab256cb 1029
1ab256cb
RM
1030 return Qnil;
1031}
1032\f
c922bc55 1033DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*",
1ab256cb 1034 "Delete the entire contents of the current buffer.\n\
2950a20e 1035Any narrowing restriction in effect (see `narrow-to-region') is removed,\n\
1ab256cb
RM
1036so the buffer is truly empty after this.")
1037 ()
1038{
1039 Fwiden ();
1040 del_range (BEG, Z);
1041 current_buffer->last_window_start = 1;
1042 /* Prevent warnings, or suspension of auto saving, that would happen
1043 if future size is less than past size. Use of erase-buffer
1044 implies that the future text is not really related to the past text. */
1045 XFASTINT (current_buffer->save_length) = 0;
1046 return Qnil;
1047}
1048
1049validate_region (b, e)
1050 register Lisp_Object *b, *e;
1051{
1052 register int i;
1053
1054 CHECK_NUMBER_COERCE_MARKER (*b, 0);
1055 CHECK_NUMBER_COERCE_MARKER (*e, 1);
1056
1057 if (XINT (*b) > XINT (*e))
1058 {
1059 i = XFASTINT (*b); /* This is legit even if *b is < 0 */
1060 *b = *e;
1061 XFASTINT (*e) = i; /* because this is all we do with i. */
1062 }
1063
1064 if (!(BEGV <= XINT (*b) && XINT (*b) <= XINT (*e)
1065 && XINT (*e) <= ZV))
1066 args_out_of_range (*b, *e);
1067}
1068\f
1069Lisp_Object
1070list_buffers_1 (files)
1071 Lisp_Object files;
1072{
1073 register Lisp_Object tail, tem, buf;
1074 Lisp_Object col1, col2, col3, minspace;
1075 register struct buffer *old = current_buffer, *b;
718cde7d 1076 Lisp_Object desired_point;
1ab256cb
RM
1077 Lisp_Object other_file_symbol;
1078
718cde7d 1079 desired_point = Qnil;
1ab256cb
RM
1080 other_file_symbol = intern ("list-buffers-directory");
1081
1082 XFASTINT (col1) = 19;
1083 XFASTINT (col2) = 25;
1084 XFASTINT (col3) = 40;
1085 XFASTINT (minspace) = 1;
1086
1087 Fset_buffer (Vstandard_output);
1088
1089 tail = intern ("Buffer-menu-mode");
1090 if (!EQ (tail, current_buffer->major_mode)
265a9e55 1091 && (tem = Ffboundp (tail), !NILP (tem)))
1ab256cb
RM
1092 call0 (tail);
1093 Fbuffer_disable_undo (Vstandard_output);
1094 current_buffer->read_only = Qnil;
1095
1096 write_string ("\
1097 MR Buffer Size Mode File\n\
1098 -- ------ ---- ---- ----\n", -1);
1099
265a9e55 1100 for (tail = Vbuffer_alist; !NILP (tail); tail = Fcdr (tail))
1ab256cb
RM
1101 {
1102 buf = Fcdr (Fcar (tail));
1103 b = XBUFFER (buf);
1104 /* Don't mention the minibuffers. */
1105 if (XSTRING (b->name)->data[0] == ' ')
1106 continue;
1107 /* Optionally don't mention buffers that lack files. */
265a9e55 1108 if (!NILP (files) && NILP (b->filename))
1ab256cb
RM
1109 continue;
1110 /* Identify the current buffer. */
1111 if (b == old)
718cde7d 1112 XFASTINT (desired_point) = point;
1ab256cb
RM
1113 write_string (b == old ? "." : " ", -1);
1114 /* Identify modified buffers */
1115 write_string (BUF_MODIFF (b) > b->save_modified ? "*" : " ", -1);
265a9e55 1116 write_string (NILP (b->read_only) ? " " : "% ", -1);
1ab256cb
RM
1117 Fprinc (b->name, Qnil);
1118 Findent_to (col1, make_number (2));
1119 XFASTINT (tem) = BUF_Z (b) - BUF_BEG (b);
1120 Fprin1 (tem, Qnil);
1121 Findent_to (col2, minspace);
1122 Fprinc (b->mode_name, Qnil);
1123 Findent_to (col3, minspace);
1124
265a9e55 1125 if (!NILP (b->filename))
1ab256cb
RM
1126 Fprinc (b->filename, Qnil);
1127 else
1128 {
1129 /* No visited file; check local value of list-buffers-directory. */
1130 Lisp_Object tem;
1131 set_buffer_internal (b);
1132 tem = Fboundp (other_file_symbol);
265a9e55 1133 if (!NILP (tem))
1ab256cb
RM
1134 {
1135 tem = Fsymbol_value (other_file_symbol);
1136 Fset_buffer (Vstandard_output);
1137 if (XTYPE (tem) == Lisp_String)
1138 Fprinc (tem, Qnil);
1139 }
1140 else
1141 Fset_buffer (Vstandard_output);
1142 }
1143 write_string ("\n", -1);
1144 }
1145
1146 current_buffer->read_only = Qt;
1147 set_buffer_internal (old);
718cde7d 1148 return desired_point;
1ab256cb
RM
1149}
1150
1151DEFUN ("list-buffers", Flist_buffers, Slist_buffers, 0, 1, "P",
1152 "Display a list of names of existing buffers.\n\
1153The list is displayed in a buffer named `*Buffer List*'.\n\
1154Note that buffers with names starting with spaces are omitted.\n\
1155Non-null optional arg FILES-ONLY means mention only file buffers.\n\
1156\n\
1157The M column contains a * for buffers that are modified.\n\
1158The R column contains a % for buffers that are read-only.")
1159 (files)
1160 Lisp_Object files;
1161{
e87f38ef
JB
1162 Lisp_Object desired_point;
1163
fd2dab90
RS
1164 desired_point
1165 = internal_with_output_to_temp_buffer ("*Buffer List*",
1166 list_buffers_1, files);
e87f38ef 1167
718cde7d
JB
1168 if (NUMBERP (desired_point))
1169 {
1170 int count = specpdl_ptr - specpdl;
1171 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
1172 Fset_buffer (build_string ("*Buffer List*"));
1173 SET_PT (XINT (desired_point));
1174 return unbind_to (count, Qnil);
1175 }
fd2dab90 1176 return Qnil;
1ab256cb
RM
1177}
1178
1179DEFUN ("kill-all-local-variables", Fkill_all_local_variables, Skill_all_local_variables,
1180 0, 0, 0,
1181 "Switch to Fundamental mode by killing current buffer's local variables.\n\
1182Most local variable bindings are eliminated so that the default values\n\
1183become effective once more. Also, the syntax table is set from\n\
1184`standard-syntax-table', the local keymap is set to nil,\n\
1185and the abbrev table from `fundamental-mode-abbrev-table'.\n\
1186This function also forces redisplay of the mode line.\n\
1187\n\
1188Every function to select a new major mode starts by\n\
1189calling this function.\n\n\
1190As a special exception, local variables whose names have\n\
1191a non-nil `permanent-local' property are not eliminated by this function.")
1192 ()
1193{
1194 register Lisp_Object alist, sym, tem;
1195 Lisp_Object oalist;
1196 oalist = current_buffer->local_var_alist;
1197
1198 /* Make sure no local variables remain set up with this buffer
1199 for their current values. */
1200
265a9e55 1201 for (alist = oalist; !NILP (alist); alist = XCONS (alist)->cdr)
1ab256cb
RM
1202 {
1203 sym = XCONS (XCONS (alist)->car)->car;
1204
1205 /* Need not do anything if some other buffer's binding is now encached. */
1206 tem = XCONS (XCONS (XSYMBOL (sym)->value)->cdr)->car;
1207 if (XBUFFER (tem) == current_buffer)
1208 {
1209 /* Symbol is set up for this buffer's old local value.
1210 Set it up for the current buffer with the default value. */
1211
1212 tem = XCONS (XCONS (XSYMBOL (sym)->value)->cdr)->cdr;
542143d7
RS
1213 /* Store the symbol's current value into the alist entry
1214 it is currently set up for. This is so that, if the
1215 local is marked permanent, and we make it local again below,
1216 we don't lose the value. */
2735b685
RS
1217 XCONS (XCONS (tem)->car)->cdr
1218 = do_symval_forwarding (XCONS (XSYMBOL (sym)->value)->car);
542143d7 1219 /* Switch to the symbol's default-value alist entry. */
1ab256cb 1220 XCONS (tem)->car = tem;
542143d7 1221 /* Mark it as current for the current buffer. */
1ab256cb 1222 XCONS (XCONS (XSYMBOL (sym)->value)->cdr)->car = Fcurrent_buffer ();
542143d7 1223 /* Store the current value into any forwarding in the symbol. */
1ab256cb
RM
1224 store_symval_forwarding (sym, XCONS (XSYMBOL (sym)->value)->car,
1225 XCONS (tem)->cdr);
1226 }
1227 }
1228
1229 /* Actually eliminate all local bindings of this buffer. */
1230
1231 reset_buffer_local_variables (current_buffer);
1232
1233 /* Redisplay mode lines; we are changing major mode. */
1234
1235 update_mode_lines++;
1236
1237 /* Any which are supposed to be permanent,
1238 make local again, with the same values they had. */
1239
265a9e55 1240 for (alist = oalist; !NILP (alist); alist = XCONS (alist)->cdr)
1ab256cb
RM
1241 {
1242 sym = XCONS (XCONS (alist)->car)->car;
1243 tem = Fget (sym, Qpermanent_local);
265a9e55 1244 if (! NILP (tem))
01050cb5
RM
1245 {
1246 Fmake_local_variable (sym);
1247 Fset (sym, XCONS (XCONS (alist)->car)->cdr);
1248 }
1ab256cb
RM
1249 }
1250
1251 /* Force mode-line redisplay. Useful here because all major mode
1252 commands call this function. */
1253 update_mode_lines++;
1254
1255 return Qnil;
1256}
1257\f
2eec3b4e
RS
1258/* Find all the overlays in the current buffer that contain position POS.
1259 Return the number found, and store them in a vector in *VEC_PTR.
1260 Store in *LEN_PTR the size allocated for the vector.
52f8ec73
JB
1261 Store in *NEXT_PTR the next position after POS where an overlay starts,
1262 or ZV if there are no more overlays.
2eec3b4e
RS
1263
1264 *VEC_PTR and *LEN_PTR should contain a valid vector and size
61d54cd5
RS
1265 when this function is called.
1266
1267 If EXTEND is non-zero, we make the vector bigger if necessary.
1268 If EXTEND is zero, we never extend the vector,
1269 and we store only as many overlays as will fit.
1270 But we still return the total number of overlays. */
2eec3b4e
RS
1271
1272int
61d54cd5 1273overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr)
2eec3b4e 1274 int pos;
61d54cd5 1275 int extend;
2eec3b4e
RS
1276 Lisp_Object **vec_ptr;
1277 int *len_ptr;
1278 int *next_ptr;
1ab256cb 1279{
2eec3b4e
RS
1280 Lisp_Object tail, overlay, start, end, result;
1281 int idx = 0;
1282 int len = *len_ptr;
1283 Lisp_Object *vec = *vec_ptr;
1284 int next = ZV;
61d54cd5
RS
1285 int inhibit_storing = 0;
1286
2eec3b4e
RS
1287 for (tail = current_buffer->overlays_before;
1288 CONSP (tail);
1289 tail = XCONS (tail)->cdr)
1290 {
52f8ec73
JB
1291 int startpos;
1292
2eec3b4e
RS
1293 overlay = XCONS (tail)->car;
1294 if (! OVERLAY_VALID (overlay))
52f8ec73 1295 abort ();
1ab256cb 1296
2eec3b4e
RS
1297 start = OVERLAY_START (overlay);
1298 end = OVERLAY_END (overlay);
1299 if (OVERLAY_POSITION (end) <= pos)
1300 break;
1301 startpos = OVERLAY_POSITION (start);
1302 if (startpos <= pos)
1303 {
1304 if (idx == len)
1305 {
61d54cd5
RS
1306 /* The supplied vector is full.
1307 Either make it bigger, or don't store any more in it. */
1308 if (extend)
1309 {
1310 *len_ptr = len *= 2;
1311 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
1312 *vec_ptr = vec;
1313 }
1314 else
1315 inhibit_storing = 1;
2eec3b4e 1316 }
61d54cd5
RS
1317
1318 if (!inhibit_storing)
1319 vec[idx] = overlay;
1320 /* Keep counting overlays even if we can't return them all. */
1321 idx++;
2eec3b4e
RS
1322 }
1323 else if (startpos < next)
1324 next = startpos;
1325 }
1326
1327 for (tail = current_buffer->overlays_after;
1328 CONSP (tail);
1329 tail = XCONS (tail)->cdr)
1ab256cb 1330 {
52f8ec73
JB
1331 int startpos;
1332
2eec3b4e
RS
1333 overlay = XCONS (tail)->car;
1334 if (! OVERLAY_VALID (overlay))
52f8ec73 1335 abort ();
2eec3b4e
RS
1336
1337 start = OVERLAY_START (overlay);
1338 end = OVERLAY_END (overlay);
1339 startpos = OVERLAY_POSITION (start);
52f8ec73 1340 if (pos < startpos)
2eec3b4e
RS
1341 {
1342 if (startpos < next)
1343 next = startpos;
1344 break;
1345 }
52f8ec73 1346 if (pos < OVERLAY_POSITION (end))
2eec3b4e
RS
1347 {
1348 if (idx == len)
1349 {
61d54cd5
RS
1350 if (extend)
1351 {
1352 *len_ptr = len *= 2;
1353 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
1354 *vec_ptr = vec;
1355 }
1356 else
1357 inhibit_storing = 1;
2eec3b4e 1358 }
61d54cd5
RS
1359
1360 if (!inhibit_storing)
1361 vec[idx] = overlay;
1362 idx++;
2eec3b4e 1363 }
1ab256cb
RM
1364 }
1365
2eec3b4e
RS
1366 *next_ptr = next;
1367 return idx;
1368}
1369\f
5985d248
KH
1370struct sortvec
1371{
1372 Lisp_Object overlay;
1373 int beg, end;
1374 int priority;
1375};
1376
1377static int
1378compare_overlays (s1, s2)
1379 struct sortvec *s1, *s2;
1380{
1381 if (s1->priority != s2->priority)
1382 return s1->priority - s2->priority;
1383 if (s1->beg != s2->beg)
1384 return s1->beg - s2->beg;
1385 if (s1->end != s2->end)
1386 return s2->end - s1->end;
1387 return 0;
1388}
1389
1390/* Sort an array of overlays by priority. The array is modified in place.
1391 The return value is the new size; this may be smaller than the original
1392 size if some of the overlays were invalid or were window-specific. */
1393int
1394sort_overlays (overlay_vec, noverlays, w)
1395 Lisp_Object *overlay_vec;
1396 int noverlays;
1397 struct window *w;
1398{
1399 int i, j;
1400 struct sortvec *sortvec;
1401 sortvec = (struct sortvec *) alloca (noverlays * sizeof (struct sortvec));
1402
1403 /* Put the valid and relevant overlays into sortvec. */
1404
1405 for (i = 0, j = 0; i < noverlays; i++)
1406 {
1407 Lisp_Object overlay = overlay_vec[i];
1408
1409 if (OVERLAY_VALID (overlay)
1410 && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0
1411 && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0)
1412 {
1413 Lisp_Object window;
1414 window = Foverlay_get (overlay, Qwindow);
1415
1416 /* Also ignore overlays limited to one window
1417 if it's not the window we are using. */
1418 if (XTYPE (window) != Lisp_Window
1419 || XWINDOW (window) == w)
1420 {
1421 Lisp_Object tem;
1422
1423 /* This overlay is good and counts:
1424 put it in sortvec. */
1425 sortvec[j].overlay = overlay;
1426 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
1427 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
1428 tem = Foverlay_get (overlay, Qpriority);
1429 if (INTEGERP (tem))
1430 sortvec[j].priority = XINT (tem);
1431 else
1432 sortvec[j].priority = 0;
1433 j++;
1434 }
1435 }
1436 }
1437 noverlays = j;
1438
1439 /* Sort the overlays into the proper order: increasing priority. */
1440
1441 if (noverlays > 1)
1442 qsort (sortvec, noverlays, sizeof (struct sortvec), compare_overlays);
1443
1444 for (i = 0; i < noverlays; i++)
1445 overlay_vec[i] = sortvec[i].overlay;
1446 return (noverlays);
1447}
1448\f
5c4f68f1 1449/* Shift overlays in BUF's overlay lists, to center the lists at POS. */
1ab256cb 1450
2eec3b4e 1451void
5c4f68f1
JB
1452recenter_overlay_lists (buf, pos)
1453 struct buffer *buf;
2eec3b4e
RS
1454 int pos;
1455{
1456 Lisp_Object overlay, tail, next, prev, beg, end;
1457
1458 /* See if anything in overlays_before should move to overlays_after. */
1459
1460 /* We don't strictly need prev in this loop; it should always be nil.
1461 But we use it for symmetry and in case that should cease to be true
1462 with some future change. */
1463 prev = Qnil;
5c4f68f1 1464 for (tail = buf->overlays_before;
2eec3b4e
RS
1465 CONSP (tail);
1466 prev = tail, tail = next)
1ab256cb 1467 {
2eec3b4e
RS
1468 next = XCONS (tail)->cdr;
1469 overlay = XCONS (tail)->car;
1470
1471 /* If the overlay is not valid, get rid of it. */
1472 if (!OVERLAY_VALID (overlay))
52f8ec73
JB
1473#if 1
1474 abort ();
1475#else
2eec3b4e
RS
1476 {
1477 /* Splice the cons cell TAIL out of overlays_before. */
1478 if (!NILP (prev))
1479 XCONS (prev)->cdr = next;
1480 else
5c4f68f1 1481 buf->overlays_before = next;
2eec3b4e
RS
1482 tail = prev;
1483 continue;
1484 }
52f8ec73 1485#endif
1ab256cb 1486
2eec3b4e
RS
1487 beg = OVERLAY_START (overlay);
1488 end = OVERLAY_END (overlay);
1ab256cb 1489
2eec3b4e 1490 if (OVERLAY_POSITION (end) > pos)
1ab256cb 1491 {
2eec3b4e
RS
1492 /* OVERLAY needs to be moved. */
1493 int where = OVERLAY_POSITION (beg);
1494 Lisp_Object other, other_prev;
1495
1496 /* Splice the cons cell TAIL out of overlays_before. */
1497 if (!NILP (prev))
1498 XCONS (prev)->cdr = next;
1499 else
5c4f68f1 1500 buf->overlays_before = next;
2eec3b4e
RS
1501
1502 /* Search thru overlays_after for where to put it. */
1503 other_prev = Qnil;
5c4f68f1 1504 for (other = buf->overlays_after;
2eec3b4e
RS
1505 CONSP (other);
1506 other_prev = other, other = XCONS (other)->cdr)
1ab256cb 1507 {
2eec3b4e
RS
1508 Lisp_Object otherbeg, otheroverlay, follower;
1509 int win;
1510
1511 otheroverlay = XCONS (other)->car;
1512 if (! OVERLAY_VALID (otheroverlay))
52f8ec73 1513 abort ();
2eec3b4e
RS
1514
1515 otherbeg = OVERLAY_START (otheroverlay);
1516 if (OVERLAY_POSITION (otherbeg) >= where)
1517 break;
1ab256cb 1518 }
2eec3b4e
RS
1519
1520 /* Add TAIL to overlays_after before OTHER. */
1521 XCONS (tail)->cdr = other;
1522 if (!NILP (other_prev))
1523 XCONS (other_prev)->cdr = tail;
1ab256cb 1524 else
5c4f68f1 1525 buf->overlays_after = tail;
2eec3b4e 1526 tail = prev;
1ab256cb 1527 }
2eec3b4e
RS
1528 else
1529 /* We've reached the things that should stay in overlays_before.
1530 All the rest of overlays_before must end even earlier,
1531 so stop now. */
1532 break;
1533 }
1534
1535 /* See if anything in overlays_after should be in overlays_before. */
1536 prev = Qnil;
5c4f68f1 1537 for (tail = buf->overlays_after;
2eec3b4e
RS
1538 CONSP (tail);
1539 prev = tail, tail = next)
1540 {
1541 next = XCONS (tail)->cdr;
1542 overlay = XCONS (tail)->car;
1543
1544 /* If the overlay is not valid, get rid of it. */
1545 if (!OVERLAY_VALID (overlay))
52f8ec73
JB
1546#if 1
1547 abort ();
1548#else
2eec3b4e
RS
1549 {
1550 /* Splice the cons cell TAIL out of overlays_after. */
1551 if (!NILP (prev))
1552 XCONS (prev)->cdr = next;
1553 else
5c4f68f1 1554 buf->overlays_after = next;
2eec3b4e
RS
1555 tail = prev;
1556 continue;
1557 }
52f8ec73 1558#endif
2eec3b4e
RS
1559
1560 beg = OVERLAY_START (overlay);
1561 end = OVERLAY_END (overlay);
1562
1563 /* Stop looking, when we know that nothing further
1564 can possibly end before POS. */
1565 if (OVERLAY_POSITION (beg) > pos)
1566 break;
1567
1568 if (OVERLAY_POSITION (end) <= pos)
1569 {
1570 /* OVERLAY needs to be moved. */
1571 int where = OVERLAY_POSITION (end);
1572 Lisp_Object other, other_prev;
1573
1574 /* Splice the cons cell TAIL out of overlays_after. */
1575 if (!NILP (prev))
1576 XCONS (prev)->cdr = next;
1577 else
5c4f68f1 1578 buf->overlays_after = next;
2eec3b4e
RS
1579
1580 /* Search thru overlays_before for where to put it. */
1581 other_prev = Qnil;
5c4f68f1 1582 for (other = buf->overlays_before;
2eec3b4e
RS
1583 CONSP (other);
1584 other_prev = other, other = XCONS (other)->cdr)
1585 {
1586 Lisp_Object otherend, otheroverlay;
1587 int win;
1588
1589 otheroverlay = XCONS (other)->car;
1590 if (! OVERLAY_VALID (otheroverlay))
52f8ec73 1591 abort ();
2eec3b4e
RS
1592
1593 otherend = OVERLAY_END (otheroverlay);
1594 if (OVERLAY_POSITION (otherend) <= where)
1595 break;
1596 }
1597
1598 /* Add TAIL to overlays_before before OTHER. */
1599 XCONS (tail)->cdr = other;
1600 if (!NILP (other_prev))
1601 XCONS (other_prev)->cdr = tail;
1602 else
5c4f68f1 1603 buf->overlays_before = tail;
2eec3b4e
RS
1604 tail = prev;
1605 }
1606 }
1607
5c4f68f1 1608 XFASTINT (buf->overlay_center) = pos;
2eec3b4e
RS
1609}
1610\f
52f8ec73
JB
1611DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
1612 "Return t if OBJECT is an overlay.")
1613 (object)
1614 Lisp_Object object;
1615{
1616 return (OVERLAYP (object) ? Qt : Qnil);
1617}
1618
5c4f68f1
JB
1619DEFUN ("make-overlay", Fmake_overlay, Smake_overlay, 2, 3, 0,
1620 "Create a new overlay with range BEG to END in BUFFER.\n\
1621If omitted, BUFFER defaults to the current buffer.\n\
2eec3b4e 1622BEG and END may be integers or markers.")
5c4f68f1
JB
1623 (beg, end, buffer)
1624 Lisp_Object beg, end, buffer;
2eec3b4e
RS
1625{
1626 Lisp_Object overlay;
5c4f68f1 1627 struct buffer *b;
2eec3b4e 1628
5c4f68f1
JB
1629 if (NILP (buffer))
1630 XSET (buffer, Lisp_Buffer, current_buffer);
883047b9
JB
1631 else
1632 CHECK_BUFFER (buffer, 2);
1633 if (MARKERP (beg)
1634 && ! EQ (Fmarker_buffer (beg), buffer))
1635 error ("Marker points into wrong buffer");
1636 if (MARKERP (end)
1637 && ! EQ (Fmarker_buffer (end), buffer))
1638 error ("Marker points into wrong buffer");
2eec3b4e 1639
883047b9
JB
1640 CHECK_NUMBER_COERCE_MARKER (beg, 1);
1641 CHECK_NUMBER_COERCE_MARKER (end, 1);
5c4f68f1 1642
883047b9 1643 if (XINT (beg) > XINT (end))
5c4f68f1 1644 {
883047b9
JB
1645 Lisp_Object temp = beg;
1646 beg = end; end = temp;
5c4f68f1 1647 }
883047b9
JB
1648
1649 b = XBUFFER (buffer);
1650
1651 beg = Fset_marker (Fmake_marker (), beg, buffer);
1652 end = Fset_marker (Fmake_marker (), end, buffer);
5c4f68f1
JB
1653
1654 overlay = Fcons (Fcons (beg, end), Qnil);
52f8ec73 1655 XSETTYPE (overlay, Lisp_Overlay);
2eec3b4e
RS
1656
1657 /* Put the new overlay on the wrong list. */
1658 end = OVERLAY_END (overlay);
5c4f68f1
JB
1659 if (OVERLAY_POSITION (end) < XINT (b->overlay_center))
1660 b->overlays_after = Fcons (overlay, b->overlays_after);
2eec3b4e 1661 else
5c4f68f1 1662 b->overlays_before = Fcons (overlay, b->overlays_before);
2eec3b4e
RS
1663
1664 /* This puts it in the right list, and in the right order. */
5c4f68f1 1665 recenter_overlay_lists (b, XINT (b->overlay_center));
2eec3b4e 1666
b61982dd
JB
1667 /* We don't need to redisplay the region covered by the overlay, because
1668 the overlay has no properties at the moment. */
1669
2eec3b4e
RS
1670 return overlay;
1671}
1672
5c4f68f1
JB
1673DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
1674 "Set the endpoints of OVERLAY to BEG and END in BUFFER.\n\
3ece337a
JB
1675If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.\n\
1676If BUFFER is omitted, and OVERLAY is in no buffer, put it in the current\n\
1677buffer.")
5c4f68f1
JB
1678 (overlay, beg, end, buffer)
1679 Lisp_Object overlay, beg, end, buffer;
2eec3b4e 1680{
0a4469c9
RS
1681 struct buffer *b, *ob;
1682 Lisp_Object obuffer;
1683 int count = specpdl_ptr - specpdl;
5c4f68f1 1684
52f8ec73 1685 CHECK_OVERLAY (overlay, 0);
5c4f68f1
JB
1686 if (NILP (buffer))
1687 buffer = Fmarker_buffer (OVERLAY_START (overlay));
3ece337a
JB
1688 if (NILP (buffer))
1689 XSET (buffer, Lisp_Buffer, current_buffer);
5c4f68f1 1690 CHECK_BUFFER (buffer, 3);
883047b9
JB
1691
1692 if (MARKERP (beg)
1693 && ! EQ (Fmarker_buffer (beg), buffer))
1694 error ("Marker points into wrong buffer");
1695 if (MARKERP (end)
1696 && ! EQ (Fmarker_buffer (end), buffer))
1697 error ("Marker points into wrong buffer");
1698
b61982dd
JB
1699 CHECK_NUMBER_COERCE_MARKER (beg, 1);
1700 CHECK_NUMBER_COERCE_MARKER (end, 1);
1701
0a4469c9
RS
1702 specbind (Qinhibit_quit, Qt);
1703
b61982dd
JB
1704 if (XINT (beg) > XINT (end))
1705 {
1706 Lisp_Object temp = beg;
1707 beg = end; end = temp;
1708 }
1709
0a4469c9 1710 obuffer = Fmarker_buffer (OVERLAY_START (overlay));
5c4f68f1 1711 b = XBUFFER (buffer);
0a4469c9 1712 ob = XBUFFER (obuffer);
2eec3b4e 1713
c82ed728 1714 /* If the overlay has changed buffers, do a thorough redisplay. */
0a4469c9 1715 if (!EQ (buffer, obuffer))
c82ed728
JB
1716 windows_or_buffers_changed = 1;
1717 else
1718 /* Redisplay the area the overlay has just left, or just enclosed. */
1719 {
be8b1c6b
RS
1720 Lisp_Object o_beg;
1721 Lisp_Object o_end;
c82ed728
JB
1722 int change_beg, change_end;
1723
be8b1c6b
RS
1724 o_beg = OVERLAY_START (overlay);
1725 o_end = OVERLAY_END (overlay);
c82ed728
JB
1726 o_beg = OVERLAY_POSITION (o_beg);
1727 o_end = OVERLAY_POSITION (o_end);
1728
1729 if (XINT (o_beg) == XINT (beg))
1730 redisplay_region (b, XINT (o_end), XINT (end));
1731 else if (XINT (o_end) == XINT (end))
1732 redisplay_region (b, XINT (o_beg), XINT (beg));
1733 else
1734 {
1735 if (XINT (beg) < XINT (o_beg)) o_beg = beg;
1736 if (XINT (end) > XINT (o_end)) o_end = end;
1737 redisplay_region (b, XINT (o_beg), XINT (o_end));
1738 }
1739 }
b61982dd 1740
0a4469c9
RS
1741 if (!NILP (obuffer))
1742 {
1743 ob->overlays_before = Fdelq (overlay, ob->overlays_before);
1744 ob->overlays_after = Fdelq (overlay, ob->overlays_after);
1745 }
5c4f68f1
JB
1746
1747 Fset_marker (OVERLAY_START (overlay), beg, buffer);
1748 Fset_marker (OVERLAY_END (overlay), end, buffer);
2eec3b4e
RS
1749
1750 /* Put the overlay on the wrong list. */
1751 end = OVERLAY_END (overlay);
5c4f68f1
JB
1752 if (OVERLAY_POSITION (end) < XINT (b->overlay_center))
1753 b->overlays_after = Fcons (overlay, b->overlays_after);
2eec3b4e 1754 else
5c4f68f1 1755 b->overlays_before = Fcons (overlay, b->overlays_before);
2eec3b4e
RS
1756
1757 /* This puts it in the right list, and in the right order. */
5c4f68f1 1758 recenter_overlay_lists (b, XINT (b->overlay_center));
2eec3b4e 1759
0a4469c9 1760 return unbind_to (count, overlay);
2eec3b4e
RS
1761}
1762
1763DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
5c4f68f1 1764 "Delete the overlay OVERLAY from its buffer.")
2eec3b4e 1765 (overlay)
5c4f68f1 1766 Lisp_Object overlay;
2eec3b4e 1767{
0a4469c9 1768 Lisp_Object buffer;
5c4f68f1 1769 struct buffer *b;
0a4469c9 1770 int count = specpdl_ptr - specpdl;
5c4f68f1 1771
52f8ec73
JB
1772 CHECK_OVERLAY (overlay, 0);
1773
0a4469c9
RS
1774 buffer = Fmarker_buffer (OVERLAY_START (overlay));
1775 if (NILP (buffer))
1776 return Qnil;
1777
1778 b = XBUFFER (buffer);
1779
1780 specbind (Qinhibit_quit, Qt);
5c4f68f1
JB
1781
1782 b->overlays_before = Fdelq (overlay, b->overlays_before);
1783 b->overlays_after = Fdelq (overlay, b->overlays_after);
1784
b61982dd 1785 redisplay_region (b,
a927f5c9
RS
1786 marker_position (OVERLAY_START (overlay)),
1787 marker_position (OVERLAY_END (overlay)));
b61982dd 1788
3ece337a
JB
1789 Fset_marker (OVERLAY_START (overlay), Qnil, Qnil);
1790 Fset_marker (OVERLAY_END (overlay), Qnil, Qnil);
1791
0a4469c9 1792 return unbind_to (count, Qnil);
2eec3b4e
RS
1793}
1794\f
8ebafa8d
JB
1795/* Overlay dissection functions. */
1796
1797DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
1798 "Return the position at which OVERLAY starts.")
1799 (overlay)
1800 Lisp_Object overlay;
1801{
1802 CHECK_OVERLAY (overlay, 0);
1803
1804 return (Fmarker_position (OVERLAY_START (overlay)));
1805}
1806
1807DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
1808 "Return the position at which OVERLAY ends.")
1809 (overlay)
1810 Lisp_Object overlay;
1811{
1812 CHECK_OVERLAY (overlay, 0);
1813
1814 return (Fmarker_position (OVERLAY_END (overlay)));
1815}
1816
1817DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
1818 "Return the buffer OVERLAY belongs to.")
1819 (overlay)
1820 Lisp_Object overlay;
1821{
1822 CHECK_OVERLAY (overlay, 0);
1823
1824 return Fmarker_buffer (OVERLAY_START (overlay));
1825}
1826
1827DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
1828 "Return a list of the properties on OVERLAY.\n\
1829This is a copy of OVERLAY's plist; modifying its conses has no effect on\n\
1830OVERLAY.")
1831 (overlay)
1832 Lisp_Object overlay;
1833{
1834 CHECK_OVERLAY (overlay, 0);
1835
1836 return Fcopy_sequence (Fcdr_safe (XCONS (overlay)->cdr));
1837}
1838
1839\f
2eec3b4e 1840DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
eb8c3be9 1841 "Return a list of the overlays that contain position POS.")
2eec3b4e
RS
1842 (pos)
1843 Lisp_Object pos;
1844{
1845 int noverlays;
1846 int endpos;
1847 Lisp_Object *overlay_vec;
1848 int len;
1849 Lisp_Object result;
1850
1851 CHECK_NUMBER_COERCE_MARKER (pos, 0);
1852
1853 len = 10;
1854 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
1855
1856 /* Put all the overlays we want in a vector in overlay_vec.
1857 Store the length in len. */
61d54cd5 1858 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, &endpos);
2eec3b4e
RS
1859
1860 /* Make a list of them all. */
1861 result = Flist (noverlays, overlay_vec);
1862
9ac0d9e0 1863 xfree (overlay_vec);
2eec3b4e
RS
1864 return result;
1865}
1866
1867DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change,
1868 1, 1, 0,
1869 "Return the next position after POS where an overlay starts or ends.")
1870 (pos)
1871 Lisp_Object pos;
1872{
1873 int noverlays;
1874 int endpos;
1875 Lisp_Object *overlay_vec;
1876 int len;
1877 Lisp_Object result;
1878 int i;
1879
1880 CHECK_NUMBER_COERCE_MARKER (pos, 0);
1881
1882 len = 10;
1883 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
1884
1885 /* Put all the overlays we want in a vector in overlay_vec.
1886 Store the length in len.
1887 endpos gets the position where the next overlay starts. */
61d54cd5 1888 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, &endpos);
2eec3b4e
RS
1889
1890 /* If any of these overlays ends before endpos,
1891 use its ending point instead. */
1892 for (i = 0; i < noverlays; i++)
1893 {
1894 Lisp_Object oend;
1895 int oendpos;
1896
1897 oend = OVERLAY_END (overlay_vec[i]);
1898 oendpos = OVERLAY_POSITION (oend);
1899 if (oendpos < endpos)
1900 endpos = oendpos;
1ab256cb
RM
1901 }
1902
9ac0d9e0 1903 xfree (overlay_vec);
2eec3b4e
RS
1904 return make_number (endpos);
1905}
1906\f
1907/* These functions are for debugging overlays. */
1908
1909DEFUN ("overlay-lists", Foverlay_lists, Soverlay_lists, 0, 0, 0,
1910 "Return a pair of lists giving all the overlays of the current buffer.\n\
1911The car has all the overlays before the overlay center;\n\
1912the cdr has all the overlays before the overlay center.\n\
1913Recentering overlays moves overlays between these lists.\n\
1914The lists you get are copies, so that changing them has no effect.\n\
1915However, the overlays you get are the real objects that the buffer uses.")
1916 ()
1917{
1918 Lisp_Object before, after;
1919 before = current_buffer->overlays_before;
1920 if (CONSP (before))
1921 before = Fcopy_sequence (before);
1922 after = current_buffer->overlays_after;
1923 if (CONSP (after))
1924 after = Fcopy_sequence (after);
1925
1926 return Fcons (before, after);
1927}
1928
1929DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
1930 "Recenter the overlays of the current buffer around position POS.")
1931 (pos)
1932 Lisp_Object pos;
1933{
1934 CHECK_NUMBER_COERCE_MARKER (pos, 0);
1935
5c4f68f1 1936 recenter_overlay_lists (current_buffer, XINT (pos));
2eec3b4e
RS
1937 return Qnil;
1938}
1939\f
1940DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0,
1941 "Get the property of overlay OVERLAY with property name NAME.")
1942 (overlay, prop)
1943 Lisp_Object overlay, prop;
1944{
1945 Lisp_Object plist;
52f8ec73
JB
1946
1947 CHECK_OVERLAY (overlay, 0);
1948
1949 for (plist = Fcdr_safe (XCONS (overlay)->cdr);
2eec3b4e
RS
1950 CONSP (plist) && CONSP (XCONS (plist)->cdr);
1951 plist = XCONS (XCONS (plist)->cdr)->cdr)
1952 {
1953 if (EQ (XCONS (plist)->car, prop))
1954 return XCONS (XCONS (plist)->cdr)->car;
1955 }
52f8ec73
JB
1956
1957 return Qnil;
2eec3b4e
RS
1958}
1959
1960DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
1961 "Set one property of overlay OVERLAY: give property PROP value VALUE.")
1962 (overlay, prop, value)
1963 Lisp_Object overlay, prop, value;
1964{
1965 Lisp_Object plist, tail;
1966
52f8ec73 1967 CHECK_OVERLAY (overlay, 0);
b61982dd 1968
25d16451
RS
1969 tail = Fmarker_buffer (OVERLAY_START (overlay));
1970 if (! NILP (tail))
1971 redisplay_region (XMARKER (OVERLAY_START (overlay))->buffer,
1972 marker_position (OVERLAY_START (overlay)),
1973 marker_position (OVERLAY_END (overlay)));
b61982dd 1974
52f8ec73 1975 plist = Fcdr_safe (XCONS (overlay)->cdr);
2eec3b4e
RS
1976
1977 for (tail = plist;
1978 CONSP (tail) && CONSP (XCONS (tail)->cdr);
1979 tail = XCONS (XCONS (tail)->cdr)->cdr)
1980 {
1981 if (EQ (XCONS (tail)->car, prop))
1982 return XCONS (XCONS (tail)->cdr)->car = value;
1983 }
1984
1985 if (! CONSP (XCONS (overlay)->cdr))
1986 XCONS (overlay)->cdr = Fcons (Qnil, Qnil);
1987
1988 XCONS (XCONS (overlay)->cdr)->cdr
1989 = Fcons (prop, Fcons (value, plist));
1990
1991 return value;
1ab256cb
RM
1992}
1993\f
173f2a64
RS
1994/* Run the modification-hooks of overlays that include
1995 any part of the text in START to END.
1996 Run the insert-before-hooks of overlay starting at END,
1997 and the insert-after-hooks of overlay ending at START. */
1998
1999void
2000verify_overlay_modification (start, end)
2001 Lisp_Object start, end;
2002{
2003 Lisp_Object prop, overlay, tail;
2004 int insertion = EQ (start, end);
2005
2006 for (tail = current_buffer->overlays_before;
2007 CONSP (tail);
2008 tail = XCONS (tail)->cdr)
2009 {
2010 int startpos, endpos;
be8b1c6b 2011 Lisp_Object ostart, oend;
173f2a64
RS
2012
2013 overlay = XCONS (tail)->car;
2014
2015 ostart = OVERLAY_START (overlay);
2016 oend = OVERLAY_END (overlay);
2017 endpos = OVERLAY_POSITION (oend);
2018 if (XFASTINT (start) > endpos)
2019 break;
2020 startpos = OVERLAY_POSITION (ostart);
2021 if (XFASTINT (end) == startpos && insertion)
2022 {
2023 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
2024 call_overlay_mod_hooks (prop, overlay, start, end);
2025 }
2026 if (XFASTINT (start) == endpos && insertion)
2027 {
2028 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
2029 call_overlay_mod_hooks (prop, overlay, start, end);
2030 }
2031 if (insertion
2032 ? (XFASTINT (start) > startpos && XFASTINT (end) < endpos)
2033 : (XFASTINT (start) >= startpos && XFASTINT (end) <= endpos))
2034 {
2035 prop = Foverlay_get (overlay, Qmodification_hooks);
2036 call_overlay_mod_hooks (prop, overlay, start, end);
2037 }
2038 }
2039
2040 for (tail = current_buffer->overlays_after;
2041 CONSP (tail);
2042 tail = XCONS (tail)->cdr)
2043 {
2044 int startpos, endpos;
be8b1c6b 2045 Lisp_Object ostart, oend;
173f2a64
RS
2046
2047 overlay = XCONS (tail)->car;
2048
2049 ostart = OVERLAY_START (overlay);
2050 oend = OVERLAY_END (overlay);
2051 startpos = OVERLAY_POSITION (ostart);
cdf0b096 2052 endpos = OVERLAY_POSITION (oend);
173f2a64
RS
2053 if (XFASTINT (end) < startpos)
2054 break;
2055 if (XFASTINT (end) == startpos && insertion)
2056 {
2057 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
2058 call_overlay_mod_hooks (prop, overlay, start, end);
2059 }
2060 if (XFASTINT (start) == endpos && insertion)
2061 {
2062 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
2063 call_overlay_mod_hooks (prop, overlay, start, end);
2064 }
2065 if (insertion
2066 ? (XFASTINT (start) > startpos && XFASTINT (end) < endpos)
2067 : (XFASTINT (start) >= startpos && XFASTINT (end) <= endpos))
2068 {
2069 prop = Foverlay_get (overlay, Qmodification_hooks);
2070 call_overlay_mod_hooks (prop, overlay, start, end);
2071 }
2072 }
2073}
2074
2075static void
2076call_overlay_mod_hooks (list, overlay, start, end)
2077 Lisp_Object list, overlay, start, end;
2078{
2079 struct gcpro gcpro1;
2080 GCPRO1 (list);
2081 while (!NILP (list))
2082 {
2083 call3 (Fcar (list), overlay, start, end);
2084 list = Fcdr (list);
2085 }
2086 UNGCPRO;
2087}
2088\f
0fa3ba92
JB
2089/* Somebody has tried to store NEWVAL into the buffer-local slot with
2090 offset XUINT (valcontents), and NEWVAL has an unacceptable type. */
2091void
2092buffer_slot_type_mismatch (valcontents, newval)
2093 Lisp_Object valcontents, newval;
2094{
2095 unsigned int offset = XUINT (valcontents);
5fcd022d 2096 unsigned char *symbol_name =
0fa3ba92
JB
2097 (XSYMBOL (*(Lisp_Object *)(offset + (char *)&buffer_local_symbols))
2098 ->name->data);
2099 char *type_name;
2100
2101 switch (XINT (*(Lisp_Object *)(offset + (char *)&buffer_local_types)))
2102 {
2103 case Lisp_Int: type_name = "integers"; break;
2104 case Lisp_String: type_name = "strings"; break;
2105 case Lisp_Marker: type_name = "markers"; break;
2106 case Lisp_Symbol: type_name = "symbols"; break;
2107 case Lisp_Cons: type_name = "lists"; break;
5fcd022d 2108 case Lisp_Vector: type_name = "vectors"; break;
0fa3ba92
JB
2109 default:
2110 abort ();
2111 }
2112
2113 error ("only %s should be stored in the buffer-local variable %s",
2114 type_name, symbol_name);
2115}
2116\f
1ab256cb
RM
2117init_buffer_once ()
2118{
2119 register Lisp_Object tem;
2120
2121 /* Make sure all markable slots in buffer_defaults
2122 are initialized reasonably, so mark_buffer won't choke. */
2123 reset_buffer (&buffer_defaults);
2124 reset_buffer (&buffer_local_symbols);
2125 XSET (Vbuffer_defaults, Lisp_Buffer, &buffer_defaults);
2126 XSET (Vbuffer_local_symbols, Lisp_Buffer, &buffer_local_symbols);
2127
2128 /* Set up the default values of various buffer slots. */
2129 /* Must do these before making the first buffer! */
2130
2131 /* real setup is done in loaddefs.el */
2132 buffer_defaults.mode_line_format = build_string ("%-");
2133 buffer_defaults.abbrev_mode = Qnil;
2134 buffer_defaults.overwrite_mode = Qnil;
2135 buffer_defaults.case_fold_search = Qt;
2136 buffer_defaults.auto_fill_function = Qnil;
2137 buffer_defaults.selective_display = Qnil;
2138#ifndef old
2139 buffer_defaults.selective_display_ellipses = Qt;
2140#endif
2141 buffer_defaults.abbrev_table = Qnil;
2142 buffer_defaults.display_table = Qnil;
1ab256cb 2143 buffer_defaults.undo_list = Qnil;
c48f61ef 2144 buffer_defaults.mark_active = Qnil;
2eec3b4e
RS
2145 buffer_defaults.overlays_before = Qnil;
2146 buffer_defaults.overlays_after = Qnil;
2147 XFASTINT (buffer_defaults.overlay_center) = 1;
1ab256cb
RM
2148
2149 XFASTINT (buffer_defaults.tab_width) = 8;
2150 buffer_defaults.truncate_lines = Qnil;
2151 buffer_defaults.ctl_arrow = Qt;
2152
54ad07d3
RS
2153#ifdef MSDOS
2154 buffer_defaults.buffer_file_type = 0; /* TEXT */
2155#endif
1ab256cb
RM
2156 XFASTINT (buffer_defaults.fill_column) = 70;
2157 XFASTINT (buffer_defaults.left_margin) = 0;
2158
2159 /* Assign the local-flags to the slots that have default values.
2160 The local flag is a bit that is used in the buffer
2161 to say that it has its own local value for the slot.
2162 The local flag bits are in the local_var_flags slot of the buffer. */
2163
2164 /* Nothing can work if this isn't true */
2165 if (sizeof (int) != sizeof (Lisp_Object)) abort ();
2166
2167 /* 0 means not a lisp var, -1 means always local, else mask */
2168 bzero (&buffer_local_flags, sizeof buffer_local_flags);
2169 XFASTINT (buffer_local_flags.filename) = -1;
2170 XFASTINT (buffer_local_flags.directory) = -1;
2171 XFASTINT (buffer_local_flags.backed_up) = -1;
2172 XFASTINT (buffer_local_flags.save_length) = -1;
2173 XFASTINT (buffer_local_flags.auto_save_file_name) = -1;
2174 XFASTINT (buffer_local_flags.read_only) = -1;
2175 XFASTINT (buffer_local_flags.major_mode) = -1;
2176 XFASTINT (buffer_local_flags.mode_name) = -1;
2177 XFASTINT (buffer_local_flags.undo_list) = -1;
c48f61ef 2178 XFASTINT (buffer_local_flags.mark_active) = -1;
1ab256cb
RM
2179
2180 XFASTINT (buffer_local_flags.mode_line_format) = 1;
2181 XFASTINT (buffer_local_flags.abbrev_mode) = 2;
2182 XFASTINT (buffer_local_flags.overwrite_mode) = 4;
2183 XFASTINT (buffer_local_flags.case_fold_search) = 8;
2184 XFASTINT (buffer_local_flags.auto_fill_function) = 0x10;
2185 XFASTINT (buffer_local_flags.selective_display) = 0x20;
2186#ifndef old
2187 XFASTINT (buffer_local_flags.selective_display_ellipses) = 0x40;
2188#endif
2189 XFASTINT (buffer_local_flags.tab_width) = 0x80;
2190 XFASTINT (buffer_local_flags.truncate_lines) = 0x100;
2191 XFASTINT (buffer_local_flags.ctl_arrow) = 0x200;
2192 XFASTINT (buffer_local_flags.fill_column) = 0x400;
2193 XFASTINT (buffer_local_flags.left_margin) = 0x800;
2194 XFASTINT (buffer_local_flags.abbrev_table) = 0x1000;
2195 XFASTINT (buffer_local_flags.display_table) = 0x2000;
1ab256cb 2196 XFASTINT (buffer_local_flags.syntax_table) = 0x8000;
54ad07d3
RS
2197#ifdef MSDOS
2198 XFASTINT (buffer_local_flags.buffer_file_type) = 0x4000;
2199#endif
1ab256cb
RM
2200
2201 Vbuffer_alist = Qnil;
2202 current_buffer = 0;
2203 all_buffers = 0;
2204
2205 QSFundamental = build_string ("Fundamental");
2206
2207 Qfundamental_mode = intern ("fundamental-mode");
2208 buffer_defaults.major_mode = Qfundamental_mode;
2209
2210 Qmode_class = intern ("mode-class");
2211
2212 Qprotected_field = intern ("protected-field");
2213
2214 Qpermanent_local = intern ("permanent-local");
2215
2216 Qkill_buffer_hook = intern ("kill-buffer-hook");
2217
2218 Vprin1_to_string_buffer = Fget_buffer_create (build_string (" prin1"));
2219 /* super-magic invisible buffer */
2220 Vbuffer_alist = Qnil;
2221
ffd56f97 2222 Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
1ab256cb
RM
2223}
2224
2225init_buffer ()
2226{
2227 char buf[MAXPATHLEN+1];
2381d133
JB
2228 char *pwd;
2229 struct stat dotstat, pwdstat;
136351b7 2230 Lisp_Object temp;
1ab256cb
RM
2231
2232 Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
2381d133
JB
2233
2234 /* If PWD is accurate, use it instead of calling getwd. This is faster
2235 when PWD is right, and may avoid a fatal error. */
2236 if ((pwd = getenv ("PWD")) != 0 && *pwd == '/'
2237 && stat (pwd, &pwdstat) == 0
2238 && stat (".", &dotstat) == 0
2239 && dotstat.st_ino == pwdstat.st_ino
2240 && dotstat.st_dev == pwdstat.st_dev
2241 && strlen (pwd) < MAXPATHLEN)
2242 strcpy (buf, pwd);
2243 else if (getwd (buf) == 0)
1ab256cb
RM
2244 fatal ("`getwd' failed: %s.\n", buf);
2245
2246#ifndef VMS
2247 /* Maybe this should really use some standard subroutine
2248 whose definition is filename syntax dependent. */
2249 if (buf[strlen (buf) - 1] != '/')
2250 strcat (buf, "/");
2251#endif /* not VMS */
2252 current_buffer->directory = build_string (buf);
136351b7
RS
2253
2254 temp = get_minibuffer (0);
2255 XBUFFER (temp)->directory = current_buffer->directory;
1ab256cb
RM
2256}
2257
2258/* initialize the buffer routines */
2259syms_of_buffer ()
2260{
188d4d11
RM
2261 extern Lisp_Object Qdisabled;
2262
1ab256cb
RM
2263 staticpro (&Vbuffer_defaults);
2264 staticpro (&Vbuffer_local_symbols);
2265 staticpro (&Qfundamental_mode);
2266 staticpro (&Qmode_class);
2267 staticpro (&QSFundamental);
2268 staticpro (&Vbuffer_alist);
2269 staticpro (&Qprotected_field);
2270 staticpro (&Qpermanent_local);
2271 staticpro (&Qkill_buffer_hook);
52f8ec73 2272 staticpro (&Qoverlayp);
294d215f
RS
2273 staticpro (&Qmodification_hooks);
2274 Qmodification_hooks = intern ("modification-hooks");
2275 staticpro (&Qinsert_in_front_hooks);
2276 Qinsert_in_front_hooks = intern ("insert-in-front-hooks");
2277 staticpro (&Qinsert_behind_hooks);
2278 Qinsert_behind_hooks = intern ("insert-behind-hooks");
5fe0b67e
RS
2279 staticpro (&Qget_file_buffer);
2280 Qget_file_buffer = intern ("get-file-buffer");
5985d248
KH
2281 Qpriority = intern ("priority");
2282 staticpro (&Qpriority);
2283 Qwindow = intern ("window");
2284 staticpro (&Qwindow);
52f8ec73
JB
2285
2286 Qoverlayp = intern ("overlayp");
1ab256cb
RM
2287
2288 Fput (Qprotected_field, Qerror_conditions,
2289 Fcons (Qprotected_field, Fcons (Qerror, Qnil)));
2290 Fput (Qprotected_field, Qerror_message,
2291 build_string ("Attempt to modify a protected field"));
2292
2293 /* All these use DEFVAR_LISP_NOPRO because the slots in
2294 buffer_defaults will all be marked via Vbuffer_defaults. */
2295
2296 DEFVAR_LISP_NOPRO ("default-mode-line-format",
2297 &buffer_defaults.mode_line_format,
2298 "Default value of `mode-line-format' for buffers that don't override it.\n\
2299This is the same as (default-value 'mode-line-format).");
2300
2301 DEFVAR_LISP_NOPRO ("default-abbrev-mode",
2302 &buffer_defaults.abbrev_mode,
2303 "Default value of `abbrev-mode' for buffers that do not override it.\n\
2304This is the same as (default-value 'abbrev-mode).");
2305
2306 DEFVAR_LISP_NOPRO ("default-ctl-arrow",
2307 &buffer_defaults.ctl_arrow,
2308 "Default value of `ctl-arrow' for buffers that do not override it.\n\
2309This is the same as (default-value 'ctl-arrow).");
2310
2311 DEFVAR_LISP_NOPRO ("default-truncate-lines",
2312 &buffer_defaults.truncate_lines,
2313 "Default value of `truncate-lines' for buffers that do not override it.\n\
2314This is the same as (default-value 'truncate-lines).");
2315
2316 DEFVAR_LISP_NOPRO ("default-fill-column",
2317 &buffer_defaults.fill_column,
2318 "Default value of `fill-column' for buffers that do not override it.\n\
2319This is the same as (default-value 'fill-column).");
2320
2321 DEFVAR_LISP_NOPRO ("default-left-margin",
2322 &buffer_defaults.left_margin,
2323 "Default value of `left-margin' for buffers that do not override it.\n\
2324This is the same as (default-value 'left-margin).");
2325
2326 DEFVAR_LISP_NOPRO ("default-tab-width",
2327 &buffer_defaults.tab_width,
2328 "Default value of `tab-width' for buffers that do not override it.\n\
2329This is the same as (default-value 'tab-width).");
2330
2331 DEFVAR_LISP_NOPRO ("default-case-fold-search",
2332 &buffer_defaults.case_fold_search,
2333 "Default value of `case-fold-search' for buffers that don't override it.\n\
2334This is the same as (default-value 'case-fold-search).");
2335
54ad07d3
RS
2336#ifdef MSDOS
2337 DEFVAR_LISP_NOPRO ("default-buffer-file-type",
2338 &buffer_defaults.buffer_file_type,
2339 "Default file type for buffers that do not override it.\n\
2340This is the same as (default-value 'buffer-file-type).\n\
2341The file type is nil for text, t for binary.");
2342#endif
2343
0fa3ba92
JB
2344 DEFVAR_PER_BUFFER ("mode-line-format", &current_buffer->mode_line_format,
2345 Qnil, 0);
1ab256cb
RM
2346
2347/* This doc string is too long for cpp; cpp dies if it isn't in a comment.
2348 But make-docfile finds it!
2349 DEFVAR_PER_BUFFER ("mode-line-format", &current_buffer->mode_line_format,
bec44fd6 2350 Qnil,
1ab256cb
RM
2351 "Template for displaying mode line for current buffer.\n\
2352Each buffer has its own value of this variable.\n\
2353Value may be a string, a symbol or a list or cons cell.\n\
2354For a symbol, its value is used (but it is ignored if t or nil).\n\
2355 A string appearing directly as the value of a symbol is processed verbatim\n\
2356 in that the %-constructs below are not recognized.\n\
2357For a list whose car is a symbol, the symbol's value is taken,\n\
2358 and if that is non-nil, the cadr of the list is processed recursively.\n\
2359 Otherwise, the caddr of the list (if there is one) is processed.\n\
2360For a list whose car is a string or list, each element is processed\n\
2361 recursively and the results are effectively concatenated.\n\
2362For a list whose car is an integer, the cdr of the list is processed\n\
2363 and padded (if the number is positive) or truncated (if negative)\n\
2364 to the width specified by that number.\n\
2365A string is printed verbatim in the mode line except for %-constructs:\n\
2366 (%-constructs are allowed when the string is the entire mode-line-format\n\
2367 or when it is found in a cons-cell or a list)\n\
2368 %b -- print buffer name. %f -- print visited file name.\n\
2369 %* -- print *, % or hyphen. %m -- print value of mode-name (obsolete).\n\
a97c374a 2370 %s -- print process status. %l -- print the current line number.\n\
1ab256cb
RM
2371 %p -- print percent of buffer above top of window, or top, bot or all.\n\
2372 %n -- print Narrow if appropriate.\n\
54ad07d3 2373 %t -- print T if files is text, B if binary.\n\
1ab256cb
RM
2374 %[ -- print one [ for each recursive editing level. %] similar.\n\
2375 %% -- print %. %- -- print infinitely many dashes.\n\
2376Decimal digits after the % specify field width to which to pad.");
2377*/
2378
2379 DEFVAR_LISP_NOPRO ("default-major-mode", &buffer_defaults.major_mode,
2380 "*Major mode for new buffers. Defaults to `fundamental-mode'.\n\
2381nil here means use current buffer's major mode.");
2382
2383 DEFVAR_PER_BUFFER ("major-mode", &current_buffer->major_mode,
0fa3ba92 2384 make_number (Lisp_Symbol),
1ab256cb
RM
2385 "Symbol for current buffer's major mode.");
2386
2387 DEFVAR_PER_BUFFER ("mode-name", &current_buffer->mode_name,
0fa3ba92 2388 make_number (Lisp_String),
1ab256cb
RM
2389 "Pretty name of current buffer's major mode (a string).");
2390
0fa3ba92 2391 DEFVAR_PER_BUFFER ("abbrev-mode", &current_buffer->abbrev_mode, Qnil,
1ab256cb
RM
2392 "Non-nil turns on automatic expansion of abbrevs as they are inserted.\n\
2393Automatically becomes buffer-local when set in any fashion.");
2394
2395 DEFVAR_PER_BUFFER ("case-fold-search", &current_buffer->case_fold_search,
0fa3ba92 2396 Qnil,
1ab256cb
RM
2397 "*Non-nil if searches should ignore case.\n\
2398Automatically becomes buffer-local when set in any fashion.");
2399
2400 DEFVAR_PER_BUFFER ("fill-column", &current_buffer->fill_column,
0fa3ba92 2401 make_number (Lisp_Int),
1ab256cb
RM
2402 "*Column beyond which automatic line-wrapping should happen.\n\
2403Automatically becomes buffer-local when set in any fashion.");
2404
2405 DEFVAR_PER_BUFFER ("left-margin", &current_buffer->left_margin,
0fa3ba92 2406 make_number (Lisp_Int),
1ab256cb
RM
2407 "*Column for the default indent-line-function to indent to.\n\
2408Linefeed indents to this column in Fundamental mode.\n\
2409Automatically becomes buffer-local when set in any fashion.");
2410
2411 DEFVAR_PER_BUFFER ("tab-width", &current_buffer->tab_width,
0fa3ba92 2412 make_number (Lisp_Int),
1ab256cb
RM
2413 "*Distance between tab stops (for display of tab characters), in columns.\n\
2414Automatically becomes buffer-local when set in any fashion.");
2415
0fa3ba92 2416 DEFVAR_PER_BUFFER ("ctl-arrow", &current_buffer->ctl_arrow, Qnil,
1ab256cb
RM
2417 "*Non-nil means display control chars with uparrow.\n\
2418Nil means use backslash and octal digits.\n\
2419Automatically becomes buffer-local when set in any fashion.\n\
2420This variable does not apply to characters whose display is specified\n\
2421in the current display table (if there is one).");
2422
0fa3ba92 2423 DEFVAR_PER_BUFFER ("truncate-lines", &current_buffer->truncate_lines, Qnil,
1ab256cb
RM
2424 "*Non-nil means do not display continuation lines;\n\
2425give each line of text one screen line.\n\
2426Automatically becomes buffer-local when set in any fashion.\n\
2427\n\
2428Note that this is overridden by the variable\n\
2429`truncate-partial-width-windows' if that variable is non-nil\n\
502b9b64 2430and this buffer is not full-frame width.");
1ab256cb 2431
54ad07d3
RS
2432#ifdef MSDOS
2433 DEFVAR_PER_BUFFER ("buffer-file-type", &current_buffer->buffer_file_type,
2434 Qnil,
2435 "*If visited file is text, nil; otherwise, t.");
2436#endif
2437
1ab256cb 2438 DEFVAR_PER_BUFFER ("default-directory", &current_buffer->directory,
0fa3ba92 2439 make_number (Lisp_String),
1ab256cb
RM
2440 "Name of default directory of current buffer. Should end with slash.\n\
2441Each buffer has its own value of this variable.");
2442
2443 DEFVAR_PER_BUFFER ("auto-fill-function", &current_buffer->auto_fill_function,
0fa3ba92 2444 Qnil,
1ab256cb
RM
2445 "Function called (if non-nil) to perform auto-fill.\n\
2446It is called after self-inserting a space at a column beyond `fill-column'.\n\
2447Each buffer has its own value of this variable.\n\
2448NOTE: This variable is not an ordinary hook;\n\
2449It may not be a list of functions.");
2450
2451 DEFVAR_PER_BUFFER ("buffer-file-name", &current_buffer->filename,
0fa3ba92 2452 make_number (Lisp_String),
1ab256cb
RM
2453 "Name of file visited in current buffer, or nil if not visiting a file.\n\
2454Each buffer has its own value of this variable.");
2455
2456 DEFVAR_PER_BUFFER ("buffer-auto-save-file-name",
3f5fcd47 2457 &current_buffer->auto_save_file_name,
0fa3ba92 2458 make_number (Lisp_String),
1ab256cb
RM
2459 "Name of file for auto-saving current buffer,\n\
2460or nil if buffer should not be auto-saved.\n\
2461Each buffer has its own value of this variable.");
2462
0fa3ba92 2463 DEFVAR_PER_BUFFER ("buffer-read-only", &current_buffer->read_only, Qnil,
1ab256cb
RM
2464 "Non-nil if this buffer is read-only.\n\
2465Each buffer has its own value of this variable.");
2466
0fa3ba92 2467 DEFVAR_PER_BUFFER ("buffer-backed-up", &current_buffer->backed_up, Qnil,
1ab256cb
RM
2468 "Non-nil if this buffer's file has been backed up.\n\
2469Backing up is done before the first time the file is saved.\n\
2470Each buffer has its own value of this variable.");
2471
2472 DEFVAR_PER_BUFFER ("buffer-saved-size", &current_buffer->save_length,
0fa3ba92 2473 make_number (Lisp_Int),
1ab256cb
RM
2474 "Length of current buffer when last read in, saved or auto-saved.\n\
24750 initially.\n\
2476Each buffer has its own value of this variable.");
2477
2478 DEFVAR_PER_BUFFER ("selective-display", &current_buffer->selective_display,
0fa3ba92 2479 Qnil,
1ab256cb
RM
2480 "Non-nil enables selective display:\n\
2481Integer N as value means display only lines\n\
2482 that start with less than n columns of space.\n\
2483A value of t means, after a ^M, all the rest of the line is invisible.\n\
2484 Then ^M's in the file are written into files as newlines.\n\n\
2485Automatically becomes buffer-local when set in any fashion.");
2486
2487#ifndef old
2488 DEFVAR_PER_BUFFER ("selective-display-ellipses",
2489 &current_buffer->selective_display_ellipses,
0fa3ba92 2490 Qnil,
1ab256cb
RM
2491 "t means display ... on previous line when a line is invisible.\n\
2492Automatically becomes buffer-local when set in any fashion.");
2493#endif
2494
0fa3ba92 2495 DEFVAR_PER_BUFFER ("overwrite-mode", &current_buffer->overwrite_mode, Qnil,
1ab256cb 2496 "Non-nil if self-insertion should replace existing text.\n\
6bbb0d4a
JB
2497If non-nil and not `overwrite-mode-binary', self-insertion still\n\
2498inserts at the end of a line, and inserts when point is before a tab,\n\
2e94b813 2499until the tab is filled in.\n\
6bbb0d4a 2500If `overwrite-mode-binary', self-insertion replaces newlines and tabs too.\n\
1ab256cb
RM
2501Automatically becomes buffer-local when set in any fashion.");
2502
54939090
RS
2503#if 0 /* The doc string is too long for some compilers,
2504 but make-docfile can find it in this comment. */
1ab256cb 2505 DEFVAR_PER_BUFFER ("buffer-display-table", &current_buffer->display_table,
5d305367 2506 Qnil,
1ab256cb
RM
2507 "Display table that controls display of the contents of current buffer.\n\
2508Automatically becomes buffer-local when set in any fashion.\n\
2509The display table is a vector created with `make-display-table'.\n\
2510The first 256 elements control how to display each possible text character.\n\
6158b3b0 2511Each value should be a vector of characters or nil;\n\
1ab256cb 2512nil means display the character in the default fashion.\n\
6158b3b0
JB
2513The remaining five elements control the display of\n\
2514 the end of a truncated screen line (element 256, a single character);\n\
2515 the end of a continued line (element 257, a single character);\n\
2516 the escape character used to display character codes in octal\n\
2517 (element 258, a single character);\n\
2518 the character used as an arrow for control characters (element 259,\n\
2519 a single character);\n\
2520 the decoration indicating the presence of invisible lines (element 260,\n\
2521 a vector of characters).\n\
1ab256cb
RM
2522If this variable is nil, the value of `standard-display-table' is used.\n\
2523Each window can have its own, overriding display table.");
54939090
RS
2524#endif
2525 DEFVAR_PER_BUFFER ("buffer-display-table", &current_buffer->display_table,
2526 Qnil, "");
1ab256cb 2527
1ab256cb
RM
2528/*DEFVAR_LISP ("debug-check-symbol", &Vcheck_symbol,
2529 "Don't ask.");
2530*/
01050cb5 2531 DEFVAR_LISP ("before-change-function", &Vbefore_change_function,
1ab256cb
RM
2532 "Function to call before each text change.\n\
2533Two arguments are passed to the function: the positions of\n\
2534the beginning and end of the range of old text to be changed.\n\
2535\(For an insertion, the beginning and end are at the same place.)\n\
2536No information is given about the length of the text after the change.\n\
2537position of the change\n\
2538\n\
2539While executing the `before-change-function', changes to buffers do not\n\
2540cause calls to any `before-change-function' or `after-change-function'.");
2541 Vbefore_change_function = Qnil;
2542
2543 DEFVAR_LISP ("after-change-function", &Vafter_change_function,
2544 "Function to call after each text change.\n\
2545Three arguments are passed to the function: the positions of\n\
2546the beginning and end of the range of changed text,\n\
2547and the length of the pre-change text replaced by that range.\n\
2548\(For an insertion, the pre-change length is zero;\n\
2549for a deletion, that length is the number of characters deleted,\n\
2550and the post-change beginning and end are at the same place.)\n\
2551\n\
2552While executing the `after-change-function', changes to buffers do not\n\
2553cause calls to any `before-change-function' or `after-change-function'.");
2554 Vafter_change_function = Qnil;
2555
dbc4e1c1
JB
2556 DEFVAR_LISP ("first-change-hook", &Vfirst_change_hook,
2557 "A list of functions to call before changing a buffer which is unmodified.\n\
2558The functions are run using the `run-hooks' function.");
2559 Vfirst_change_hook = Qnil;
2560 Qfirst_change_hook = intern ("first-change-hook");
2561 staticpro (&Qfirst_change_hook);
1ab256cb 2562
54939090
RS
2563#if 0 /* The doc string is too long for some compilers,
2564 but make-docfile can find it in this comment. */
3f5fcd47 2565 DEFVAR_PER_BUFFER ("buffer-undo-list", &current_buffer->undo_list, Qnil,
1ab256cb
RM
2566 "List of undo entries in current buffer.\n\
2567Recent changes come first; older changes follow newer.\n\
2568\n\
2569An entry (START . END) represents an insertion which begins at\n\
2570position START and ends at position END.\n\
2571\n\
2572An entry (TEXT . POSITION) represents the deletion of the string TEXT\n\
2573from (abs POSITION). If POSITION is positive, point was at the front\n\
2574of the text being deleted; if negative, point was at the end.\n\
2575\n\
2576An entry (t HIGHWORD LOWWORD) indicates that the buffer had been\n\
2577previously unmodified. HIGHWORD and LOWWORD are the high and low\n\
257816-bit words of the buffer's modification count at the time. If the\n\
2579modification count of the most recent save is different, this entry is\n\
2580obsolete.\n\
2581\n\
483c1fd3
RS
2582An entry (nil PROP VAL BEG . END) indicates that a text property\n\
2583was modified between BEG and END. PROP is the property name,\n\
2584and VAL is the old value.\n\
2585\n\
bec44fd6
JB
2586An entry of the form POSITION indicates that point was at the buffer\n\
2587location given by the integer. Undoing an entry of this form places\n\
2588point at POSITION.\n\
2589\n\
1ab256cb
RM
2590nil marks undo boundaries. The undo command treats the changes\n\
2591between two undo boundaries as a single step to be undone.\n\
2592\n\
bec44fd6 2593If the value of the variable is t, undo information is not recorded.");
54939090
RS
2594#endif
2595 DEFVAR_PER_BUFFER ("buffer-undo-list", &current_buffer->undo_list, Qnil,
2596 "");
1ab256cb 2597
c48f61ef
RS
2598 DEFVAR_PER_BUFFER ("mark-active", &current_buffer->mark_active, Qnil,
2599 "Non-nil means the mark and region are currently active in this buffer.\n\
2600Automatically local in all buffers.");
2601
2602 DEFVAR_LISP ("transient-mark-mode", &Vtransient_mark_mode,
2603 "*Non-nil means deactivate the mark when the buffer contents change.");
2604 Vtransient_mark_mode = Qnil;
2605
0a4469c9 2606 DEFVAR_LISP ("inhibit-read-only", &Vinhibit_read_only,
a96b68f1
RS
2607 "*Non-nil means disregard read-only status of buffers or characters.\n\
2608If the value is t, disregard `buffer-read-only' and all `read-only'\n\
2609text properties. If the value is a list, disregard `buffer-read-only'\n\
2610and disregard a `read-only' text property if the property value\n\
2611is a member of the list.");
2612 Vinhibit_read_only = Qnil;
2613
1ab256cb
RM
2614 defsubr (&Sbuffer_list);
2615 defsubr (&Sget_buffer);
2616 defsubr (&Sget_file_buffer);
2617 defsubr (&Sget_buffer_create);
01050cb5 2618 defsubr (&Sgenerate_new_buffer_name);
1ab256cb
RM
2619 defsubr (&Sbuffer_name);
2620/*defsubr (&Sbuffer_number);*/
2621 defsubr (&Sbuffer_file_name);
2622 defsubr (&Sbuffer_local_variables);
2623 defsubr (&Sbuffer_modified_p);
2624 defsubr (&Sset_buffer_modified_p);
2625 defsubr (&Sbuffer_modified_tick);
2626 defsubr (&Srename_buffer);
2627 defsubr (&Sother_buffer);
2628 defsubr (&Sbuffer_disable_undo);
2629 defsubr (&Sbuffer_enable_undo);
2630 defsubr (&Skill_buffer);
2631 defsubr (&Serase_buffer);
2632 defsubr (&Sswitch_to_buffer);
2633 defsubr (&Spop_to_buffer);
2634 defsubr (&Scurrent_buffer);
2635 defsubr (&Sset_buffer);
2636 defsubr (&Sbarf_if_buffer_read_only);
2637 defsubr (&Sbury_buffer);
2638 defsubr (&Slist_buffers);
2639 defsubr (&Skill_all_local_variables);
2eec3b4e 2640
52f8ec73 2641 defsubr (&Soverlayp);
2eec3b4e
RS
2642 defsubr (&Smake_overlay);
2643 defsubr (&Sdelete_overlay);
2644 defsubr (&Smove_overlay);
8ebafa8d
JB
2645 defsubr (&Soverlay_start);
2646 defsubr (&Soverlay_end);
2647 defsubr (&Soverlay_buffer);
2648 defsubr (&Soverlay_properties);
2eec3b4e
RS
2649 defsubr (&Soverlays_at);
2650 defsubr (&Snext_overlay_change);
2651 defsubr (&Soverlay_recenter);
2652 defsubr (&Soverlay_lists);
2653 defsubr (&Soverlay_get);
2654 defsubr (&Soverlay_put);
1ab256cb
RM
2655}
2656
2657keys_of_buffer ()
2658{
2659 initial_define_key (control_x_map, 'b', "switch-to-buffer");
2660 initial_define_key (control_x_map, 'k', "kill-buffer");
2661 initial_define_key (control_x_map, Ctl ('B'), "list-buffers");
4158c17d
RM
2662
2663 /* This must not be in syms_of_buffer, because Qdisabled is not
2664 initialized when that function gets called. */
2665 Fput (intern ("erase-buffer"), Qdisabled, Qt);
1ab256cb 2666}