/* Buffer insertion/deletion and gap motion for GNU Emacs.
- Copyright (C) 1985, 86,93,94,95,97,98, 1999, 2000, 01, 2003
- Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include <config.h>
{
if (nbytes > 0)
{
- int opoint = PT;
- insert_1 (string, nbytes, 0, 1, 0);
- signal_after_change (opoint, 0, PT - opoint);
+ int len = chars_in_text (string, nbytes), opoint;
+ insert_1_both (string, len, nbytes, 0, 1, 0);
+ opoint = PT - len;
+ signal_after_change (opoint, 0, len);
update_compositions (opoint, PT, CHECK_BORDER);
}
}
{
if (nbytes > 0)
{
- int opoint = PT;
- insert_1 (string, nbytes, 1, 1, 0);
- signal_after_change (opoint, 0, PT - opoint);
+ int len = chars_in_text (string, nbytes), opoint;
+ insert_1_both (string, len, nbytes, 1, 1, 0);
+ opoint = PT - len;
+ signal_after_change (opoint, 0, len);
update_compositions (opoint, PT, CHECK_BORDER);
}
}
{
if (nbytes > 0)
{
- int opoint = PT;
-
- insert_1 (string, nbytes, 0, 1, 1);
- signal_after_change (opoint, 0, PT - opoint);
+ int len = chars_in_text (string, nbytes), opoint;
+ insert_1_both (string, len, nbytes, 0, 1, 1);
+ opoint = PT - len;
+ signal_after_change (opoint, 0, len);
update_compositions (opoint, PT, CHECK_BORDER);
}
}
{
if (nbytes > 0)
{
- int opoint = PT;
-
- insert_1 (string, nbytes, 1, 1, 1);
- signal_after_change (opoint, 0, PT - opoint);
+ int len = chars_in_text (string, nbytes), opoint;
+ insert_1_both (string, len, nbytes, 1, 1, 1);
+ opoint = PT - len;
+ signal_after_change (opoint, 0, len);
update_compositions (opoint, PT, CHECK_BORDER);
}
}
will add up to the right stuff in the undo list. */
record_insert (PT, nchars);
MODIFF++;
+ CHARS_MODIFF = MODIFF;
bcopy (string, GPT_ADDR, nbytes);
int inherit;
{
int opoint = PT;
+
+ if (SCHARS (string) == 0)
+ return;
+
insert_from_string_1 (string, pos, pos_byte, length, length_byte,
inherit, 0);
signal_after_change (opoint, 0, PT - opoint);
int inherit;
{
int opoint = PT;
+
+ if (SCHARS (string) == 0)
+ return;
+
insert_from_string_1 (string, pos, pos_byte, length, length_byte,
inherit, 1);
signal_after_change (opoint, 0, PT - opoint);
record_insert (PT, nchars);
MODIFF++;
+ CHARS_MODIFF = MODIFF;
GAP_SIZE -= outgoing_nbytes;
GPT += nchars;
record_insert (PT, nchars);
MODIFF++;
+ CHARS_MODIFF = MODIFF;
GAP_SIZE -= outgoing_nbytes;
GPT += nchars;
if (len == 0)
evaporate_overlays (from);
MODIFF++;
+ CHARS_MODIFF = MODIFF;
}
/* Like adjust_after_replace, but doesn't require PREV_TEXT.
if (len == 0)
evaporate_overlays (from);
MODIFF++;
+ CHARS_MODIFF = MODIFF;
}
/* Record undo information, adjust markers and position keepers for an
CHECK_MARKERS ();
MODIFF++;
+ CHARS_MODIFF = MODIFF;
UNGCPRO;
signal_after_change (from, nchars_del, GPT - from);
/* Adjust markers for the deletion and the insertion. */
if (markers
- && ! (nchars_del == 1 && inschars == 1))
+ && ! (nchars_del == 1 && inschars == 1 && nbytes_del == insbytes))
adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
inschars, insbytes);
offset_intervals (current_buffer, from, inschars - nchars_del);
/* Relocate point as if it were a marker. */
- if (from < PT && nchars_del != inschars)
- adjust_point ((from + inschars - (PT < to ? PT : to)),
- (from_byte + insbytes
- - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
+ if (from < PT && (nchars_del != inschars || nbytes_del != insbytes))
+ {
+ if (PT < to)
+ /* PT was within the deleted text. Move it to FROM. */
+ adjust_point (from - PT, from_byte - PT_BYTE);
+ else
+ adjust_point (inschars - nchars_del, insbytes - nbytes_del);
+ }
if (insbytes == 0)
evaporate_overlays (from);
CHECK_MARKERS ();
MODIFF++;
+ CHARS_MODIFF = MODIFF;
}
\f
/* Delete characters in current buffer
if (! EQ (current_buffer->undo_list, Qt))
record_delete (from, deletion);
MODIFF++;
+ CHARS_MODIFF = MODIFF;
/* Relocate point as if it were a marker. */
if (from < PT)
character positions START to END. This checks the read-only
properties of the region, calls the necessary modification hooks,
and warns the next redisplay that it should pay attention to that
- area. */
+ area.
+
+ If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF.
+ Otherwise set CHARS_MODIFF to the new value of MODIFF. */
void
-modify_region (buffer, start, end)
+modify_region (buffer, start, end, preserve_chars_modiff)
struct buffer *buffer;
- int start, end;
+ int start, end, preserve_chars_modiff;
{
struct buffer *old_buffer = current_buffer;
if (MODIFF <= SAVE_MODIFF)
record_first_change ();
MODIFF++;
+ if (! preserve_chars_modiff)
+ CHARS_MODIFF = MODIFF;
buffer->point_before_scroll = Qnil;
int start, end;
int *preserve_ptr;
{
+ struct buffer *base_buffer;
+
if (!NILP (current_buffer->read_only))
Fbarf_if_buffer_read_only ();
verify_interval_modification (current_buffer, start, end);
}
+ /* For indirect buffers, use the base buffer to check clashes. */
+ if (current_buffer->base_buffer != 0)
+ base_buffer = current_buffer->base_buffer;
+ else
+ base_buffer = current_buffer;
+
#ifdef CLASH_DETECTION
- if (!NILP (current_buffer->file_truename)
+ if (!NILP (base_buffer->file_truename)
/* Make binding buffer-file-name to nil effective. */
- && !NILP (current_buffer->filename)
+ && !NILP (base_buffer->filename)
&& SAVE_MODIFF >= MODIFF)
- lock_file (current_buffer->file_truename);
+ lock_file (base_buffer->file_truename);
#else
/* At least warn if this file has changed on disk since it was visited. */
- if (!NILP (current_buffer->filename)
+ if (!NILP (base_buffer->filename)
&& SAVE_MODIFF >= MODIFF
&& NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
- && !NILP (Ffile_exists_p (current_buffer->filename)))
+ && !NILP (Ffile_exists_p (base_buffer->filename)))
call1 (intern ("ask-user-about-supersession-threat"),
- current_buffer->filename);
+ base_buffer->filename);
#endif /* not CLASH_DETECTION */
signal_before_change (start, end, preserve_ptr);
if (NILP (combine_after_change_list))
return Qnil;
+ /* It is rare for combine_after_change_buffer to be invalid, but
+ possible. It can happen when combine-after-change-calls is
+ non-nil, and insertion calls a file handler (e.g. through
+ lock_file) which scribbles into a temp file -- cyd */
+ if (!BUFFERP (combine_after_change_buffer)
+ || NILP (XBUFFER (combine_after_change_buffer)->name))
+ {
+ combine_after_change_list = Qnil;
+ return Qnil;
+ }
+
record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
Fset_buffer (combine_after_change_buffer);
syms_of_insdel ()
{
staticpro (&combine_after_change_list);
+ staticpro (&combine_after_change_buffer);
combine_after_change_list = Qnil;
combine_after_change_buffer = Qnil;