一千萬個為什麽

搜索

idefun:一個將defun變成'互動'defun的宏?

我有一個像這樣分散的遍布我的.emacs 的模式:

(defun my/function ()
   (interactive)
   (....stuff)
)

我想寫一個 idefun 宏,所以我可以編寫如下代碼:

(idefun my/function() 
   (... stuff)
)

到目前為止,基於我以前的ilambda宏帖子,我試過這個行:

   (defmacro idefun (name para &rest body) 
       `(defun ,name ,para (interactive) ,body))


   (idefun my/idefun-test ()
            (message "defun function"))

   ;I would like it to translate to:
   ;(defun my/idefun-test ()
   ;         (interactive)
   ;         (message "defun function")
   ;  )

現在'my/idefun-test'列在M-x下,但是在運行時它告訴我“無效功能”。

我有兩個問題/要求:
1)有誰知道如何讓上述工作?
2)如果第一項是字符串,是否可以實現有條件地插入函數文檔的版本? (例如 lambda帖子)即:

(idefun my/test() "function docu" (message "MEH"))
Should translate to:
(define my/test() "function docu" (interactive) (message "MEH"))

[EDIT SOLUTION]
NOTE: It is not reccomended to use a macro like this in a public package/library as it may lead to confusion. But for a personal .emacs it might just about prevent rsi.

基於下面的答案,我拼湊了以下工作宏:

(defmacro idefun (name para docOrBody &rest body)
  (if (and (stringp docOrBody) body) ;if first arg is a string type
  ;then
  `(defun ,name ,para
     ,docOrBody ;this is the function documentation string in this case.
     (interactive)
     ,@body)
  ;else
  `(defun ,name ,para
     (interactive)
     ,docOrBody ,@body)) ;otherwise it is the body.
  )

;-------
;Examples follow
;-------
(idefun my/id2 ()
         (message "it works"))
(idefun my/id2-with-docu ()
         "Function documentation"
         (message "it works with docu"))

(idefun my/id2-args (a)
        (message a))

(idefun my/hello-moto ()
    "Function docu :-D!"
    (message "Hello moto"))

(global-unset-key (kbd ""))
(global-set-key (kbd "") 'my/hello-moto)

;This is funny if read out loud.
(idefun u() (message "I am your father"))

最佳答案

1)有誰知道如何讓上述工作?

macroexpand-1 is your friend. Let's se what we get by running it:

(macroexpand-1 '(idefun my/test() (message "MEH")))
;; => (defun my/test nil (interactive) ((message "MEH")))

Do you see the problem with that? There's an extra pair of parentheses around the message call. That's because the &rest body argument is a list of all arguments passed (besides the first two, of course).

你需要將拼接該列表放入 defun 的主體中(註意 額外的 @ ):

(defmacro idefun (name para &rest body) 
  `(defun ,name ,para
     (interactive)
     ,@body))

2)是否可以有條件地實施版本   如果第一項是字符串,則插入函數文檔? (喜歡   在lambda帖子中)I.e:

是的,你可以像在裏面那樣做 此答案 你聯系的問題。 defunlambda 沒有什麽不同。 同樣的技術應該有效。

轉載註明原文: idefun:一個將defun變成'互動'defun的宏?