summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c237
1 files changed, 136 insertions, 101 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 6c31b83572d..57d88b0f791 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -100,17 +100,6 @@ DECL_ALIGN (struct buffer, buffer_local_symbols);
/* A Lisp_Object pointer to the above, used for staticpro */
static Lisp_Object Vbuffer_local_symbols;
-/* This structure holds the required types for the values in the
- buffer-local slots. If a slot contains Qnil, then the
- corresponding buffer slot may contain a value of any type. If a
- slot contains an integer, then prospective values' tags must be
- equal to that integer (except nil is always allowed).
- When a tag does not match, the function
- buffer_slot_type_mismatch will signal an error.
-
- If a slot here contains -1, the corresponding variable is read-only. */
-struct buffer buffer_local_types;
-
/* Flags indicating which built-in buffer-local variables
are permanent locals. */
static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
@@ -119,12 +108,14 @@ static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
int last_per_buffer_idx;
-Lisp_Object Fset_buffer ();
-void set_buffer_internal ();
-void set_buffer_internal_1 ();
-static void call_overlay_mod_hooks ();
-static void swap_out_buffer_local_variables ();
-static void reset_buffer_local_variables ();
+EXFUN (Fset_buffer, 1);
+void set_buffer_internal P_ ((struct buffer *b));
+void set_buffer_internal_1 P_ ((struct buffer *b));
+static void call_overlay_mod_hooks P_ ((Lisp_Object list, Lisp_Object overlay,
+ int after, Lisp_Object arg1,
+ Lisp_Object arg2, Lisp_Object arg3));
+static void swap_out_buffer_local_variables P_ ((struct buffer *b));
+static void reset_buffer_local_variables P_ ((struct buffer *b, int permanent_too));
/* Alist of all buffer names vs the buffers. */
/* This used to be a variable, but is no longer,
@@ -216,25 +207,38 @@ frame parameter come first, followed by the rest of the buffers. */)
(frame)
Lisp_Object frame;
{
- Lisp_Object framelist, general;
+ Lisp_Object general;
general = Fmapcar (Qcdr, Vbuffer_alist);
if (FRAMEP (frame))
{
- Lisp_Object tail;
+ Lisp_Object framelist, prevlist, tail;
+ Lisp_Object args[3];
CHECK_FRAME (frame);
framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
+ prevlist = Fnreverse (Fcopy_sequence (XFRAME (frame)->buried_buffer_list));
- /* Remove from GENERAL any buffer that duplicates one in FRAMELIST. */
+ /* Remove from GENERAL any buffer that duplicates one in
+ FRAMELIST or PREVLIST. */
tail = framelist;
- while (! NILP (tail))
+ while (CONSP (tail))
+ {
+ general = Fdelq (XCAR (tail), general);
+ tail = XCDR (tail);
+ }
+ tail = prevlist;
+ while (CONSP (tail))
{
general = Fdelq (XCAR (tail), general);
tail = XCDR (tail);
}
- return nconc2 (framelist, general);
+
+ args[0] = framelist;
+ args[1] = general;
+ args[2] = prevlist;
+ return Fnconc (3, args);
}
return general;
@@ -347,9 +351,7 @@ The value is never nil. */)
if (SCHARS (name) == 0)
error ("Empty string for buffer name is not allowed");
- b = (struct buffer *) allocate_buffer ();
-
- b->size = sizeof (struct buffer) / sizeof (EMACS_INT);
+ b = allocate_buffer ();
/* An ordinary buffer uses its own struct buffer_text. */
b->text = &b->own_text;
@@ -404,10 +406,7 @@ The value is never nil. */)
STRING_SET_INTERVALS (name, NULL_INTERVAL);
b->name = name;
- if (SREF (name, 0) != ' ')
- b->undo_list = Qnil;
- else
- b->undo_list = Qt;
+ b->undo_list = (SREF (name, 0) != ' ') ? Qnil : Qt;
reset_buffer (b);
reset_buffer_local_variables (b, 1);
@@ -553,13 +552,11 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
if (SCHARS (name) == 0)
error ("Empty string for buffer name is not allowed");
- b = (struct buffer *) allocate_buffer ();
- b->size = sizeof (struct buffer) / sizeof (EMACS_INT);
+ b = allocate_buffer ();
- if (XBUFFER (base_buffer)->base_buffer)
- b->base_buffer = XBUFFER (base_buffer)->base_buffer;
- else
- b->base_buffer = XBUFFER (base_buffer);
+ b->base_buffer = (XBUFFER (base_buffer)->base_buffer
+ ? XBUFFER (base_buffer)->base_buffer
+ : XBUFFER (base_buffer));
/* Use the base buffer's text object. */
b->text = b->base_buffer->text;
@@ -722,7 +719,7 @@ reset_buffer (b)
it does not treat permanent locals consistently.
Instead, use Fkill_all_local_variables.
- If PERMANENT_TOO is 1, then we reset permanent built-in
+ If PERMANENT_TOO is 1, then we reset permanent
buffer-local variables. If PERMANENT_TOO is 0,
we preserve those. */
@@ -760,7 +757,23 @@ reset_buffer_local_variables (b, permanent_too)
#endif
/* Reset all (or most) per-buffer variables to their defaults. */
- b->local_var_alist = Qnil;
+ if (permanent_too)
+ b->local_var_alist = Qnil;
+ else
+ {
+ Lisp_Object tmp, last = Qnil;
+ for (tmp = b->local_var_alist; CONSP (tmp); tmp = XCDR (tmp))
+ if (CONSP (XCAR (tmp))
+ && SYMBOLP (XCAR (XCAR (tmp)))
+ && !NILP (Fget (XCAR (XCAR (tmp)), Qpermanent_local)))
+ /* If permanent-local, keep it. */
+ last = tmp;
+ else if (NILP (last))
+ b->local_var_alist = XCDR (tmp);
+ else
+ XSETCDR (last, XCDR (tmp));
+ }
+
for (i = 0; i < last_per_buffer_idx; ++i)
if (permanent_too || buffer_permanent_local_flags[i] == 0)
SET_PER_BUFFER_VALUE_P (b, i, 0);
@@ -890,8 +903,7 @@ is the default binding of the variable. */)
CHECK_BUFFER (buffer);
buf = XBUFFER (buffer);
- if (SYMBOLP (variable))
- variable = indirect_variable (variable);
+ variable = indirect_variable (variable);
/* Look in local_var_list */
result = Fassoc (variable, buf->local_var_alist);
@@ -1176,7 +1188,9 @@ buffer as BUFFER. */)
}
DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2,
- "sRename buffer (to new name): \nP",
+ "(list (read-string \"Rename buffer (to new name): \" \
+ nil 'buffer-name-history (buffer-name (current-buffer))) \
+ current-prefix-arg)",
doc: /* Change current buffer's name to NEWNAME (a string).
If second arg UNIQUE is nil or omitted, it is an error if a
buffer named NEWNAME already exists.
@@ -1584,6 +1598,23 @@ record_buffer (buf)
XSETCDR (link, Vbuffer_alist);
Vbuffer_alist = link;
+ /* Effectively do a delq on buried_buffer_list. */
+
+ prev = Qnil;
+ for (link = XFRAME (frame)->buried_buffer_list; CONSP (link);
+ link = XCDR (link))
+ {
+ if (EQ (XCAR (link), buf))
+ {
+ if (NILP (prev))
+ XFRAME (frame)->buried_buffer_list = XCDR (link);
+ else
+ XSETCDR (prev, XCDR (XCDR (prev)));
+ break;
+ }
+ prev = link;
+ }
+
/* Now move this buffer to the front of frame_buffer_list also. */
prev = Qnil;
@@ -1887,8 +1918,7 @@ set_buffer_internal_1 (b)
for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail))
{
valcontents = SYMBOL_VALUE (XCAR (XCAR (tail)));
- if ((BUFFER_LOCAL_VALUEP (valcontents)
- || SOME_BUFFER_LOCAL_VALUEP (valcontents))
+ if ((BUFFER_LOCAL_VALUEP (valcontents))
&& (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
(BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
/* Just reference the variable
@@ -1902,8 +1932,7 @@ set_buffer_internal_1 (b)
for (tail = old_buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
{
valcontents = SYMBOL_VALUE (XCAR (XCAR (tail)));
- if ((BUFFER_LOCAL_VALUEP (valcontents)
- || SOME_BUFFER_LOCAL_VALUEP (valcontents))
+ if ((BUFFER_LOCAL_VALUEP (valcontents))
&& (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
(BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
/* Just reference the variable
@@ -2066,10 +2095,10 @@ selected window if it is displayed there. */)
XSETCDR (link, Qnil);
Vbuffer_alist = nconc2 (Vbuffer_alist, link);
- /* Removing BUFFER from frame-specific lists
- has the effect of putting BUFFER at the end
- of the combined list in each frame. */
- frames_discard_buffer (buffer);
+ XFRAME (selected_frame)->buffer_list
+ = Fdelq (buffer, XFRAME (selected_frame)->buffer_list);
+ XFRAME (selected_frame)->buried_buffer_list
+ = Fcons (buffer, Fdelq (buffer, XFRAME (selected_frame)->buried_buffer_list));
}
return Qnil;
@@ -2443,14 +2472,10 @@ The first thing this function does is run
the normal hook `change-major-mode-hook'. */)
()
{
- register Lisp_Object alist, sym, tem;
- Lisp_Object oalist;
-
if (!NILP (Vrun_hooks))
call1 (Vrun_hooks, Qchange_major_mode_hook);
- oalist = current_buffer->local_var_alist;
- /* Make sure none of the bindings in oalist
+ /* Make sure none of the bindings in local_var_alist
remain swapped in, in their symbols. */
swap_out_buffer_local_variables (current_buffer);
@@ -2459,20 +2484,6 @@ the normal hook `change-major-mode-hook'. */)
reset_buffer_local_variables (current_buffer, 0);
- /* Any which are supposed to be permanent,
- make local again, with the same values they had. */
-
- for (alist = oalist; !NILP (alist); alist = XCDR (alist))
- {
- sym = XCAR (XCAR (alist));
- tem = Fget (sym, Qpermanent_local);
- if (! NILP (tem))
- {
- Fmake_local_variable (sym);
- Fset (sym, XCDR (XCAR (alist)));
- }
- }
-
/* Force mode-line redisplay. Useful here because all major mode
commands call this function. */
update_mode_lines++;
@@ -2492,32 +2503,17 @@ swap_out_buffer_local_variables (b)
XSETBUFFER (buffer, b);
oalist = b->local_var_alist;
- for (alist = oalist; !NILP (alist); alist = XCDR (alist))
+ for (alist = oalist; CONSP (alist); alist = XCDR (alist))
{
sym = XCAR (XCAR (alist));
/* Need not do anything if some other buffer's binding is now encached. */
tem = XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer;
- if (BUFFERP (tem) && XBUFFER (tem) == current_buffer)
+ if (EQ (tem, buffer))
{
- /* Symbol is set up for this buffer's old local value.
- Set it up for the current buffer with the default value. */
-
- tem = XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->cdr;
- /* Store the symbol's current value into the alist entry
- it is currently set up for. This is so that, if the
- local is marked permanent, and we make it local again
- later in Fkill_all_local_variables, we don't lose the value. */
- XSETCDR (XCAR (tem),
- do_symval_forwarding (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue));
- /* Switch to the symbol's default-value alist entry. */
- XSETCAR (tem, tem);
- /* Mark it as current for buffer B. */
- XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer = buffer;
- /* Store the current value into any forwarding in the symbol. */
- store_symval_forwarding (sym,
- XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue,
- XCDR (tem), NULL);
+ /* Symbol is set up for this buffer's old local value:
+ swap it out! */
+ swap_in_global_binding (sym);
}
}
}
@@ -4187,15 +4183,8 @@ add_overlay_mod_hooklist (functionlist, overlay)
int oldsize = XVECTOR (last_overlay_modification_hooks)->size;
if (last_overlay_modification_hooks_used == oldsize)
- {
- Lisp_Object old;
- old = last_overlay_modification_hooks;
- last_overlay_modification_hooks
- = Fmake_vector (make_number (oldsize * 2), Qnil);
- bcopy (XVECTOR (old)->contents,
- XVECTOR (last_overlay_modification_hooks)->contents,
- sizeof (Lisp_Object) * oldsize);
- }
+ last_overlay_modification_hooks = larger_vector
+ (last_overlay_modification_hooks, oldsize * 2, Qnil);
AREF (last_overlay_modification_hooks, last_overlay_modification_hooks_used++) = functionlist;
AREF (last_overlay_modification_hooks, last_overlay_modification_hooks_used++) = overlay;
}
@@ -4405,13 +4394,13 @@ evaporate_overlays (pos)
in the slot with offset OFFSET. */
void
-buffer_slot_type_mismatch (offset)
- int offset;
+buffer_slot_type_mismatch (sym, type)
+ Lisp_Object sym;
+ int type;
{
- Lisp_Object sym;
char *type_name;
- switch (XINT (PER_BUFFER_TYPE (offset)))
+ switch (type)
{
case Lisp_Int:
type_name = "integers";
@@ -4429,7 +4418,6 @@ buffer_slot_type_mismatch (offset)
abort ();
}
- sym = PER_BUFFER_SYMBOL (offset);
error ("Only %s should be stored in the buffer-local variable %s",
type_name, SDATA (SYMBOL_NAME (sym)));
}
@@ -5007,7 +4995,9 @@ init_buffer_once ()
buffer_local_symbols.text = &buffer_local_symbols.own_text;
BUF_INTERVALS (&buffer_defaults) = 0;
BUF_INTERVALS (&buffer_local_symbols) = 0;
+ XSETPVECTYPE (&buffer_defaults, PVEC_BUFFER);
XSETBUFFER (Vbuffer_defaults, &buffer_defaults);
+ XSETPVECTYPE (&buffer_local_symbols, PVEC_BUFFER);
XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols);
/* Set up the default values of various buffer slots. */
@@ -5246,6 +5236,46 @@ init_buffer ()
free (pwd);
}
+/* Similar to defvar_lisp but define a variable whose value is the Lisp
+ Object stored in the current buffer. address is the address of the slot
+ in the buffer that is current now. */
+
+/* TYPE is nil for a general Lisp variable.
+ An integer specifies a type; then only LIsp values
+ with that type code are allowed (except that nil is allowed too).
+ LNAME is the LIsp-level variable name.
+ VNAME is the name of the buffer slot.
+ DOC is a dummy where you write the doc string as a comment. */
+#define DEFVAR_PER_BUFFER(lname, vname, type, doc) \
+ defvar_per_buffer (lname, vname, type, 0)
+
+static void
+defvar_per_buffer (namestring, address, type, doc)
+ char *namestring;
+ Lisp_Object *address;
+ Lisp_Object type;
+ char *doc;
+{
+ Lisp_Object sym, val;
+ int offset;
+
+ sym = intern (namestring);
+ val = allocate_misc ();
+ offset = (char *)address - (char *)current_buffer;
+
+ XMISCTYPE (val) = Lisp_Misc_Buffer_Objfwd;
+ XBUFFER_OBJFWD (val)->offset = offset;
+ XBUFFER_OBJFWD (val)->slottype = type;
+ SET_SYMBOL_VALUE (sym, val);
+ PER_BUFFER_SYMBOL (offset) = sym;
+
+ if (PER_BUFFER_IDX (offset) == 0)
+ /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
+ slot of buffer_local_flags */
+ abort ();
+}
+
+
/* initialize the buffer routines */
void
syms_of_buffer ()
@@ -5506,6 +5536,8 @@ A string is printed verbatim in the mode line except for %-constructs:
%z -- print mnemonics of keyboard, terminal, and buffer coding systems.
%Z -- like %z, but including the end-of-line format.
%e -- print error message about full memory.
+ %@ -- print @ or hyphen. @ means that default-directory is on a
+ remote machine.
%[ -- print one [ for each recursive editing level. %] similar.
%% -- print %. %- -- print infinitely many dashes.
Decimal digits after the % specify field width to which to pad. */);
@@ -5529,6 +5561,9 @@ its hooks should not expect certain variables such as
Qnil,
doc: /* Pretty name of current buffer's major mode (a string). */);
+ DEFVAR_PER_BUFFER ("local-abbrev-table", &current_buffer->abbrev_table, Qnil,
+ doc: /* Local (mode-specific) abbrev table of current buffer. */);
+
DEFVAR_PER_BUFFER ("abbrev-mode", &current_buffer->abbrev_mode, Qnil,
doc: /* Non-nil turns on automatic expansion of abbrevs as they are inserted. */);