help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Macro Expansion Inconsistency


From: Alexander Shukaev
Subject: Re: Macro Expansion Inconsistency
Date: Wed, 17 Dec 2014 15:03:53 +0100

Thank you very much, John and Nicolas. I think I finally understand how
macros expand in Emacs Lisp better now. I'm sure it's not a coincidence
that you both came up with almost identical solutions. It suggests that the
style of returning forms for evaluation from macro is probably the best way
to go in most cases when `let' is involved. So the final tested solution is:

(defmacro bm-define-flag
    (name index character foreground)
  (let* ((symbol           (intern (format "bm-%s-flag"
                                           (symbol-name name))))
         (character-symbol (intern (format "%s-character"
                                           (symbol-name symbol)))))
    (put symbol 'index     index)
    (put symbol 'character character-symbol)
    `(progn
       (defcustom ,character-symbol
         ,character
         "Character for flag."
         :tag "BM Flag Character"
         :group 'buffer-manager
         :type 'character)
       (defface ,symbol
         '((t :foreground ,foreground
              :weight     bold))
         "Face for flag."
         :tag "BM Flag Face"
         :group 'buffer-manager-faces))))

(put 'bm-define-flag 'lisp-indent-function 'defun)

As a final exam for myself, considering what I've learned, I've implemented
a collective definition macro as well:

(defmacro bm-define-flags
    (name index character foreground &rest ...)
  (let ((name       `,name)
        (index      `,index)
        (character  `,character)
        (foreground `,foreground)
        (...        `(,@...))
        (body       '()))
    (while name
      (push `(bm-define-flag ,name ,index ,character ,foreground) body)
      (setq name       (pop ...)
            index      (pop ...)
            character  (pop ...)
            foreground (pop ...)))
    `(progn ,@body)))

(put 'bm-define-flags 'lisp-indent-function 'defun)

How do you like this one? Now I simply write:

(bm-define-flags
  delete    0 ?D "#FF0000"
  open      0 ?O "#00FFFF"
  previous  0 ?P nil
  modified  1 ?M "#FFFF00"
  write     1 ?W "#00FF00"
  read-only 2 ? "#FF0000")

Looks absolutely amazing ;)

Kind regards,
Alexander


reply via email to

[Prev in Thread] Current Thread [Next in Thread]