+(require 'easymenu)
+
+;; General Emacs/XEmacs-compatibility compile-time macros
+(eval-when-compile
+ (require 'cl)
+ (defmacro cond-emacs-xemacs (&rest args)
+ (cond-emacs-xemacs-macfn
+ args "`cond-emacs-xemacs' must return exactly one element"))
+ (defun cond-emacs-xemacs-macfn (args &optional msg)
+ (if (atom args) args
+ (and (eq (car args) :@) (null msg) ; (:@ ...spliced...)
+ (setq args (cdr args)
+ msg "(:@ ....) must return exactly one element"))
+ (let ((ignore (if (string-match "XEmacs" emacs-version) :EMACS :XEMACS))
+ (mode :BOTH) code)
+ (while (consp args)
+ (if (memq (car args) '(:EMACS :XEMACS :BOTH)) (setq mode (pop args)))
+ (if (atom args)
+ (or args (error "Used selector %s without elements" mode))
+ (or (eq ignore mode)
+ (push (cond-emacs-xemacs-macfn (car args)) code))
+ (pop args)))
+ (cond (msg (if (or args (cdr code)) (error msg) (car code)))
+ ((or (null args) (eq ignore mode)) (nreverse code))
+ (t (nconc (nreverse code) args))))))
+ ;; Emacs/XEmacs-compatibility `defun': remove interactive "_" for Emacs, use
+ ;; existing functions when they are `fboundp', provide shortcuts if they are
+ ;; known to be defined in a specific Emacs branch (for short .elc)
+ (defmacro defunx (name arglist &rest definition)
+ (let ((xemacsp (string-match "XEmacs" emacs-version)) reuses)
+ (while (memq (car definition)
+ '(:try :emacs-and-try :xemacs-and-try))
+ (if (eq (pop definition) (if xemacsp :xemacs-and-try :emacs-and-try))
+ (setq reuses (car definition)
+ definition nil)
+ (push (pop definition) reuses)))
+ (if (and reuses (symbolp reuses))
+ `(defalias ',name ',reuses)
+ (let* ((docstring (if (stringp (car definition)) (pop definition)))
+ (spec (and (not xemacsp)
+ (eq (car-safe (car definition)) 'interactive)
+ (null (cddar definition))
+ (cadar definition))))
+ (if (and (stringp spec)
+ (not (string-equal spec ""))
+ (eq (aref spec 0) ?_))
+ (setq definition
+ (cons (if (string-equal spec "_")
+ '(interactive)
+ `(interactive ,(substring spec 1)))
+ (cdr definition))))
+ (if (null reuses)
+ `(defun ,name ,arglist ,docstring
+ ,@(cond-emacs-xemacs-macfn definition))
+ ;; no dynamic docstring in this case
+ `(eval-and-compile ; no warnings in Emacs
+ (defalias ',name
+ (cond ,@(mapcar (lambda (func) `((fboundp ',func) ',func))
+ (nreverse reuses))
+ (t ,(if definition
+ `(lambda ,arglist ,docstring
+ ,@(cond-emacs-xemacs-macfn definition))
+ 'ignore))))))))))
+ (defmacro ignore-errors-x (&rest body)
+ (let ((specials '((scan-sexps . 4) (scan-lists . 5)))
+ spec nils)
+ (if (and (string-match "XEmacs" emacs-version)
+ (null (cdr body)) (consp (car body))
+ (setq spec (assq (caar body) specials))
+ (>= (setq nils (- (cdr spec) (length (car body)))) 0))
+ `(,@(car body) ,@(make-list nils nil) t)
+ `(ignore-errors ,@body)))))
+
+;; More compile-time-macros
+(eval-when-compile
+ (defmacro save-buffer-state-x (&rest body) ; similar to EMACS/lazy-lock.el
+ (let ((modified (with-no-warnings (gensym "save-buffer-state-x-modified-"))))
+ `(let ((,modified (buffer-modified-p)))
+ (unwind-protect
+ (let ((buffer-undo-list t) (inhibit-read-only t)
+ ,@(unless (string-match "XEmacs" emacs-version)
+ '((inhibit-point-motion-hooks t) deactivate-mark))
+ before-change-functions after-change-functions
+ buffer-file-name buffer-file-truename)
+ ,@body)
+ (and (not ,modified) (buffer-modified-p)
+ (set-buffer-modified-p nil)))))))
+(put 'save-buffer-state-x 'lisp-indent-function 0)
+
+;; get rid of byte-compile warnings