diff --git a/json-mode.el b/json-mode.el index 33c46cb..723eb2e 100644 --- a/json-mode.el +++ b/json-mode.el @@ -1,4 +1,4 @@ -;;; json-mode.el --- Major mode for editing JSON files +;;; json-mode.el --- Major mode for editing JSON files. ;; Copyright (C) 2011-2014 Josh Johnston @@ -31,6 +31,57 @@ (require 'json-snatcher) (require 'json-reformat) +(defgroup json-mode '() + "Major mode for editing JSON files." + :group 'js) + +;;;###autoload +(defconst json-mode-standard-file-ext '(".json" ".jsonld") + "List of JSON file extensions.") + +;; This is to be sure the customization is loaded. Otherwise, +;; autoload discards any defun or defcustom. +;;;###autoload +(defsubst json-mode--update-auto-mode (filenames) + "Update the `json-mode' entry of `auto-mode-alist'. + +FILENAMES should be a list of file as string. +Return the new `auto-mode-alist' entry" + (let* ((new-regexp + (rx-to-string + `(seq (eval + (cons 'or + (append json-mode-standard-file-ext + ',filenames))) eot))) + (new-entry (cons new-regexp 'json-mode)) + (old-entry (when (boundp 'json-mode--auto-mode-entry) + json-mode--auto-mode-entry))) + (setq auto-mode-alist (delete old-entry auto-mode-alist)) + (add-to-list 'auto-mode-alist new-entry) + new-entry)) + +;;;###autoload +(defcustom json-mode-auto-mode-list '(".babelrc" ".bowerrc") + "List of filename as string to pass for the JSON entry of +`auto-mode-alist'. + +Note however that custom `json-mode' entries in `auto-mode-alist' +won’t be affected." + :group 'json-mode + :type '(repeat string) + :set (lambda (symbol value) + "Update SYMBOL with a new regexp made from VALUE. + +This function calls `json-mode--update-auto-mode' to change the +`json-mode--auto-mode-entry' entry in `auto-mode-alist'." + (set-default symbol value) + (setq json-mode--auto-mode-entry (json-mode--update-auto-mode value)))) + +;; Autoload needed to initalize the the `auto-list-mode' entry. +;;;###autoload +(defvar json-mode--auto-mode-entry (json-mode--update-auto-mode json-mode-auto-mode-list) + "Regexp generated from the `json-mode-auto-mode-list'.") + (defconst json-mode-quoted-string-re (rx (group (char ?\") (zero-or-more (or (seq ?\\ ?\\) @@ -65,16 +116,8 @@ "Major mode for editing JSON files" (set (make-local-variable 'font-lock-defaults) '(json-font-lock-keywords-1 t))) -;;;###autoload -(add-to-list 'auto-mode-alist '("\\.json$" . json-mode)) -;;;###autoload -(add-to-list 'auto-mode-alist '("\\.jsonld$" . json-mode)) -;;;###autoload -(add-to-list 'auto-mode-alist (cons (rx (or - ".babelrc" - ".bowerrc" - ) eos) - 'json-mode)) +;; Well formatted JSON files almost always begin with “{” or “[”. +(add-to-list 'magic-mode-alist '("^[{[]$" . json-mode)) ;;;###autoload (defun json-mode-show-path () @@ -86,12 +129,12 @@ ;; delete the window if we have one, ;; so we can recreate it in the correct position (if temp-window - (delete-window temp-window)) + (delete-window temp-window)) ;; always put the temp window below the json window (set-window-buffer (if (fboundp 'split-window-below) - (split-window-below) - (split-window-vertically)) temp-name)) + (split-window-below) + (split-window-vertically)) temp-name)) )) (define-key json-mode-map (kbd "C-c C-p") 'json-mode-show-path)