2012-11-18 10 views
5

Ho notato una tendenza nel mio codice di ripetere lo stesso (with-current-buffer .... ripetutamente così ho deciso di definire una macro basata su quella definizione di macro di with-current-buffer - questo è quello che ho finora:Corpo di defmacro non eseguito

(defmacro with-assembla-buffer(asm-buffer-name heading-str &rest body) 
    "Create buffer with name of ASM-BUFFER-NAME, or uses it if exists,                          
    preps it with readonly/erase/heading - executes `body' - then puts                          
    readonly back on, goes to beginning of buffer, and switches to it." 
    (with-current-buffer (get-buffer-create asm-buffer-name) 
    (assembla-mode) 
    (toggle-read-only -1) 
    (erase-buffer) 
    (insert (format "-- %s --------------------" heading-str)) 
    (newline) 
    `(progn ,@body) 
    (toggle-read-only 1) 
    (goto-char (point-min)) 
    (switch-to-buffer (current-buffer)))) 

Il corpo di questo è mai realizzazione, tuttavia quando è commutato defun anziché defmacro è non funziona perfettamente. Quindi, a parte il numero , perché il corpo non è mai stato eseguito, la mia altra domanda è - ha più senso come macro rispetto a un defun?

+0

Per citare "Ch f ​​switch-to-buffer' di Emacs-23:" ATTENZIONE: NON è il modo di lavorare temporaneamente su un altro buffer all'interno di un programma Lisp !, invece di usare "set-buffer" .Questo evita lo schermaggio con le corrispondenze del buffer di finestre " – Stefan

risposta

4

Ricordare che una macro genera codice. La tua macro sembra che non sia così. Scopri una macro espansione di una chiamata di esempio. Il primo passo del debug di una macro è controllare l'espansione della macro di alcuni codici.

....

(with-current-buffer (get-buffer-create asm-buffer-name) 

Sopra: perché è questo come codice nella macro e non come codice sorgente? Questo codice verrà eseguito quando la macro viene espansa, non verrà visualizzata nel codice generato. Probabilmente lo vuoi backquote.

(assembla-mode) 
    (toggle-read-only -1) 
    (erase-buffer) 
    (insert (format "-- %s --------------------" heading-str)) 
    (newline) 

    `(progn ,@body) 

Sopra: questo non farà quello che vuoi. Devi riorganizzare TUTTO il codice che vuoi generare, non solo questo modulo.

+0

ho fatto il backquote dell'intera cosa, e questo ha molto più senso. Grazie! –

+1

Dan: Si noti inoltre che per elisp compilato in byte, le macro vengono espanse in fase di compilazione, e quindi il codice che viene eseguito dalla macro * non * verrà eseguito in fase di esecuzione quando si esegue il codice compilato in byte. (Questa sfumatura critica è facile da perdere, perché per il codice non compilato la macro verrà espansa dinamicamente e il codice * viene * eseguito ogni volta.) – phils

Problemi correlati