1 ;;; emu.el --- Emulation module for each Emacs variants
3 ;; Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.
5 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
6 ;; Keywords: emulation, compatibility, NEmacs, MULE, Emacs/mule, XEmacs
8 ;; This file is part of emu.
10 ;; This program is free software; you can redistribute it and/or
11 ;; modify it under the terms of the GNU General Public License as
12 ;; published by the Free Software Foundation; either version 2, or (at
13 ;; your option) any later version.
15 ;; This program is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ;; General Public License for more details.
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 the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
29 (defvar running-emacs-18 (<= emacs-major-version 18))
30 (defvar running-xemacs (string-match "XEmacs" emacs-version))
32 (defvar running-mule-merged-emacs (and (not (boundp 'MULE))
33 (not running-xemacs) (featurep 'mule)))
34 (defvar running-xemacs-with-mule (and running-xemacs (featurep 'mule)))
36 (defvar running-emacs-19 (and (not running-xemacs) (= emacs-major-version 19)))
37 (defvar running-emacs-19_29-or-later
38 (or (and running-emacs-19 (>= emacs-minor-version 29))
39 (and (not running-xemacs)(>= emacs-major-version 20))))
41 (defvar running-xemacs-19 (and running-xemacs
42 (= emacs-major-version 19)))
43 (defvar running-xemacs-20-or-later (and running-xemacs
44 (>= emacs-major-version 20)))
45 (defvar running-xemacs-19_14-or-later
46 (or (and running-xemacs-19 (>= emacs-minor-version 14))
47 running-xemacs-20-or-later))
51 (defvar mouse-button-1 'button1)
52 (defvar mouse-button-2 'button2)
53 (defvar mouse-button-3 'button3)
55 ((>= emacs-major-version 19)
57 (defalias 'tl:make-overlay 'make-overlay)
58 (defalias 'tl:overlay-put 'overlay-put)
59 (defalias 'tl:overlay-buffer 'overlay-buffer)
61 (make-obsolete 'tl:make-overlay 'make-overlay)
62 (make-obsolete 'tl:overlay-put 'overlay-put)
63 (make-obsolete 'tl:overlay-buffer 'overlay-buffer)
66 (defvar mouse-button-1 [mouse-1])
67 (defvar mouse-button-2 [mouse-2])
68 (defvar mouse-button-3 [down-mouse-3])
72 (defvar mouse-button-1 nil)
73 (defvar mouse-button-2 nil)
74 (defvar mouse-button-3 nil)
79 ;; for XEmacs with MULE
81 ;; for XEmacs without MULE
84 (running-mule-merged-emacs
85 ;; for Emacs 20.1 and 20.2
89 ;; for MULE 1.* and 2.*
93 ;; for NEmacs and NEpoch
105 (defun charsets-to-mime-charset (charsets)
106 "Return MIME charset from list of charset CHARSETS.
107 This function refers variable `charsets-mime-charset-alist'
108 and `default-mime-charset'."
111 (let ((rest charsets-mime-charset-alist)
113 (while (setq cell (car rest))
114 (if (catch 'not-subset
115 (let ((set1 charsets)
119 (setq obj (car set1))
121 (throw 'not-subset nil))
122 (setq set1 (cdr set1)))
124 (throw 'tag (cdr cell)))
125 (setq rest (cdr rest)))))
126 default-mime-charset)))
129 ;;; @ Emacs 19.30 emulation
132 ;; This function was imported Emacs 19.30.
133 (defun-maybe add-to-list (list-var element)
134 "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet.
135 If you want to use `add-to-list' on a variable that is not defined
136 until a certain package is loaded, you should put the call to `add-to-list'
137 into a hook function that will be run only after loading the package.
138 \[Emacs 19.30 emulating function]"
139 (or (member element (symbol-value list-var))
140 (set list-var (cons element (symbol-value list-var)))))
142 (cond ((fboundp 'insert-file-contents-literally)
144 ((boundp 'file-name-handler-alist)
145 (defun insert-file-contents-literally
146 (filename &optional visit beg end replace)
147 "Like `insert-file-contents', q.v., but only reads in the file.
148 A buffer may be modified in several ways after reading into the buffer due
149 to advanced Emacs features, such as file-name-handlers, format decoding,
150 find-file-hooks, etc.
151 This function ensures that none of these modifications will take place.
152 \[Emacs 19.30 emulating function]"
153 (let (file-name-handler-alist)
154 (insert-file-contents filename visit beg end replace)))
157 (defalias 'insert-file-contents-literally 'insert-file-contents)
161 ;;; @ Emacs 19.31 emulation
164 (defun-maybe buffer-live-p (object)
165 "Return non-nil if OBJECT is a buffer which has not been killed.
166 Value is nil if OBJECT is not a buffer or if it has been killed.
167 \[Emacs 19.31 emulating function]"
170 (buffer-name (get-buffer object))))
172 ;; This macro was imported Emacs 19.33.
173 (defmacro-maybe save-selected-window (&rest body)
174 "Execute BODY, then select the window that was selected before BODY.
175 \[Emacs 19.31 emulating function]"
177 '((save-selected-window-window (selected-window)))
178 (list 'unwind-protect
180 (list 'select-window 'save-selected-window-window))))
183 ;;; @ Emacs 20.1 emulation
186 ;; This macro was imported Emacs 20.2.
187 (defmacro-maybe when (cond &rest body)
188 "(when COND BODY...): if COND yields non-nil, do BODY, else return nil."
189 (list 'if cond (cons 'progn body)))
191 (defmacro-maybe save-current-buffer (&rest body)
192 "Save the current buffer; execute BODY; restore the current buffer.
193 Executes BODY just like `progn'."
194 (` (let ((orig-buffer (current-buffer)))
197 (set-buffer orig-buffer)))))
199 ;; This macro was imported Emacs 20.2.
200 (defmacro-maybe with-current-buffer (buffer &rest body)
201 "Execute the forms in BODY with BUFFER as the current buffer.
202 The value returned is the value of the last form in BODY.
203 See also `with-temp-buffer'."
204 (` (save-current-buffer
205 (set-buffer (, buffer))
208 ;; This macro was imported Emacs 20.2.
209 (defmacro-maybe with-temp-file (file &rest forms)
210 "Create a new buffer, evaluate FORMS there, and write the buffer to FILE.
211 The value of the last form in FORMS is returned, like `progn'.
212 See also `with-temp-buffer'."
213 (let ((temp-file (make-symbol "temp-file"))
214 (temp-buffer (make-symbol "temp-buffer")))
215 (` (let (((, temp-file) (, file))
217 (get-buffer-create (generate-new-buffer-name " *temp file*"))))
220 (with-current-buffer (, temp-buffer)
222 (with-current-buffer (, temp-buffer)
224 (write-region (point-min) (point-max) (, temp-file) nil 0)))
225 (and (buffer-name (, temp-buffer))
226 (kill-buffer (, temp-buffer))))))))
228 ;; This macro was imported Emacs 20.2.
229 (defmacro-maybe with-temp-buffer (&rest forms)
230 "Create a temporary buffer, and evaluate FORMS there like `progn'.
231 See also `with-temp-file' and `with-output-to-string'."
232 (let ((temp-buffer (make-symbol "temp-buffer")))
233 (` (let (((, temp-buffer)
234 (get-buffer-create (generate-new-buffer-name " *temp*"))))
236 (with-current-buffer (, temp-buffer)
238 (and (buffer-name (, temp-buffer))
239 (kill-buffer (, temp-buffer))))))))
241 ;; This function was imported Emacs 20.3.
242 (defun-maybe last (x &optional n)
243 "Return the last link of the list X. Its car is the last element.
244 If X is nil, return nil.
245 If N is non-nil, return the Nth-to-last link of X.
246 If N is bigger than the length of X, return X."
250 (setq m (1+ m) p (cdr p)))
252 (if (< n m) (nthcdr (- m n) x) x)))
257 ;; This function was imported Emacs 20.3. (cl function)
258 (defun-maybe butlast (x &optional n)
259 "Returns a copy of LIST with the last N elements removed."
260 (if (and n (<= n 0)) x
261 (nbutlast (copy-sequence x) n)))
263 ;; This function was imported Emacs 20.3. (cl function)
264 (defun-maybe nbutlast (x &optional n)
265 "Modifies LIST to remove the last N elements."
266 (let ((m (length x)))
270 (if (> n 0) (setcdr (nthcdr (- (1- m) n) x) nil))
273 ;; This function was imported from XEmacs 21.
274 (defun-maybe split-string (string &optional pattern)
275 "Return a list of substrings of STRING which are separated by PATTERN.
276 If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
278 (setq pattern "[ \f\t\n\r\v]+"))
279 ;; The FSF version of this function takes care not to cons in case
280 ;; of infloop. Maybe we should synch?
281 (let (parts (start 0))
282 (while (string-match pattern string start)
283 (setq parts (cons (substring string start (match-beginning 0)) parts)
284 start (match-end 0)))
285 (nreverse (cons (substring string start) parts))))
288 ;;; @ Emacs 20.3 emulation
291 (defmacro-maybe string-as-unibyte (string)
292 "Return a unibyte string with the same individual bytes as STRING.
293 If STRING is unibyte, the result is STRING itself.
294 \[Emacs 20.3 emulating macro]"
297 (defmacro-maybe string-as-multibyte (string)
298 "Return a multibyte string with the same individual bytes as STRING.
299 If STRING is multibyte, the result is STRING itself.
300 \[Emacs 20.3 emulating macro]"
304 ;;; @ XEmacs emulation
307 (defun-maybe functionp (obj)
308 "Returns t if OBJ is a function, nil otherwise.
309 \[XEmacs emulating function]"
311 (byte-code-function-p obj)
312 (and (symbolp obj)(fboundp obj))
313 (and (consp obj)(eq (car obj) 'lambda))
316 (defun-maybe point-at-eol (&optional arg buffer)
317 "Return the character position of the last character on the current line.
318 With argument N not nil or 1, move forward N - 1 lines first.
319 If scan reaches end of buffer, return that position.
320 This function does not move point. [XEmacs emulating function]"
326 (forward-line (1- arg))
335 (or (fboundp 'char-int)
336 (fset 'char-int (symbol-function 'identity))
338 (or (fboundp 'int-char)
339 (fset 'int-char (symbol-function 'identity))
341 (or (fboundp 'char-or-char-int-p)
342 (fset 'char-or-char-int-p (symbol-function 'integerp))
346 ;;; @ for text/richtext and text/enriched
349 (cond ((fboundp 'richtext-decode)
352 ((or running-emacs-19_29-or-later running-xemacs-19_14-or-later)
354 (autoload 'richtext-decode "richtext")
355 (or (assq 'text/richtext format-alist)
359 '("Extended MIME text/richtext format."
360 "Content-[Tt]ype:[ \t]*text/richtext"
361 richtext-decode richtext-encode t enriched-mode))
365 ;; don't have enriched.el
366 (autoload 'richtext-decode "tinyrich")
367 (autoload 'enriched-decode "tinyrich")