Mercurial > emacs
comparison src/fileio.c @ 83652:5b644ae74c91
Merge from emacs--devo--0
Patches applied:
* emacs--devo--0 (patch 846-851)
- Update from CVS
- Merge from emacs--rel--22
* emacs--rel--22 (patch 88-92)
- Update from CVS
- Merge from gnus--rel--5.10
* gnus--rel--5.10 (patch 242-244)
- Update from CVS
Revision: emacs@sv.gnu.org/emacs--multi-tty--0--patch-31
author | Miles Bader <miles@gnu.org> |
---|---|
date | Mon, 13 Aug 2007 13:51:08 +0000 |
parents | 984b1dfd7601 e5a68f18fcb9 |
children | 27d11c1d4e46 |
comparison
equal
deleted
inserted
replaced
83651:47230f3f349b | 83652:5b644ae74c91 |
---|---|
3690 | 3690 |
3691 DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents, | 3691 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 { |
3719 struct stat st; | 3717 struct stat st; |
3720 register int fd; | 3718 register int fd; |
3721 int inserted = 0; | 3719 int inserted = 0; |
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; |
3730 unsigned char read_buf[READ_BUF_SIZE]; | 3728 unsigned char read_buf[READ_BUF_SIZE]; |
3731 struct coding_system coding; | 3729 struct coding_system coding; |
3744 Fbarf_if_buffer_read_only (); | 3742 Fbarf_if_buffer_read_only (); |
3745 | 3743 |
3746 val = Qnil; | 3744 val = Qnil; |
3747 p = Qnil; | 3745 p = Qnil; |
3748 orig_filename = Qnil; | 3746 orig_filename = Qnil; |
3749 | 3747 old_undo = Qnil; |
3750 GCPRO4 (filename, val, p, orig_filename); | 3748 |
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); |
3754 | 3753 |
3755 /* If the file name has special constructs in it, | 3754 /* If the file name has special constructs in it, |
4704 } | 4703 } |
4705 | 4704 |
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. */ |
4710 | 4709 int count = SPECPDL_INDEX (); |
4711 /* If we're anyway going to discard undo information, don't | 4710 specbind (Qinhibit_point_motion_hooks, Qt); |
4712 record it in the first place. The buffer's undo list at this | 4711 specbind (Qinhibit_modification_hooks, Qt); |
4713 point is either nil or t when visiting a file. */ | 4712 |
4714 if (!NILP (visit)) | 4713 /* Save old undo list and don't record undo for decoding. */ |
4715 { | 4714 old_undo = current_buffer->undo_list; |
4716 empty_undo_list_p = NILP (current_buffer->undo_list); | 4715 current_buffer->undo_list = Qt; |
4717 current_buffer->undo_list = Qt; | 4716 |
4718 } | 4717 if (NILP (replace)) |
4719 | 4718 { |
4720 insval = call3 (Qformat_decode, | 4719 insval = call3 (Qformat_decode, |
4721 Qnil, make_number (inserted), visit); | 4720 Qnil, make_number (inserted), visit); |
4722 CHECK_NUMBER (insval); | 4721 CHECK_NUMBER (insval); |
4723 inserted = XFASTINT (insval); | 4722 inserted = XFASTINT (insval); |
4724 | 4723 } |
4725 if (!NILP (visit)) | 4724 else |
4726 current_buffer->undo_list = empty_undo_list_p ? Qnil : Qt; | 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); | |
4746 } | |
4747 | |
4748 /* For consistency with format-decode call these now iff inserted > 0 | |
4749 (martin 2007-06-28) */ | |
4750 p = Vafter_insert_file_functions; | |
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; | |
4803 | |
4804 unbind_to (count, Qnil); | |
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 |
4730 of normal visiting (not with REPLACE), which is done in a new buffer | 4808 of normal visiting (not with REPLACE), which is done in a new buffer |
4731 "before" the buffer is changed. */ | 4809 "before" the buffer is changed. */ |
4732 if (inserted > 0 && total > 0 | 4810 if (inserted > 0 && total > 0 |
4733 && (NILP (visit) || !NILP (replace))) | 4811 && (NILP (visit) || !NILP (replace))) |
4734 { | 4812 { |
4735 signal_after_change (PT, 0, inserted); | 4813 signal_after_change (PT, 0, inserted); |
4736 update_compositions (PT, PT, CHECK_BORDER); | 4814 update_compositions (PT, PT, CHECK_BORDER); |
4737 } | |
4738 | |
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 } | 4815 } |
4751 | 4816 |
4752 if (!NILP (visit) | 4817 if (!NILP (visit) |
4753 && current_buffer->modtime == -1) | 4818 && current_buffer->modtime == -1) |
4754 { | 4819 { |
5191 /* | 5256 /* |
5192 * Kludge Warning: The VMS C RTL likes to insert carriage returns | 5257 * Kludge Warning: The VMS C RTL likes to insert carriage returns |
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 |
5200 * get one at the gap as well. The easiest way to fix this (honest) | 5265 * get one at the gap as well. The easiest way to fix this (honest) |
5201 * is to move the gap to the next newline (or the end of the buffer). | 5266 * is to move the gap to the next newline (or the end of the buffer). |