2012-11-18 5 views
5

Ich habe einen Trend in meinem Code der Wiederholung der gleichen (with-current-buffer .... immer und immer wieder festgestellt, so habe ich beschlossen, ein Makro basierend auf dieser Makrodefinition von with-current-buffer zu definieren - das ist, was ich bisher habe:Body of defmacro wird nicht ausgeführt

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

der Körper wird dies jedoch nie ausgeführt wird, wenn es um defun statt defmacro eingeschaltet ist, ist perfekt funktioniert. Also abgesehen von warum Körper nie ausgeführt wird, ist meine andere Frage - macht das mehr Sinn als ein Makro als ein defun?

+0

Emacs-23 'Ch f Switch-to-buffer' zitieren:„WARNING:. Dies ist nicht der Weg auf einen anderen Puffer vorübergehend innerhalb eines Lisp-Programm zu arbeiten Verwenden 'Set-buffer' anstelle Das vermeidet Messing mit den Window-Buffer-Korrespondenzen " – Stefan

Antwort

4

Denken Sie daran, ein Makro generiert Code. Ihr Makro sieht nicht so aus. Überprüfen Sie eine Makroerweiterung eines Beispielanrufs. Der erste Schritt beim Debuggen eines Makros besteht darin, die Makroexpansion eines Codes zu überprüfen.

....

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

Oben: Warum ist dies als Code in dem Makro und nicht als Quellcode? Dieser Code wird ausgeführt, wenn das Makro erweitert wird. Es wird nicht im generierten Code angezeigt. Wahrscheinlich möchtest du es rückbuchen.

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

    `(progn ,@body) 

Oben: Dies wird nicht tun, was Sie wollen. Sie müssen ALLEN Code, den Sie generieren möchten, zurücksetzen - nicht nur dieses Formular.

+0

habe ich das ganze Ding zurück zitiert, und das macht viel mehr Sinn. Vielen Dank! –

+1

Dan: Beachten Sie auch, dass Makros bei der Kompilierung von byte-compiliert zur Kompilierungszeit expandiert werden, so dass Code, der vom Makro ausgeführt wird, zur Laufzeit nicht ausgeführt wird, wenn Bytekompilierter Code ausgeführt wird. (Diese kritische Nuance ist leicht zu übersehen, da bei nicht kompiliertem Code das Makro dynamisch expandiert und der Code * jedes Mal ausgeführt wird.) – phils