aboutsummaryrefslogtreecommitdiffstats
path: root/src/fileio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fileio.c')
-rw-r--r--src/fileio.c167
1 files changed, 116 insertions, 51 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 6e47670f09c..37a694da01d 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3692,27 +3692,25 @@ DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
3692 1, 5, 0, 3692 1, 5, 0,
3693 doc: /* Insert contents of file FILENAME after point. 3693 doc: /* Insert contents of file FILENAME after point.
3694Returns list of absolute file name and number of characters inserted. 3694Returns list of absolute file name and number of characters inserted.
3695If second argument VISIT is non-nil, the buffer's visited filename 3695If second argument VISIT is non-nil, the buffer's visited filename and
3696and last save file modtime are set, and it is marked unmodified. 3696last save file modtime are set, and it is marked unmodified. If
3697If visiting and the file does not exist, visiting is completed 3697visiting and the file does not exist, visiting is completed before the
3698before the error is signaled. 3698error is signaled.
3699The optional third and fourth arguments BEG and END 3699
3700specify what portion of the file to insert. 3700The optional third and fourth arguments BEG and END specify what portion
3701These arguments count bytes in the file, not characters in the buffer. 3701of the file to insert. These arguments count bytes in the file, not
3702If VISIT is non-nil, BEG and END must be nil. 3702characters in the buffer. If VISIT is non-nil, BEG and END must be nil.
3703 3703
3704If optional fifth argument REPLACE is non-nil, 3704If optional fifth argument REPLACE is non-nil, replace the current
3705it means replace the current buffer contents (in the accessible portion) 3705buffer contents (in the accessible portion) with the file contents.
3706with the file contents. This is better than simply deleting and inserting 3706This is better than simply deleting and inserting the whole thing
3707the whole thing because (1) it preserves some marker positions 3707because (1) it preserves some marker positions and (2) it puts less data
3708and (2) it puts less data in the undo list. 3708in the undo list. When REPLACE is non-nil, the second return value is
3709When REPLACE is non-nil, the value is the number of characters actually read, 3709the number of characters that replace previous buffer contents.
3710which is often less than the number of characters to be read. 3710
3711 3711This function does code conversion according to the value of
3712This does code conversion according to the value of 3712`coding-system-for-read' or `file-coding-system-alist', and sets the
3713`coding-system-for-read' or `file-coding-system-alist', 3713variable `last-coding-system-used' to the coding system actually used. */)
3714and sets the variable `last-coding-system-used' to the coding system
3715actually used. */)
3716 (filename, visit, beg, end, replace) 3714 (filename, visit, beg, end, replace)
3717 Lisp_Object filename, visit, beg, end, replace; 3715 Lisp_Object filename, visit, beg, end, replace;
3718{ 3716{
@@ -3722,8 +3720,8 @@ actually used. */)
3722 register int how_much; 3720 register int how_much;
3723 register int unprocessed; 3721 register int unprocessed;
3724 int count = SPECPDL_INDEX (); 3722 int count = SPECPDL_INDEX ();
3725 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 3723 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3726 Lisp_Object handler, val, insval, orig_filename; 3724 Lisp_Object handler, val, insval, orig_filename, old_undo;
3727 Lisp_Object p; 3725 Lisp_Object p;
3728 int total = 0; 3726 int total = 0;
3729 int not_regular = 0; 3727 int not_regular = 0;
@@ -3746,8 +3744,9 @@ actually used. */)
3746 val = Qnil; 3744 val = Qnil;
3747 p = Qnil; 3745 p = Qnil;
3748 orig_filename = Qnil; 3746 orig_filename = Qnil;
3747 old_undo = Qnil;
3749 3748
3750 GCPRO4 (filename, val, p, orig_filename); 3749 GCPRO5 (filename, val, p, orig_filename, old_undo);
3751 3750
3752 CHECK_STRING (filename); 3751 CHECK_STRING (filename);
3753 filename = Fexpand_file_name (filename, Qnil); 3752 filename = Fexpand_file_name (filename, Qnil);
@@ -4706,24 +4705,103 @@ actually used. */)
4706 /* Decode file format */ 4705 /* Decode file format */
4707 if (inserted > 0) 4706 if (inserted > 0)
4708 { 4707 {
4709 int empty_undo_list_p = 0; 4708 /* Don't run point motion or modification hooks when decoding. */
4709 int count = SPECPDL_INDEX ();
4710 specbind (Qinhibit_point_motion_hooks, Qt);
4711 specbind (Qinhibit_modification_hooks, Qt);
4712
4713 /* Save old undo list and don't record undo for decoding. */
4714 old_undo = current_buffer->undo_list;
4715 current_buffer->undo_list = Qt;
4710 4716
4711 /* If we're anyway going to discard undo information, don't 4717 if (NILP (replace))
4712 record it in the first place. The buffer's undo list at this
4713 point is either nil or t when visiting a file. */
4714 if (!NILP (visit))
4715 { 4718 {
4716 empty_undo_list_p = NILP (current_buffer->undo_list); 4719 insval = call3 (Qformat_decode,
4717 current_buffer->undo_list = Qt; 4720 Qnil, make_number (inserted), visit);
4721 CHECK_NUMBER (insval);
4722 inserted = XFASTINT (insval);
4723 }
4724 else
4725 {
4726 /* If REPLACE is non-nil and we succeeded in not replacing the
4727 beginning or end of the buffer text with the file's contents,
4728 call format-decode with `point' positioned at the beginning of
4729 the buffer and `inserted' equalling the number of characters
4730 in the buffer. Otherwise, format-decode might fail to
4731 correctly analyze the beginning or end of the buffer. Hence
4732 we temporarily save `point' and `inserted' here and restore
4733 `point' iff format-decode did not insert or delete any text.
4734 Otherwise we leave `point' at point-min. */
4735 int opoint = PT;
4736 int opoint_byte = PT_BYTE;
4737 int oinserted = ZV - BEGV;
4738
4739 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
4740 insval = call3 (Qformat_decode,
4741 Qnil, make_number (oinserted), visit);
4742 CHECK_NUMBER (insval);
4743 if (XINT (insval) == oinserted)
4744 SET_PT_BOTH (opoint, opoint_byte);
4745 inserted = XFASTINT (insval);
4718 } 4746 }
4719 4747
4720 insval = call3 (Qformat_decode, 4748 /* For consistency with format-decode call these now iff inserted > 0
4721 Qnil, make_number (inserted), visit); 4749 (martin 2007-06-28) */
4722 CHECK_NUMBER (insval); 4750 p = Vafter_insert_file_functions;
4723 inserted = XFASTINT (insval); 4751 while (CONSP (p))
4752 {
4753 if (NILP (replace))
4754 {
4755 insval = call1 (XCAR (p), make_number (inserted));
4756 if (!NILP (insval))
4757 {
4758 CHECK_NUMBER (insval);
4759 inserted = XFASTINT (insval);
4760 }
4761 }
4762 else
4763 {
4764 /* For the rationale of this see the comment on format-decode above. */
4765 int opoint = PT;
4766 int opoint_byte = PT_BYTE;
4767 int oinserted = ZV - BEGV;
4768
4769 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
4770 insval = call1 (XCAR (p), make_number (oinserted));
4771 if (!NILP (insval))
4772 {
4773 CHECK_NUMBER (insval);
4774 if (XINT (insval) == oinserted)
4775 SET_PT_BOTH (opoint, opoint_byte);
4776 inserted = XFASTINT (insval);
4777 }
4778 }
4779
4780 QUIT;
4781 p = XCDR (p);
4782 }
4783
4784 if (NILP (visit))
4785 {
4786 Lisp_Object lbeg, lend;
4787 XSETINT (lbeg, PT);
4788 XSETINT (lend, PT + inserted);
4789 if (CONSP (old_undo))
4790 {
4791 Lisp_Object tem = XCAR (old_undo);
4792 if (CONSP (tem) && INTEGERP (XCAR (tem)) &&
4793 INTEGERP (XCDR (tem)) && EQ (XCAR (tem), lbeg))
4794 /* In the non-visiting case record only the final insertion. */
4795 current_buffer->undo_list =
4796 Fcons (Fcons (lbeg, lend), Fcdr (old_undo));
4797 }
4798 }
4799 else
4800 /* If undo_list was Qt before, keep it that way.
4801 Otherwise start with an empty undo_list. */
4802 current_buffer->undo_list = EQ (old_undo, Qt) ? Qt : Qnil;
4724 4803
4725 if (!NILP (visit)) 4804 unbind_to (count, Qnil);
4726 current_buffer->undo_list = empty_undo_list_p ? Qnil : Qt;
4727 } 4805 }
4728 4806
4729 /* 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
@@ -4736,19 +4814,6 @@ actually used. */)
4736 update_compositions (PT, PT, CHECK_BORDER); 4814 update_compositions (PT, PT, CHECK_BORDER);
4737 } 4815 }
4738 4816
4739 p = Vafter_insert_file_functions;
4740 while (CONSP (p))
4741 {
4742 insval = call1 (XCAR (p), make_number (inserted));
4743 if (!NILP (insval))
4744 {
4745 CHECK_NUMBER (insval);
4746 inserted = XFASTINT (insval);
4747 }
4748 QUIT;
4749 p = XCDR (p);
4750 }
4751
4752 if (!NILP (visit) 4817 if (!NILP (visit)
4753 && current_buffer->modtime == -1) 4818 && current_buffer->modtime == -1)
4754 { 4819 {
@@ -5193,7 +5258,7 @@ This does code conversion according to the value of
5193 * if we do writes that don't end with a carriage return. Furthermore 5258 * if we do writes that don't end with a carriage return. Furthermore
5194 * it cannot handle writes of more then 16K. The modified 5259 * it cannot handle writes of more then 16K. The modified
5195 * version of "sys_write" in SYSDEP.C (see comment there) copes with 5260 * version of "sys_write" in SYSDEP.C (see comment there) copes with
5196 * this EXCEPT for the last record (iff it doesn't end with a carriage 5261 * this EXCEPT for the last record (if it doesn't end with a carriage
5197 * return). This implies that if your buffer doesn't end with a carriage 5262 * return). This implies that if your buffer doesn't end with a carriage
5198 * return, you get one free... tough. However it also means that if 5263 * return, you get one free... tough. However it also means that if
5199 * we make two calls to sys_write (a la the following code) you can 5264 * we make two calls to sys_write (a la the following code) you can