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

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

Need some education on defmacro define-toggle


From: Lennart Borgman
Subject: Need some education on defmacro define-toggle
Date: Mon, 28 Dec 2009 06:16:59 +0100

I just got into some trouble because of a badly written macro I
believe. After the long discussions about defmacro here I wonder if
anyone wants to help me out. How should I write the defmacro below?


I need to be able to autolad the defmacro in a little bit strange way
too. It is not a normal autoload. I want to redefine it. I do
something like:

  (defun web-autoload (fun src docstring interactive type)
  "Similar to autoload, but the SRC arg is different."
  (let ((int (when interactive '(interactive))))
    (cond
     ((eq type 'macro)
      (setq type 'defmacro))
     (t
      (setq type 'defun)))
    (eval
     `(web-autoload-1 ,fun ,src ,docstring ,int ,type))))

   (defmacro web-autoload-1 (fun src docstring interactive type)
           ....
                   (let ((the-macro (append '(,fun) args nil)))
                     (eval the-macro))
        )




Here is the troublesome macro:


(defmacro define-toggle (symbol value doc &rest args)
  "Declare SYMBOL as a customizable variable with a toggle function.
The purpose of this macro is to define a defcustom and a toggle
function suitable for use in a menu.

The arguments have the same meaning as for `defcustom' with these
restrictions:

- The :type keyword cannot be used.  Type is always 'boolean.
- VALUE must be t or nil.

DOC and ARGS are just passed to `defcustom'.

A `defcustom' named SYMBOL with doc-string DOC and a function
named SYMBOL-toggle is defined.  The function toggles the value
of SYMBOL.  It takes no parameters.

To create a menu item something similar to this can be used:

    \(define-key map [SYMBOL]
      \(list 'menu-item \"Toggle nice SYMBOL\"
            'SYMBOL-toggle
            :button '(:toggle . SYMBOL)))"
  (declare (doc-string 3))
  (list
   'progn
   (let ((var-decl (list 'custom-declare-variable
                         (list 'quote symbol)
                         (list 'quote value)
                         doc)))
     (while args
       (let ((arg (car args)))
         (setq args (cdr args))
         (unless (symbolp arg)
           (error "Junk in args %S" args))
         (let ((keyword arg)
               (value (car args)))
           (unless args
             (error "Keyword %s is missing an argument" keyword))
           (setq args (cdr args))
           (cond
            ((not (memq keyword '(:type)))
             (setq var-decl (append var-decl (list keyword value))))
            (t
             (lwarn '(define-toggle) :error "Keyword %s can't be used here"
                    keyword))))))
     (when (assoc :type var-decl) (error ":type is set.  Should not happen!"))
     (setq var-decl (append var-decl (list :type '(quote boolean))))
     var-decl)
   (let* ((SYMBOL-toggle (intern (concat (symbol-name symbol) "-toggle")))
          (SYMBOL-name (symbol-name symbol))
          (fun-doc (concat "Toggles the \(boolean) value of `"
                           SYMBOL-name
                           "'.\n"
                           "For how to set it permanently see this variable.\n"
                           ;;"\nDescription of `" SYMBOL-name "':\n" doc
                           )))
     `(defun ,SYMBOL-toggle ()
        ,fun-doc
        (interactive)
        (customize-set-variable (quote ,symbol) (not ,symbol)))
     )))




reply via email to

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