Skip to content

Commit

Permalink
Add feature to decide major-mode from file-type-ext
Browse files Browse the repository at this point in the history
  • Loading branch information
10sr committed Sep 22, 2018
1 parent 94ca8d6 commit a1c83c8
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true

[a.txt]
file_type_ext = ini
[b.txt]
file_type_emacs = conf



[*.el]
indent_style = space
Expand Down
60 changes: 60 additions & 0 deletions editorconfig.el
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 to a hook that run when changin
`major-mode', it is possible that `major-mode' function is called infinitely.
This funcion will avoid that and set `major-mode' safely.
Just checking `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)))
(editorconfig--find-mode-from-ext "ini")

(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))
Expand Down
2 changes: 1 addition & 1 deletion ert-tests/test_files_secondary/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ indent_size = 2
indent_style = tab

[a.txt]
file_type_ext = ini
file_type_ext = ini

0 comments on commit a1c83c8

Please sign in to comment.