Mercurial > emacs
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 |