;;; mmm-auto.el --- loading and enabling MMM Mode automatically -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2004, 2012, 2013, 2018, 2022 Free Software Foundation, Inc. ;; Author: Michael Abraham Shulman ;;{{{ GPL ;; This file 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 file 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 GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains functions and hooks to load and enable MMM Mode ;; automatically. It sets up autoloads for the main MMM Mode functions ;; and interactive commands, and also sets up MMM Global Mode. ;;{{{ Comments on MMM Global Mode ;; This is a kludge borrowed from `global-font-lock-mode'. The idea ;; is the same: we have a function (here `mmm-mode-on-maybe') that we ;; want to be run whenever a major mode starts. Unfortunately, there ;; is no hook (like, say `major-mode-hook') that all major modes run ;; when they are finished. `post-command-hook', however, is run after ;; *every* command, so we do our work in there. (Actually, using ;; `post-command-hook' is even better than being run by major mode ;; functions, since it is run after all local variables and text are ;; loaded, which may not be true in certain cases for the other.) ;; FIXME: There's now after-change-major-mode-hook which should DTRT. ;; In order to do this magic, we rely on the fact that there *is* a ;; hook that all major modes run when *beginning* their work. They ;; call `kill-all-local-variables' (unless they are broken), which in ;; turn runs `change-major-mode-hook'. So we add a function to *that* ;; hook which saves the current buffer and temporarily adds a function ;; to `post-command-hook' which processes that buffer. ;; Actually, in the interests of generality, what that function does ;; is run the hook `mmm-major-mode-hook'. Our desired function ;; `mmm-mode-on-maybe' is then added to that hook. This way, if the ;; user wants to run something else on every major mode, they can just ;; add it to `mmm-major-mode-hook' and take advantage of this hack. ;;}}} ;;; Code: (require 'mmm-vars) ;;{{{ Autoload Submode Classes (defvar mmm-autoloaded-classes '((mason "mmm-mason" nil) (myghty "mmm-myghty" nil) (html-css "mmm-sample" nil) (html-js "mmm-sample" nil) (here-doc "mmm-sample" nil) (sh-here-doc "mmm-sample" nil) (embperl "mmm-sample" nil) (eperl "mmm-sample" nil) (jsp "mmm-sample" nil) (file-variables "mmm-sample" nil) (rpm-sh "mmm-rpm" t) (rpm "mmm-rpm" nil) (cweb "mmm-cweb" nil) (sgml-dtd "mmm-sample" nil) (noweb "mmm-noweb" nil) (html-php "mmm-sample" nil) ) "Alist of submode classes autoloaded from files. Elements look like \(CLASS FILE PRIVATE) where CLASS is a submode class symbol, FILE is a string suitable for passing to `load', and PRIVATE is non-nil if the class is invisible to the user. Classes can be added to this list with `mmm-autoload-class'.") (defun mmm-autoload-class (class file &optional private) "Autoload submode class CLASS from file FILE. PRIVATE, if non-nil, means the class is user-invisible. In general, private classes need not be autoloaded, since they will usually be invoked by a public class in the same file." ;; Don't autoload already defined classes (unless (assq class mmm-classes-alist) (add-to-list 'mmm-autoloaded-classes (list class file private)))) (defun mmm-autoload-class-private-p (autoload-class-entry) "Return t if AUTOLOAD-CLASS-ENTRY is marked as private. AUTOLOAD-CLASS-ENTRY shall be an entry of the variable `mmm-autoloaded-classes'." (nth 2 autoload-class-entry)) ;;}}} ;;{{{ Autoload Functions ;; To shut up the byte compiler. (eval-and-compile (autoload 'mmm-mode-on "mmm-mode" "Turn on MMM Mode. See `mmm-mode'.") (autoload 'mmm-mode-off "mmm-mode" "Turn off MMM Mode. See `mmm-mode'.") (autoload 'mmm-update-font-lock-buffer "mmm-region") (autoload 'mmm-ensure-fboundp "mmm-utils") (autoload 'mmm-mode "mmm-mode" "Minor mode to allow multiple major modes in one buffer. Without ARG, toggle MMM Mode. With ARG, turn MMM Mode on iff ARG is positive and off otherwise." t)) ;; These may actually be used. (autoload 'mmm-ify-by-class "mmm-cmds" "" t) (autoload 'mmm-ify-by-regexp "mmm-cmds" "" t) (autoload 'mmm-ify-region "mmm-cmds" "" t) (autoload 'mmm-parse-buffer "mmm-cmds" "" t) (autoload 'mmm-parse-region "mmm-cmds" "" t) (autoload 'mmm-parse-block "mmm-cmds" "" t) (autoload 'mmm-clear-current-region "mmm-cmds" "" t) (autoload 'mmm-reparse-current-region "mmm-cmds" "" t) (autoload 'mmm-end-current-region "mmm-cmds" "" t) (autoload 'mmm-insertion-help "mmm-cmds" "" t) (autoload 'mmm-insert-region "mmm-cmds" "" t) ;;}}} ;;{{{ MMM Global Mode (defvar mmm-changed-buffers-list () "Buffers that need to be checked for running the major mode hook.") (defun mmm-major-mode-change () "Add this buffer to `mmm-changed-buffers-list' for checking. When the current command is over, MMM Mode will be turned on in this buffer depending on the value of `mmm-global-mode'. Actually, everything in `mmm-major-mode-hook' will be run." (and (boundp 'mmm-mode) mmm-mode (mmm-mode-off)) (add-to-list 'mmm-changed-buffers-list (current-buffer)) (add-hook 'post-command-hook #'mmm-check-changed-buffers)) (add-hook 'change-major-mode-hook #'mmm-major-mode-change) (defun mmm-check-changed-buffers () "Run major mode hook for the buffers in `mmm-changed-buffers-list'." (remove-hook 'post-command-hook #'mmm-check-changed-buffers) (dolist (buffer mmm-changed-buffers-list) (when (buffer-live-p buffer) (with-current-buffer buffer (mmm-run-major-mode-hook)))) (setq mmm-changed-buffers-list '())) (defun mmm-mode-on-maybe () "Conditionally turn on MMM Mode. Turn on MMM Mode if `mmm-global-mode' is non-nil and there are classes to apply, or always if `mmm-global-mode' is t." (cond ((eq mmm-global-mode t) (mmm-mode-on)) ((not mmm-global-mode)) ((mmm-get-all-classes nil) (mmm-mode-on))) (when mmm-mode (mmm-update-font-lock-buffer))) (add-hook 'mmm-major-mode-hook #'mmm-mode-on-maybe) ;;}}} (provide 'mmm-auto) ;;; mmm-auto.el ends here