of the specified region, that will also be handled correctly.
begin_multiple_change() returns a number (actually a specpdl depth)
- that you must pass to end_multiple_change() when you are done. */
+ that you must pass to end_multiple_change() when you are done.
+
+ FSF Emacs 20 implements a similar feature, accessible from Lisp
+ through a `combine-after-change-calls' special form, which is
+ essentially equivalent to this function. We should consider
+ whether we want to introduce a similar Lisp form. */
int
begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end)
/* We should first reset the variable and then change the buffer,
because Fset_buffer() can throw. */
inside_change_hook = 0;
- Fset_buffer (buffer);
+ if (XBUFFER (buffer) != current_buffer)
+ Fset_buffer (buffer);
return Qnil;
}
if (!inside_change_hook)
{
Lisp_Object buffer;
+ int speccount;
/* Are we in a multiple-change session? */
if (buf->text->changes->in_multiple_change &&
}
/* Now in any case run the before-change-functions if any. */
+ speccount = specpdl_depth ();
+ record_unwind_protect (change_function_restore, Fcurrent_buffer ());
+ inside_change_hook = 1;
MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
{
/* Obsolete, for compatibility */
|| !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer)))
{
- int speccount = specpdl_depth ();
- record_unwind_protect (change_function_restore, Fcurrent_buffer ());
set_buffer_internal (buf);
- inside_change_hook = 1;
va_run_hook_with_args (Qbefore_change_functions, 2,
make_int (start), make_int (end));
/* Obsolete, for compatibility */
va_run_hook_with_args (Qbefore_change_function, 2,
make_int (start), make_int (end));
- unbind_to (speccount, Qnil);
}
}
+ /* Make sure endpoints remain valid. before-change-functions
+ might have modified the buffer. */
+ if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf);
+ if (start > BUF_ZV (buf)) start = BUF_ZV (buf);
+ if (end < BUF_BEGV (buf)) end = BUF_BEGV (buf);
+ if (end > BUF_ZV (buf)) end = BUF_ZV (buf);
+
MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
{
XSETBUFFER (buffer, mbuf);
- report_extent_modification (buffer, start, end,
- &inside_change_hook, 0);
+ report_extent_modification (buffer, start, end, 0);
}
+ unbind_to (speccount, Qnil);
/* Only now do we indicate that the before-change-functions have
been called, in case some function throws out. */
if (!inside_change_hook)
{
Lisp_Object buffer;
+ int speccount;
if (buf->text->changes->in_multiple_change &&
buf->text->changes->mc_begin != 0)
return; /* after-change-functions signalled when all changes done */
}
+ speccount = specpdl_depth ();
+ record_unwind_protect (change_function_restore, Fcurrent_buffer ());
+ inside_change_hook = 1;
MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
{
XSETBUFFER (buffer, mbuf);
/* Obsolete, for compatibility */
|| !NILP (symbol_value_in_buffer (Qafter_change_function, buffer)))
{
- int speccount = specpdl_depth ();
- record_unwind_protect (change_function_restore, Fcurrent_buffer ());
set_buffer_internal (buf);
- inside_change_hook = 1;
/* The actual after-change functions take slightly
different arguments than what we were passed. */
va_run_hook_with_args (Qafter_change_functions, 3,
va_run_hook_with_args (Qafter_change_function, 3,
make_int (start), make_int (new_end),
make_int (orig_end - start));
- unbind_to (speccount, Qnil);
}
}
+ /* Make sure endpoints remain valid. after-change-functions
+ might have modified the buffer. */
+ if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf);
+ if (start > BUF_ZV (buf)) start = BUF_ZV (buf);
+ if (new_end < BUF_BEGV (buf)) new_end = BUF_BEGV (buf);
+ if (new_end > BUF_ZV (buf)) new_end = BUF_ZV (buf);
+ if (orig_end < BUF_BEGV (buf)) orig_end = BUF_BEGV (buf);
+ if (orig_end > BUF_ZV (buf)) orig_end = BUF_ZV (buf);
+
MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
{
XSETBUFFER (buffer, mbuf);
- report_extent_modification (buffer, start, new_end,
- &inside_change_hook, 1);
+ report_extent_modification (buffer, start, new_end, 1);
}
+ unbind_to (speccount, Qnil); /* sets inside_change_hook back to 0 */
}
}
}
void
-find_charsets_in_bufbyte_string (unsigned char *charsets, CONST Bufbyte *str,
+find_charsets_in_bufbyte_string (Charset_ID *charsets, CONST Bufbyte *str,
Bytecount len)
{
#ifndef MULE
charsets[0] = 1;
#else
CONST Bufbyte *strend = str + len;
- memset (charsets, 0, NUM_LEADING_BYTES);
+ memset (charsets, 0, NUM_LEADING_BYTES * sizeof(Charset_ID));
while (str < strend)
{
- charsets[CHAR_LEADING_BYTE (charptr_emchar (str)) - 128] = 1;
+#ifdef UTF2000
+ charsets[CHAR_CHARSET_ID (charptr_emchar (str))
+ - MIN_LEADING_BYTE] = 1;
+#else /* I'm not sure the definition for UTF2000 works with leading-byte
+ representation. */
+ charsets[CHAR_LEADING_BYTE (charptr_emchar (str))
+ - MIN_LEADING_BYTE] = 1;
+#endif
INC_CHARPTR (str);
}
#endif
}
void
-find_charsets_in_emchar_string (unsigned char *charsets, CONST Emchar *str,
+find_charsets_in_emchar_string (Charset_ID *charsets, CONST Emchar *str,
Charcount len)
{
#ifndef MULE
#else
int i;
- memset (charsets, 0, NUM_LEADING_BYTES);
+ memset (charsets, 0, NUM_LEADING_BYTES * sizeof(Charset_ID));
for (i = 0; i < len; i++)
{
- charsets[CHAR_LEADING_BYTE (str[i]) - 128] = 1;
+#ifdef UTF2000
+ charsets[CHAR_CHARSET_ID (str[i]) - MIN_LEADING_BYTE] = 1;
+#else /* I'm not sure the definition for UTF2000 works with leading-byte
+ representation. */
+ charsets[CHAR_LEADING_BYTE (str[i]) - MIN_LEADING_BYTE] = 1;
+#endif
}
#endif
}
{
#ifdef MULE
Emchar ch = charptr_emchar (str);
- cols += XCHARSET_COLUMNS (CHAR_CHARSET (ch));
+ cols += CHAR_COLUMNS (ch);
#else
cols++;
#endif
int i;
for (i = 0; i < len; i++)
- cols += XCHARSET_COLUMNS (CHAR_CHARSET (str[i]));
+ cols += CHAR_COLUMNS (str[i]);
return cols;
#else /* not MULE */
/************************************************************************/
void
-vars_of_insdel (void)
+reinit_vars_of_insdel (void)
{
+#ifndef UTF2000
int i;
+#endif
inside_change_hook = 0;
in_first_change = 0;
}
void
+vars_of_insdel (void)
+{
+ reinit_vars_of_insdel ();
+}
+
+void
init_buffer_text (struct buffer *b)
{
if (!b->base_buffer)