├── .editorconfig ├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.adoc └── editorconfig-custom-majormode.el /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_style = space 3 | 4 | end_of_line = lf 5 | 6 | max_line_length = 80 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.adoc] 11 | emacs_mode = adoc 12 | 13 | [LICENSE] 14 | max_line_length = 70 15 | emacs_mode = text 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled 2 | *.elc 3 | 4 | # Packaging 5 | .cask 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: emacs-lisp 2 | env: 3 | - EMACS=emacs24 4 | - EMACS=emacs-snapshot 5 | before_install: 6 | - sudo add-apt-repository -y ppa:cassou/emacs 7 | - sudo apt-get update -qq 8 | install: 9 | - sudo apt-get install -qq $EMACS 10 | before_script: 11 | - $EMACS --version 12 | script: make test emacs=$EMACS 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | emacs ?= emacs 2 | 3 | ert_tests_el = $(wildcard test/*.el) 4 | el = $(wildcard *.el) 5 | elc = $(el:%.el=%.elc) 6 | 7 | .PHONY: all test test-ert build 8 | 9 | all: 10 | 11 | test: build test-ert info 12 | 13 | build: $(elc) 14 | 15 | $(elc): %.elc: %.el 16 | $(emacs) -batch -Q -f batch-byte-compile $< 17 | 18 | 19 | test-ert: $(ert_tests_el) 20 | $(emacs) -batch -Q -L . --eval "(require 'ert)" $(^:%=-l "%") \ 21 | -f ert-run-tests-batch-and-exit 22 | 23 | 24 | elisp_get_file_package_info := \ 25 | (lambda (f) \ 26 | (with-temp-buffer \ 27 | (insert-file-contents-literally f) \ 28 | (package-buffer-info))) 29 | 30 | elisp_print_infos := \ 31 | (mapc \ 32 | (lambda (f) \ 33 | (message \"Loading info: %s\" f) \ 34 | (message \"%S\" (funcall $(elisp_get_file_package_info) f))) \ 35 | command-line-args-left) 36 | 37 | info: $(el) 38 | $(emacs) -batch -Q \ 39 | --eval "(require 'package)" \ 40 | --eval "$(elisp_print_infos)" \ 41 | $^ 42 | 43 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = editorconfig-custom-majormode.el 2 | 3 | image:https://travis-ci.org/10sr/editorconfig-custom-majormode-el.svg?branch=master["Build Status", link=https://travis-ci.org/10sr/editorconfig-custom-majormode-el] 4 | image:https://melpa.org/packages/editorconfig-custom-majormode-badge.svg["MELPA", link=https://melpa.org/\#/editorconfig-custom-majormode] 5 | image:https://stable.melpa.org/packages/editorconfig-custom-majormode-badge.svg["MELPA Stable", link=https://stable.melpa.org/#/editorconfig-custom-majormode] 6 | 7 | 8 | 9 | Decide major-mode from EditorConfig 10 | 11 | This package is an link:http://editorconfig.org/[EditorConfig] extension that defines a property 12 | to specify which Emacs major-mode to use for files. 13 | 14 | If `package.el` is installed on your Emacs and the major-mode specified is 15 | installable, this plugin asks whether you want to install and enable it 16 | automatically. 17 | 18 | 19 | == Usage 20 | 21 | Add `emacs_mode` to your `.editorconfig` as follows, and `nginx-mode` will be 22 | always enabled when visiting `*.conf` files. 23 | 24 | .`.editorconfig` 25 | [source,ini] 26 | ---- 27 | [*.conf] 28 | emacs_mode = nginx 29 | ---- 30 | 31 | 32 | Also this library has an experimental mmm-mode support. 33 | To use it, add properties like: 34 | 35 | [source,ini] 36 | ---- 37 | [*.conf.j2] 38 | emacs_mode = nginx 39 | emacs_mmm_classes = jinja2 40 | ---- 41 | 42 | Multiple mmm_classes can be specified by separating classes with commmas. 43 | 44 | 45 | 46 | To enable this plugin, add `editorconfig-custom-majormode` to 47 | `editorconfig-custom-hooks`: 48 | 49 | [source,emacslisp] 50 | ---- 51 | (add-hook 'editorconfig-custom-hooks 52 | 'editorconfig-custom-majormode) 53 | ---- 54 | 55 | == License 56 | 57 | This software is unlicensed. See `LICENSE` for details. 58 | -------------------------------------------------------------------------------- /editorconfig-custom-majormode.el: -------------------------------------------------------------------------------- 1 | ;;; editorconfig-custom-majormode.el --- Decide major-mode and mmm-mode from EditorConfig 2 | 3 | ;; Author: 10sr <8slashes+el [at] gmail [dot] com> 4 | ;; URL: https://github.com/10sr/editorconfig-custom-majormode-el 5 | ;; Version: 0.0.3 6 | ;; Package-Requires: ((editorconfig "0.6.0")) 7 | ;; Keywords: editorconfig util 8 | 9 | ;; This file is not part of GNU Emacs. 10 | 11 | ;; This is free and unencumbered software released into the public domain. 12 | 13 | ;; Anyone is free to copy, modify, publish, use, compile, sell, or 14 | ;; distribute this software, either in source code form or as a compiled 15 | ;; binary, for any purpose, commercial or non-commercial, and by any 16 | ;; means. 17 | 18 | ;; In jurisdictions that recognize copyright laws, the author or authors 19 | ;; of this software dedicate any and all copyright interest in the 20 | ;; software to the public domain. We make this dedication for the benefit 21 | ;; of the public at large and to the detriment of our heirs and 22 | ;; successors. We intend this dedication to be an overt act of 23 | ;; relinquishment in perpetuity of all present and future rights to this 24 | ;; software under copyright law. 25 | 26 | ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 | ;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 | ;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 29 | ;; IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 30 | ;; OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 31 | ;; ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 32 | ;; OTHER DEALINGS IN THE SOFTWARE. 33 | 34 | ;; For more information, please refer to 35 | 36 | 37 | ;;; Commentary: 38 | 39 | ;; An EditorConfig extension that defines a property to specify which 40 | ;; Emacs major-mode to use for files. 41 | 42 | ;; For example, add emacs_mode to your .editorconfig as follows, and 43 | ;; `nginx-mode' will be always enabled when visiting *.conf files. 44 | 45 | ;; [*.conf] 46 | ;; emacs_mode = nginx 47 | 48 | ;; Also this library has an experimental mmm-mode support. 49 | ;; To use it, add properties like: 50 | 51 | ;; [*.conf.j2] 52 | ;; emacs_mode = nginx 53 | ;; emacs_mmm_classes = jinja2 54 | 55 | ;; Multiple mmm_classes can be specified by separating classes with 56 | ;; commmas. 57 | 58 | ;; To enable this plugin, add `editorconfig-custom-majormode' to 59 | ;; `editorconfig-custom-hooks': 60 | 61 | ;; (add-hook 'editorconfig-custom-hooks 62 | ;; 'editorconfig-custom-majormode) 63 | 64 | ;;; Code: 65 | 66 | (eval-when-compile 67 | (defvar mmm-classes) 68 | (defvar mmm-classes-alist)) 69 | 70 | (defvar editorconfig-custom-majormode--already 71 | nil 72 | "Flag used internaly to avoid infinite loop.") 73 | 74 | (defun editorconfig-custom-majormode--is-a-mode-p (target want) 75 | "Return non-nil if major mode TARGET is a major mode WANT." 76 | (or (eq target 77 | want) 78 | (let ((parent (get target 'derived-mode-parent))) 79 | (and parent 80 | (editorconfig-custom-majormode--is-a-mode-p parent want))))) 81 | 82 | (defun editorconfig-custom-majormode--require-or-install (lib) 83 | "Try to install LIB if not found and load it. 84 | 85 | Return non-nil if LIB has been successfully loaded." 86 | (or (require lib nil t) 87 | (and (eval-and-compile (require 'package nil t)) 88 | (assq lib 89 | package-archive-contents) 90 | (yes-or-no-p (format "editorconfig-custom-majormode: Library `%S' not found but available as a package. Install?" 91 | lib)) 92 | (progn 93 | (package-install lib) 94 | (require lib))))) 95 | 96 | (defun editorconfig-custom-majormode--set-majormode (mode) 97 | "Set majormode to MODE." 98 | (when (and mode 99 | (not (editorconfig-custom-majormode--is-a-mode-p major-mode 100 | mode))) 101 | (if (or (fboundp mode) 102 | (editorconfig-custom-majormode--require-or-install mode)) 103 | (funcall mode) 104 | (display-warning :error (format "Major-mode `%S' not found" 105 | mode))))) 106 | 107 | (defun editorconfig-custom-majormode--set-mmm-classes (classes) 108 | "Set mmm-classes to CLASSES." 109 | (setq mmm-classes nil) 110 | (dolist (class classes) 111 | ;; Expect class is available as mmm- library 112 | ;; TODO: auto install 113 | (unless (assq class 114 | mmm-classes-alist) 115 | (editorconfig-custom-majormode--require-or-install 116 | (intern (concat "mmm-" 117 | (symbol-name class))))) 118 | ;; Make sure it has been loaded 119 | (require (intern (concat "mmm-" 120 | (symbol-name class))) 121 | nil t) 122 | ;; Add even when package was not found 123 | (add-to-list 'mmm-classes 124 | class))) 125 | 126 | ;;;###autoload 127 | (defun editorconfig-custom-majormode (hash) 128 | "Get emacs_mode property from HASH and set major mode. 129 | 130 | If `package' is installed on your Emacs and the major mode specified is 131 | installable, this plugin asks whether you want to install and enable it 132 | automatically." 133 | (when (not editorconfig-custom-majormode--already) 134 | (let* ((editorconfig-custom-majormode--already t) 135 | (mode-str (gethash 'emacs_mode 136 | hash)) 137 | (mode (and mode-str 138 | (not (string= mode-str 139 | "")) 140 | (intern (concat mode-str 141 | "-mode")))) 142 | (mmm-classes-str (gethash 'emacs_mmm_classes 143 | hash)) 144 | ;; FIXME: Split by comma and make list 145 | (ed-mmm-classes (and mmm-classes-str 146 | (not (string= "" 147 | mmm-classes-str)) 148 | (mapcar 'intern 149 | (split-string mmm-classes-str 150 | ","))))) 151 | (when mode 152 | (editorconfig-custom-majormode--set-majormode mode)) 153 | (when (and ed-mmm-classes 154 | (editorconfig-custom-majormode--require-or-install 'mmm-mode)) 155 | (editorconfig-custom-majormode--set-mmm-classes ed-mmm-classes) 156 | (mmm-mode-on))))) 157 | 158 | (provide 'editorconfig-custom-majormode) 159 | 160 | ;;; editorconfig-custom-majormode.el ends here 161 | --------------------------------------------------------------------------------