-
Notifications
You must be signed in to change notification settings - Fork 32
/
mmm-auto.el
178 lines (144 loc) · 6.66 KB
/
mmm-auto.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
;;; 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 <[email protected]>
;;{{{ 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