branch: scratch/editorconfig-cc commit 9beb04599ac4e94b434cb4db2e2e68239e7d12cd Author: 10sr <8.slas...@gmail.com> Commit: Stefan Monnier <monn...@iro.umontreal.ca>
Refactor find-file advices (#340) * Add coding-system test * Refactor find-file advices * Fix test * Fix test * Update * Update --- editorconfig.el | 54 +++++++++++++++++++++++------------------------ ert-tests/editorconfig.el | 13 ++++++++++++ 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/editorconfig.el b/editorconfig.el index 681ba115c9..7466bc3a5c 100644 --- a/editorconfig.el +++ b/editorconfig.el @@ -642,11 +642,11 @@ This function also executes `editorconfig-after-apply-functions' functions." (format "Error while running `editorconfig-after-apply-functions': %S" err)))))) -(defvar editorconfig--cons-filename-codingsystem nil +(defvar editorconfig--filename-codingsystem-hash (make-hash-table :test 'equal) "Used interally. -`editorconfig--advice-find-file-noselect' will set this variable, and -`editorconfig--advice-insert-file-contents' will use this variable to set +`editorconfig--advice-find-file-noselect' will put value to this hash, and +`editorconfig--advice-insert-file-contents' will use the value to set `coding-system-for-read' value.") (defun editorconfig--advice-insert-file-contents (f filename &rest args) @@ -654,26 +654,23 @@ This function also executes `editorconfig-after-apply-functions' functions." This function should be added as an advice function to `insert-file-contents'. F is that function, and FILENAME and ARGS are arguments passed to F." - ;; This function uses `editorconfig--cons-filename-codingsystem' to decide what coding-system + ;; This function uses `editorconfig--filename-codingsystem-hash' to decide what coding-system ;; should be used, which will be set by `editorconfig--advice-find-file-noselect'. (display-warning '(editorconfig editorconfig--advice-insert-file-contents) (format "editorconfig--advice-insert-file-contents: filename: %S args: %S codingsystem: %S bufferfilename: %S" filename args - editorconfig--cons-filename-codingsystem + editorconfig--filename-codingsystem-hash buffer-file-name) :debug) - (if (and (stringp filename) - (stringp (car editorconfig--cons-filename-codingsystem)) - (string= (expand-file-name filename) - (car editorconfig--cons-filename-codingsystem)) - (cdr editorconfig--cons-filename-codingsystem) - (not (eq (cdr editorconfig--cons-filename-codingsystem) - 'undecided))) - (let ((coding-system-for-read (cdr editorconfig--cons-filename-codingsystem)) - ;; (coding-system-for-read 'undecided) - ) - (apply f filename args)) - (apply f filename args))) + (let ((coding-system (and (stringp filename) + (gethash (expand-file-name filename) + editorconfig--filename-codingsystem-hash)))) + (if (and coding-system + (not (eq coding-system + 'undecided))) + (let ((coding-system-for-read coding-system)) + (apply f filename args)) + (apply f filename args)))) (defun editorconfig--advice-find-file-noselect (f filename &rest args) "Get EditorConfig properties and apply them to buffer to be visited. @@ -689,36 +686,39 @@ F is that function, and FILENAME and ARGS are arguments passed to F." (setq props (editorconfig-call-get-properties-function filename)) (setq coding-system (editorconfig-merge-coding-systems (gethash 'end_of_line props) - (gethash 'charset props)))) + (gethash 'charset props))) + (puthash (expand-file-name filename) + coding-system + editorconfig--filename-codingsystem-hash)) (error (display-warning '(editorconfig editorconfig--advice-find-file-noselect) (format "Failed to get properties, styles will not be applied: %S" err) :warning))) - (let ((editorconfig--cons-filename-codingsystem (cons (expand-file-name filename) - coding-system))) - (setq ret (apply f filename args))) + (setq ret (apply f filename args)) + (clrhash editorconfig--filename-codingsystem-hash) (condition-case err (with-current-buffer ret (when (and props ;; filename has already been checked (not (editorconfig--disabled-for-majormode major-mode))) + + ;; When file path indicates it is a remote file and it actually + ;; does not exists, `buffer-file-coding-system' will not be set. + ;; (Seems `insert-file-contents' will not be called) + ;; For this case, explicitly set this value so that saving will be done + ;; with expected coding system. (when (and (file-remote-p filename) (not (local-variable-p 'buffer-file-coding-system)) (not (file-exists-p filename)) coding-system (not (eq coding-system 'undecided))) - ;; When file path indicates it is a remote file and it actually - ;; does not exists, `buffer-file-coding-system' will not be set. - ;; (Seems `insert-file-contents' will not be called) - ;; For that case, explicitly set this value so that saving will be done - ;; with expected coding system. (set-buffer-file-coding-system coding-system)) - ;; NOTE: When using editorconfig-2-mode, hack-properties-functions cannot affect coding-system value, + ;; NOTE: hack-properties-functions cannot affect coding-system value, ;; because it has to be set before initializing buffers. (condition-case err (run-hook-with-args 'editorconfig-hack-properties-functions props) diff --git a/ert-tests/editorconfig.el b/ert-tests/editorconfig.el index b281f8014b..2581b11351 100644 --- a/ert-tests/editorconfig.el +++ b/ert-tests/editorconfig.el @@ -95,6 +95,19 @@ write-file-functions)))) (editorconfig-mode -1)) +(ert-deftest test-charset nil + (editorconfig-mode 1) + (with-visit-file (concat editorconfig-ert-dir "latin1.txt") + (set-buffer-file-coding-system 'undecided-unix) + (should (eq buffer-file-coding-system + 'iso-latin-1-unix))) + (with-visit-file (concat editorconfig-ert-dir "utf-16be.txt") + (set-buffer-file-coding-system 'undecided-unix) + (should (eq buffer-file-coding-system + 'utf-16be-with-signature-unix))) + (editorconfig-mode -1)) + + (ert-deftest test-local-variables nil (editorconfig-mode 1) (with-visit-file (concat editorconfig-local-variables-ert-dir "file_locals.rb")