2013-06-11 4 views
3

В Emacs 23 и 24, следующие прекрасно работает:обратной совместимости для (интерактивный "^") в Emacs 22

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

ответ

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

Я думаю, что вы должны сделать что-то вроде

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

Если аргумент interactive не string, он должен оценить в список (помните, что interactive является не функция, она является специальная форма).

+2

Действительно, лучше использовать '(fboundp 'handle-shift-selection)' вместо '(> emacs-major-version 22)'. – Stefan

+2

Есть ли способ избежать переопределения того, что '(интерактивный)' делает для меня? Я бы предпочел не понимать, как переопределить '(интерактивный"^NEnter число: ")'. Глядя на [источник Emacs для 'call-interactiveively'] (http://git.savannah.gnu.org/cgit/emacs.git/tree/src/callint.c?id=EMACS_22_3#n692) Я предполагаю здесь нет пути. –

+0

@Stefan: если бы у emacs были условия времени на чтение, это было бы еще проще: '# + handle-shift-selection '^ p" # -handle-shift-selection "p" ' – sds

Смежные вопросы