aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2016-09-02 11:44:13 -0400
committerStefan Monnier2016-09-02 11:44:13 -0400
commit5a4bffb6617a274ca19bc7f5c1b1ceb6345651ab (patch)
treee46b22767dd63377aa2ae58c845a9e2e29cb000e
parent7dc4c3ba3fd243efa51fe8c2092b4a030be8307d (diff)
downloademacs-5a4bffb6617a274ca19bc7f5c1b1ceb6345651ab.tar.gz
emacs-5a4bffb6617a274ca19bc7f5c1b1ceb6345651ab.zip
Check actual contents before promting about changed file
* lisp/userlock.el (userlock--check-content-unchanged) (userlock--ask-user-about-supersession-threat): New functions. * src/filelock.c (lock_file): Use them to avoid spurious prompting. * doc/lispref/buffers.texi (Modification Time): Update doc of ask-user-about-supersession-threat.
-rw-r--r--doc/lispref/buffers.texi5
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/userlock.el35
-rw-r--r--src/filelock.c2
4 files changed, 43 insertions, 3 deletions
diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi
index 740d7cfd8a1..e4ef4d5db6e 100644
--- a/doc/lispref/buffers.texi
+++ b/doc/lispref/buffers.texi
@@ -669,8 +669,9 @@ reason.
669This function is used to ask a user how to proceed after an attempt to 669This function is used to ask a user how to proceed after an attempt to
670modify an buffer visiting file @var{filename} when the file is newer 670modify an buffer visiting file @var{filename} when the file is newer
671than the buffer text. Emacs detects this because the modification 671than the buffer text. Emacs detects this because the modification
672time of the file on disk is newer than the last save-time of the 672time of the file on disk is newer than the last save-time and its contents
673buffer. This means some other program has probably altered the file. 673have changed.
674This means some other program has probably altered the file.
674 675
675@kindex file-supersession 676@kindex file-supersession
676Depending on the user's answer, the function may return normally, in 677Depending on the user's answer, the function may return normally, in
diff --git a/etc/NEWS b/etc/NEWS
index 18975cbcb94..3092e9f22b9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -213,6 +213,10 @@ In modes where form feed was treated as a whitespace character,
213It now deletes whitespace after the last form feed thus behaving the 213It now deletes whitespace after the last form feed thus behaving the
214same as in modes where the character is not whitespace. 214same as in modes where the character is not whitespace.
215 215
216** No more prompt about changed file when the file's content is unchanged.
217Instead of only checking the modification time, Emacs now also checks
218the file's actual content before prompting the user.
219
216 220
217* Changes in Specialized Modes and Packages in Emacs 25.2 221* Changes in Specialized Modes and Packages in Emacs 25.2
218 222
diff --git a/lisp/userlock.el b/lisp/userlock.el
index a0c55fd1e13..1cfc3b9d64a 100644
--- a/lisp/userlock.el
+++ b/lisp/userlock.el
@@ -97,6 +97,41 @@ You can <q>uit; don't modify this file.")
97 97
98(define-error 'file-supersession nil 'file-error) 98(define-error 'file-supersession nil 'file-error)
99 99
100(defun userlock--check-content-unchanged (fn)
101 (with-demoted-errors "Unchanged content check: %S"
102 ;; Even tho we receive `fn', we know that `fn' refers to the current
103 ;; buffer's file.
104 (cl-assert (equal fn (expand-file-name buffer-file-truename)))
105 ;; Note: rather than read the file and compare to the buffer, we could save
106 ;; the buffer and compare to the file, but for encrypted data this
107 ;; wouldn't work well (and would risk exposing the data).
108 (save-restriction
109 (widen)
110 (let ((buf (current-buffer))
111 (cs buffer-file-coding-system)
112 (start (point-min))
113 (end (point-max)))
114 ;; FIXME: To avoid a slow `insert-file-contents' on large or
115 ;; remote files, it'd be good to include file size in the
116 ;; "visited-modtime" check.
117 (when (with-temp-buffer
118 (let ((coding-system-for-read cs)
119 (non-essential t))
120 (insert-file-contents fn))
121 (when (= (buffer-size) (- end start)) ;Minor optimization.
122 (= 0 (let ((case-fold-search nil))
123 (compare-buffer-substrings
124 buf start end
125 (current-buffer) (point-min) (point-max))))))
126 (set-visited-file-modtime)
127 'unchanged)))))
128
129;;;###autoload
130(defun userlock--ask-user-about-supersession-threat (fn)
131 ;; Called from filelock.c.
132 (unless (userlock--check-content-unchanged fn)
133 (ask-user-about-supersession-threat fn)))
134
100;;;###autoload 135;;;###autoload
101(defun ask-user-about-supersession-threat (fn) 136(defun ask-user-about-supersession-threat (fn)
102 "Ask a user who is about to modify an obsolete buffer what to do. 137 "Ask a user who is about to modify an obsolete buffer what to do.
diff --git a/src/filelock.c b/src/filelock.c
index 2f92e0fdc83..bde34e2c6c2 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -684,7 +684,7 @@ lock_file (Lisp_Object fn)
684 if (!NILP (subject_buf) 684 if (!NILP (subject_buf)
685 && NILP (Fverify_visited_file_modtime (subject_buf)) 685 && NILP (Fverify_visited_file_modtime (subject_buf))
686 && !NILP (Ffile_exists_p (fn))) 686 && !NILP (Ffile_exists_p (fn)))
687 call1 (intern ("ask-user-about-supersession-threat"), fn); 687 call1 (intern ("userlock--ask-user-about-supersession-threat"), fn);
688 688
689 } 689 }
690 690