From 94d2fc1815a919734353c942f224db1de4b4fcb8 Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Mon, 7 Mar 2011 09:04:49 +0100 Subject: Django, org * Added nxhtml, mostly for django support. * Changed some org settings. --- emacs.d/nxhtml/util/majmodpri.el | 448 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 448 insertions(+) create mode 100644 emacs.d/nxhtml/util/majmodpri.el (limited to 'emacs.d/nxhtml/util/majmodpri.el') diff --git a/emacs.d/nxhtml/util/majmodpri.el b/emacs.d/nxhtml/util/majmodpri.el new file mode 100644 index 0000000..7bdbea6 --- /dev/null +++ b/emacs.d/nxhtml/util/majmodpri.el @@ -0,0 +1,448 @@ +;;; majmodpri.el --- Major mode priorities handling +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: 2008-08-26 +(defconst majmodpri:version "0.62") ;;Version: +;; Last-Updated: 2009-04-30 Thu +;; URL: +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Different elisp libraries may try to handle the same type of files. +;; They normally do that by entering their major mode for a file type +;; in `auto-mode-alist' or the other lists affecting `normal-mode'. +;; Since the libraries may be loaded in different orders in different +;; Emacs sessions this can lead to rather stochastic choices of major +;; mode. +;; +;; This library tries to give the control of which major modes will be +;; used back to the user. It does that by letting the user set up +;; priorities among the major modes. This priorities are used to sort +;; the lists used by `normal-mode'. +;; +;; To setup this libray and get more information do +;; +;; M-x customize-group RET majmodpri RET +;; +;; Or, see the commands `majmodpri-sort-lists'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile (require 'mumamo nil t)) +(eval-when-compile (require 'ourcomments-indirect-fun nil t)) + +;;;; Idle sorting + +(defvar majmodpri-idle-sort-timer nil) + +(defun majmodpri-cancel-idle-sort () + "Cancel idle sorting request." + (when majmodpri-idle-sort-timer + (cancel-timer majmodpri-idle-sort-timer) + (setq majmodpri-idle-sort-timer nil))) + +(defun majmodpri-start-idle-sort () + "Request idle sorting." + (majmodpri-cancel-idle-sort) + (setq majmodpri-idle-sort-timer + (run-with-idle-timer 0 nil 'majmodpri-sort-lists-in-timer))) + +(defun majmodpri-sort-lists-in-timer () + (condition-case err + (save-match-data ;; runs in timer + (majmodpri-sort-lists)) + (error (message "(majmodpri-sort-lists): %s" err)))) + + +;;;; Sorting + +(defvar majmodpri-schwarzian-ordnum nil) +(defun majmodpri-schwarzian-in (rec) + "Transform REC before sorting." + (setq majmodpri-schwarzian-ordnum (1+ majmodpri-schwarzian-ordnum)) + (let ((mode (cdr rec))) + (list + (list mode majmodpri-schwarzian-ordnum) + rec))) + +(defun majmodpri-schwarzian-out (rec) + "Get original value of REC after sorting." + (cadr rec)) + +;; Fix-me: default for Emacs 22?? +(defcustom majmodpri-no-nxml (< emacs-major-version 23) + "Don't use multi major modes with nxml if non-nil. +The default for Emacs prior to version 23 is to not use this +multi major modes by default since there are some problems. + +This gives those multi major mode lower priority, but it does not +prevent use of them." + :type 'boolean + :group 'majmodpri) + +;; (majmodpri-priority 'html-mumamo-mode) +;; (majmodpri-priority 'nxhtml-mumamo-mode) +(defsubst majmodpri-priority (mode) + "Return major mode MODE priority." + (if (and majmodpri-no-nxml + ;; (symbolp mode) + ;; (save-match-data + ;; (string-match "nxhtml-mumamo" (symbol-name mode)))) + (let* ((real (or (ourcomments-indirect-fun mode) + mode)) + (chunk (when real (get real 'mumamo-chunk-family))) + (major-mode (when chunk + (cadr chunk)))) + (when major-mode + (derived-mode-p 'nxml-mode)))) + 0 + (length (memq mode majmodpri-mode-priorities)))) + +(defun majmodpri-compare-auto-modes (rec1 rec2) + "Compare record REC1 and record REC2. +Comparision: + +- First check `majmodpri-mode-priorities'. +- Then use old order in list." + (let* ((schw1 (car rec1)) + (schw2 (car rec2)) + (mod1 (nth 0 schw1)) + (mod2 (nth 0 schw2)) + (ord1 (nth 1 schw1)) + (ord2 (nth 1 schw2)) + (pri1 (majmodpri-priority mod1)) + (pri2 (majmodpri-priority mod2))) + (cond + ((/= pri1 pri2) (> pri1 pri2)) + (t (> ord1 ord2))))) + +;;(benchmark 100 (quote (majmodpri-sort-lists))) +;;(defvar my-auto-mode-alist nil) +(defun majmodpri-sort-auto-mode-alist () + "Sort `auto-mode-alist' after users priorities." + (setq majmodpri-schwarzian-ordnum 0) + ;; Do not reorder function part, but put it first. + (let (fun-list + mod-list) + (dolist (rec auto-mode-alist) + (if (listp (cdr rec)) + (setq fun-list (cons rec fun-list)) + (setq mod-list (cons rec mod-list)))) + (setq fun-list (nreverse fun-list)) + (setq auto-mode-alist + (append + fun-list + (mapcar 'majmodpri-schwarzian-out + (sort + (mapcar 'majmodpri-schwarzian-in mod-list) + 'majmodpri-compare-auto-modes)))))) + +(defun majmodpri-sort-magic-list (magic-mode-list-sym) + "Sort list MAGIC-MODE-LIST-SYM after users priorities." + (let ((orig-ordnum 0)) + (set magic-mode-list-sym + ;; S out + (mapcar (lambda (rec) + (cadr rec)) + ;; Sort + (sort + ;; S in + (mapcar (lambda (rec) + (setq orig-ordnum (1+ orig-ordnum)) + (let ((mode (cdr rec))) + (list + (list mode orig-ordnum) + rec))) + (symbol-value magic-mode-list-sym)) + (lambda (rec1 rec2) + (let* ((schw1 (car rec1)) + (schw2 (car rec2)) + (mod1 (nth 0 schw1)) + (mod2 (nth 0 schw2)) + (ord1 (nth 1 schw1)) + (ord2 (nth 1 schw2)) + (pri1 (majmodpri-priority mod1)) + (pri2 (majmodpri-priority mod2))) + (cond + ((/= pri1 pri2) (> pri1 pri2)) + (t (> ord1 ord2)))))))))) + +;;;###autoload +(defun majmodpri-sort-lists () + "Sort the list used when selecting major mode. +Only sort those lists choosen in `majmodpri-lists-to-sort'. +Sort according to priorities in `majmodpri-mode-priorities'. +Keep the old order in the list otherwise. + +The lists can be sorted when loading elisp libraries, see +`majmodpri-sort-after-load'. + +See also `majmodpri-apply-priorities'." + (interactive) + ;;(message "majmodpri-sort-lists running ...") + (majmodpri-cancel-idle-sort) + (when (memq 'magic-mode-alist majmodpri-lists-to-sort) + (majmodpri-sort-magic-list 'magic-mode-alist)) + (when (memq 'auto-mode-alist majmodpri-lists-to-sort) + (majmodpri-sort-auto-mode-alist)) + (when (memq 'magic-fallback-mode-alist majmodpri-lists-to-sort) + (majmodpri-sort-magic-list 'magic-fallback-mode-alist)) + ;;(message "majmodpri-sort-lists running ... (done)") + ) + + +;;;###autoload +(defun majmodpri-apply () + "Sort major mode lists and apply to existing buffers. +Note: This function is suitable to add to +`desktop-after-read-hook'. It will restore the multi major modes +in buffers." + (majmodpri-apply-priorities t)) + +(defun majmodpri-sort-apply-to-current () + "Sort lists and apply to current buffer." + (majmodpri-sort-lists) + (add-hook 'find-file-hook 'normal-mode t t)) + +(defun majmodpri-check-normal-mode () + "Like `normal-mode', but keep major mode if same." + (let ((keep-mode-if-same t) + (old-major-mode major-mode) + (old-mumamo-multi-major-mode (when (boundp 'mumamo-multi-major-mode) + mumamo-multi-major-mode))) + (report-errors "File mode specification error: %s" + (set-auto-mode t)) + ;;(msgtrc "majmodpri-check %s %s %s" (current-buffer) major-mode mumamo-multi-major-mode) + (unless (and (eq old-major-mode major-mode) + (or (not old-mumamo-multi-major-mode) + (eq old-mumamo-multi-major-mode mumamo-multi-major-mode))) + (msgtrc "majmodpri-check changing") + (report-errors "File local-variables error: %s" + (hack-local-variables)) + ;; Turn font lock off and on, to make sure it takes account of + ;; whatever file local variables are relevant to it. + (when (and font-lock-mode + ;; Font-lock-mode (now in font-core.el) can be ON when + ;; font-lock.el still hasn't been loaded. + (boundp 'font-lock-keywords) + (eq (car font-lock-keywords) t)) + (setq font-lock-keywords (cadr font-lock-keywords)) + (font-lock-mode 1)) + (message "majmodpri-apply-priorities: buffer=%s, %s,%s => %s,%s" + (current-buffer) + old-major-mode + old-mumamo-multi-major-mode + major-mode + (when (boundp 'mumamo-multi-major-mode) + mumamo-multi-major-mode))))) + +;;;###autoload +(defun majmodpri-apply-priorities (change-modes) + "Apply major mode priorities. +First run `majmodpri-sort-lists' and then if CHANGE-MODES is +non-nil apply to existing file buffers. If interactive ask +before applying." + (interactive '(nil)) + (message "majmodpri-apply-priorities running ...") + (majmodpri-sort-lists) + (when (or change-modes + (with-no-warnings (called-interactively-p))) + (let (file-buffers) + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (let ((name (buffer-name)) + (file buffer-file-name)) + (or (string= (substring name 0 1) " ") ;; Internal + (not file) + (setq file-buffers (cons buffer file-buffers)))))) + (if (not file-buffers) + (when change-modes + ;;(message "majmodpri-apply-priorities: No file buffers to change modes in") + ) + (when (with-no-warnings (called-interactively-p)) + (setq change-modes + (y-or-n-p "Check major mode in all file visiting buffers? "))) + (when change-modes + (dolist (buffer file-buffers) + (with-current-buffer buffer + (let ((old-major major-mode)) + (majmodpri-check-normal-mode) + ))))))) + (message "majmodpri-apply-priorities running ... (done)")) + + +;;;; Custom + +;;;###autoload +(defgroup majmodpri nil + "Customization group for majmodpri.el" + :group 'nxhtml + ) + +(defcustom majmodpri-mode-priorities + '( + cperl-mumamo-mode + csound-sgml-mumamo-mode + django-nxhtml-mumamo-mode + django-html-mumamo-mode + embperl-nxhtml-mumamo-mode + embperl-html-mumamo-mode + eruby-nxhtml-mumamo-mode + eruby-html-mumamo-mode + genshi-nxhtml-mumamo-mode + genshi-html-mumamo-mode + jsp-nxhtml-mumamo-mode + jsp-html-mumamo-mode + laszlo-nxml-mumamo-mode + metapost-mumamo-mode + mjt-nxhtml-mumamo-mode + mjt-html-mumamo-mode + noweb2-mumamo-mode + ;;org-mumamo-mode + perl-mumamo-mode + smarty-nxhtml-mumamo-mode + smarty-html-mumamo-mode + ;;tt-html-mumamo-mode + + nxhtml-mumamo-mode + html-mumamo-mode + nxml-mumamo-mode + nxml-mode + + javascript-mode + ;;espresso-mode + rhtml-mode + ) + "Priority list for major modes. +Modes that comes first have higher priority. +See `majmodpri-sort-lists' for more information." + :type '(repeat symbol) + :set (lambda (sym val) + (set-default sym val) + (when (and (boundp 'majmodpri-sort-after-load) + majmodpri-sort-after-load) + (majmodpri-start-idle-sort))) + :group 'majmodpri) + +(defcustom majmodpri-lists-to-sort + '(magic-mode-alist auto-mode-alist magic-fallback-mode-alist) + ;;nil + "Which major mode lists to sort. +See `majmodpri-sort-lists' for more information." + :type '(set (const magic-mode-alist) + (const auto-mode-alist) + (const magic-fallback-mode-alist)) + :set (lambda (sym val) + (set-default sym val) + (when (and (boundp 'majmodpri-sort-after-load) + majmodpri-sort-after-load) + (majmodpri-start-idle-sort))) + :group 'majmodpri) + +(defcustom majmodpri-sort-after-load + '( + chart + gpl + ;;nxhtml-autoload + php-mode + rnc-mode + ruby-mode + ) + "Sort major mode lists after loading elisp libraries if non-nil. +This should not really be needed since just loading a library +should not change how Emacs behaves. There are however quite a +few thirt party libraries that does change `auto-mode-alist' +\(including some of my own) since that sometimes seems +reasonable. Some of them are in the default value of this +variable. + +There are two possibilities for sorting here: + +- Value=list of features (default). Sort immediately after loading a + library in the list. Apply to current buffer. + +- Value=t. Sort after loading any library. Sorting is then not + done immediately. Instead it runs in an idle timer. This + means that if several elisp libraries are loaded in a command + then the sorting will only be done once, after the command has + finished. After sorting apply to all buffers. + +Note that the default does break Emacs rule that loading a +library should not change how Emacs behave. On the other hand +the default tries to compensate for that the loaded libraries +breaks this rule by changing `auto-mode-alist'. + +See `majmodpri-sort-lists' for more information." + :type '(choice (const :tag "Never" nil) + (const :tag "After loading any elisp library" t) + (repeat :tag "After loading specified features" symbol)) + :set (lambda (sym val) + (set-default sym val) + ;; Clean up `after-load-alist' first. + (setq after-load-alist + (delq nil + (mapcar (lambda (rec) + (unless (member (cadr rec) + '((majmodpri-start-idle-sort) + (majmodpri-sort-lists))) + rec)) + after-load-alist))) + (when val + ;;(message "majmodpri-sort-after-load: val=%s" val) + (let ((sort-and-apply nil)) + (if (not (listp val)) + (add-to-list 'after-load-alist + (if (eq val t) + '(".*" (majmodpri-start-idle-sort)) + '("." (majmodpri-sort-lists)))) + (dolist (feat val) + ;;(message "feat=%s" feat) + (if (featurep feat) + (setq sort-and-apply t) + (if (eq val t) + (eval-after-load feat '(majmodpri-start-idle-sort)) + (eval-after-load feat '(majmodpri-sort-apply-to-current)))))) + (when sort-and-apply + ;;(message "majmodpri-sort-after-load: sort-and-apply") + (majmodpri-apply-priorities t)) + (if (eq val t) + (majmodpri-start-idle-sort) + (majmodpri-apply-priorities t))))) + :group 'majmodpri) + + +(provide 'majmodpri) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; majmodpri.el ends here -- cgit v1.2.3-54-g00ecf