diff options
Diffstat (limited to 'src/fileio.c')
| -rw-r--r-- | src/fileio.c | 167 |
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. |
| 3694 | Returns list of absolute file name and number of characters inserted. | 3694 | Returns list of absolute file name and number of characters inserted. |
| 3695 | If second argument VISIT is non-nil, the buffer's visited filename | 3695 | If second argument VISIT is non-nil, the buffer's visited filename and |
| 3696 | and last save file modtime are set, and it is marked unmodified. | 3696 | last save file modtime are set, and it is marked unmodified. If |
| 3697 | If visiting and the file does not exist, visiting is completed | 3697 | visiting and the file does not exist, visiting is completed before the |
| 3698 | before the error is signaled. | 3698 | error is signaled. |
| 3699 | The optional third and fourth arguments BEG and END | 3699 | |
| 3700 | specify what portion of the file to insert. | 3700 | The optional third and fourth arguments BEG and END specify what portion |
| 3701 | These arguments count bytes in the file, not characters in the buffer. | 3701 | of the file to insert. These arguments count bytes in the file, not |
| 3702 | If VISIT is non-nil, BEG and END must be nil. | 3702 | characters in the buffer. If VISIT is non-nil, BEG and END must be nil. |
| 3703 | 3703 | ||
| 3704 | If optional fifth argument REPLACE is non-nil, | 3704 | If optional fifth argument REPLACE is non-nil, replace the current |
| 3705 | it means replace the current buffer contents (in the accessible portion) | 3705 | buffer contents (in the accessible portion) with the file contents. |
| 3706 | with the file contents. This is better than simply deleting and inserting | 3706 | This is better than simply deleting and inserting the whole thing |
| 3707 | the whole thing because (1) it preserves some marker positions | 3707 | because (1) it preserves some marker positions and (2) it puts less data |
| 3708 | and (2) it puts less data in the undo list. | 3708 | in the undo list. When REPLACE is non-nil, the second return value is |
| 3709 | When REPLACE is non-nil, the value is the number of characters actually read, | 3709 | the number of characters that replace previous buffer contents. |
| 3710 | which is often less than the number of characters to be read. | 3710 | |
| 3711 | 3711 | This function does code conversion according to the value of | |
| 3712 | This 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', | 3713 | variable `last-coding-system-used' to the coding system actually used. */) |
| 3714 | and sets the variable `last-coding-system-used' to the coding system | ||
| 3715 | actually 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 |