[Top][All Lists]

[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))))
     ((eq type 'macro)
      (setq type 'defmacro))
      (setq type 'defun)))
     `(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

- 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\"
            :button '(:toggle . SYMBOL)))"
  (declare (doc-string 3))
   (let ((var-decl (list 'custom-declare-variable
                         (list 'quote symbol)
                         (list 'quote value)
     (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))
            ((not (memq keyword '(:type)))
             (setq var-decl (append var-decl (list keyword value))))
             (lwarn '(define-toggle) :error "Keyword %s can't be used here"
     (when (assoc :type var-decl) (error ":type is set.  Should not happen!"))
     (setq var-decl (append var-decl (list :type '(quote boolean))))
   (let* ((SYMBOL-toggle (intern (concat (symbol-name symbol) "-toggle")))
          (SYMBOL-name (symbol-name symbol))
          (fun-doc (concat "Toggles the \(boolean) value of `"
                           "For how to set it permanently see this variable.\n"
                           ;;"\nDescription of `" SYMBOL-name "':\n" doc
     `(defun ,SYMBOL-toggle ()
        (customize-set-variable (quote ,symbol) (not ,symbol)))

reply via email to

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