【问题标题】:backward compatibility for (interactive "^") in Emacs 22Emacs 22 中 (interactive "^") 的向后兼容性
【发布时间】:2013-06-11 18:26:54
【问题描述】:

在 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 中的最佳方式是什么?

【问题讨论】:

    标签: emacs elisp compatibility backwards-compatibility


    【解决方案1】:

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

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

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

    【讨论】:

    • 确实,最好使用(fboundp 'handle-shift-selection) 而不是(> emacs-major-version 22)
    • 有没有办法避免重新实现(interactive) 为我做的事情?我宁愿不必弄清楚如何重新实现(interactive "^NEnter a number: ")。看着the Emacs source for call-interactively我猜没办法。
    • @Stefan:如果 emacs 有读取时间条件,那就更容易了:#+handle-shift-selection "^p" #-handle-shift-selection "p"
    【解决方案2】:

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

    (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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多