From 9dbda100755158fd070931748f2b80ad09bc6815 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Wed, 30 Jan 2013 22:35:45 -0800 Subject: [PATCH] Reduce delay between backing up a file and saving new version * lisp/files.el (basic-save-buffer-2): Choose coding system for writing the file before backing it up. * src/fileio.c (choose_write_coding_system): Make it callable from Lisp. (Fwrite_region): If coding-system-for-write is set, don't call choose_write_coding_system. Move the last piece of choose_write_coding_system here. (syms_of_fileio): Add choose-write-coding-system. Fixes: debbugs:13522 --- lisp/ChangeLog | 6 ++++++ lisp/files.el | 13 +++++++++++-- src/ChangeLog | 8 ++++++++ src/fileio.c | 37 ++++++++++++++++++++++++++----------- 4 files changed, 51 insertions(+), 13 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6ac51724328..c1142a45e8d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2013-01-31 Glenn Morris + + * files.el (basic-save-buffer-2): Choose coding system for + writing the file before backing it up, to reduce delay between + backing up and writing the new version. (Bug#13522) + 2013-01-31 Michal Nazarewicz * simple.el (cycle-spacing): New command. diff --git a/lisp/files.el b/lisp/files.el index b015b53db3c..3bc3059c68f 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -4656,7 +4656,7 @@ Before and after saving the buffer, this function runs ;; This returns a value (MODES EXTENDED-ATTRIBUTES BACKUPNAME), like ;; backup-buffer. (defun basic-save-buffer-2 () - (let (tempsetmodes setmodes) + (let (tempsetmodes setmodes writecoding) (if (not (file-writable-p buffer-file-name)) (let ((dir (file-name-directory buffer-file-name))) (if (not (file-directory-p dir)) @@ -4672,6 +4672,14 @@ Before and after saving the buffer, this function runs buffer-file-name))) (setq tempsetmodes t) (error "Attempt to save to a file which you aren't allowed to write")))))) + ;; This may involve prompting, so do it now before backing up the file. + ;; Otherwise there can be a delay while the user answers the + ;; prompt during which the original file has been renamed. (Bug#13522) + (setq writecoding + ;; Args here should match write-region call below around + ;; which we use writecoding. + (choose-write-coding-system nil nil buffer-file-name nil t + buffer-file-truename)) (or buffer-backed-up (setq setmodes (backup-buffer))) (let* ((dir (file-name-directory buffer-file-name)) @@ -4753,10 +4761,11 @@ Before and after saving the buffer, this function runs (logior (car setmodes) 128)))))) (let (success) (unwind-protect - (progn ;; Pass in nil&nil rather than point-min&max to indicate ;; we're saving the buffer rather than just a region. ;; write-region-annotate-functions may make us of it. + (let ((coding-system-for-write writecoding) + (coding-system-require-warning nil)) (write-region nil nil buffer-file-name nil t buffer-file-truename) (setq success t)) diff --git a/src/ChangeLog b/src/ChangeLog index bb03ba10bb0..08eb9b50a9b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2013-01-31 Glenn Morris + + * fileio.c (choose_write_coding_system): Make it callable from Lisp. + (Fwrite_region): If coding-system-for-write is set, don't + call choose_write_coding_system. Move the last piece of + choose_write_coding_system here. (Bug#13522) + (syms_of_fileio): Add choose-write-coding-system. + 2013-01-30 Eli Zaretskii * w32.c (sys_open): Zero out the flags for the new file descriptor. diff --git a/src/fileio.c b/src/fileio.c index e788bebab61..ac0ce202a02 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -249,6 +249,7 @@ static Lisp_Object Qfile_acl; static Lisp_Object Qset_file_acl; static Lisp_Object Qfile_newer_than_file_p; Lisp_Object Qinsert_file_contents; +Lisp_Object Qchoose_write_coding_system; Lisp_Object Qwrite_region; static Lisp_Object Qverify_visited_file_modtime; static Lisp_Object Qset_visited_file_modtime; @@ -4615,14 +4616,24 @@ build_annotations_unwind (Lisp_Object arg) /* Decide the coding-system to encode the data with. */ -static Lisp_Object -choose_write_coding_system (Lisp_Object start, Lisp_Object end, Lisp_Object filename, - Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, - struct coding_system *coding) +DEFUN ("choose-write-coding-system", Fchoose_write_coding_system, + Schoose_write_coding_system, 3, 6, 0, + doc: /* Choose the coding system for writing a file. +Arguments are as for `write-region'. +This function is for internal use only. It may prompt the user. */ ) + (Lisp_Object start, Lisp_Object end, Lisp_Object filename, + Lisp_Object append, Lisp_Object visit, Lisp_Object lockname) { Lisp_Object val; Lisp_Object eol_parent = Qnil; + /* Mimic write-region behavior. */ + if (NILP (start)) + { + XSETFASTINT (start, BEGV); + XSETFASTINT (end, ZV); + } + if (auto_saving && NILP (Fstring_equal (BVAR (current_buffer, filename), BVAR (current_buffer, auto_save_file_name)))) @@ -4715,10 +4726,6 @@ choose_write_coding_system (Lisp_Object start, Lisp_Object end, Lisp_Object file } val = coding_inherit_eol_type (val, eol_parent); - setup_coding_system (val, coding); - - if (!STRINGP (start) && !NILP (BVAR (current_buffer, selective_display))) - coding->mode |= CODING_MODE_SELECTIVE_DISPLAY; return val; } @@ -4874,9 +4881,15 @@ This calls `write-region-annotate-functions' at the start, and We used to make this choice before calling build_annotations, but that leads to problems when a write-annotate-function takes care of unsavable chars (as was the case with X-Symbol). */ - Vlast_coding_system_used - = choose_write_coding_system (start, end, filename, - append, visit, lockname, &coding); + Vlast_coding_system_used = NILP (Vcoding_system_for_write) ? + Fchoose_write_coding_system (start, end, filename, + append, visit, lockname) : + Vcoding_system_for_write; + + setup_coding_system (Vlast_coding_system_used, &coding); + + if (!STRINGP (start) && !NILP (BVAR (current_buffer, selective_display))) + coding.mode |= CODING_MODE_SELECTIVE_DISPLAY; #ifdef CLASH_DETECTION if (!auto_saving) @@ -5861,6 +5874,7 @@ syms_of_fileio (void) DEFSYM (Qset_file_acl, "set-file-acl"); DEFSYM (Qfile_newer_than_file_p, "file-newer-than-file-p"); DEFSYM (Qinsert_file_contents, "insert-file-contents"); + DEFSYM (Qchoose_write_coding_system, "choose-write-coding-system"); DEFSYM (Qwrite_region, "write-region"); DEFSYM (Qverify_visited_file_modtime, "verify-visited-file-modtime"); DEFSYM (Qset_visited_file_modtime, "set-visited-file-modtime"); @@ -6085,6 +6099,7 @@ This includes interactive calls to `delete-file' and defsubr (&Sdefault_file_modes); defsubr (&Sfile_newer_than_file_p); defsubr (&Sinsert_file_contents); + defsubr (&Schoose_write_coding_system); defsubr (&Swrite_region); defsubr (&Scar_less_than_car); defsubr (&Sverify_visited_file_modtime); -- 2.39.2