diff options
| author | Martin Rudalics | 2007-08-07 12:23:20 +0000 |
|---|---|---|
| committer | Martin Rudalics | 2007-08-07 12:23:20 +0000 |
| commit | 6f2528d8d8c66e7bfbd0cd33280fabeebcf445aa (patch) | |
| tree | a012cc695e96da9b0fa93e70aca828c8d74a6c95 /src | |
| parent | 3ceeb306d2d5843f7277a51c5425386d64678e31 (diff) | |
| download | emacs-6f2528d8d8c66e7bfbd0cd33280fabeebcf445aa.tar.gz emacs-6f2528d8d8c66e7bfbd0cd33280fabeebcf445aa.zip | |
(Finsert_file_contents): Run format-decode and
after_insert_file_functions on entire buffer when REPLACE is
non-nil and inhibit modification_hooks and point_motion_hooks.
For consistency, run after_insert_file_functions iff something
got inserted. Move signal_after_change and update_compositions
after code running after_insert_file_functions. Make sure that
undo_list doesn't record intermediate steps of the decoding
process.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 11 | ||||
| -rw-r--r-- | src/fileio.c | 167 |
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 @@ | |||
| 1 | 2007-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 | |||
| 1 | 2007-08-07 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | 12 | 2007-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. |
| 3692 | Returns list of absolute file name and number of characters inserted. | 3692 | Returns list of absolute file name and number of characters inserted. |
| 3693 | If second argument VISIT is non-nil, the buffer's visited filename | 3693 | If second argument VISIT is non-nil, the buffer's visited filename and |
| 3694 | and last save file modtime are set, and it is marked unmodified. | 3694 | last save file modtime are set, and it is marked unmodified. If |
| 3695 | If visiting and the file does not exist, visiting is completed | 3695 | visiting and the file does not exist, visiting is completed before the |
| 3696 | before the error is signaled. | 3696 | error is signaled. |
| 3697 | The optional third and fourth arguments BEG and END | 3697 | |
| 3698 | specify what portion of the file to insert. | 3698 | The optional third and fourth arguments BEG and END specify what portion |
| 3699 | These arguments count bytes in the file, not characters in the buffer. | 3699 | of the file to insert. These arguments count bytes in the file, not |
| 3700 | If VISIT is non-nil, BEG and END must be nil. | 3700 | characters in the buffer. If VISIT is non-nil, BEG and END must be nil. |
| 3701 | 3701 | ||
| 3702 | If optional fifth argument REPLACE is non-nil, | 3702 | If optional fifth argument REPLACE is non-nil, replace the current |
| 3703 | it means replace the current buffer contents (in the accessible portion) | 3703 | buffer contents (in the accessible portion) with the file contents. |
| 3704 | with the file contents. This is better than simply deleting and inserting | 3704 | This is better than simply deleting and inserting the whole thing |
| 3705 | the whole thing because (1) it preserves some marker positions | 3705 | because (1) it preserves some marker positions and (2) it puts less data |
| 3706 | and (2) it puts less data in the undo list. | 3706 | in the undo list. When REPLACE is non-nil, the second return value is |
| 3707 | When REPLACE is non-nil, the value is the number of characters actually read, | 3707 | the number of characters that replace previous buffer contents. |
| 3708 | which is often less than the number of characters to be read. | 3708 | |
| 3709 | 3709 | This function does code conversion according to the value of | |
| 3710 | This 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', | 3711 | variable `last-coding-system-used' to the coding system actually used. */) |
| 3712 | and sets the variable `last-coding-system-used' to the coding system | ||
| 3713 | actually 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 | { |