comparison src/fileio.c @ 96974:fa6516860909

(Finsert_file_contents): Properly adjust undo list after format conversion.
author Andreas Schwab <schwab@suse.de>
date Thu, 24 Jul 2008 13:00:20 +0000
parents cb1bfa1dca4f
children 9592c50233ab
comparison
equal deleted inserted replaced
96973:32a1bbf01ebb 96974:fa6516860909
4668 CHECK_NUMBER (insval); 4668 CHECK_NUMBER (insval);
4669 inserted = XFASTINT (insval); 4669 inserted = XFASTINT (insval);
4670 } 4670 }
4671 } 4671 }
4672 4672
4673 /* Decode file format */ 4673 /* Decode file format. */
4674 if (inserted > 0) 4674 if (inserted > 0)
4675 { 4675 {
4676 /* Don't run point motion or modification hooks when decoding. */ 4676 /* Don't run point motion or modification hooks when decoding. */
4677 int count = SPECPDL_INDEX (); 4677 int count = SPECPDL_INDEX ();
4678 int old_inserted = inserted;
4678 specbind (Qinhibit_point_motion_hooks, Qt); 4679 specbind (Qinhibit_point_motion_hooks, Qt);
4679 specbind (Qinhibit_modification_hooks, Qt); 4680 specbind (Qinhibit_modification_hooks, Qt);
4680 4681
4681 /* Save old undo list and don't record undo for decoding. */ 4682 /* Save old undo list and don't record undo for decoding. */
4682 old_undo = current_buffer->undo_list; 4683 old_undo = current_buffer->undo_list;
4683 current_buffer->undo_list = Qt; 4684 current_buffer->undo_list = Qt;
4684 4685
4685 if (NILP (replace)) 4686 if (NILP (replace))
4686 { 4687 {
4690 inserted = XFASTINT (insval); 4691 inserted = XFASTINT (insval);
4691 } 4692 }
4692 else 4693 else
4693 { 4694 {
4694 /* If REPLACE is non-nil and we succeeded in not replacing the 4695 /* If REPLACE is non-nil and we succeeded in not replacing the
4695 beginning or end of the buffer text with the file's contents, 4696 beginning or end of the buffer text with the file's contents,
4696 call format-decode with `point' positioned at the beginning of 4697 call format-decode with `point' positioned at the beginning
4697 the buffer and `inserted' equalling the number of characters 4698 of the buffer and `inserted' equalling the number of
4698 in the buffer. Otherwise, format-decode might fail to 4699 characters in the buffer. Otherwise, format-decode might
4699 correctly analyze the beginning or end of the buffer. Hence 4700 fail to correctly analyze the beginning or end of the buffer.
4700 we temporarily save `point' and `inserted' here and restore 4701 Hence we temporarily save `point' and `inserted' here and
4701 `point' iff format-decode did not insert or delete any text. 4702 restore `point' iff format-decode did not insert or delete
4702 Otherwise we leave `point' at point-min. */ 4703 any text. Otherwise we leave `point' at point-min. */
4703 int opoint = PT; 4704 int opoint = PT;
4704 int opoint_byte = PT_BYTE; 4705 int opoint_byte = PT_BYTE;
4705 int oinserted = ZV - BEGV; 4706 int oinserted = ZV - BEGV;
4706 int ochars_modiff = CHARS_MODIFF; 4707 int ochars_modiff = CHARS_MODIFF;
4707 4708
4710 Qnil, make_number (oinserted), visit); 4711 Qnil, make_number (oinserted), visit);
4711 CHECK_NUMBER (insval); 4712 CHECK_NUMBER (insval);
4712 if (ochars_modiff == CHARS_MODIFF) 4713 if (ochars_modiff == CHARS_MODIFF)
4713 /* format_decode didn't modify buffer's characters => move 4714 /* format_decode didn't modify buffer's characters => move
4714 point back to position before inserted text and leave 4715 point back to position before inserted text and leave
4715 value of inserted alone. */ 4716 value of inserted alone. */
4716 SET_PT_BOTH (opoint, opoint_byte); 4717 SET_PT_BOTH (opoint, opoint_byte);
4717 else 4718 else
4718 /* format_decode modified buffer's characters => consider 4719 /* format_decode modified buffer's characters => consider
4719 entire buffer changed and leave point at point-min. */ 4720 entire buffer changed and leave point at point-min. */
4720 inserted = XFASTINT (insval); 4721 inserted = XFASTINT (insval);
4721 } 4722 }
4722 4723
4723 /* For consistency with format-decode call these now iff inserted > 0 4724 /* For consistency with format-decode call these now iff inserted > 0
4724 (martin 2007-06-28) */ 4725 (martin 2007-06-28). */
4725 p = Vafter_insert_file_functions; 4726 p = Vafter_insert_file_functions;
4726 while (CONSP (p)) 4727 while (CONSP (p))
4727 { 4728 {
4728 if (NILP (replace)) 4729 if (NILP (replace))
4729 { 4730 {
4734 inserted = XFASTINT (insval); 4735 inserted = XFASTINT (insval);
4735 } 4736 }
4736 } 4737 }
4737 else 4738 else
4738 { 4739 {
4739 /* For the rationale of this see the comment on format-decode above. */ 4740 /* For the rationale of this see the comment on
4741 format-decode above. */
4740 int opoint = PT; 4742 int opoint = PT;
4741 int opoint_byte = PT_BYTE; 4743 int opoint_byte = PT_BYTE;
4742 int oinserted = ZV - BEGV; 4744 int oinserted = ZV - BEGV;
4743 int ochars_modiff = CHARS_MODIFF; 4745 int ochars_modiff = CHARS_MODIFF;
4744 4746
4749 CHECK_NUMBER (insval); 4751 CHECK_NUMBER (insval);
4750 if (ochars_modiff == CHARS_MODIFF) 4752 if (ochars_modiff == CHARS_MODIFF)
4751 /* after_insert_file_functions didn't modify 4753 /* after_insert_file_functions didn't modify
4752 buffer's characters => move point back to 4754 buffer's characters => move point back to
4753 position before inserted text and leave value of 4755 position before inserted text and leave value of
4754 inserted alone. */ 4756 inserted alone. */
4755 SET_PT_BOTH (opoint, opoint_byte); 4757 SET_PT_BOTH (opoint, opoint_byte);
4756 else 4758 else
4757 /* after_insert_file_functions did modify buffer's 4759 /* after_insert_file_functions did modify buffer's
4758 characters => consider entire buffer changed and 4760 characters => consider entire buffer changed and
4759 leave point at point-min. */ 4761 leave point at point-min. */
4760 inserted = XFASTINT (insval); 4762 inserted = XFASTINT (insval);
4761 } 4763 }
4762 } 4764 }
4763 4765
4764 QUIT; 4766 QUIT;
4765 p = XCDR (p); 4767 p = XCDR (p);
4766 } 4768 }
4767 4769
4768 if (NILP (visit)) 4770 if (NILP (visit))
4769 { 4771 {
4770 Lisp_Object lbeg, lend; 4772 current_buffer->undo_list = old_undo;
4771 XSETINT (lbeg, PT); 4773 if (CONSP (old_undo) && inserted != old_inserted)
4772 XSETINT (lend, PT + inserted);
4773 if (CONSP (old_undo))
4774 { 4774 {
4775 /* Adjust the last undo record for the size change during
4776 the format conversion. */
4775 Lisp_Object tem = XCAR (old_undo); 4777 Lisp_Object tem = XCAR (old_undo);
4776 if (CONSP (tem) && INTEGERP (XCAR (tem)) && 4778 if (CONSP (tem) && INTEGERP (XCAR (tem))
4777 INTEGERP (XCDR (tem)) && EQ (XCAR (tem), lbeg)) 4779 && INTEGERP (XCDR (tem))
4778 /* In the non-visiting case record only the final insertion. */ 4780 && XFASTINT (XCDR (tem)) == PT + old_inserted)
4779 current_buffer->undo_list = 4781 XSETCDR (tem, make_number (PT + inserted));
4780 Fcons (Fcons (lbeg, lend), Fcdr (old_undo));
4781 } 4782 }
4782 } 4783 }
4783 else 4784 else
4784 /* If undo_list was Qt before, keep it that way. 4785 /* If undo_list was Qt before, keep it that way.
4785 Otherwise start with an empty undo_list. */ 4786 Otherwise start with an empty undo_list. */
4786 current_buffer->undo_list = EQ (old_undo, Qt) ? Qt : Qnil; 4787 current_buffer->undo_list = EQ (old_undo, Qt) ? Qt : Qnil;
4787 4788
4788 unbind_to (count, Qnil); 4789 unbind_to (count, Qnil);
4789 } 4790 }
4790 4791