aboutsummaryrefslogtreecommitdiffstats
path: root/src/fileio.c
diff options
context:
space:
mode:
authorMiles Bader <[email protected]>2007-08-13 13:51:08 +0000
committerMiles Bader <[email protected]>2007-08-13 13:51:08 +0000
commitaaf34461ff5804e5cebe163b31e535da72e81d87 (patch)
treeb096310b459b78e437f08ac0f1f00954840a5db5 /src/fileio.c
parent61d032dfd91b811d59acd7605ac02758be97e912 (diff)
parent37cc095b6a175fb5a2fb18fa029eaf3aa3b3fa53 (diff)
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: [email protected]/emacs--multi-tty--0--patch-31
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 6e47670f09..37a694da01 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3692,27 +3692,25 @@ DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
1, 5, 0,
doc: /* Insert contents of file FILENAME after point.
Returns list of absolute file name and number of characters inserted.
-If second argument VISIT is non-nil, the buffer's visited filename
-and last save file modtime are set, and it is marked unmodified.
-If visiting and the file does not exist, visiting is completed
-before the error is signaled.
-The optional third and fourth arguments BEG and END
-specify what portion of the file to insert.
-These arguments count bytes in the file, not characters in the buffer.
-If VISIT is non-nil, BEG and END must be nil.
-
-If optional fifth argument REPLACE is non-nil,
-it means replace the current buffer contents (in the accessible portion)
-with the file contents. This is better than simply deleting and inserting
-the whole thing because (1) it preserves some marker positions
-and (2) it puts less data in the undo list.
-When REPLACE is non-nil, the value is the number of characters actually read,
-which is often less than the number of characters to be read.
-
-This does code conversion according to the value of
-`coding-system-for-read' or `file-coding-system-alist',
-and sets the variable `last-coding-system-used' to the coding system
-actually used. */)
+If second argument VISIT is non-nil, the buffer's visited filename and
+last save file modtime are set, and it is marked unmodified. If
+visiting and the file does not exist, visiting is completed before the
+error is signaled.
+
+The optional third and fourth arguments BEG and END specify what portion
+of the file to insert. These arguments count bytes in the file, not
+characters in the buffer. If VISIT is non-nil, BEG and END must be nil.
+
+If optional fifth argument REPLACE is non-nil, replace the current
+buffer contents (in the accessible portion) with the file contents.
+This is better than simply deleting and inserting the whole thing
+because (1) it preserves some marker positions and (2) it puts less data
+in the undo list. When REPLACE is non-nil, the second return value is
+the number of characters that replace previous buffer contents.
+
+This function does code conversion according to the value of
+`coding-system-for-read' or `file-coding-system-alist', and sets the
+variable `last-coding-system-used' to the coding system actually used. */)
(filename, visit, beg, end, replace)
Lisp_Object filename, visit, beg, end, replace;
{
@@ -3722,8 +3720,8 @@ actually used. */)
register int how_much;
register int unprocessed;
int count = SPECPDL_INDEX ();
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
- Lisp_Object handler, val, insval, orig_filename;
+ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
+ Lisp_Object handler, val, insval, orig_filename, old_undo;
Lisp_Object p;
int total = 0;
int not_regular = 0;
@@ -3746,8 +3744,9 @@ actually used. */)
val = Qnil;
p = Qnil;
orig_filename = Qnil;
+ old_undo = Qnil;
- GCPRO4 (filename, val, p, orig_filename);
+ GCPRO5 (filename, val, p, orig_filename, old_undo);
CHECK_STRING (filename);
filename = Fexpand_file_name (filename, Qnil);
@@ -4706,24 +4705,103 @@ actually used. */)
/* Decode file format */
if (inserted > 0)
{
- int empty_undo_list_p = 0;
+ /* Don't run point motion or modification hooks when decoding. */
+ int count = SPECPDL_INDEX ();
+ specbind (Qinhibit_point_motion_hooks, Qt);
+ specbind (Qinhibit_modification_hooks, Qt);
+
+ /* Save old undo list and don't record undo for decoding. */
+ old_undo = current_buffer->undo_list;
+ current_buffer->undo_list = Qt;
- /* If we're anyway going to discard undo information, don't
- record it in the first place. The buffer's undo list at this
- point is either nil or t when visiting a file. */
- if (!NILP (visit))
+ if (NILP (replace))
{
- empty_undo_list_p = NILP (current_buffer->undo_list);
- current_buffer->undo_list = Qt;
+ insval = call3 (Qformat_decode,
+ Qnil, make_number (inserted), visit);
+ CHECK_NUMBER (insval);
+ inserted = XFASTINT (insval);
+ }
+ else
+ {
+ /* If REPLACE is non-nil and we succeeded in not replacing the
+ beginning or end of the buffer text with the file's contents,
+ call format-decode with `point' positioned at the beginning of
+ the buffer and `inserted' equalling the number of characters
+ in the buffer. Otherwise, format-decode might fail to
+ correctly analyze the beginning or end of the buffer. Hence
+ we temporarily save `point' and `inserted' here and restore
+ `point' iff format-decode did not insert or delete any text.
+ Otherwise we leave `point' at point-min. */
+ int opoint = PT;
+ int opoint_byte = PT_BYTE;
+ int oinserted = ZV - BEGV;
+
+ TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
+ insval = call3 (Qformat_decode,
+ Qnil, make_number (oinserted), visit);
+ CHECK_NUMBER (insval);
+ if (XINT (insval) == oinserted)
+ SET_PT_BOTH (opoint, opoint_byte);
+ inserted = XFASTINT (insval);
}
- insval = call3 (Qformat_decode,
- Qnil, make_number (inserted), visit);
- CHECK_NUMBER (insval);
- inserted = XFASTINT (insval);
+ /* For consistency with format-decode call these now iff inserted > 0
+ (martin 2007-06-28) */
+ p = Vafter_insert_file_functions;
+ while (CONSP (p))
+ {
+ if (NILP (replace))
+ {
+ insval = call1 (XCAR (p), make_number (inserted));
+ if (!NILP (insval))
+ {
+ CHECK_NUMBER (insval);
+ inserted = XFASTINT (insval);
+ }
+ }
+ else
+ {
+ /* For the rationale of this see the comment on format-decode above. */
+ int opoint = PT;
+ int opoint_byte = PT_BYTE;
+ int oinserted = ZV - BEGV;
+
+ TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
+ insval = call1 (XCAR (p), make_number (oinserted));
+ if (!NILP (insval))
+ {
+ CHECK_NUMBER (insval);
+ if (XINT (insval) == oinserted)
+ SET_PT_BOTH (opoint, opoint_byte);
+ inserted = XFASTINT (insval);
+ }
+ }
+
+ QUIT;
+ p = XCDR (p);
+ }
+
+ if (NILP (visit))
+ {
+ Lisp_Object lbeg, lend;
+ XSETINT (lbeg, PT);
+ XSETINT (lend, PT + inserted);
+ if (CONSP (old_undo))
+ {
+ Lisp_Object tem = XCAR (old_undo);
+ if (CONSP (tem) && INTEGERP (XCAR (tem)) &&
+ INTEGERP (XCDR (tem)) && EQ (XCAR (tem), lbeg))
+ /* In the non-visiting case record only the final insertion. */
+ current_buffer->undo_list =
+ Fcons (Fcons (lbeg, lend), Fcdr (old_undo));
+ }
+ }
+ else
+ /* If undo_list was Qt before, keep it that way.
+ Otherwise start with an empty undo_list. */
+ current_buffer->undo_list = EQ (old_undo, Qt) ? Qt : Qnil;
- if (!NILP (visit))
- current_buffer->undo_list = empty_undo_list_p ? Qnil : Qt;
+ unbind_to (count, Qnil);
}
/* Call after-change hooks for the inserted text, aside from the case
@@ -4736,19 +4814,6 @@ actually used. */)
update_compositions (PT, PT, CHECK_BORDER);
}
- p = Vafter_insert_file_functions;
- while (CONSP (p))
- {
- insval = call1 (XCAR (p), make_number (inserted));
- if (!NILP (insval))
- {
- CHECK_NUMBER (insval);
- inserted = XFASTINT (insval);
- }
- QUIT;
- p = XCDR (p);
- }
-
if (!NILP (visit)
&& current_buffer->modtime == -1)
{
@@ -5193,7 +5258,7 @@ This does code conversion according to the value of
* if we do writes that don't end with a carriage return. Furthermore
* it cannot handle writes of more then 16K. The modified
* version of "sys_write" in SYSDEP.C (see comment there) copes with
- * this EXCEPT for the last record (iff it doesn't end with a carriage
+ * this EXCEPT for the last record (if it doesn't end with a carriage
* return). This implies that if your buffer doesn't end with a carriage
* return, you get one free... tough. However it also means that if
* we make two calls to sys_write (a la the following code) you can