(if electric-help-map
()
(let ((map (make-keymap)))
- ;; allow all non-self-inserting keys - search, scroll, etc
+ ;; allow all non-self-inserting keys - search, scroll, etc, but
+ ;; let M-x and C-x exit ehelp mode and retain buffer:
(suppress-keymap map)
+ (define-key map "\C-u" 'electric-help-undefined)
+ (define-key map [?\C-0] 'electric-help-undefined)
+ (define-key map [?\C-1] 'electric-help-undefined)
+ (define-key map [?\C-2] 'electric-help-undefined)
+ (define-key map [?\C-3] 'electric-help-undefined)
+ (define-key map [?\C-4] 'electric-help-undefined)
+ (define-key map [?\C-5] 'electric-help-undefined)
+ (define-key map [?\C-6] 'electric-help-undefined)
+ (define-key map [?\C-7] 'electric-help-undefined)
+ (define-key map [?\C-8] 'electric-help-undefined)
+ (define-key map [?\C-9] 'electric-help-undefined)
(define-key map (char-to-string help-char) 'electric-help-help)
(define-key map "?" 'electric-help-help)
(define-key map " " 'scroll-up)
;;a better key than this?
(define-key map "r" 'electric-help-retain)
(define-key map "R" 'electric-help-retain)
+ (define-key map "\ex" 'electric-help-execute-extended)
+ (define-key map "\C-x" 'electric-help-ctrl-x-prefix)
(setq electric-help-map map)))
-
+
(defun electric-help-mode ()
"`with-electric-help' temporarily places its buffer in this mode.
\(On exit from `with-electric-help', the buffer is put in `default-major-mode'.)"
(setq major-mode 'help)
(setq mode-line-buffer-identification '(" Help: %b"))
(use-local-map electric-help-map)
+ (setq mouse-leave-buffer-hook '(electric-help-retain))
;; this is done below in with-electric-help
;(run-hooks 'electric-help-mode-hook)
)
;;;###autoload
(defun with-electric-help (thunk &optional buffer noerase)
"Pop up an \"electric\" help buffer.
-Arguments are THUNK &optional BUFFER NOERASE. BUFFER defaults to `*Help*'.
-THUNK is a function of no arguments which is called to initialize
-the contents of BUFFER. BUFFER will be erased before THUNK is called unless
-NOERASE is non-nil. THUNK will be called with `standard-output' bound to
+The arguments are THUNK &optional BUFFER NOERASE MINHEIGHT.
+THUNK is a function of no arguments which is called to initialize the
+contents of BUFFER. BUFFER defaults to `*Help*'. BUFFER will be
+erased before THUNK is called unless NOERASE is non-nil. THUNK will
+be called while BUFFER is current and with `standard-output' bound to
the buffer specified by BUFFER.
If THUNK returns nil, we display BUFFER starting at the top, and
After THUNK has been called, this function \"electrically\" pops up a window
in which BUFFER is displayed and allows the user to scroll through that buffer
-in electric-help-mode.
+in electric-help-mode. The window's height will be at least MINHEIGHT if
+this value is non-nil.
+
+If THUNK returns nil, we display BUFFER starting at the top, and
+shrink the window to fit. If THUNK returns non-nil, we don't do those
+things.
+
When the user exits (with `electric-help-exit', or otherwise) the help
buffer's window disappears (i.e., we use `save-window-excursion')
BUFFER is put into `default-major-mode' (or `fundamental-mode') when we exit."
(setq buffer (get-buffer-create (or buffer "*Help*")))
(let ((one (one-window-p t))
(config (current-window-configuration))
- (bury nil))
+ (bury nil)
+ (to-be-executed nil))
(unwind-protect
(save-excursion
(if one (goto-char (window-start (selected-window))))
(pop-to-buffer buffer))
(save-excursion
(set-buffer buffer)
+ (if (and minheight (< (window-height) minheight))
+ (enlarge-window (- minheight (window-height))))
(electric-help-mode)
- (setq buffer-read-only nil)
(or noerase (erase-buffer)))
(let ((standard-output buffer))
(if (not (funcall thunk))
;; so that when we say "Press space to bury" we mean it
(replace-buffer-in-windows buffer)
;; must do this outside of save-window-excursion
- (bury-buffer buffer))))))
+ (bury-buffer buffer)))
+ (eval to-be-executed))))
(defun electric-help-command-loop ()
(catch 'exit
(Electric-command-loop
'exit
(function (lambda ()
+ (sit-for 0) ;necessary if last command was end-of-buffer or
+ ;beginning-of-buffer - otherwise pos-visible-in-window-p
+ ;will yield a wrong result.
(let ((min (pos-visible-in-window-p (point-min)))
(max (pos-visible-in-window-p (point-max))))
- (cond ((and min max)
+ (cond (isearch-mode 'noprompt)
+ ((and min max)
(cond (standard "Press q to exit, r to retain ")
(neither)
(t (setq neither (substitute-command-keys "Press \\[electric-help-exit] to exit, \\[electric-help-retain] to retain ")))))
(up)
(t (setq up (substitute-command-keys "Press \\[scroll-up] to scroll, \\[electric-help-exit] to exit, \\[electric-help-retain] to retain ")))))
(max
- (cond (standard "Press DEL to scroll back, q to exit ")
+ (cond (standard "Press DEL to scroll back, q to exit, r to retain ")
(down)
(t (setq down (substitute-command-keys "Press \\[scroll-down] to scroll back, \\[electric-help-exit] to exit, \\[electric-help-retain] to retain ")))))
(t
- (cond (standard "Press SPC to scroll, DEL to scroll back, q to exit ")
+ (cond (standard "Press SPC to scroll, DEL to scroll back, q to exit, r to retain ")
(both)
(t (setq both (substitute-command-keys "Press \\[scroll-up] to scroll, \\[scroll-down] to scroll back, \\[electric-help-exit] to exit, \\[electric-help-retain] to retain ")))))))))
t))))
\(The *Help* buffer will not be selected, but \\[switch-to-buffer-other-window] RET
will select it.)"
(interactive)
- (throw 'exit '(retain)))
+ ;; Make sure that we don't throw twice, even if two events cause
+ ;; calling this function:
+ (if mouse-leave-buffer-hook
+ (progn
+ (setq mouse-leave-buffer-hook nil)
+ (throw 'exit '(retain)))))
(defun electric-help-undefined ()
(interactive)
(error "%s is undefined -- Press %s to exit"
(mapconcat 'single-key-description (this-command-keys) " ")
- (if (eq (key-binding "Q") 'electric-help-exit)
- "Q"
+ (if (eq (key-binding "q") 'electric-help-exit)
+ "q"
(substitute-command-keys "\\[electric-help-exit]"))))
(set-buffer-modified-p m))))))
(with-electric-help 'ignore name t))))
+\f
+
+;; This is to be bound to M-x in ehelp mode. Retains ehelp buffer and then
+;; continues with execute-extended-command.
+(defun electric-help-execute-extended (prefixarg)
+ (interactive "p")
+ (setq to-be-executed '(execute-extended-command nil))
+ (electric-help-retain))
+
+;; This is to be buond to C-x in ehelp mode. Retains ehelp buffer and then
+;; continues with ctrl-x prefix.
+(defun electric-help-ctrl-x-prefix (prefixarg)
+ (interactive "p")
+ (setq to-be-executed '(progn (message nil) (setq unread-command-char ?\C-x)))
+ (electric-help-retain))
+
\f
(defun electric-describe-key ()
(interactive)
(if ehelp-map
nil
(let ((map (copy-keymap help-map)))
+ (substitute-key-definition 'apropos 'electric-apropos map)
(substitute-key-definition 'command-apropos 'electric-command-apropos map)
(substitute-key-definition 'describe-key 'electric-describe-key map)
(substitute-key-definition 'describe-mode 'electric-describe-mode map)