branch: scratch/editorconfig-cc
commit 316b03ce211f5e909013e74eb884047744bdd8dd
Author: 10sr <[email protected]>
Commit: Stefan Monnier <[email protected]>
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 b085c33ec4..c87e730af9 100644
--- a/editorconfig.el
+++ b/editorconfig.el
@@ -243,6 +243,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)
@@ -329,6 +332,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 ()
)
@@ -401,6 +461,7 @@ applies available properties."
(gethash 'charset 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