TURN-ON is a function that will be called with no args in every buffer
and that should try to turn MODE on if applicable for that buffer.
KEYS is a list of CL-style keyword arguments:
-:group to specify the custom group."
+:group to specify the custom group.
+
+If MODE's set-up depends on the major mode in effect when it was
+enabled, then disabling and reenabling MODE should make MODE work
+correctly with the current major mode. This is important to
+prevent problems with derived modes, that is, major modes that
+call another major mode in their body."
+
(let* ((global-mode-name (symbol-name global-mode))
(pretty-name (easy-mmode-pretty-mode-name mode))
(pretty-global-name (easy-mmode-pretty-mode-name global-mode))
(group nil)
(extra-args nil)
- (buffers (intern (concat global-mode-name "-buffers")))
- (cmmh (intern (concat global-mode-name "-cmmh"))))
+ (MODE-buffers (intern (concat global-mode-name "-buffers")))
+ (MODE-enable-in-buffers
+ (intern (concat global-mode-name "-enable-in-buffers")))
+ (MODE-check-buffers
+ (intern (concat global-mode-name "-check-buffers")))
+ (MODE-cmhh (intern (concat global-mode-name "-cmhh")))
+ (MODE-major-mode (intern (concat (symbol-name mode) "-major-mode"))))
;; Check keys.
(while (keywordp (car keys))
"-mode\\'" "" (symbol-name mode))))))
`(progn
+ (defvar ,MODE-major-mode nil)
+ (make-variable-buffer-local ',MODE-major-mode)
;; The actual global minor-mode
(define-minor-mode ,global-mode
,(format "Toggle %s in every buffer.
;; Setup hook to handle future mode changes and new buffers.
(if ,global-mode
(progn
- (add-hook 'after-change-major-mode-hook ',buffers)
- (add-hook 'change-major-mode-hook ',cmmh))
- (remove-hook 'after-change-major-mode-hook ',buffers)
- (remove-hook 'change-major-mode-hook ',cmmh))
+ (add-hook 'after-change-major-mode-hook
+ ',MODE-enable-in-buffers)
+ (add-hook 'find-file-hook ',MODE-check-buffers)
+ (add-hook 'change-major-mode-hook ',MODE-cmhh))
+ (remove-hook 'after-change-major-mode-hook ',MODE-enable-in-buffers)
+ (remove-hook 'find-file-hook ',MODE-check-buffers)
+ (remove-hook 'change-major-mode-hook ',MODE-cmhh))
;; Go through existing buffers.
(dolist (buf (buffer-list))
:autoload-end
;; List of buffers left to process.
- (defvar ,buffers nil)
+ (defvar ,MODE-buffers nil)
;; The function that calls TURN-ON in each buffer.
- (defun ,buffers ()
- (remove-hook 'post-command-hook ',buffers)
- (while ,buffers
- (let ((buf (pop ,buffers)))
- (when (buffer-live-p buf)
- (with-current-buffer buf (,turn-on))))))
- (put ',buffers 'definition-name ',global-mode)
+ (defun ,MODE-enable-in-buffers ()
+ (dolist (buf ,MODE-buffers)
+ (when (buffer-live-p buf)
+ (with-current-buffer buf
+ (if ,mode
+ (unless (eq ,MODE-major-mode major-mode)
+ (,mode -1)
+ (,turn-on)
+ (setq ,MODE-major-mode major-mode))
+ (,turn-on)
+ (setq ,MODE-major-mode major-mode))))))
+ (put ',MODE-enable-in-buffers 'definition-name ',global-mode)
+
+ (defun ,MODE-check-buffers ()
+ (,MODE-enable-in-buffers)
+ (setq ,MODE-buffers nil)
+ (remove-hook 'post-command-hook ',MODE-check-buffers))
+ (put ',MODE-check-buffers 'definition-name ',global-mode)
;; The function that catches kill-all-local-variables.
- (defun ,cmmh ()
- (add-to-list ',buffers (current-buffer))
- (add-hook 'post-command-hook ',buffers))
- (put ',cmmh 'definition-name ',global-mode))))
+ (defun ,MODE-cmhh ()
+ (add-to-list ',MODE-buffers (current-buffer))
+ (add-hook 'post-command-hook ',MODE-check-buffers))
+ (put ',MODE-cmhh 'definition-name ',global-mode))))
;;;
;;; easy-mmode-defmap