X-Git-Url: http://cgit.sxemacs.org/?p=gnus;a=blobdiff_plain;f=lisp%2Fgmm-utils.el;h=ef607133a654afeb268a2c2032fef87ab4860fce;hp=3d504d73ceee9c8ee2a6d968550f783c914ab1fa;hb=d6d90fbbda04a990e100832c709d6c746d872aa3;hpb=4701091fb20fe41f824040bd0ce4513a58b00468 diff --git a/lisp/gmm-utils.el b/lisp/gmm-utils.el index 3d504d73c..ef607133a 100644 --- a/lisp/gmm-utils.el +++ b/lisp/gmm-utils.el @@ -417,64 +417,45 @@ coding-system." (write-region start end filename append visit lockname)) (write-region start end filename append visit lockname mustbenew))) -;; `flet' and `labels' got obsolete since Emacs 24.3. +;; `interactive-p' is obsolete since Emacs 23.2. +(defmacro gmm-called-interactively-p (kind) + (condition-case nil + (progn + (eval '(called-interactively-p 'any)) + ;; Emacs >=23.2 + `(called-interactively-p ,kind)) + ;; Emacs <23.2 + (wrong-number-of-arguments '(called-interactively-p)) + ;; XEmacs + (void-function '(interactive-p)))) + +;; `flet' and `labels' are obsolete since Emacs 24.3. (defmacro gmm-flet (bindings &rest body) "Make temporary overriding function definitions. +This is an analogue of a dynamically scoped `let' that operates on +the function cell of FUNCs rather than their value cell. \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" - `(let (fn origs) - (dolist (bind ',bindings) - (setq fn (car bind)) - (push (cons fn (and (fboundp fn) (symbol-function fn))) origs) - (fset fn (cons 'lambda (cdr bind)))) - (unwind-protect - (progn ,@body) - (dolist (orig origs) - (if (cdr orig) - (fset (car orig) (cdr orig)) - (fmakunbound (car orig))))))) + (require 'cl) + (if (fboundp 'cl-letf) + `(cl-letf ,(mapcar (lambda (binding) + `((symbol-function ',(car binding)) + (lambda ,@(cdr binding)))) + bindings) + ,@body) + `(flet ,bindings ,@body))) (put 'gmm-flet 'lisp-indent-function 1) -;; An alist of original function names and those unique names. -(defvar gmm-labels-environment) - -(defun gmm-labels-expand (form) - "Expand funcalls in FORM according to `gmm-labels-environment'. -This function is a subroutine that `gmm-labels' uses to convert any -`(FN ...)' and #'FN elements in FORM into `(funcall UN ...)' and `UN' -respectively if `(FN . UN)' is listed in `gmm-labels-environment'." - (cond ((or (not (consp form)) (memq (car form) '(\` backquote quote))) - form) - ((assq (car form) gmm-labels-environment) - `(funcall ,(cdr (assq (car form) gmm-labels-environment)) - ,@(mapcar #'gmm-labels-expand (cdr form)))) - ((eq (car form) 'function) - (if (and (assq (cadr form) gmm-labels-environment) - (not (cddr form))) - (cdr (assq (cadr form) gmm-labels-environment)) - (cons 'function (mapcar #'gmm-labels-expand (cdr form))))) - (t - (mapcar #'gmm-labels-expand form)))) - (defmacro gmm-labels (bindings &rest body) "Make temporary function bindings. -The lexical scoping is handled via `lexical-let' rather than relying -on `lexical-binding'. +The bindings can be recursive and the scoping is lexical, but capturing +them in closures will only work if `lexical-binding' is in use. But in +Emacs 24.2 and older, the lexical scoping is handled via `lexical-let' +rather than relying on `lexical-binding'. \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" - (let (gmm-labels-environment def defs) - (dolist (binding bindings) - (push (cons (car binding) - (make-symbol (format "--gmm-%s--" (car binding)))) - gmm-labels-environment)) - `(lexical-let ,(mapcar #'cdr gmm-labels-environment) - (setq ,@(dolist (env gmm-labels-environment (nreverse defs)) - (setq def (cdr (assq (car env) bindings))) - (push (cdr env) defs) - (push `(lambda ,(car def) - ,@(mapcar #'gmm-labels-expand (cdr def))) - defs))) - ,@(mapcar #'gmm-labels-expand body)))) + `(,(progn (require 'cl) (if (fboundp 'cl-labels) 'cl-labels 'labels)) + ,bindings ,@body)) (put 'gmm-labels 'lisp-indent-function 1) (provide 'gmm-utils)