]> code.delx.au - gnu-emacs/blobdiff - src/insdel.c
Add description of +LINE:COLUMN.
[gnu-emacs] / src / insdel.c
index 4229fb6abb531c72be1fd986194ab00ce0b83983..99576218b4b35383a11e38f665d860ddb224c1e7 100644 (file)
@@ -1,5 +1,6 @@
 /* Buffer insertion/deletion and gap motion for GNU Emacs.
-   Copyright (C) 1985, 86,93,94,95,97,98, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1985, 86,93,94,95,97,98, 1999, 2000, 2001
+   Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -366,14 +367,33 @@ adjust_markers_for_delete (from, from_byte, to, to_byte)
          m->charpos -= to - from;
          m->bytepos -= to_byte - from_byte;
        }
-
       /* Here's the case where a marker is inside text being deleted.  */
       else if (charpos > from)
        {
-         record_marker_adjustment (marker, from - charpos);
+         if (! m->insertion_type)
+           /* Normal markers will end up at the beginning of the
+              re-inserted text after undoing a deletion, and must be
+              adjusted to move them to the correct place.  */ 
+           record_marker_adjustment (marker, from - charpos);
+         else if (charpos < to)
+           /* Before-insertion markers will automatically move forward
+              upon re-inserting the deleted text, so we have to arrange
+              for them to move backward to the correct position.  */
+           record_marker_adjustment (marker, charpos - to);
+
          m->charpos = from;
          m->bytepos = from_byte;
        }
+      /* Here's the case where a before-insertion marker is immediately
+        before the deleted region.  */
+      else if (charpos == from && m->insertion_type)
+       {
+         /* Undoing the change uses normal insertion, which will
+            incorrectly make MARKER move forward, so we arrange for it
+            to then move backward to the correct place at the beginning
+            of the deleted region.  */
+         record_marker_adjustment (marker, to - from);
+       }
 
       marker = m->chain;
     }
@@ -503,7 +523,6 @@ void
 make_gap (nbytes_added)
      int nbytes_added;
 {
-  unsigned char *result;
   Lisp_Object tem;
   int real_gap_loc;
   int real_gap_loc_byte;
@@ -1534,7 +1553,7 @@ del_range_1 (from, to, prepare, ret_string)
     {
       int range_length = to - from;
       prepare_to_modify_buffer (from, to, &from);
-      to = from + range_length;
+      to = min (ZV, from + range_length);
     }
 
   from_byte = CHAR_TO_BYTE (from);
@@ -1577,7 +1596,12 @@ del_range_byte (from_byte, to_byte, prepare)
 
       if (old_from != from)
        from_byte = CHAR_TO_BYTE (from);
-      if (old_to == Z - to)
+      if (to > ZV)
+       {
+         to = ZV;
+         to_byte = ZV_BYTE;
+       }
+      else if (old_to == Z - to)
        to_byte = CHAR_TO_BYTE (to);
     }
 
@@ -1616,7 +1640,12 @@ del_range_both (from, from_byte, to, to_byte, prepare)
 
       if (old_from != from)
        from_byte = CHAR_TO_BYTE (from);
-      if (old_to == Z - to)
+      if (to > ZV)
+       {
+         to = ZV;
+         to_byte = ZV_BYTE;
+       }
+      else if (old_to == Z - to)
        to_byte = CHAR_TO_BYTE (to);
     }
 
@@ -1873,6 +1902,8 @@ signal_before_change (start_int, end_int, preserve_ptr)
       Lisp_Object before_change_functions;
       Lisp_Object after_change_functions;
       struct gcpro gcpro1, gcpro2;
+      struct buffer *old = current_buffer;
+      struct buffer *new;
 
       PRESERVE_VALUE;
       PRESERVE_START_END;
@@ -1892,9 +1923,21 @@ signal_before_change (start_int, end_int, preserve_ptr)
       args[2] = FETCH_END;
       run_hook_list_with_args (before_change_functions, 3, args);
 
-      /* "Unbind" the variables we "bound" to nil.  */
-      Vbefore_change_functions = before_change_functions;
-      Vafter_change_functions = after_change_functions;
+      /* "Unbind" the variables we "bound" to nil.  Beware a
+        buffer-local hook which changes the buffer when run (e.g. W3).  */
+      if (old != current_buffer)
+       {
+         new = current_buffer;
+         set_buffer_internal (old);
+         Vbefore_change_functions = before_change_functions;
+         Vafter_change_functions = after_change_functions;
+         set_buffer_internal (new);
+       }
+      else
+       {
+         Vbefore_change_functions = before_change_functions;
+         Vafter_change_functions = after_change_functions;
+       }
       UNGCPRO;
     }
 
@@ -1960,6 +2003,8 @@ signal_after_change (charpos, lendel, lenins)
       Lisp_Object args[4];
       Lisp_Object before_change_functions;
       Lisp_Object after_change_functions;
+      struct buffer *old = current_buffer;
+      struct buffer *new;
       struct gcpro gcpro1, gcpro2;
 
       /* "Bind" before-change-functions and after-change-functions
@@ -1979,9 +2024,21 @@ signal_after_change (charpos, lendel, lenins)
       run_hook_list_with_args (after_change_functions,
                               4, args);
 
-      /* "Unbind" the variables we "bound" to nil.  */
-      Vbefore_change_functions = before_change_functions;
-      Vafter_change_functions = after_change_functions;
+      /* "Unbind" the variables we "bound" to nil.  Beware a
+        buffer-local hook which changes the buffer when run (e.g. W3).  */
+      if (old != current_buffer)
+       {
+         new = current_buffer;
+         set_buffer_internal (old);
+         Vbefore_change_functions = before_change_functions;
+         Vafter_change_functions = after_change_functions;
+         set_buffer_internal (new);
+       }
+      else
+       {
+         Vbefore_change_functions = before_change_functions;
+         Vafter_change_functions = after_change_functions;
+       }
       UNGCPRO;
     }