branch: scratch/editorconfig-cc commit 316b03ce211f5e909013e74eb884047744bdd8dd Author: 10sr <8.slas...@gmail.com> Commit: Stefan Monnier <monn...@iro.umontreal.ca>
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