diff options
| author | Philipp Stephani | 2017-04-22 00:12:23 +0200 |
|---|---|---|
| committer | Philipp | 2017-05-06 21:26:04 +0200 |
| commit | 5e47c2e52b9b7616668c5586084e0128b231272a (patch) | |
| tree | c4d3659f9877abc23732d140169e48c8fcc05d0f | |
| parent | 26c71bfe8cb37332b4806ca7f43d59fd1a616c3b (diff) | |
| download | emacs-5e47c2e52b9b7616668c5586084e0128b231272a.tar.gz emacs-5e47c2e52b9b7616668c5586084e0128b231272a.zip | |
Fix quoted files for 'verify-visited-file-modtime'
Fixes Bug#25951.
* lisp/files.el (file-name-non-special): Set the file name for the
correct buffer.
* test/lisp/files-tests.el (files-tests--file-name-non-special--buffers):
Add unit test.
(files-tests--with-advice, files-tests--with-temp-file): New helper
macros.
| -rw-r--r-- | lisp/files.el | 8 | ||||
| -rw-r--r-- | test/lisp/files-tests.el | 64 |
2 files changed, 70 insertions, 2 deletions
diff --git a/lisp/files.el b/lisp/files.el index d193749bb88..7e627d36d49 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | ;;; Code: | 29 | ;;; Code: |
| 30 | 30 | ||
| 31 | (eval-when-compile | 31 | (eval-when-compile |
| 32 | (require 'cl-lib) | ||
| 32 | (require 'pcase) | 33 | (require 'pcase) |
| 33 | (require 'easy-mmode)) ; For `define-minor-mode'. | 34 | (require 'easy-mmode)) ; For `define-minor-mode'. |
| 34 | 35 | ||
| @@ -7031,7 +7032,12 @@ only these files will be asked to be saved." | |||
| 7031 | (when (and visit buffer-file-name) | 7032 | (when (and visit buffer-file-name) |
| 7032 | (setq buffer-file-name (concat "/:" buffer-file-name)))))) | 7033 | (setq buffer-file-name (concat "/:" buffer-file-name)))))) |
| 7033 | (`unquote-then-quote | 7034 | (`unquote-then-quote |
| 7034 | (let ((buffer-file-name (substring buffer-file-name 2))) | 7035 | (cl-letf* ((buffer (or (car arguments) (current-buffer))) |
| 7036 | ((buffer-local-value 'buffer-file-name buffer) | ||
| 7037 | (substring (buffer-file-name buffer) 2))) | ||
| 7038 | ;; `unquote-then-quote' is only used for the | ||
| 7039 | ;; `verify-visited-file-modtime' action, which takes a buffer | ||
| 7040 | ;; as only optional argument. | ||
| 7035 | (apply operation arguments))) | 7041 | (apply operation arguments))) |
| 7036 | (_ | 7042 | (_ |
| 7037 | (apply operation arguments))))) | 7043 | (apply operation arguments))))) |
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el index 80bbeb1bc54..4583b1af3c3 100644 --- a/test/lisp/files-tests.el +++ b/test/lisp/files-tests.el | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | ;;; files-tests.el --- tests for files.el. | 1 | ;;; files-tests.el --- tests for files.el. -*- lexical-binding: t; -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 2012-2017 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 2012-2017 Free Software Foundation, Inc. |
| 4 | 4 | ||
| @@ -20,6 +20,7 @@ | |||
| 20 | ;;; Code: | 20 | ;;; Code: |
| 21 | 21 | ||
| 22 | (require 'ert) | 22 | (require 'ert) |
| 23 | (require 'nadvice) | ||
| 23 | 24 | ||
| 24 | ;; Set to t if the local variable was set, `query' if the query was | 25 | ;; Set to t if the local variable was set, `query' if the query was |
| 25 | ;; triggered. | 26 | ;; triggered. |
| @@ -251,5 +252,66 @@ be $HOME." | |||
| 251 | (start-file-process "foo" nil "true")))) | 252 | (start-file-process "foo" nil "true")))) |
| 252 | (should (eq (let ((default-directory "/:/")) (shell-command "true")) 0))) | 253 | (should (eq (let ((default-directory "/:/")) (shell-command "true")) 0))) |
| 253 | 254 | ||
| 255 | (defmacro files-tests--with-advice (symbol where function &rest body) | ||
| 256 | (declare (indent 3)) | ||
| 257 | (cl-check-type symbol symbol) | ||
| 258 | (cl-check-type where keyword) | ||
| 259 | (cl-check-type function function) | ||
| 260 | (macroexp-let2 nil function function | ||
| 261 | `(progn | ||
| 262 | (advice-add #',symbol ,where ,function) | ||
| 263 | (unwind-protect | ||
| 264 | (progn ,@body) | ||
| 265 | (advice-remove #',symbol ,function))))) | ||
| 266 | |||
| 267 | (defmacro files-tests--with-temp-file (name &rest body) | ||
| 268 | (declare (indent 1)) | ||
| 269 | (cl-check-type name symbol) | ||
| 270 | `(let ((,name (make-temp-file "emacs"))) | ||
| 271 | (unwind-protect | ||
| 272 | (progn ,@body) | ||
| 273 | (delete-file ,name)))) | ||
| 274 | |||
| 275 | (ert-deftest files-tests--file-name-non-special--buffers () | ||
| 276 | "Check that Bug#25951 is fixed. | ||
| 277 | We call `verify-visited-file-modtime' on a buffer visiting a file | ||
| 278 | with a quoted name. We use two different variants: first with | ||
| 279 | the buffer current and a nil argument, second passing the buffer | ||
| 280 | object explicitly. In both cases no error should be raised and | ||
| 281 | the `file-name-non-special' handler for quoted file names should | ||
| 282 | be invoked with the right arguments." | ||
| 283 | (files-tests--with-temp-file temp-file-name | ||
| 284 | (with-temp-buffer | ||
| 285 | (let* ((buffer-visiting-file (current-buffer)) | ||
| 286 | (actual-args ()) | ||
| 287 | (log (lambda (&rest args) (push args actual-args)))) | ||
| 288 | (insert-file-contents (concat "/:" temp-file-name) :visit) | ||
| 289 | (should (stringp buffer-file-name)) | ||
| 290 | (should (string-prefix-p "/:" buffer-file-name)) | ||
| 291 | (should (consp (visited-file-modtime))) | ||
| 292 | (should (equal (find-file-name-handler buffer-file-name | ||
| 293 | #'verify-visited-file-modtime) | ||
| 294 | #'file-name-non-special)) | ||
| 295 | (files-tests--with-advice file-name-non-special :before log | ||
| 296 | ;; This should call the file name handler with the right | ||
| 297 | ;; buffer and not signal an error. The file hasn't been | ||
| 298 | ;; modified, so `verify-visited-file-modtime' should return | ||
| 299 | ;; t. | ||
| 300 | (should (equal (verify-visited-file-modtime) t)) | ||
| 301 | (with-temp-buffer | ||
| 302 | (should (stringp (buffer-file-name buffer-visiting-file))) | ||
| 303 | ;; This should call the file name handler with the right | ||
| 304 | ;; buffer and not signal an error. The file hasn't been | ||
| 305 | ;; modified, so `verify-visited-file-modtime' should return | ||
| 306 | ;; t. | ||
| 307 | (should (equal (verify-visited-file-modtime buffer-visiting-file) | ||
| 308 | t)))) | ||
| 309 | ;; Verify that the handler was actually called. We called | ||
| 310 | ;; `verify-visited-file-modtime' twice, so both calls should be | ||
| 311 | ;; recorded in reverse order. | ||
| 312 | (should (equal actual-args | ||
| 313 | `((verify-visited-file-modtime ,buffer-visiting-file) | ||
| 314 | (verify-visited-file-modtime nil)))))))) | ||
| 315 | |||
| 254 | (provide 'files-tests) | 316 | (provide 'files-tests) |
| 255 | ;;; files-tests.el ends here | 317 | ;;; files-tests.el ends here |