From: Alex S. <al...@em...> - 2002-10-06 13:14:59
|
Is there a define-minor-mode in the latest XEmacs, or the lastest fsf-compat package? If not, I have a simple (untested) proposal that should do enough to be usable for ERC, and IRC client for Emacs and XEmacs. Here it is: (defmacro define-minor-mode (mode doc &optional init-value lighter keymap &rest body) "Define a minor mode like in Emacs." `(progn (devar ,mode ,init-value "Non-nil if the corresponding mode is enabled.") (defun ,mode (&optional arg) ,doc (setq ,mode (if arg (> (prefix-numeric-value arg) 0) (not foo))) ,@body ,mode) (add-minor-mode ,mode ,lighter ,keymap))) Here is the result: (pp (macroexpand '(define-minor-mode foo "doc" 'init " f" 'map (goo) (gaa))) (current-buffer)) (progn (devar foo 'init "Non-nil if the corresponding mode is enabled.") (defun foo (&optional arg) "doc" (setq foo (if arg (> (prefix-numeric-value arg) 0) (not foo))) (goo) (gaa) foo) (add-minor-mode foo " f" 'map)) Here is the result for Emacs. Note that it does hooks, and keymap stuff, which we currently do not need, so I did not bother. (pp (macroexpand '(define-minor-mode foo "doc" 'init " f" 'map (goo) (gaa))) (current-buffer)) (progn (progn (defvar foo 'init "Non-nil if foo mode is enabled.\nUse the command `foo' to change this variable.") (make-variable-buffer-local 'foo)) (defun foo (&optional arg) "doc" (interactive) (setq foo (if arg (> (prefix-numeric-value arg) 0) (not foo))) (goo) (gaa) (run-hooks 'foo-hook (if foo 'foo-on-hook 'foo-off-hook)) (if (interactive-p) (message "foo mode %sabled" (if foo "en" "dis"))) (force-mode-line-update) foo) :autoload-end (defcustom foo-hook nil "Hook run at the end of function `foo'." :group 'foo :type 'hook) (defvar foo-map (let ((m 'map)) (cond ((keymapp m) m) ((listp m) (easy-mmode-define-keymap m)) (t (error "Invalid keymap %S" 'map)))) "Keymap for `foo'.") (add-minor-mode 'foo '#(" f" 0 2 (local-map (keymap (header-line keymap (down-mouse-3 . mode-line-mode-menu-1)) (mode-line keymap (down-mouse-3 . mode-line-mode-menu-1))) help-echo "mouse-3: minor mode menu")) foo-map) nil) And the doc string, in case you are interested: define-minor-mode is a Lisp macro in `easy-mmode'. (define-minor-mode MODE DOC &optional INIT-VALUE LIGHTER KEYMAP &rest BODY) Define a new minor mode MODE. This function defines the associated control variable MODE, keymap MODE-map, toggle command MODE, and hook MODE-hook. DOC is the documentation for the mode toggle command. Optional INIT-VALUE is the initial value of the mode's variable. Optional LIGHTER is displayed in the modeline when the mode is on. Optional KEYMAP is the default (defvar) keymap bound to the mode keymap. If it is a list, it is passed to `easy-mmode-define-keymap' in order to build a valid keymap. It's generally better to use a separate MODE-map variable than to use this argument. The above three arguments can be skipped if keyword arguments are used (see below). BODY contains code that will be executed each time the mode is (dis)activated. It will be executed after any toggling but before running the hooks. BODY can start with a list of CL-style keys specifying additional arguments. The following keyword arguments are supported: :group Followed by the group name to use for any generated `defcustom'. :global If non-nil specifies that the minor mode is not meant to be buffer-local. By default, the variable is made buffer-local. :init-value Same as the INIT-VALUE argument. :lighter Same as the LIGHTER argument. |