Initial Commit
[packages] / xemacs-packages / mmm-mode / mmm-compat.el
1 ;;; mmm-compat.el --- MMM Hacks for compatibility with other Emacsen
2
3 ;; Copyright (C) 2000 by Michael Abraham Shulman
4
5 ;; Author: Michael Abraham Shulman <viritrilbia@users.sourceforge.net>
6 ;; Version: $Id: mmm-compat.el,v 1.3 2008-12-22 14:02:24 mharnisch Exp $
7
8 ;;{{{ GPL
9
10 ;; This file is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; This file is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;}}}
26
27 ;;; Commentary:
28
29 ;; This file provides a number of hacks that are necessary for MMM
30 ;; Mode to function in different Emacsen.  MMM Mode is designed for
31 ;; FSF Emacs 20 and 21, but these hacks usually enable it to work
32 ;; almost perfectly in Emacs 19 and XEmacs 20 or 21.
33
34 ;;; Code:
35
36 (require 'cl)
37
38 ;;{{{ Emacsen Detection
39
40 (defvar mmm-xemacs (featurep 'xemacs)
41   "Whether we are running XEmacs.")
42
43 ;;}}}
44 ;;{{{ Keywords (Emacs 19)
45
46 ;; Emacs 19 doesn't automatically set keyword variables to themselves.
47 ;; We shouldn't have to do any more than these, since CL automatically
48 ;; defines all keywords used for function arguments.
49 (defvar mmm-keywords-used
50   '(:group :regexp :region :function :insert :classes :private)
51   "List of extra keywords used by MMM Mode.")
52
53 (dolist (keyword mmm-keywords-used)
54   (set keyword keyword))
55
56 ;;}}}
57 ;;{{{ Customization (Emacs 19)
58
59 (condition-case ()
60     (require 'custom)
61   (error nil))
62
63 (unless (and (featurep 'custom)
64              (fboundp 'custom-declare-variable))
65   (defmacro defgroup (&rest args)
66     nil)
67   (defmacro defface (var values doc &rest args)
68     (` (make-face (quote (, var)))))
69   (defmacro defcustom (var value doc &rest args) 
70     (` (defvar (, var) (, value) (, doc)))))
71
72 ;;}}}
73 ;;{{{ Regexp-Opt (Emacs 19)
74
75 (condition-case ()
76     (require 'regexp-opt)
77   (error nil))
78
79 (unless (and (featurep 'regexp-opt)
80              (fboundp 'regexp-opt))
81   ;; No regexp-opt; create one
82   (defun regexp-opt (strings &optional paren)
83     (concat (if paren "\\(" "")
84             (mapconcat 'regexp-quote strings "\\|")
85             (if paren "\\)" ""))))
86
87 ;;}}}
88 ;;{{{ Regexp-Opt (XEmacs)
89
90 ;; XEmacs change: not needed since xemacs-base > 1.81.
91 (defalias 'mmm-regexp-opt 'regexp-opt)
92 ;(defmacro mmm-regexp-opt (strings paren)
93 ;  "Act like FSF Emacs' `regexp-opt', whichever Emacs we're in.
94 ;XEmacs' `regexp-opt' requires an extra parameter to do grouping."
95 ;  (if (featurep 'xemacs)
96 ;      `(regexp-opt ,strings ,paren t)
97 ;    `(regexp-opt ,strings ,paren)))
98
99 ;;}}}
100 ;;{{{ Overlays (XEmacs)
101
102 ;; The main thing we use from FSF Emacs that XEmacs doesn't support
103 ;; are overlays. XEmacs uses extents instead, but comes with a package
104 ;; to emulate overlays.
105 (when mmm-xemacs
106   ;; This does almost everything we need.
107   (require 'overlay))
108
109 ;; We also use a couple "special" overlay properties which have
110 ;; different names for XEmacs extents.
111 (defvar mmm-evaporate-property
112   (if (featurep 'xemacs) 'detachable 'evaporate)
113   "The name of the overlay property controlling evaporation.")
114
115 ;; We don't use this any more, since its behavior is different in FSF
116 ;; and XEmacs: in the one it replaces the buffer's local map, but in
117 ;; the other it gets stacked on top of it. Instead we just set the
118 ;; buffer's local map temporarily.
119 ;;;(defvar mmm-keymap-property
120 ;;;  (if (featurep 'xemacs) 'keymap 'local-map)
121 ;;;  "The name of the overlay property controlling keymaps.")
122
123 ;;}}}
124 ;;{{{ Keymaps and Events (XEmacs)
125
126 ;; In XEmacs, keymaps are a primitive type, while in FSF Emacs, they
127 ;; are a list whose car is the symbol `keymap'. Among other things,
128 ;; this means that they handle default bindings differently.
129 (defmacro mmm-set-keymap-default (keymap binding)
130   (if (featurep 'xemacs)
131       `(set-keymap-default-binding ,keymap ,binding)
132     `(define-key ,keymap [t] ,binding)))
133
134 ;; In XEmacs, events are a primitive type, while in FSF Emacs, they
135 ;; are represented by characters or vectors. We treat them as vectors.
136 ;; We can use `event-modifiers' in both Emacsen to extract the
137 ;; modifiers, but the function to extract the basic key is different.
138 (defmacro mmm-event-key (event)
139   (if (featurep 'xemacs)
140       `(event-key ,event)
141     `(event-basic-type ,event)))
142
143 ;;}}}
144 ;;{{{ Skeleton (XEmacs)
145
146 ;; XEmacs' `skeleton' package doesn't provide `@' to record positions.
147 (defvar skeleton-positions ())
148 (defun mmm-fixup-skeleton ()
149   "Add `@' to `skeleton-further-elements' if XEmacs and not there.
150 This makes `@' in skeletons act approximately like it does in FSF."
151   (and (featurep 'xemacs)
152        (defvar skeleton-further-elements ())
153        (not (assoc '@ skeleton-further-elements))
154        (add-to-list 'skeleton-further-elements
155                     '(@ ''(push (point) skeleton-positions)))))
156
157 ;;}}}
158 ;;{{{ Make Temp Buffers (XEmacs)
159
160 (defmacro mmm-make-temp-buffer (buffer name)
161   "Return a buffer called NAME including the text of BUFFER.
162 This text should not be modified."
163   (if (fboundp 'make-indirect-buffer)
164       `(make-indirect-buffer ,buffer ,name)
165     `(save-excursion
166        (set-buffer (get-buffer-create ,name))
167        (insert-buffer ,buffer)
168        (current-buffer))))
169
170 ;;}}}
171 ;;{{{ Font Lock Available (Emacs w/o X)
172
173 (defvar mmm-font-lock-available-p (or window-system mmm-xemacs)
174   "Whether font-locking is available.
175 Emacs 19 and 20 only provide font-lock with a window system in use.")
176
177 ;;}}}
178 ;;{{{ Font Lock Defaults (XEmacs)
179
180 (defmacro mmm-set-font-lock-defaults ()
181   "Set font-lock defaults without trying to turn font-lock on.
182 In XEmacs, `font-lock-set-defaults' calls `font-lock-set-defaults-1'
183 to do the real work but then `turn-on-font-lock', which in turn calls
184 `font-lock-mode', which unsets the defaults if running in a hidden
185 buffer \(name begins with a space).  So in XEmacs, we just call
186 `font-lock-set-defaults-1' directly."
187   (if mmm-xemacs
188       `(font-lock-set-defaults-1)
189     `(font-lock-set-defaults)))
190
191 ;;}}}
192
193 (provide 'mmm-compat)
194
195 ;;; mmm-compat.el ends here