aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/fileio.c167
2 files changed, 128 insertions, 50 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c2bb18b6575..2d1a9653f2b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
12007-08-07 Martin Rudalics <rudalics@gmx.at>
2
3 * fileio.c (Finsert_file_contents): Run format-decode and
4 after_insert_file_functions on entire buffer when REPLACE is
5 non-nil and inhibit modification_hooks and point_motion_hooks.
6 For consistency, run after_insert_file_functions iff something
7 got inserted. Move signal_after_change and update_compositions
8 after code running after_insert_file_functions. Make sure that
9 undo_list doesn't record intermediate steps of the decoding
10 process.
11
12007-08-07 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> 122007-08-07 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
2 13
3 * emacs.c (main) 14 * emacs.c (main)
diff --git a/src/fileio.c b/src/fileio.c
index 328b90a0a94..6037eec5d7d 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3690,27 +3690,25 @@ DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
3690 1, 5, 0, 3690 1, 5, 0,
3691 doc: /* Insert contents of file FILENAME after point. 3691 doc: /* Insert contents of file FILENAME after point.
3692Returns list of absolute file name and number of characters inserted. 3692Returns list of absolute file name and number of characters inserted.
3693If second argument VISIT is non-nil, the buffer's visited filename 3693If second argument VISIT is non-nil, the buffer's visited filename and
3694and last save file modtime are set, and it is marked unmodified. 3694last save file modtime are set, and it is marked unmodified. If
3695If visiting and the file does not exist, visiting is completed 3695visiting and the file does not exist, visiting is completed before the
3696before the error is signaled. 3696error is signaled.
3697The optional third and fourth arguments BEG and END 3697
3698specify what portion of the file to insert. 3698The optional third and fourth arguments BEG and END specify what portion
3699These arguments count bytes in the file, not characters in the buffer. 3699of the file to insert. These arguments count bytes in the file, not
3700If VISIT is non-nil, BEG and END must be nil. 3700characters in the buffer. If VISIT is non-nil, BEG and END must be nil.
3701 3701
3702If optional fifth argument REPLACE is non-nil, 3702If optional fifth argument REPLACE is non-nil, replace the current
3703it means replace the current buffer contents (in the accessible portion) 3703buffer contents (in the accessible portion) with the file contents.
3704with the file contents. This is better than simply deleting and inserting 3704This is better than simply deleting and inserting the whole thing
3705the whole thing because (1) it preserves some marker positions 3705because (1) it preserves some marker positions and (2) it puts less data
3706and (2) it puts less data in the undo list. 3706in the undo list. When REPLACE is non-nil, the second return value is
3707When REPLACE is non-nil, the value is the number of characters actually read, 3707the number of characters that replace previous buffer contents.
3708which is often less than the number of characters to be read. 3708
3709 3709This function does code conversion according to the value of
3710This does code conversion according to the value of 3710`coding-system-for-read' or `file-coding-system-alist', and sets the
3711`coding-system-for-read' or `file-coding-system-alist', 3711variable `last-coding-system-used' to the coding system actually used. */)
3712and sets the variable `last-coding-system-used' to the coding system
3713actually used. */)
3714 (filename, visit, beg, end, replace) 3712 (filename, visit, beg, end, replace)
3715 Lisp_Object filename, visit, beg, end, replace; 3713 Lisp_Object filename, visit, beg, end, replace;
3716{ 3714{
@@ -3720,8 +3718,8 @@ actually used. */)
3720 register int how_much; 3718 register int how_much;
3721 register int unprocessed; 3719 register int unprocessed;
3722 int count = SPECPDL_INDEX (); 3720 int count = SPECPDL_INDEX ();
3723 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 3721 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3724 Lisp_Object handler, val, insval, orig_filename; 3722 Lisp_Object handler, val, insval, orig_filename, old_undo;
3725 Lisp_Object p; 3723 Lisp_Object p;
3726 int total = 0; 3724 int total = 0;
3727 int not_regular = 0; 3725 int not_regular = 0;
@@ -3744,8 +3742,9 @@ actually used. */)
3744 val = Qnil; 3742 val = Qnil;
3745 p = Qnil; 3743 p = Qnil;
3746 orig_filename = Qnil; 3744 orig_filename = Qnil;
3745 old_undo = Qnil;
3747 3746
3748 GCPRO4 (filename, val, p, orig_filename); 3747 GCPRO5 (filename, val, p, orig_filename, old_undo);
3749 3748
3750 CHECK_STRING (filename); 3749 CHECK_STRING (filename);
3751 filename = Fexpand_file_name (filename, Qnil); 3750 filename = Fexpand_file_name (filename, Qnil);
@@ -4704,24 +4703,105 @@ actually used. */)
4704 /* Decode file format */ 4703 /* Decode file format */
4705 if (inserted > 0) 4704 if (inserted > 0)
4706 { 4705 {
4707 int empty_undo_list_p = 0; 4706 /* Don't run point motion or modification hooks when decoding. */
4707 int count = SPECPDL_INDEX ();
4708 specbind (Qinhibit_point_motion_hooks, Qt);
4709 specbind (Qinhibit_modification_hooks, Qt);
4710
4711 /* Save old undo list and don't record undo for decoding. */
4712 old_undo = current_buffer->undo_list;
4713 current_buffer->undo_list = Qt;
4708 4714
4709 /* If we're anyway going to discard undo information, don't 4715 if (NILP (replace))
4710 record it in the first place. The buffer's undo list at this
4711 point is either nil or t when visiting a file. */
4712 if (!NILP (visit))
4713 { 4716 {
4714 empty_undo_list_p = NILP (current_buffer->undo_list); 4717 insval = call3 (Qformat_decode,
4715 current_buffer->undo_list = Qt; 4718 Qnil, make_number (inserted), visit);
4719 CHECK_NUMBER (insval);
4720 inserted = XFASTINT (insval);
4721 }
4722 else
4723 {
4724 /* If REPLACE is non-nil and we succeeded in not replacing the
4725 beginning or end of the buffer text with the file's contents,
4726 call format-decode with `point' positioned at the beginning of
4727 the buffer and `inserted' equalling the number of characters
4728 in the buffer. Otherwise, format-decode might fail to
4729 correctly analyze the beginning or end of the buffer. Hence
4730 we temporarily save `point' and `inserted' here and restore
4731 `point' iff format-decode did not insert or delete any text.
4732 Otherwise we leave `point' at point-min. */
4733 int opoint = PT;
4734 int opoint_byte = PT_BYTE;
4735 int oinserted = ZV - BEGV;
4736
4737 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
4738 insval = call3 (Qformat_decode,
4739 Qnil, make_number (oinserted), visit);
4740 CHECK_NUMBER (insval);
4741 if (insval = oinserted)
4742 SET_PT_BOTH (opoint, opoint_byte);
4743 inserted = XFASTINT (insval);
4744 }
4745
4746 /* For consistency with format-decode call these now iff inserted > 0
4747 (martin 2007-06-28) */
4748 p = Vafter_insert_file_functions;
4749 while (CONSP (p))
4750 {
4751 if (NILP (replace))
4752 {
4753 insval = call1 (XCAR (p), make_number (inserted));
4754 if (!NILP (insval))
4755 {
4756 CHECK_NUMBER (insval);
4757 inserted = XFASTINT (insval);
4758 }
4759 }
4760 else
4761 {
4762 /* For the rationale of this see the comment on format-decode above. */
4763 int opoint = PT;
4764 int opoint_byte = PT_BYTE;
4765 int oinserted = ZV - BEGV;
4766
4767 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
4768 insval = call1 (XCAR (p), make_number (oinserted));
4769 if (!NILP (insval))
4770 {
4771 CHECK_NUMBER (insval);
4772 if (insval = oinserted)
4773 SET_PT_BOTH (opoint, opoint_byte);
4774 inserted = XFASTINT (insval);
4775 }
4776 }
4777
4778 QUIT;
4779 p = XCDR (p);
4716 } 4780 }
4717 4781
4718 insval = call3 (Qformat_decode, 4782 if (NILP (visit))
4719 Qnil, make_number (inserted), visit); 4783 {
4720 CHECK_NUMBER (insval); 4784 Lisp_Object lbeg, lend;
4721 inserted = XFASTINT (insval); 4785 XSETINT (lbeg, PT);
4786 XSETINT (lend, PT + inserted);
4787 if (CONSP (old_undo))
4788 {
4789 Lisp_Object tem = XCAR (old_undo);
4790 if (CONSP (tem) && INTEGERP (XCAR (tem)) &&
4791 INTEGERP (XCDR (tem)) && (XCAR (tem)) == lbeg)
4792 /* In the non-visiting case record only the final insertion. */
4793 current_buffer->undo_list =
4794 Fcons (Fcons (lbeg, lend), Fcdr (old_undo));
4795 }
4796 }
4797 else if (old_undo == Qt)
4798 /* If undo_list was Qt before, keep it that way. */
4799 current_buffer->undo_list = Qt;
4800 else
4801 /* Otherwise start with an empty undo_list. */
4802 current_buffer->undo_list = Qnil;
4722 4803
4723 if (!NILP (visit)) 4804 unbind_to (count, Qnil);
4724 current_buffer->undo_list = empty_undo_list_p ? Qnil : Qt;
4725 } 4805 }
4726 4806
4727 /* Call after-change hooks for the inserted text, aside from the case 4807 /* Call after-change hooks for the inserted text, aside from the case
@@ -4734,19 +4814,6 @@ actually used. */)
4734 update_compositions (PT, PT, CHECK_BORDER); 4814 update_compositions (PT, PT, CHECK_BORDER);
4735 } 4815 }
4736 4816
4737 p = Vafter_insert_file_functions;
4738 while (CONSP (p))
4739 {
4740 insval = call1 (XCAR (p), make_number (inserted));
4741 if (!NILP (insval))
4742 {
4743 CHECK_NUMBER (insval);
4744 inserted = XFASTINT (insval);
4745 }
4746 QUIT;
4747 p = XCDR (p);
4748 }
4749
4750 if (!NILP (visit) 4817 if (!NILP (visit)
4751 && current_buffer->modtime == -1) 4818 && current_buffer->modtime == -1)
4752 { 4819 {