*** fileio.c.~1.602.~ Thu Feb 14 20:41:44 2008 --- fileio.c Sun Mar 2 12:03:00 2008 *************** *** 3730,3735 **** --- 3730,3736 ---- int read_quit = 0; Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark; int we_locked_file = 0; + int empty_undo_list = NILP (current_buffer->undo_list); if (current_buffer->base_buffer && ! NILP (visit)) error ("Cannot do file visiting in an indirect buffer"); *************** *** 4593,4598 **** --- 4594,4622 ---- if (CODING_MAY_REQUIRE_DECODING (&coding) && (inserted > 0 || CODING_REQUIRE_FLUSHING (&coding))) { + if (CONSP (current_buffer->undo_list) + && ! NILP (XCAR (current_buffer->undo_list))) + /* If the undo list is non-empty and undo information is + recorded, insert an undo boundary unless we already have one. + This is needed to avoid that record_insert combines the + present insertion with an earlier one and consequently the + mechanism fails that compares the start position of the + insertion before vs that after the format-decode step. */ + Fundo_boundary (); + else if (empty_undo_list + && MODIFF <= SAVE_MODIFF + && NILP (visit) && NILP (replace)) + /* Else if the present insertion is the very first change of the + current buffer, undo information is recorded, and we are + neither visiting a file nor replacing buffer contents, make + sure we record the insertion as a first change in the + undo-list. This is needed in order to avoid that undoing the + insertion leaves the buffer's modified state set. */ + { + current_buffer->undo_list = Qnil; + record_first_change (); + } + move_gap_both (PT, PT_BYTE); GAP_SIZE += inserted; ZV_BYTE -= inserted; *************** *** 4604,4611 **** coding_system = CODING_ID_NAME (coding.id); } else if (inserted > 0) ! adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, ! inserted); /* Now INSERTED is measured in characters. */ --- 4628,4651 ---- coding_system = CODING_ID_NAME (coding.id); } else if (inserted > 0) ! { ! if (CONSP (current_buffer->undo_list) ! && ! NILP (XCAR (current_buffer->undo_list))) ! /* Insert an undo boundary unless there's one here. See ! explanation above. */ ! Fundo_boundary (); ! else if (empty_undo_list ! && MODIFF <= SAVE_MODIFF ! && NILP (visit) && NILP (replace)) ! /* Make sure the first insertion is counted as a change. See ! explanation above. */ ! { ! current_buffer->undo_list = Qnil; ! record_first_change (); ! } ! adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, ! inserted); ! } /* Now INSERTED is measured in characters. */