Backport fix for Bug#8219 from trunk.
* buffer.h (BUF_BEGV, BUF_BEGV_BYTE, BUF_ZV, BUF_ZV_BYTE, BUF_PT) (BUF_PT_BYTE): Rewrite to handle indirect buffers (Bug#8219). These macros can no longer be used for assignment. * buffer.c (Fget_buffer_create, Fmake_indirect_buffer): Assign struct members directly, instead of using BUF_BEGV etc. (record_buffer_markers, fetch_buffer_markers): New functions for recording and fetching special buffer markers. (set_buffer_internal_1, set_buffer_temp): Use them. * lread.c (unreadchar): Use SET_BUF_PT_BOTH. * insdel.c (adjust_point): Use SET_BUF_PT_BOTH. * intervals.c (temp_set_point_both): Use SET_BUF_PT_BOTH. (get_local_map): Use SET_BUF_BEGV_BOTH and SET_BUF_ZV_BOTH. * xdisp.c (hscroll_window_tree): (reconsider_clip_changes): Use PT instead of BUF_PT.
This commit is contained in:
parent
576bce3267
commit
20f5695598
7 changed files with 148 additions and 133 deletions
|
@ -1,3 +1,25 @@
|
|||
2011-03-19 Chong Yidong <cyd@stupidchicken.com>
|
||||
|
||||
* buffer.h (BUF_BEGV, BUF_BEGV_BYTE, BUF_ZV, BUF_ZV_BYTE, BUF_PT)
|
||||
(BUF_PT_BYTE): Rewrite to handle indirect buffers (Bug#8219).
|
||||
These macros can no longer be used for assignment.
|
||||
|
||||
* buffer.c (Fget_buffer_create, Fmake_indirect_buffer): Assign
|
||||
struct members directly, instead of using BUF_BEGV etc.
|
||||
(record_buffer_markers, fetch_buffer_markers): New functions for
|
||||
recording and fetching special buffer markers.
|
||||
(set_buffer_internal_1, set_buffer_temp): Use them.
|
||||
|
||||
* lread.c (unreadchar): Use SET_BUF_PT_BOTH.
|
||||
|
||||
* insdel.c (adjust_point): Use SET_BUF_PT_BOTH.
|
||||
|
||||
* intervals.c (temp_set_point_both): Use SET_BUF_PT_BOTH.
|
||||
(get_local_map): Use SET_BUF_BEGV_BOTH and SET_BUF_ZV_BOTH.
|
||||
|
||||
* xdisp.c (hscroll_window_tree):
|
||||
(reconsider_clip_changes): Use PT instead of BUF_PT.
|
||||
|
||||
2011-03-17 Juanma Barranquero <lekktu@gmail.com>
|
||||
|
||||
* xfaces.c (Fx_load_color_file):
|
||||
|
|
187
src/buffer.c
187
src/buffer.c
|
@ -371,15 +371,17 @@ even if it is dead. The return value is never nil. */)
|
|||
if (! BUF_BEG_ADDR (b))
|
||||
buffer_memory_full ();
|
||||
|
||||
BUF_PT (b) = BEG;
|
||||
b->pt = BEG;
|
||||
b->begv = BEG;
|
||||
b->zv = BEG;
|
||||
b->pt_byte = BEG_BYTE;
|
||||
b->begv_byte = BEG_BYTE;
|
||||
b->zv_byte = BEG_BYTE;
|
||||
|
||||
BUF_GPT (b) = BEG;
|
||||
BUF_BEGV (b) = BEG;
|
||||
BUF_ZV (b) = BEG;
|
||||
BUF_Z (b) = BEG;
|
||||
BUF_PT_BYTE (b) = BEG_BYTE;
|
||||
BUF_GPT_BYTE (b) = BEG_BYTE;
|
||||
BUF_BEGV_BYTE (b) = BEG_BYTE;
|
||||
BUF_ZV_BYTE (b) = BEG_BYTE;
|
||||
|
||||
BUF_Z (b) = BEG;
|
||||
BUF_Z_BYTE (b) = BEG_BYTE;
|
||||
BUF_MODIFF (b) = 1;
|
||||
BUF_CHARS_MODIFF (b) = 1;
|
||||
|
@ -533,6 +535,53 @@ clone_per_buffer_values (from, to)
|
|||
to->local_var_alist = buffer_lisp_local_variables (from);
|
||||
}
|
||||
|
||||
|
||||
/* If buffer B has markers to record PT, BEGV and ZV when it is not
|
||||
current, update these markers. */
|
||||
|
||||
static void
|
||||
record_buffer_markers (struct buffer *b)
|
||||
{
|
||||
if (! NILP (b->pt_marker))
|
||||
{
|
||||
Lisp_Object buffer;
|
||||
|
||||
eassert (!NILP (b->begv_marker));
|
||||
eassert (!NILP (b->zv_marker));
|
||||
|
||||
XSETBUFFER (buffer, b);
|
||||
set_marker_both (b->pt_marker, buffer, b->pt, b->pt_byte);
|
||||
set_marker_both (b->begv_marker, buffer, b->begv, b->begv_byte);
|
||||
set_marker_both (b->zv_marker, buffer, b->zv, b->zv_byte);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If buffer B has markers to record PT, BEGV and ZV when it is not
|
||||
current, fetch these values into B->begv etc. */
|
||||
|
||||
static void
|
||||
fetch_buffer_markers (struct buffer *b)
|
||||
{
|
||||
if (! NILP (b->pt_marker))
|
||||
{
|
||||
Lisp_Object m;
|
||||
|
||||
eassert (!NILP (b->begv_marker));
|
||||
eassert (!NILP (b->zv_marker));
|
||||
|
||||
m = b->pt_marker;
|
||||
SET_BUF_PT_BOTH (b, marker_position (m), marker_byte_position (m));
|
||||
|
||||
m = b->begv_marker;
|
||||
SET_BUF_BEGV_BOTH (b, marker_position (m), marker_byte_position (m));
|
||||
|
||||
m = b->zv_marker;
|
||||
SET_BUF_ZV_BOTH (b, marker_position (m), marker_byte_position (m));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, Smake_indirect_buffer,
|
||||
2, 3,
|
||||
"bMake indirect buffer (to buffer): \nBName of indirect buffer: ",
|
||||
|
@ -572,12 +621,12 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
|
|||
/* Use the base buffer's text object. */
|
||||
b->text = b->base_buffer->text;
|
||||
|
||||
BUF_BEGV (b) = BUF_BEGV (b->base_buffer);
|
||||
BUF_ZV (b) = BUF_ZV (b->base_buffer);
|
||||
BUF_PT (b) = BUF_PT (b->base_buffer);
|
||||
BUF_BEGV_BYTE (b) = BUF_BEGV_BYTE (b->base_buffer);
|
||||
BUF_ZV_BYTE (b) = BUF_ZV_BYTE (b->base_buffer);
|
||||
BUF_PT_BYTE (b) = BUF_PT_BYTE (b->base_buffer);
|
||||
b->pt = b->base_buffer->pt;
|
||||
b->begv = b->base_buffer->begv;
|
||||
b->zv = b->base_buffer->zv;
|
||||
b->pt_byte = b->base_buffer->pt_byte;
|
||||
b->begv_byte = b->base_buffer->begv_byte;
|
||||
b->zv_byte = b->base_buffer->zv_byte;
|
||||
|
||||
b->newline_cache = 0;
|
||||
b->width_run_cache = 0;
|
||||
|
@ -607,24 +656,23 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
|
|||
/* Make sure the base buffer has markers for its narrowing. */
|
||||
if (NILP (b->base_buffer->pt_marker))
|
||||
{
|
||||
eassert (NILP (b->base_buffer->begv_marker));
|
||||
eassert (NILP (b->base_buffer->zv_marker));
|
||||
|
||||
b->base_buffer->pt_marker = Fmake_marker ();
|
||||
set_marker_both (b->base_buffer->pt_marker, base_buffer,
|
||||
BUF_PT (b->base_buffer),
|
||||
BUF_PT_BYTE (b->base_buffer));
|
||||
}
|
||||
if (NILP (b->base_buffer->begv_marker))
|
||||
{
|
||||
b->base_buffer->pt,
|
||||
b->base_buffer->pt_byte);
|
||||
|
||||
b->base_buffer->begv_marker = Fmake_marker ();
|
||||
set_marker_both (b->base_buffer->begv_marker, base_buffer,
|
||||
BUF_BEGV (b->base_buffer),
|
||||
BUF_BEGV_BYTE (b->base_buffer));
|
||||
}
|
||||
if (NILP (b->base_buffer->zv_marker))
|
||||
{
|
||||
b->base_buffer->begv,
|
||||
b->base_buffer->begv_byte);
|
||||
|
||||
b->base_buffer->zv_marker = Fmake_marker ();
|
||||
set_marker_both (b->base_buffer->zv_marker, base_buffer,
|
||||
BUF_ZV (b->base_buffer),
|
||||
BUF_ZV_BYTE (b->base_buffer));
|
||||
b->base_buffer->zv,
|
||||
b->base_buffer->zv_byte);
|
||||
XMARKER (b->base_buffer->zv_marker)->insertion_type = 1;
|
||||
}
|
||||
|
||||
|
@ -632,11 +680,11 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
|
|||
{
|
||||
/* Give the indirect buffer markers for its narrowing. */
|
||||
b->pt_marker = Fmake_marker ();
|
||||
set_marker_both (b->pt_marker, buf, BUF_PT (b), BUF_PT_BYTE (b));
|
||||
set_marker_both (b->pt_marker, buf, b->pt, b->pt_byte);
|
||||
b->begv_marker = Fmake_marker ();
|
||||
set_marker_both (b->begv_marker, buf, BUF_BEGV (b), BUF_BEGV_BYTE (b));
|
||||
set_marker_both (b->begv_marker, buf, b->begv, b->begv_byte);
|
||||
b->zv_marker = Fmake_marker ();
|
||||
set_marker_both (b->zv_marker, buf, BUF_ZV (b), BUF_ZV_BYTE (b));
|
||||
set_marker_both (b->zv_marker, buf, b->zv, b->zv_byte);
|
||||
XMARKER (b->zv_marker)->insertion_type = 1;
|
||||
}
|
||||
else
|
||||
|
@ -1890,27 +1938,7 @@ set_buffer_internal_1 (b)
|
|||
|
||||
/* If the old current buffer has markers to record PT, BEGV and ZV
|
||||
when it is not current, update them now. */
|
||||
if (! NILP (old_buf->pt_marker))
|
||||
{
|
||||
Lisp_Object obuf;
|
||||
XSETBUFFER (obuf, old_buf);
|
||||
set_marker_both (old_buf->pt_marker, obuf,
|
||||
BUF_PT (old_buf), BUF_PT_BYTE (old_buf));
|
||||
}
|
||||
if (! NILP (old_buf->begv_marker))
|
||||
{
|
||||
Lisp_Object obuf;
|
||||
XSETBUFFER (obuf, old_buf);
|
||||
set_marker_both (old_buf->begv_marker, obuf,
|
||||
BUF_BEGV (old_buf), BUF_BEGV_BYTE (old_buf));
|
||||
}
|
||||
if (! NILP (old_buf->zv_marker))
|
||||
{
|
||||
Lisp_Object obuf;
|
||||
XSETBUFFER (obuf, old_buf);
|
||||
set_marker_both (old_buf->zv_marker, obuf,
|
||||
BUF_ZV (old_buf), BUF_ZV_BYTE (old_buf));
|
||||
}
|
||||
record_buffer_markers (old_buf);
|
||||
}
|
||||
|
||||
/* Get the undo list from the base buffer, so that it appears
|
||||
|
@ -1920,21 +1948,7 @@ set_buffer_internal_1 (b)
|
|||
|
||||
/* If the new current buffer has markers to record PT, BEGV and ZV
|
||||
when it is not current, fetch them now. */
|
||||
if (! NILP (b->pt_marker))
|
||||
{
|
||||
BUF_PT (b) = marker_position (b->pt_marker);
|
||||
BUF_PT_BYTE (b) = marker_byte_position (b->pt_marker);
|
||||
}
|
||||
if (! NILP (b->begv_marker))
|
||||
{
|
||||
BUF_BEGV (b) = marker_position (b->begv_marker);
|
||||
BUF_BEGV_BYTE (b) = marker_byte_position (b->begv_marker);
|
||||
}
|
||||
if (! NILP (b->zv_marker))
|
||||
{
|
||||
BUF_ZV (b) = marker_position (b->zv_marker);
|
||||
BUF_ZV_BYTE (b) = marker_byte_position (b->zv_marker);
|
||||
}
|
||||
fetch_buffer_markers (b);
|
||||
|
||||
/* Look down buffer's list of local Lisp variables
|
||||
to find and update any that forward into C variables. */
|
||||
|
@ -1984,50 +1998,13 @@ set_buffer_temp (b)
|
|||
old_buf = current_buffer;
|
||||
current_buffer = b;
|
||||
|
||||
if (old_buf)
|
||||
{
|
||||
/* If the old current buffer has markers to record PT, BEGV and ZV
|
||||
when it is not current, update them now. */
|
||||
if (! NILP (old_buf->pt_marker))
|
||||
{
|
||||
Lisp_Object obuf;
|
||||
XSETBUFFER (obuf, old_buf);
|
||||
set_marker_both (old_buf->pt_marker, obuf,
|
||||
BUF_PT (old_buf), BUF_PT_BYTE (old_buf));
|
||||
}
|
||||
if (! NILP (old_buf->begv_marker))
|
||||
{
|
||||
Lisp_Object obuf;
|
||||
XSETBUFFER (obuf, old_buf);
|
||||
set_marker_both (old_buf->begv_marker, obuf,
|
||||
BUF_BEGV (old_buf), BUF_BEGV_BYTE (old_buf));
|
||||
}
|
||||
if (! NILP (old_buf->zv_marker))
|
||||
{
|
||||
Lisp_Object obuf;
|
||||
XSETBUFFER (obuf, old_buf);
|
||||
set_marker_both (old_buf->zv_marker, obuf,
|
||||
BUF_ZV (old_buf), BUF_ZV_BYTE (old_buf));
|
||||
}
|
||||
}
|
||||
/* If the old current buffer has markers to record PT, BEGV and ZV
|
||||
when it is not current, update them now. */
|
||||
record_buffer_markers (old_buf);
|
||||
|
||||
/* If the new current buffer has markers to record PT, BEGV and ZV
|
||||
when it is not current, fetch them now. */
|
||||
if (! NILP (b->pt_marker))
|
||||
{
|
||||
BUF_PT (b) = marker_position (b->pt_marker);
|
||||
BUF_PT_BYTE (b) = marker_byte_position (b->pt_marker);
|
||||
}
|
||||
if (! NILP (b->begv_marker))
|
||||
{
|
||||
BUF_BEGV (b) = marker_position (b->begv_marker);
|
||||
BUF_BEGV_BYTE (b) = marker_byte_position (b->begv_marker);
|
||||
}
|
||||
if (! NILP (b->zv_marker))
|
||||
{
|
||||
BUF_ZV (b) = marker_position (b->zv_marker);
|
||||
BUF_ZV_BYTE (b) = marker_byte_position (b->zv_marker);
|
||||
}
|
||||
fetch_buffer_markers (b);
|
||||
}
|
||||
|
||||
DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0,
|
||||
|
|
42
src/buffer.h
42
src/buffer.h
|
@ -107,22 +107,46 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#define BUF_BEG(buf) (BEG)
|
||||
#define BUF_BEG_BYTE(buf) (BEG_BYTE)
|
||||
|
||||
/* The BUF_BEGV[_BYTE], BUF_ZV[_BYTE], and BUF_PT[_BYTE] macros cannot
|
||||
be used for assignment; use SET_BUF_* macros below for that. */
|
||||
|
||||
/* Position of beginning of accessible range of buffer. */
|
||||
#define BUF_BEGV(buf) ((buf)->begv)
|
||||
#define BUF_BEGV_BYTE(buf) ((buf)->begv_byte)
|
||||
#define BUF_BEGV(buf) \
|
||||
(buf == current_buffer ? BEGV \
|
||||
: NILP (buf->begv_marker) ? buf->begv \
|
||||
: marker_position (buf->begv_marker))
|
||||
|
||||
#define BUF_BEGV_BYTE(buf) \
|
||||
(buf == current_buffer ? BEGV_BYTE \
|
||||
: NILP (buf->begv_marker) ? buf->begv_byte \
|
||||
: marker_byte_position (buf->begv_marker))
|
||||
|
||||
/* Position of point in buffer. */
|
||||
#define BUF_PT(buf) ((buf)->pt)
|
||||
#define BUF_PT_BYTE(buf) ((buf)->pt_byte)
|
||||
#define BUF_PT(buf) \
|
||||
(buf == current_buffer ? PT \
|
||||
: NILP (buf->pt_marker) ? buf->pt \
|
||||
: marker_position (buf->pt_marker))
|
||||
|
||||
#define BUF_PT_BYTE(buf) \
|
||||
(buf == current_buffer ? PT_BYTE \
|
||||
: NILP (buf->pt_marker) ? buf->pt_byte \
|
||||
: marker_byte_position (buf->pt_marker))
|
||||
|
||||
/* Position of end of accessible range of buffer. */
|
||||
#define BUF_ZV(buf) \
|
||||
(buf == current_buffer ? ZV \
|
||||
: NILP (buf->zv_marker) ? buf->zv \
|
||||
: marker_position (buf->zv_marker))
|
||||
|
||||
#define BUF_ZV_BYTE(buf) \
|
||||
(buf == current_buffer ? ZV_BYTE \
|
||||
: NILP (buf->zv_marker) ? buf->zv_byte \
|
||||
: marker_byte_position (buf->zv_marker))
|
||||
|
||||
/* Position of gap in buffer. */
|
||||
#define BUF_GPT(buf) ((buf)->text->gpt)
|
||||
#define BUF_GPT_BYTE(buf) ((buf)->text->gpt_byte)
|
||||
|
||||
/* Position of end of accessible range of buffer. */
|
||||
#define BUF_ZV(buf) ((buf)->zv)
|
||||
#define BUF_ZV_BYTE(buf) ((buf)->zv_byte)
|
||||
|
||||
/* Position of end of buffer. */
|
||||
#define BUF_Z(buf) ((buf)->text->z)
|
||||
#define BUF_Z_BYTE(buf) ((buf)->text->z_byte)
|
||||
|
@ -230,8 +254,6 @@ extern void enlarge_buffer_text P_ ((struct buffer *, EMACS_INT));
|
|||
|
||||
/* Macros for setting the BEGV, ZV or PT of a given buffer.
|
||||
|
||||
SET_BUF_PT* seet to be redundant. Get rid of them?
|
||||
|
||||
The ..._BOTH macros take both a charpos and a bytepos,
|
||||
which must correspond to each other.
|
||||
|
||||
|
|
|
@ -459,9 +459,7 @@ adjust_markers_for_insert (EMACS_INT from, EMACS_INT from_byte,
|
|||
static void
|
||||
adjust_point (EMACS_INT nchars, EMACS_INT nbytes)
|
||||
{
|
||||
BUF_PT (current_buffer) += nchars;
|
||||
BUF_PT_BYTE (current_buffer) += nbytes;
|
||||
|
||||
SET_BUF_PT_BOTH (current_buffer, PT + nchars, PT_BYTE + nbytes);
|
||||
/* In a single-byte buffer, the two positions must be equal. */
|
||||
eassert (PT_BYTE >= PT && PT_BYTE - PT <= ZV_BYTE - ZV);
|
||||
}
|
||||
|
|
|
@ -1949,8 +1949,7 @@ temp_set_point_both (struct buffer *buffer,
|
|||
if (charpos > BUF_ZV (buffer) || charpos < BUF_BEGV (buffer))
|
||||
abort ();
|
||||
|
||||
BUF_PT_BYTE (buffer) = bytepos;
|
||||
BUF_PT (buffer) = charpos;
|
||||
SET_BUF_PT_BOTH (buffer, charpos, bytepos);
|
||||
}
|
||||
|
||||
/* Set point in BUFFER to CHARPOS. If the target position is
|
||||
|
@ -2366,10 +2365,9 @@ get_local_map (position, buffer, type)
|
|||
old_zv = BUF_ZV (buffer);
|
||||
old_begv_byte = BUF_BEGV_BYTE (buffer);
|
||||
old_zv_byte = BUF_ZV_BYTE (buffer);
|
||||
BUF_BEGV (buffer) = BUF_BEG (buffer);
|
||||
BUF_ZV (buffer) = BUF_Z (buffer);
|
||||
BUF_BEGV_BYTE (buffer) = BUF_BEG_BYTE (buffer);
|
||||
BUF_ZV_BYTE (buffer) = BUF_Z_BYTE (buffer);
|
||||
|
||||
SET_BUF_BEGV_BOTH (buffer, BUF_BEG (buffer), BUF_BEG_BYTE (buffer));
|
||||
SET_BUF_ZV_BOTH (buffer, BUF_Z (buffer), BUF_Z_BYTE (buffer));
|
||||
|
||||
XSETFASTINT (lispy_position, position);
|
||||
XSETBUFFER (lispy_buffer, buffer);
|
||||
|
@ -2383,10 +2381,8 @@ get_local_map (position, buffer, type)
|
|||
if (NILP (prop))
|
||||
prop = get_pos_property (lispy_position, type, lispy_buffer);
|
||||
|
||||
BUF_BEGV (buffer) = old_begv;
|
||||
BUF_ZV (buffer) = old_zv;
|
||||
BUF_BEGV_BYTE (buffer) = old_begv_byte;
|
||||
BUF_ZV_BYTE (buffer) = old_zv_byte;
|
||||
SET_BUF_BEGV_BOTH (buffer, old_begv, old_begv_byte);
|
||||
SET_BUF_ZV_BOTH (buffer, old_zv, old_zv_byte);
|
||||
|
||||
/* Use the local map only if it is valid. */
|
||||
prop = get_keymap (prop, 0, 0);
|
||||
|
|
|
@ -458,15 +458,15 @@ unreadchar (readcharfun, c)
|
|||
else if (BUFFERP (readcharfun))
|
||||
{
|
||||
struct buffer *b = XBUFFER (readcharfun);
|
||||
int bytepos = BUF_PT_BYTE (b);
|
||||
EMACS_INT charpos = BUF_PT (b);
|
||||
EMACS_INT bytepos = BUF_PT_BYTE (b);
|
||||
|
||||
BUF_PT (b)--;
|
||||
if (! NILP (b->enable_multibyte_characters))
|
||||
BUF_DEC_POS (b, bytepos);
|
||||
else
|
||||
bytepos--;
|
||||
|
||||
BUF_PT_BYTE (b) = bytepos;
|
||||
SET_BUF_PT_BOTH (b, charpos - 1, bytepos);
|
||||
}
|
||||
else if (MARKERP (readcharfun))
|
||||
{
|
||||
|
|
|
@ -10760,7 +10760,7 @@ hscroll_window_tree (window)
|
|||
current_buffer = XBUFFER (w->buffer);
|
||||
|
||||
if (w == XWINDOW (selected_window))
|
||||
pt = BUF_PT (current_buffer);
|
||||
pt = PT;
|
||||
else
|
||||
{
|
||||
pt = marker_position (w->pointm);
|
||||
|
@ -11194,7 +11194,7 @@ reconsider_clip_changes (w, b)
|
|||
int pt;
|
||||
|
||||
if (w == XWINDOW (selected_window))
|
||||
pt = BUF_PT (current_buffer);
|
||||
pt = PT;
|
||||
else
|
||||
pt = marker_position (w->pointm);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue