From 6e48132c68169df98180bcea745679dcbf5233ce Mon Sep 17 00:00:00 2001 From: 10sr <8.slashes@gmail.com> Date: Fri, 21 Sep 2018 13:43:11 +0900 Subject: [PATCH 1/4] Add ert-test for file_type_ext --- ert-tests/editorconfig.el | 20 ++++++++++++++++++++ ert-tests/test_files_secondary/.editorconfig | 7 +++++++ 2 files changed, 27 insertions(+) diff --git a/ert-tests/editorconfig.el b/ert-tests/editorconfig.el index 66051dfe..957c7511 100644 --- a/ert-tests/editorconfig.el +++ b/ert-tests/editorconfig.el @@ -1,5 +1,13 @@ (require 'editorconfig) +(defun display-warning (type message &optional level buffer-name) + "When testing overwrite this function to throw error when called." + (error "display-warning called: %S %S %S %S" + type + message + level + buffer-name)) + (defmacro with-visit-file (path &rest body) "Visit PATH and evaluate BODY." (declare (indent 1) (debug t)) @@ -87,3 +95,15 @@ "c.txt") (should (eq major-mode 'conf-unix-mode))) (editorconfig-mode -1)) + +(ert-deftest test-file-type-ext nil + (editorconfig-mode 1) + (with-visit-file (concat editorconfig-secondary-ert-dir + "a.txt") + (should (eq major-mode 'conf-unix-mode))) + + (with-visit-file (concat editorconfig-secondary-ert-dir + "bin/perlscript") + (should (eq major-mode 'perl-mode)) + (should (eq perl-indent-level 5))) + (editorconfig-mode -1)) diff --git a/ert-tests/test_files_secondary/.editorconfig b/ert-tests/test_files_secondary/.editorconfig index eeb02d62..7f10833f 100644 --- a/ert-tests/test_files_secondary/.editorconfig +++ b/ert-tests/test_files_secondary/.editorconfig @@ -6,3 +6,10 @@ indent_style = tab [c.txt] file_type_emacs = conf + +[a.txt] +file_type_ext = ini + +[/bin/*] +file_type_ext = pl +indent_size = 5 From 88f4a4349549569f5ce8e292794320f7ce597560 Mon Sep 17 00:00:00 2001 From: 10sr <8.slashes@gmail.com> Date: Thu, 20 Sep 2018 16:54:51 +0900 Subject: [PATCH 2/4] Set major-mode from file_type_ext value --- editorconfig.el | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/editorconfig.el b/editorconfig.el index e558d7a3..d70cf5bb 100644 --- a/editorconfig.el +++ b/editorconfig.el @@ -272,6 +272,9 @@ number - `lisp-indent-offset' is not set only if indent_size is equal to this number. For example, if this is set to 2, `lisp-indent-offset'will not be set only if indent_size is 2.") +(defconst editorconfig-unset-value "unset" + "String used to unset properties in .editorconfig .") + (defun editorconfig-string-integer-p (string) "Return non-nil if STRING represents integer." (and (stringp string) @@ -444,6 +447,63 @@ FILETYPE should be s string like `\"ini\"`, if not nil or empty string." mode)) nil)))) +(defvar editorconfig--apply-major-mode-currently nil + "Used internally.") +(make-variable-buffer-local 'editorconfig--apply-major-mode-currently) +(put 'editorconfig--apply-major-mode-currently + 'permanent-local + t) + +(defun editorconig-apply-major-mode-safely (mode) + "Set `major-mode' to MODE. +Normally `editorconfig-apply' will be hooked so that it runs when changing +`major-mode', so there is a possibility that MODE is called infinitely if +MODE is called naively from inside of `editorconfig-apply'. +This funcion will avoid such cases and set `major-mode' safely. + +Just checking current `major-mode' value is not enough, because it can be +different from MODE value (for example, `conf-mode' will set `major-mode' to +`conf-unix-mode' or another conf mode)." + (unless (eq mode + editorconfig--apply-major-mode-currently) + (unwind-protect + (progn + (setq editorconfig--apply-major-mode-currently + mode) + (funcall mode)) + (setq editorconfig--apply-major-mode-currently + nil)))) + +(defun editorconfig--find-mode-from-ext (ext &optional filename) + "Get suitable `major-mode' from EXT and FILENAME. +If FILENAME is omitted filename of current buffer is used." + (cl-assert ext) + (cl-assert (not (string= ext ""))) + (let* ((name (concat (or filename + buffer-file-name) + "." + ext))) + (assoc-default name + auto-mode-alist + 'string-match))) + +(defun editorconfig-set-major-mode-from-ext (ext) + "Set buffer `major-mode' by EXT. + +EXT should be a string like `\"ini\"`, if not nil or empty string." + (cl-assert buffer-file-name) + (when (and ext + (not (string= ext "")) + (not (string= ext editorconfig-unset-value))) + + (let ((mode (editorconfig--find-mode-from-ext ext + buffer-file-name))) + (if mode + (editorconig-apply-major-mode-safely mode) + (display-warning :error (format "Major-mode for `%s' not found" + ext)) + nil)))) + (defun editorconfig-call-editorconfig-exec () "Call EditorConfig core and return output." (let* ((filename (buffer-file-name)) @@ -541,6 +601,7 @@ applies available properties." (editorconfig-set-trailing-ws (gethash 'trim_trailing_whitespace props)) (editorconfig-set-line-length (gethash 'max_line_length props)) (editorconfig-set-major-mode (gethash 'file_type_emacs props)) + (editorconfig-set-major-mode-from-ext (gethash 'file_type_ext props)) (condition-case err (run-hook-with-args 'editorconfig-custom-hooks props) (error From 813f9b5de62986dabc7017d9fc4b0753a81e6f9d Mon Sep 17 00:00:00 2001 From: 10sr <8.slashes@gmail.com> Date: Sat, 22 Sep 2018 15:19:47 +0900 Subject: [PATCH 3/4] Update doc --- README.md | 29 ++++++++++++++++++++--------- doc/editorconfig.texi | 30 +++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 34f91072..4467cbf9 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ Current Emacs plugin coverage for EditorConfig's [properties][]: we just buffer-locally override any preferences that would auto-add them to files `.editorconfig` marks as trailing-newline-free * `max_line_length` +* `file_type_ext` (Experimental) * `file_type_emacs` (Experimental) * `root` (only used by EditorConfig core) @@ -66,15 +67,25 @@ we might not yet cover some mode you use, but we try to add the ones that show up on our radar. Similarly, we don't yet hook in to all different packages for whitespace trimming to inform them about editorconfig settings, but aim for better coverage -of things like [ws-trim](ftp://ftp.lysator.liu.se/pub/emacs/ws-trim.el). - -This plugin also has an experimental support for `file_type_emacs`, -which specifies "file types" for files. -As for Emacs, it means `major-mode` can be specified: for example, -when `file_type_emacs` is set to `markdown` for `a.txt`, -`markdown-mode` will be enabled when opening `a.txt`. -This property is experimental and its meaning might change in -the future updates. +of things like +[ws-trim](ftp://ftp.lysator.liu.se/pub/emacs/ws-trim.el). + + +### File Type + +This plugin also has experimental supports for `file_type_ext` and +`file_type_emacs`, which specify "file types" for files. +As for Emacs, it means `major-mode` can be set. + +**file_type_ext** When it is set to `md` for `a.txt`, for example, +`major-mode` will be decided as if the file name would be `a.txt.md` +(and thus `markdown-mode` is likely to be used). + +**file_type_emacs** When it is set to `markdown` for `a.txt`, +`markdown-mode` will be enabled when opening `a.txt`. + +These property are experimental and their meanings might change in the +future updates. When both are specified, `file_type_ext` takes precedence. ## Customize diff --git a/doc/editorconfig.texi b/doc/editorconfig.texi index a201279e..0b6817cf 100644 --- a/doc/editorconfig.texi +++ b/doc/editorconfig.texi @@ -84,6 +84,8 @@ trailing-newline-free @item @code{max_line_length} @item +@code{file_type_ext} (Experimental) +@item @code{file_type_emacs} (Experimental) @item @code{root} (only used by EditorConfig core) @@ -100,14 +102,28 @@ on our radar. Similarly, we don't yet hook in to all different packages for whitespace trimming to inform them about editorconfig settings, but aim for better coverage of things like @uref{ftp://ftp.lysator.liu.se/pub/emacs/ws-trim.el,ws-trim}. +@menu +* File Type:: +@end menu + +@node File Type +@subsection File Type +@anchor{#file-type} +This plugin also has experimental supports for @code{file_type_ext} and +@code{file_type_emacs}, which specify ``file types'' for files. As for +Emacs, it means @code{major-mode} can be set. + +@strong{file_type_ext} When it is set to @code{md} for @code{a.txt}, for +example, @code{major-mode} will be decided as if the file name would be +@code{a.txt.md} (and thus @code{markdown-mode} is likely to be used). + +@strong{file_type_emacs} When it is set to @code{markdown} for +@code{a.txt}, @code{markdown-mode} will be enabled when opening +@code{a.txt}. -This plugin also has an experimental support for @code{file_type_emacs}, -which specifies ``file types'' for files. As for Emacs, it means -@code{major-mode} can be specified: for example, when -@code{file_type_emacs} is set to @code{markdown} for @code{a.txt}, -@code{markdown-mode} will be enabled when opening @code{a.txt}. This -property is experimental and its meaning might change in the future -updates. +These property are experimental and their meanings might change in the +future updates. When both are specified, @code{file_type_ext} takes +precedence. @node Customize @section Customize From eedc4297c048036f489f6080f75b333009a2acbb Mon Sep 17 00:00:00 2001 From: 10sr <8.slashes@gmail.com> Date: Sat, 22 Sep 2018 15:25:02 +0900 Subject: [PATCH 4/4] Rename existing function set-major-mode -> set-major-mode-from-name --- editorconfig.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editorconfig.el b/editorconfig.el index d70cf5bb..954850e3 100644 --- a/editorconfig.el +++ b/editorconfig.el @@ -429,7 +429,7 @@ TRIM-TRAILING-WS." (and parent (editorconfig--is-a-mode-p parent want))))) -(defun editorconfig-set-major-mode (filetype) +(defun editorconfig-set-major-mode-from-name (filetype) "Set buffer `major-mode' by FILETYPE. FILETYPE should be s string like `\"ini\"`, if not nil or empty string." @@ -600,7 +600,7 @@ applies available properties." (editorconfig-set-trailing-nl (gethash 'insert_final_newline props)) (editorconfig-set-trailing-ws (gethash 'trim_trailing_whitespace props)) (editorconfig-set-line-length (gethash 'max_line_length props)) - (editorconfig-set-major-mode (gethash 'file_type_emacs props)) + (editorconfig-set-major-mode-from-name (gethash 'file_type_emacs props)) (editorconfig-set-major-mode-from-ext (gethash 'file_type_ext props)) (condition-case err (run-hook-with-args 'editorconfig-custom-hooks props)