3

在 Emacs 23 和 24 中,以下工作正常:

(defun foo (&optional arg)
  (interactive "^p")
  (message "arg is %i" arg))

在 Emacs 22 中,我收到以下错误:

Invalid control letter `^' (136) in interactive calling string

我试过这个:

(defun foo (&optional arg)
  (interactive (concat (if (> emacs-major-version 22) "^" "") "p"))
  (message "arg is %i" arg))

但我得到:

Wrong type argument: listp, "^p"

^在 Emacs 23 或 24 中使用而不是在 Emacs 22中使用的最佳方法是什么?

4

2 回答 2

3

我认为你需要做类似的事情

(interactive
  (progn
    (when (fboundp 'handle-shift-selection)
      (handle-shift-selection))
    (list (prefix-numeric-value current-prefix-arg))))

如果 to 的参数interactive不是 a string,它应该评估为一个列表(记住它interactive不是一个函数,它是一种特殊形式)。

于 2013-06-11T21:39:06.917 回答
2

您可以定义一个扩展为 a 的宏,如果支持移位选择defuninteractive表单将以 a 开头。^例如:

(defmacro my-defun (name args doc inter &rest body)
  "Like `defun' but enables shift selection, if supported.

Note that the documentation string and the `interactive' form
must be present. Requires a string literal as argument to
`interactive'.

See `this-command-keys-shift-translated' for the meaning of shift
translation.

This is implemented by adding the `^' token to the `interactive'
string, when shift selection is supported."
  `(defun ,name ,args
     ,doc
     ,(progn
        (assert (stringp doc))
        (assert (listp inter))
        (assert (eq (length inter) 2))
        (assert (eq (car inter) 'interactive))
        (let ((s (nth 1 inter)))
          (assert (stringp s))
          (if (fboundp 'handle-shift-selection)
              (setq s (concat "^" s)))
          (list 'interactive s)))
     ,@body))
于 2013-06-13T06:48:27.490 回答