如何管理elisp中的底层接口更改

时间:2012-06-20 15:38:47

标签: emacs elisp

在emacs 23.1和24.1之间,url-retrieve的界面发生了变化。在emacs 23.1中,它看起来像这样:

(url-retrieve URL CALLBACK &optional CBARGS)

在版本24.1中,它看起来像这样:

(url-retrieve URL CALLBACK &optional CBARGS SILENT INHIBIT-COOKIES)

我有一个使用此功能的emacs包。我想利用emacs 24.1上新的 SILENT 参数,同时保持与不支持它的旧版emacs的向后兼容性。

管理此问题的最佳方法是什么?我可以在运行时获取最大数量的参数吗?

4 个答案:

答案 0 :(得分:5)

您可以使用此函数获取参数列表:

(defun my-get-arglist (obj)
  ;; code taken from disassemble-internal
  (let ((macro 'nil)
        (name 'nil)
        (doc 'nil)
        args)
    (while (symbolp obj)
      (setq name obj
            obj (symbol-function obj)))
    (if (subrp obj)
        (error "Can't disassemble #<subr %s>" name))
    (if (and (listp obj) (eq (car obj) 'autoload))
        (progn
          (load (nth 1 obj))
          (setq obj (symbol-function name))))
    (if (eq (car-safe obj) 'macro)  ;handle macros
        (setq macro t
              obj (cdr obj)))
    (if (and (listp obj) (eq (car obj) 'byte-code))
        (setq obj (list 'lambda nil obj)))
    (if (and (listp obj) (not (eq (car obj) 'lambda)))
        (error "not a function"))
    (if (consp obj)
        (if (assq 'byte-code obj)
            nil
          (setq obj (byte-compile obj))))
    (cond ((consp obj)
           (setq obj (cdr obj))     ;throw lambda away
           (setq args (car obj))    ;save arg list
           (setq obj (cdr obj)))
          ((byte-code-function-p obj)
           (setq args (aref obj 0)))
          (t (error "Compilation failed")))
    args))

答案 1 :(得分:3)

您可以检查emacs-major-version并确保它是&gt; = 24。

答案 2 :(得分:2)

(defun try-call-with-more-args (function a b c d)
  (condition-case var
      (progn
        (funcall function a b c d)
        (message "there was no error"))
    (wrong-number-of-arguments (funcall function a b c))))

(try-call-with-more-args #'message "b = %d, c = %d" 1 2 3)

即使Trey Jackson发布的内容更聪明,但这更简单,实际上很有可能工作,即使你的目标是本机C函数:)

答案 3 :(得分:1)

如果是旧的emacs版本,请在旧函数周围编写一个包装器:

(let ((orig-fun #'symbol-name-of-orig-fun))
  (defun symbol-name-of-orig-fun (arglist of new function interface)
    (declare (ignore new function interface))
    (funcall orig-fun arglist of)))

这将生成一个词法闭包,用于在新函数中存储旧函数的引用。我不知道emacs方言,但我敢打赌这种模式可以在emacs中使用。我常常在普通的lisp中使用它。