/* Buffer manipulation primitives for GNU Emacs.
Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994,
1995, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007, 2008
+ 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <sys/param.h>
#include <errno.h>
#include <stdio.h>
-
-#ifndef USE_CRT_DLL
-extern int errno;
-#endif
-
+#include <setjmp.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
be a DEFVAR_PER_BUFFER for the slot, there is no default value for it;
and the corresponding slot in buffer_defaults is not used.
- If a slot is -2, then there is no DEFVAR_PER_BUFFER for it,
- but there is a default value which is copied into each buffer.
-
If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is
zero, that is a bug */
/* A Lisp_Object pointer to the above, used for staticpro */
static Lisp_Object Vbuffer_local_symbols;
+/* Return the symbol of the per-buffer variable at offset OFFSET in
+ the buffer structure. */
+
+#define PER_BUFFER_SYMBOL(OFFSET) \
+ (*(Lisp_Object *)((OFFSET) + (char *) &buffer_local_symbols))
+
/* Flags indicating which built-in buffer-local variables
are permanent locals. */
static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
continue;
obj = PER_BUFFER_VALUE (from, offset);
- if (MARKERP (obj))
+ if (MARKERP (obj) && XMARKER (obj)->buffer == from)
{
struct Lisp_Marker *m = XMARKER (obj);
obj = Fmake_marker ();
b->file_truename = Qnil;
b->directory = (current_buffer) ? current_buffer->directory : Qnil;
b->modtime = 0;
+ b->modtime_size = -1;
XSETFASTINT (b->save_length, 0);
b->last_window_start = 1;
/* It is more conservative to start out "changed" than "unchanged". */
b->clip_changed = 0;
b->prevent_redisplay_optimizations_p = 1;
b->backed_up = Qnil;
- b->auto_save_modified = 0;
+ BUF_AUTOSAVE_MODIFF (b) = 0;
b->auto_save_failure_time = -1;
b->auto_save_file_name = Qnil;
b->read_only = Qnil;
{
Lisp_Object tmp, prop, last = Qnil;
for (tmp = b->local_var_alist; CONSP (tmp); tmp = XCDR (tmp))
- if (CONSP (XCAR (tmp))
- && SYMBOLP (XCAR (XCAR (tmp)))
- && !NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local)))
+ if (!NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local)))
{
/* If permanent-local, keep it. */
last = tmp;
int idx = PER_BUFFER_IDX (offset);
if ((idx > 0
&& (permanent_too
- || buffer_permanent_local_flags[idx] == 0))
- /* Is -2 used anywhere? */
- || idx == -2)
+ || buffer_permanent_local_flags[idx] == 0)))
PER_BUFFER_VALUE (b, offset) = PER_BUFFER_DEFAULT (offset);
}
}
\f
DEFUN ("buffer-name", Fbuffer_name, Sbuffer_name, 0, 1, 0,
doc: /* Return the name of BUFFER, as a string.
-With no argument or nil as argument, return the name of the current buffer. */)
+BUFFER defaults to the current buffer.
+Return nil if BUFFER has been killed. */)
(buffer)
register Lisp_Object buffer;
{
CHECK_SYMBOL (variable);
CHECK_BUFFER (buffer);
buf = XBUFFER (buffer);
+ sym = XSYMBOL (variable);
- sym = indirect_variable (XSYMBOL (variable));
- XSETSYMBOL (variable, sym);
-
- /* Look in local_var_list */
- result = Fassoc (variable, buf->local_var_alist);
- if (NILP (result))
+ start:
+ switch (sym->redirect)
{
- int offset, idx;
- int found = 0;
-
- /* Look in special slots */
- /* buffer-local Lisp variables start at `undo_list',
- tho only the ones from `name' on are GC'd normally. */
- for (offset = PER_BUFFER_VAR_OFFSET (undo_list);
- offset < sizeof (struct buffer);
- /* sizeof EMACS_INT == sizeof Lisp_Object */
- offset += (sizeof (EMACS_INT)))
- {
- idx = PER_BUFFER_IDX (offset);
- if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
- && SYMBOLP (PER_BUFFER_SYMBOL (offset))
- && EQ (PER_BUFFER_SYMBOL (offset), variable))
- {
- result = PER_BUFFER_VALUE (buf, offset);
- found = 1;
- break;
- }
- }
-
- if (!found)
- result = Fdefault_value (variable);
- }
- else
- {
- Lisp_Object valcontents;
- Lisp_Object current_alist_element;
-
- /* What binding is loaded right now? */
- valcontents = sym->value;
- current_alist_element
- = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr);
-
- /* The value of the currently loaded binding is not
- stored in it, but rather in the realvalue slot.
- Store that value into the binding it belongs to
- in case that is the one we are about to use. */
+ case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
+ case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break;
+ case SYMBOL_LOCALIZED:
+ { /* Look in local_var_alist. */
+ struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
+ XSETSYMBOL (variable, sym); /* Update In case of aliasing. */
+ result = Fassoc (variable, buf->local_var_alist);
+ if (!NILP (result))
+ {
+ if (blv->fwd)
+ { /* What binding is loaded right now? */
+ Lisp_Object current_alist_element = blv->valcell;
- Fsetcdr (current_alist_element,
- do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue));
+ /* The value of the currently loaded binding is not
+ stored in it, but rather in the realvalue slot.
+ Store that value into the binding it belongs to
+ in case that is the one we are about to use. */
- /* Now get the (perhaps updated) value out of the binding. */
- result = XCDR (result);
+ XSETCDR (current_alist_element,
+ do_symval_forwarding (blv->fwd));
+ }
+ /* Now get the (perhaps updated) value out of the binding. */
+ result = XCDR (result);
+ }
+ else
+ result = Fdefault_value (variable);
+ break;
+ }
+ case SYMBOL_FORWARDED:
+ {
+ union Lisp_Fwd *fwd = SYMBOL_FWD (sym);
+ if (BUFFER_OBJFWDP (fwd))
+ result = PER_BUFFER_VALUE (buf, XBUFFER_OBJFWD (fwd)->offset);
+ else
+ result = Fdefault_value (variable);
+ break;
+ }
+ default: abort ();
}
if (!EQ (result, Qunbound))
if (buf != current_buffer)
val = XCDR (elt);
- /* If symbol is unbound, put just the symbol in the list. */
- if (EQ (val, Qunbound))
- result = Fcons (XCAR (elt), result);
- /* Otherwise, put (symbol . value) in the list. */
- else
- result = Fcons (Fcons (XCAR (elt), val), result);
+ result = Fcons (Fcons (XCAR (elt), val), result);
}
return result;
}
#endif /* CLASH_DETECTION */
- SAVE_MODIFF = NILP (flag) ? MODIFF : 0;
+ /* Here we have a problem. SAVE_MODIFF is used here to encode
+ buffer-modified-p (as SAVE_MODIFF<MODIFF) as well as
+ recent-auto-save-p (as SAVE_MODIFF<auto_save_modified). So if we
+ modify SAVE_MODIFF to affect one, we may affect the other
+ as well.
+ E.g. if FLAG is nil we need to set SAVE_MODIFF to MODIFF, but
+ if SAVE_MODIFF<auto_save_modified that means we risk changing
+ recent-auto-save-p from t to nil.
+ Vice versa, if FLAG is non-nil and SAVE_MODIFF>=auto_save_modified
+ we risk changing recent-auto-save-p from nil to t. */
+ SAVE_MODIFF = (NILP (flag)
+ /* FIXME: This unavoidably sets recent-auto-save-p to nil. */
+ ? MODIFF
+ /* Let's try to preserve recent-auto-save-p. */
+ : SAVE_MODIFF < MODIFF ? SAVE_MODIFF
+ /* If SAVE_MODIFF == auto_save_modified == MODIFF,
+ we can either decrease SAVE_MODIFF and auto_save_modified
+ or increase MODIFF. */
+ : MODIFF++);
/* Set update_mode_lines only if buffer is displayed in some window.
Packages like jit-lock or lazy-lock preserve a buffer's modified
if (NILP (frame))
frame = selected_frame;
+ CHECK_FRAME (frame);
+
tail = Vbuffer_alist;
pred = frame_buffer_predicate (frame);
/* Delete any auto-save file, if we saved it in this session.
But not if the buffer is modified. */
if (STRINGP (b->auto_save_file_name)
- && b->auto_save_modified != 0
- && BUF_SAVE_MODIFF (b) < b->auto_save_modified
+ && BUF_AUTOSAVE_MODIFF (b) != 0
+ && BUF_SAVE_MODIFF (b) < BUF_AUTOSAVE_MODIFF (b)
&& BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
&& NILP (Fsymbol_value (intern ("auto-save-visited-file-name"))))
{
DEFUN ("switch-to-buffer", Fswitch_to_buffer, Sswitch_to_buffer, 1, 2,
"(list (read-buffer-to-switch \"Switch to buffer: \"))",
- doc: /* Make BUFFER-OR-NAME current and display it in the selected window.
-BUFFER-OR-NAME may be a buffer, a string, or nil. If BUFFER-OR-NAME is
-nil, then this function chooses a buffer using `other-buffer'. If
-BUFFER-OR-NAME is a string and does not identify an existing buffer,
-then this function creates a buffer with that name.
+ doc: /* Make BUFFER-OR-NAME current and display it in selected window.
+BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
+nil. Return the buffer switched to.
+
+If BUFFER-OR-NAME is a string and does not identify an existing
+buffer, create a new buffer with that name. Interactively, if
+`confirm-nonexistent-file-or-buffer' is non-nil, request
+confirmation before creating a new buffer. If BUFFER-OR-NAME is
+nil, switch to buffer returned by `other-buffer'.
-Optional second arg NORECORD non-nil means do not put this buffer at the
-front of the list of recently selected ones. This function returns the
-buffer it switched to as a Lisp object.
+Optional second arg NORECORD non-nil means do not put this buffer
+at the front of the list of recently selected ones. This
+function returns the buffer it switched to as a Lisp object.
-If the selected window is the minibuffer window or dedicated to its
-buffer, use `pop-to-buffer' for displaying the buffer.
+If the selected window is the minibuffer window or dedicated to
+its buffer, use `pop-to-buffer' for displaying the buffer.
WARNING: This is NOT the way to work on another buffer temporarily
-within a Lisp program! Use `set-buffer' instead. That avoids messing
-with the window-buffer correspondences. */)
+within a Lisp program! Use `set-buffer' instead. That avoids
+messing with the window-buffer correspondences. */)
(buffer_or_name, norecord)
Lisp_Object buffer_or_name, norecord;
{
- char *err;
-
if (EQ (buffer_or_name, Fwindow_buffer (selected_window)))
{
/* Basically a NOP. Avoid signalling an error in the case where
record_buffer (buffer_or_name);
return Fset_buffer (buffer_or_name);
}
-
- if (EQ (minibuf_window, selected_window)
- || !NILP (Fwindow_dedicated_p (selected_window)))
+ else if (EQ (minibuf_window, selected_window)
+ /* If `dedicated' is neither nil nor t, it means it's
+ dedicatedness can be overridden by an explicit request
+ such as a call to switch-to-buffer. */
+ || EQ (Fwindow_dedicated_p (selected_window), Qt))
/* We can't use the selected window so let `pop-to-buffer' try some
other window. */
return call3 (intern ("pop-to-buffer"), buffer_or_name, Qnil, norecord);
register struct buffer *b;
{
register struct buffer *old_buf;
- register Lisp_Object tail, valcontents;
- Lisp_Object tem;
+ register Lisp_Object tail;
#ifdef USE_MMAP_FOR_BUFFERS
if (b->text->beg == NULL)
/* Look down buffer's list of local Lisp variables
to find and update any that forward into C variables. */
- for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail))
+ do
{
- valcontents = SYMBOL_VALUE (XCAR (XCAR (tail)));
- if ((BUFFER_LOCAL_VALUEP (valcontents))
- && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
- (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
- /* Just reference the variable
- to cause it to become set for this buffer. */
- Fsymbol_value (XCAR (XCAR (tail)));
+ for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail))
+ {
+ Lisp_Object var = XCAR (XCAR (tail));
+ struct Lisp_Symbol *sym = XSYMBOL (var);
+ if (sym->redirect == SYMBOL_LOCALIZED /* Just to be sure. */
+ && SYMBOL_BLV (sym)->fwd)
+ /* Just reference the variable
+ to cause it to become set for this buffer. */
+ Fsymbol_value (var);
+ }
}
-
/* Do the same with any others that were local to the previous buffer */
-
- if (old_buf)
- for (tail = old_buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
- {
- valcontents = SYMBOL_VALUE (XCAR (XCAR (tail)));
- if ((BUFFER_LOCAL_VALUEP (valcontents))
- && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
- (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
- /* Just reference the variable
- to cause it to become set for this buffer. */
- Fsymbol_value (XCAR (XCAR (tail)));
- }
+ while (b != old_buf && (b = old_buf, b));
}
/* Switch to buffer B temporarily for redisplay purposes.
return byte_pos;
}
+#ifdef REL_ALLOC
+extern void r_alloc_reset_variable P_ ((POINTER_TYPE *, POINTER_TYPE *));
+#endif /* REL_ALLOC */
+
DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
1, 1, 0,
doc: /* Swap the text between current buffer and BUFFER. */)
CHECK_BUFFER (buffer);
other_buffer = XBUFFER (buffer);
+ if (NILP (other_buffer->name))
+ error ("Cannot swap a dead buffer's text");
+
/* Actually, it probably works just fine.
* if (other_buffer == current_buffer)
* error ("Cannot swap a buffer's text with itself"); */
swapfield (own_text, struct buffer_text);
eassert (current_buffer->text == ¤t_buffer->own_text);
eassert (other_buffer->text == &other_buffer->own_text);
+#ifdef REL_ALLOC
+ r_alloc_reset_variable ((POINTER_TYPE **) ¤t_buffer->own_text.beg,
+ (POINTER_TYPE **) &other_buffer->own_text.beg);
+ r_alloc_reset_variable ((POINTER_TYPE **) &other_buffer->own_text.beg,
+ (POINTER_TYPE **) ¤t_buffer->own_text.beg);
+#endif /* REL_ALLOC */
+
swapfield (pt, EMACS_INT);
swapfield (pt_byte, EMACS_INT);
swapfield (begv, EMACS_INT);
swapfield (overlay_center, EMACS_INT);
swapfield (undo_list, Lisp_Object);
swapfield (mark, Lisp_Object);
- if (MARKERP (current_buffer->mark) && XMARKER (current_buffer->mark)->buffer)
- XMARKER (current_buffer->mark)->buffer = current_buffer;
- if (MARKERP (other_buffer->mark) && XMARKER (other_buffer->mark)->buffer)
- XMARKER (other_buffer->mark)->buffer = other_buffer;
swapfield (enable_multibyte_characters, Lisp_Object);
+ swapfield (bidi_display_reordering, Lisp_Object);
+ swapfield (bidi_paragraph_direction, Lisp_Object);
/* FIXME: Not sure what we should do with these *_marker fields.
Hopefully they're just nil anyway. */
swapfield (pt_marker, Lisp_Object);
current_buffer->text->overlay_modiff++; other_buffer->text->overlay_modiff++;
current_buffer->text->beg_unchanged = current_buffer->text->gpt;
current_buffer->text->end_unchanged = current_buffer->text->gpt;
- other_buffer->text->beg_unchanged = current_buffer->text->gpt;
- other_buffer->text->end_unchanged = current_buffer->text->gpt;
+ other_buffer->text->beg_unchanged = other_buffer->text->gpt;
+ other_buffer->text->end_unchanged = other_buffer->text->gpt;
{
struct Lisp_Marker *m;
for (m = BUF_MARKERS (current_buffer); m; m = m->next)
if (m->buffer == other_buffer)
m->buffer = current_buffer;
+ else
+ /* Since there's no indirect buffer in sight, markers on
+ BUF_MARKERS(buf) should either be for `buf' or dead. */
+ eassert (!m->buffer);
for (m = BUF_MARKERS (other_buffer); m; m = m->next)
if (m->buffer == current_buffer)
m->buffer = other_buffer;
+ else
+ /* Since there's no indirect buffer in sight, markers on
+ BUF_MARKERS(buf) should either be for `buf' or dead. */
+ eassert (!m->buffer);
}
{ /* Some of the C code expects that w->buffer == w->pointm->buffer.
So since we just swapped the markers between the two buffers, we need
p++, pos++;
else if (CHAR_BYTE8_HEAD_P (*p))
{
- c = STRING_CHAR_AND_LENGTH (p, stop - pos, bytes);
+ c = STRING_CHAR_AND_LENGTH (p, bytes);
/* Delete all bytes for this 8-bit character but the
last one, and change the last one to the charcter
code. */
unsigned char *p = GPT_ADDR - 1;
while (! CHAR_HEAD_P (*p) && p > BEG_ADDR) p--;
- if (BASE_LEADING_CODE_P (*p))
+ if (LEADING_CODE_P (*p))
{
int new_gpt = GPT_BYTE - (GPT_ADDR - p);
if (ASCII_BYTE_P (*p))
p++, pos++;
- else if (EQ (flag, Qt) && (bytes = MULTIBYTE_LENGTH (p, pend)) > 0)
+ else if (EQ (flag, Qt)
+ && ! CHAR_BYTE8_HEAD_P (*p)
+ && (bytes = MULTIBYTE_LENGTH (p, pend)) > 0)
p += bytes, pos += bytes;
else
{
swap_out_buffer_local_variables (b)
struct buffer *b;
{
- Lisp_Object oalist, alist, sym, tem, buffer;
+ Lisp_Object oalist, alist, buffer;
XSETBUFFER (buffer, b);
oalist = b->local_var_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 (EQ (tem, buffer))
+ Lisp_Object sym = XCAR (XCAR (alist));
+ eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED);
+ /* Need not do anything if some other buffer's binding is
+ now encached. */
+ if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
{
/* Symbol is set up for this buffer's old local value:
swap it out! */
- swap_in_global_binding (sym);
+ swap_in_global_binding (XSYMBOL (sym));
}
}
}
int oldsize = XVECTOR (last_overlay_modification_hooks)->size;
if (last_overlay_modification_hooks_used == oldsize)
- last_overlay_modification_hooks = larger_vector
+ last_overlay_modification_hooks = larger_vector
(last_overlay_modification_hooks, oldsize * 2, Qnil);
ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
functionlist); last_overlay_modification_hooks_used++;
switch (type)
{
- case Lisp_Int: predicate = Qintegerp; break;
+ case_Lisp_Int: predicate = Qintegerp; break;
case Lisp_String: predicate = Qstringp; break;
case Lisp_Symbol: predicate = Qsymbolp; break;
default: abort ();
#endif
#include <stdio.h>
-#include <errno.h>
#if MAP_ANON == 0
#include <fcntl.h>
/* Make sure all markable slots in buffer_defaults
are initialized reasonably, so mark_buffer won't choke. */
reset_buffer (&buffer_defaults);
+ eassert (EQ (buffer_defaults.name, make_number (0)));
reset_buffer_local_variables (&buffer_defaults, 1);
+ eassert (EQ (buffer_local_symbols.name, make_number (0)));
reset_buffer (&buffer_local_symbols);
reset_buffer_local_variables (&buffer_local_symbols, 1);
/* Prevent GC from getting confused. */
/* Must do these before making the first buffer! */
/* real setup is done in bindings.el */
- buffer_defaults.mode_line_format = build_string ("%-");
+ buffer_defaults.mode_line_format = make_pure_c_string ("%-");
buffer_defaults.header_line_format = Qnil;
buffer_defaults.abbrev_mode = Qnil;
buffer_defaults.overwrite_mode = Qnil;
buffer_defaults.truncate_lines = Qnil;
buffer_defaults.word_wrap = Qnil;
buffer_defaults.ctl_arrow = Qt;
- buffer_defaults.direction_reversed = Qnil;
+ buffer_defaults.bidi_display_reordering = Qnil;
+ buffer_defaults.bidi_paragraph_direction = Qnil;
buffer_defaults.cursor_type = Qt;
buffer_defaults.extra_line_spacing = Qnil;
buffer_defaults.cursor_in_non_selected_windows = Qt;
XSETFASTINT (buffer_local_flags.syntax_table, idx); ++idx;
XSETFASTINT (buffer_local_flags.cache_long_line_scans, idx); ++idx;
XSETFASTINT (buffer_local_flags.category_table, idx); ++idx;
- XSETFASTINT (buffer_local_flags.direction_reversed, idx); ++idx;
+ XSETFASTINT (buffer_local_flags.bidi_display_reordering, idx); ++idx;
+ XSETFASTINT (buffer_local_flags.bidi_paragraph_direction, idx); ++idx;
XSETFASTINT (buffer_local_flags.buffer_file_coding_system, idx);
/* Make this one a permanent local. */
buffer_permanent_local_flags[idx++] = 1;
current_buffer = 0;
all_buffers = 0;
- QSFundamental = build_string ("Fundamental");
+ QSFundamental = make_pure_c_string ("Fundamental");
- Qfundamental_mode = intern ("fundamental-mode");
+ Qfundamental_mode = intern_c_string ("fundamental-mode");
buffer_defaults.major_mode = Qfundamental_mode;
- Qmode_class = intern ("mode-class");
+ Qmode_class = intern_c_string ("mode-class");
- Qprotected_field = intern ("protected-field");
+ Qprotected_field = intern_c_string ("protected-field");
- Qpermanent_local = intern ("permanent-local");
+ Qpermanent_local = intern_c_string ("permanent-local");
- Qkill_buffer_hook = intern ("kill-buffer-hook");
+ Qkill_buffer_hook = intern_c_string ("kill-buffer-hook");
Fput (Qkill_buffer_hook, Qpermanent_local, Qt);
- Qucs_set_table_for_input = intern ("ucs-set-table-for-input");
-
- Vprin1_to_string_buffer = Fget_buffer_create (build_string (" prin1"));
+ Qucs_set_table_for_input = intern_c_string ("ucs-set-table-for-input");
/* super-magic invisible buffer */
+ Vprin1_to_string_buffer = Fget_buffer_create (make_pure_c_string (" prin1"));
Vbuffer_alist = Qnil;
- Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
+ Fset_buffer (Fget_buffer_create (make_pure_c_string ("*scratch*")));
inhibit_modification_hooks = 0;
}
if (!(IS_DIRECTORY_SEP (pwd[len - 1])))
{
/* Grow buffer to add directory separator and '\0'. */
- pwd = (char *) xrealloc (pwd, len + 2);
+ pwd = (char *) realloc (pwd, len + 2);
+ if (!pwd)
+ fatal ("`get_current_dir_name' failed: %s\n", strerror (errno));
pwd[len] = DIRECTORY_SEP;
pwd[len + 1] = '\0';
}
in the buffer that is current now. */
/* TYPE is nil for a general Lisp variable.
- An integer specifies a type; then only LIsp values
+ 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.
+ 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)
+#define DEFVAR_PER_BUFFER(lname, vname, type, doc) \
+ do { \
+ static struct Lisp_Buffer_Objfwd bo_fwd; \
+ defvar_per_buffer (&bo_fwd, lname, vname, type, 0); \
+ } while (0)
static void
-defvar_per_buffer (namestring, address, type, doc)
+defvar_per_buffer (bo_fwd, namestring, address, type, doc)
+ struct Lisp_Buffer_Objfwd *bo_fwd;
char *namestring;
Lisp_Object *address;
Lisp_Object type;
char *doc;
{
- Lisp_Object sym, val;
+ struct Lisp_Symbol *sym;
int offset;
- sym = intern (namestring);
- val = allocate_misc ();
+ sym = XSYMBOL (intern (namestring));
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;
+ bo_fwd->type = Lisp_Fwd_Buffer_Obj;
+ bo_fwd->offset = offset;
+ bo_fwd->slottype = type;
+ sym->declared_special = 1;
+ sym->redirect = SYMBOL_FORWARDED;
+ {
+ /* I tried to do the job without a cast, but it seems impossible.
+ union Lisp_Fwd *fwd; &(fwd->u_buffer_objfwd) = bo_fwd; */
+ SET_SYMBOL_FWD (sym, (union Lisp_Fwd *)bo_fwd);
+ }
+ XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym);
if (PER_BUFFER_IDX (offset) == 0)
/* Did a DEFVAR_PER_BUFFER without initializing the corresponding
staticpro (&Vbuffer_alist);
staticpro (&Qprotected_field);
staticpro (&Qpermanent_local);
- Qpermanent_local_hook = intern ("permanent-local-hook");
+ Qpermanent_local_hook = intern_c_string ("permanent-local-hook");
staticpro (&Qpermanent_local_hook);
staticpro (&Qkill_buffer_hook);
- Qoverlayp = intern ("overlayp");
+ Qoverlayp = intern_c_string ("overlayp");
staticpro (&Qoverlayp);
- Qevaporate = intern ("evaporate");
+ Qevaporate = intern_c_string ("evaporate");
staticpro (&Qevaporate);
- Qmodification_hooks = intern ("modification-hooks");
+ Qmodification_hooks = intern_c_string ("modification-hooks");
staticpro (&Qmodification_hooks);
- Qinsert_in_front_hooks = intern ("insert-in-front-hooks");
+ Qinsert_in_front_hooks = intern_c_string ("insert-in-front-hooks");
staticpro (&Qinsert_in_front_hooks);
- Qinsert_behind_hooks = intern ("insert-behind-hooks");
+ Qinsert_behind_hooks = intern_c_string ("insert-behind-hooks");
staticpro (&Qinsert_behind_hooks);
- Qget_file_buffer = intern ("get-file-buffer");
+ Qget_file_buffer = intern_c_string ("get-file-buffer");
staticpro (&Qget_file_buffer);
- Qpriority = intern ("priority");
+ Qpriority = intern_c_string ("priority");
staticpro (&Qpriority);
- Qwindow = intern ("window");
+ Qwindow = intern_c_string ("window");
staticpro (&Qwindow);
- Qbefore_string = intern ("before-string");
+ Qbefore_string = intern_c_string ("before-string");
staticpro (&Qbefore_string);
- Qafter_string = intern ("after-string");
+ Qafter_string = intern_c_string ("after-string");
staticpro (&Qafter_string);
- Qfirst_change_hook = intern ("first-change-hook");
+ Qfirst_change_hook = intern_c_string ("first-change-hook");
staticpro (&Qfirst_change_hook);
- Qbefore_change_functions = intern ("before-change-functions");
+ Qbefore_change_functions = intern_c_string ("before-change-functions");
staticpro (&Qbefore_change_functions);
- Qafter_change_functions = intern ("after-change-functions");
+ Qafter_change_functions = intern_c_string ("after-change-functions");
staticpro (&Qafter_change_functions);
/* The next one is initialized in init_buffer_once. */
staticpro (&Qucs_set_table_for_input);
- Qkill_buffer_query_functions = intern ("kill-buffer-query-functions");
+ Qkill_buffer_query_functions = intern_c_string ("kill-buffer-query-functions");
staticpro (&Qkill_buffer_query_functions);
Fput (Qprotected_field, Qerror_conditions,
- Fcons (Qprotected_field, Fcons (Qerror, Qnil)));
+ pure_cons (Qprotected_field, pure_cons (Qerror, Qnil)));
Fput (Qprotected_field, Qerror_message,
- build_string ("Attempt to modify a protected field"));
+ make_pure_c_string ("Attempt to modify a protected field"));
/* All these use DEFVAR_LISP_NOPRO because the slots in
buffer_defaults will all be marked via Vbuffer_defaults. */
doc: /* Default value of `ctl-arrow' for buffers that do not override it.
This is the same as (default-value 'ctl-arrow). */);
- DEFVAR_LISP_NOPRO ("default-direction-reversed",
- &buffer_defaults.direction_reversed,
- doc: /* Default value of `direction-reversed' for buffers that do not override it.
-This is the same as (default-value 'direction-reversed). */);
-
DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters",
&buffer_defaults.enable_multibyte_characters,
doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it.
Decimal digits after the % specify field width to which to pad. */);
DEFVAR_LISP_NOPRO ("default-major-mode", &buffer_defaults.major_mode,
- doc: /* *Major mode for new buffers. Defaults to `fundamental-mode'.
-A value of nil means use current buffer's major mode,
-provided it is not marked as "special".
-
-When a mode is used by default, `find-file' switches to it
-before it reads the contents into the buffer and before
-it finishes setting up the buffer. Thus, the mode and
-its hooks should not expect certain variables such as
-`buffer-read-only' and `buffer-file-coding-system' to be set up. */);
+ doc: /* *Value of `major-mode' for new buffers. */);
DEFVAR_PER_BUFFER ("major-mode", ¤t_buffer->major_mode,
make_number (Lisp_Symbol),
- doc: /* Symbol for current buffer's major mode. */);
+ doc: /* Symbol for current buffer's major mode.
+The default value (normally `fundamental-mode') affects new buffers.
+A value of nil means to use the current buffer's major mode, provided
+it is not marked as "special".
+
+When a mode is used by default, `find-file' switches to it before it
+reads the contents into the buffer and before it finishes setting up
+the buffer. Thus, the mode and its hooks should not expect certain
+variables such as `buffer-read-only' and `buffer-file-coding-system'
+to be set up. */);
DEFVAR_PER_BUFFER ("mode-name", ¤t_buffer->mode_name,
Qnil,
doc: /* *Non-nil if searches and matches should ignore case. */);
DEFVAR_PER_BUFFER ("fill-column", ¤t_buffer->fill_column,
- make_number (Lisp_Int),
+ make_number (LISP_INT_TAG),
doc: /* *Column beyond which automatic line-wrapping should happen.
Interactively, you can set the buffer local value using \\[set-fill-column]. */);
DEFVAR_PER_BUFFER ("left-margin", ¤t_buffer->left_margin,
- make_number (Lisp_Int),
+ make_number (LISP_INT_TAG),
doc: /* *Column for the default `indent-line-function' to indent to.
Linefeed indents to this column in Fundamental mode. */);
DEFVAR_PER_BUFFER ("tab-width", ¤t_buffer->tab_width,
- make_number (Lisp_Int),
+ make_number (LISP_INT_TAG),
doc: /* *Distance between tab stops (for display of tab characters), in columns. */);
DEFVAR_PER_BUFFER ("ctl-arrow", ¤t_buffer->ctl_arrow, Qnil,
Changing its default value with `setq-default' is supported.
See also variable `default-enable-multibyte-characters' and Info node
`(elisp)Text Representations'. */);
- XSYMBOL (intern ("enable-multibyte-characters"))->constant = 1;
+ XSYMBOL (intern_c_string ("enable-multibyte-characters"))->constant = 1;
DEFVAR_PER_BUFFER ("buffer-file-coding-system",
¤t_buffer->buffer_file_coding_system, Qnil,
This variable is never applied to a way of decoding a file while reading it. */);
- DEFVAR_PER_BUFFER ("direction-reversed", ¤t_buffer->direction_reversed,
- Qnil,
- doc: /* *Non-nil means lines in the buffer are displayed right to left. */);
+ DEFVAR_PER_BUFFER ("bidi-display-reordering",
+ ¤t_buffer->bidi_display_reordering, Qnil,
+ doc: /* Non-nil means reorder bidirectional text for display in the visual order. */);
- DEFVAR_PER_BUFFER ("truncate-lines", ¤t_buffer->truncate_lines, Qnil,
+ DEFVAR_PER_BUFFER ("bidi-paragraph-direction",
+ ¤t_buffer->bidi_paragraph_direction, Qnil,
+ doc: /* *If non-nil, forces directionality of text paragraphs in the buffer.
+
+If this is nil (the default), the direction of each paragraph is
+determined by the first strong directional character of its text.
+The values of `right-to-left' and `left-to-right' override that.
+Any other value is treated as nil.
+
+This variable has no effect unless the buffer's value of
+\`bidi-display-reordering' is non-nil. */);
+
+ DEFVAR_PER_BUFFER ("truncate-lines", ¤t_buffer->truncate_lines, Qnil,
doc: /* *Non-nil means do not display continuation lines.
Instead, give each line of text just one screen line.
Backing up is done before the first time the file is saved. */);
DEFVAR_PER_BUFFER ("buffer-saved-size", ¤t_buffer->save_length,
- make_number (Lisp_Int),
+ make_number (LISP_INT_TAG),
doc: /* Length of current buffer when last read in, saved or auto-saved.
-0 initially. */);
+0 initially.
+-1 means auto-saving turned off until next real save.
+
+If you set this to -2, that means don't turn off auto-saving in this buffer
+if its text size shrinks. If you use `buffer-swap-text' on a buffer,
+you probably should set this to -2 in that buffer. */);
DEFVAR_PER_BUFFER ("selective-display", ¤t_buffer->selective_display,
Qnil,
DEFVAR_PER_BUFFER ("line-spacing",
¤t_buffer->extra_line_spacing, Qnil,
doc: /* Additional space to put between lines when displaying a buffer.
-The space is measured in pixels, and put below lines on window systems.
+The space is measured in pixels, and put below lines on graphic displays,
+see `display-graphic-p'.
If value is a floating point number, it specifies the spacing relative
to the default frame line height. A value of nil means add no extra space. */);
doc: /* Normal hook run before changing the major mode of a buffer.
The function `kill-all-local-variables' runs this before doing anything else. */);
Vchange_major_mode_hook = Qnil;
- Qchange_major_mode_hook = intern ("change-major-mode-hook");
+ Qchange_major_mode_hook = intern_c_string ("change-major-mode-hook");
staticpro (&Qchange_major_mode_hook);
defsubr (&Sbuffer_live_p);
/* This must not be in syms_of_buffer, because Qdisabled is not
initialized when that function gets called. */
- Fput (intern ("erase-buffer"), Qdisabled, Qt);
+ Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt);
}
/* arch-tag: e48569bf-69a9-4b65-a23b-8e68769436e1