X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/4b08b7ed056226e8b49a7f2ec2233d0492d933fe..73ea6d945d4af5352122e3a1470c4533187e9dcc:/lisp/help.el diff --git a/lisp/help.el b/lisp/help.el index afe7f49e22..387c4cdd73 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -1,6 +1,6 @@ ;;; help.el --- help commands for Emacs -;; Copyright (C) 1985, 1986, 1993, 1994, 1998 Free Software Foundation, Inc. +;; Copyright (C) 1985, 1986, 1993, 1994, 1998, 1999 Free Software Foundation, Inc. ;; Maintainer: FSF ;; Keywords: help, internal @@ -25,13 +25,14 @@ ;;; Commentary: ;; This code implements GNU Emacs' on-line help system, the one invoked by -;;`M-x help-for-help'. +;; `M-x help-for-help'. ;;; Code: ;; Get the macro make-help-screen when this is compiled, ;; or run interpreted, but not when the compiled code is loaded. (eval-when-compile (require 'help-macro)) +(eval-when-compile (require 'view)) (defvar help-map (make-sparse-keymap) "Keymap for characters following the Help key.") @@ -135,6 +136,11 @@ The format is (FUNCTION ARGS...).") (setq-default help-xref-stack nil help-xref-stack-item nil) +(defcustom help-mode-hook nil + "Hook run by `help-mode'." + :type 'hook + :group 'help) + (defun help-mode () "Major mode for viewing help text and navigating references in it. Entry to this mode runs the normal hook `help-mode-hook'. @@ -154,9 +160,13 @@ Commands: ;; `help-mode-maybe'. (run-hooks 'help-mode-hook)) -(defun help-mode-maybe () - (if (eq major-mode 'fundamental-mode) - (help-mode)) +(defun help-mode-setup () + (help-mode) + (setq buffer-read-only nil)) + +(add-hook 'temp-buffer-setup-hook 'help-mode-setup) + +(defun help-mode-finish () (when (eq major-mode 'help-mode) ;; View mode's read-only status of existing *Help* buffer is lost ;; by with-output-to-temp-buffer. @@ -165,9 +175,10 @@ Commands: (setq view-return-to-alist (list (cons (selected-window) help-return-method)))) -(add-hook 'temp-buffer-show-hook 'help-mode-maybe) +(add-hook 'temp-buffer-show-hook 'help-mode-finish) (defun help-quit () + "Just exit from the Help command's command loop." (interactive) nil) @@ -211,6 +222,19 @@ With arg, you are asked to choose which language." (goto-char (point-min)) (set-buffer-modified-p nil)))) +(defun mode-line-key-binding (key) + "Value is the binding of KEY in the mode line or nil if none." + (let (string-info defn) + (when (and (eq 'mode-line (aref key 0)) + (consp (setq string-info (nth 4 (event-start (aref key 1)))))) + (let* ((string (car string-info)) + (pos (cdr string-info)) + (local-map (and (> pos 0) + (< pos (length string)) + (get-text-property pos 'local-map string)))) + (setq defn (and local-map (lookup-key local-map key))))) + defn)) + (defun describe-key-briefly (key &optional insert) "Print the name of the function KEY invokes. KEY is a string. If INSERT (the prefix arg) is non-nil, insert the message in the buffer." @@ -231,7 +255,8 @@ If INSERT (the prefix arg) is non-nil, insert the message in the buffer." (set-buffer (window-buffer window)) (goto-char position))) ;; Ok, now look up the key and name the command. - (let ((defn (key-binding key)) + (let ((defn (or (mode-line-key-binding key) + (key-binding key))) (key-desc (key-description key))) (if (or (null defn) (integerp defn)) (princ (format "%s is undefined" key-desc)) @@ -312,7 +337,7 @@ If FUNCTION is nil, applies `message' to it, thus printing it." (progn (set-buffer (window-buffer window)) (goto-char position))) - (let ((defn (key-binding key))) + (let ((defn (or (mode-line-key-binding key) (key-binding key)))) (if (or (null defn) (integerp defn)) (message "%s is undefined" (key-description key)) (with-output-to-temp-buffer "*Help*" @@ -322,18 +347,27 @@ If FUNCTION is nil, applies `message' to it, thus printing it." (princ " runs the command ") (prin1 defn) (princ "\n which is ") - (describe-function-1 defn nil) + (describe-function-1 defn nil (interactive-p)) (print-help-return-message))))))) (defun describe-mode () "Display documentation of current major mode and minor modes. +The major mode description comes first, followed by the minor modes, +each on a separate page. + For this to work correctly for a minor mode, the mode's indicator variable \(listed in `minor-mode-alist') must also be a function whose documentation describes the minor mode." (interactive) (with-output-to-temp-buffer "*Help*" - (let ((minor-modes minor-mode-alist) - (first t)) + (when minor-mode-alist + (princ "The major mode is described first. +For minor modes, see following pages.\n\n")) + (princ mode-name) + (princ " mode:\n") + (princ (documentation major-mode)) + (help-setup-xref (list #'help-xref-mode (current-buffer)) (interactive-p)) + (let ((minor-modes minor-mode-alist)) (while minor-modes (let* ((minor-mode (car (car minor-modes))) (indicator (car (cdr (car minor-modes))))) @@ -348,24 +382,18 @@ describes the minor mode." (capitalize (substring (symbol-name minor-mode) 0 (match-beginning 0))))) - (while (and indicator (symbolp indicator)) + (while (and indicator (symbolp indicator) + (boundp indicator) + (not (eq indicator (symbol-value indicator)))) (setq indicator (symbol-value indicator))) - (if first - (princ "The minor modes are described first, -followed by the major mode, which is described on the last page.\n\f\n")) - (setq first nil) + (princ "\n\f\n") (princ (format "%s minor mode (%s):\n" pretty-minor-mode (if indicator (format "indicator%s" indicator) "no indicator"))) - (princ (documentation minor-mode)) - (princ "\n\f\n")))) + (princ (documentation minor-mode))))) (setq minor-modes (cdr minor-modes)))) - (princ mode-name) - (princ " mode:\n") - (princ (documentation major-mode)) - (help-setup-xref (list #'help-xref-mode (current-buffer)) (interactive-p)) (print-help-return-message))) ;; So keyboard macro definitions are documented correctly @@ -430,7 +458,8 @@ With numeric argument display information on correspondingly older changes." (defun view-emacs-FAQ () "Display the Emacs Frequently Asked Questions (FAQ) file." (interactive) - (find-file-read-only (expand-file-name "FAQ" data-directory))) +;;; (find-file-read-only (expand-file-name "FAQ" data-directory)) + (info "(emacs-faq)")) (defun view-lossage () "Display last 100 input keystrokes." @@ -457,7 +486,7 @@ With numeric argument display information on correspondingly older changes." (defalias 'help 'help-for-help) (make-help-screen help-for-help "a b c C f F C-f i I k C-k l L m n p s t v w C-c C-d C-n C-p C-w; ? for help:" - "You have typed \\[help-command], the help character. Type a Help option: + "You have typed %THIS-KEY%, the help character. Type a Help option: \(Use SPC or DEL to scroll through this text. Type \\\\[help-quit] to exit the Help command.) a command-apropos. Give a substring, and see a list of commands @@ -475,17 +504,19 @@ C-f Info-goto-emacs-command-node. Type a function name; i info. The info documentation reader. I describe-input-method. Describe a specific input method (if you type its name) or the current input method (if you type just RET). +C-i info-lookup-symbol. Display the definition of a specific symbol + as found in the manual for the language this buffer is written in. k describe-key. Type a command key sequence; it displays the full documentation. C-k Info-goto-emacs-key-command-node. Type a command key sequence; it takes you to the Info node for the command bound to that key. -l view-lossage. Shows last 100 characters you typed. +l view-lossage. Show last 100 characters you typed. L describe-language-environment. This describes either the a specific language environment (if you type its name) or the current language environment (if you type just RET). m describe-mode. Print documentation of current minor modes, and the current major mode, including their special commands. -n view-emacs-news. Shows emacs news file. +n view-emacs-news. Display news of recent Emacs changes. p finder-by-keyword. Find packages matching a given topic keyword. s describe-syntax. Display contents of syntax table, plus explanations t help-with-tutorial. Select the Emacs learn-by-doing tutorial. @@ -503,14 +534,23 @@ C-p Display information about the GNU project. C-w Display information on absence of warranty for GNU Emacs." help-map) -;; Return a function which is called by the list containing point. -;; If that gives no function, return a function whose name is around point. -;; If that doesn't give a function, return nil. (defun function-called-at-point () + "Return a function around point or else called by the list containing point. +If that doesn't give a function, return nil." (let ((stab (syntax-table))) (set-syntax-table emacs-lisp-mode-syntax-table) (unwind-protect (or (condition-case () + (save-excursion + (or (not (zerop (skip-syntax-backward "_w"))) + (eq (char-syntax (following-char)) ?w) + (eq (char-syntax (following-char)) ?_) + (forward-sexp -1)) + (skip-chars-forward "'") + (let ((obj (read (current-buffer)))) + (and (symbolp obj) (fboundp obj) obj))) + (error nil)) + (condition-case () (save-excursion (save-restriction (narrow-to-region (max (point-min) (- (point) 1000)) (point-max)) @@ -524,20 +564,30 @@ C-w Display information on absence of warranty for GNU Emacs." (let (obj) (setq obj (read (current-buffer))) (and (symbolp obj) (fboundp obj) obj)))) - (error nil)) - (condition-case () - (save-excursion - (or (not (zerop (skip-syntax-backward "_w"))) - (eq (char-syntax (following-char)) ?w) - (eq (char-syntax (following-char)) ?_) - (forward-sexp -1)) - (skip-chars-forward "'") - (let ((obj (read (current-buffer)))) - (and (symbolp obj) (fboundp obj) obj))) (error nil))) (set-syntax-table stab)))) -(defun describe-function-find-file (function) +(defvar symbol-file-load-history-loaded nil + "Non-nil means we have loaded the file `fns-VERSION.el' in `exec-directory'. +That file records the part of `load-history' for preloaded files, +which is cleared out before dumping to make Emacs smaller.") + +(defun symbol-file (function) + "Return the input source from which FUNCTION was loaded. +The value is normally a string that was passed to `load': +either an absolute file name, or a library name +\(with no directory name and no `.el' or `.elc' at the end). +It can also be nil, if the definition is not associated with any file." + (unless symbol-file-load-history-loaded + (load (expand-file-name + ;; fns-XX.YY.ZZ.el does not work on DOS filesystem. + (if (eq system-type 'ms-dos) + "fns.el" + (format "fns-%s.el" emacs-version)) + exec-directory) + ;; The file name fns-%s.el already has a .el extension. + nil nil t) + (setq symbol-file-load-history-loaded t)) (let ((files load-history) file functions) (while files @@ -564,7 +614,7 @@ C-w Display information on absence of warranty for GNU Emacs." ;; Use " is " instead of a colon so that ;; it is easier to get out the function name using forward-sexp. (princ " is ") - (describe-function-1 function nil) + (describe-function-1 function nil (interactive-p)) (print-help-return-message) (save-excursion (set-buffer standard-output) @@ -572,8 +622,10 @@ C-w Display information on absence of warranty for GNU Emacs." (buffer-string))) (message "You didn't specify a function"))) -(defun describe-function-1 (function parens) - (let* ((def (symbol-function function)) +(defun describe-function-1 (function parens interactive-p) + (let* ((def (if (symbolp function) + (symbol-function function) + function)) file-name string need-close (beg (if (commandp def) "an interactive " "a "))) (setq string @@ -585,7 +637,9 @@ C-w Display information on absence of warranty for GNU Emacs." ((byte-code-function-p def) (concat beg "compiled Lisp function")) ((symbolp def) - (format "alias for `%s'" def)) + (while (symbolp (symbol-function def)) + (setq def (symbol-function def))) + (format "an alias for `%s'" def)) ((eq (car-safe def) 'lambda) (concat beg "Lisp function")) ((eq (car-safe def) 'macro) @@ -594,17 +648,35 @@ C-w Display information on absence of warranty for GNU Emacs." "a mocklisp function") ((eq (car-safe def) 'autoload) (setq file-name (nth 1 def)) - (format "%s autoloaded Lisp %s" + (format "%s autoloaded %s" (if (commandp def) "an interactive" "an") - (if (nth 4 def) "macro" "function") + (if (eq (nth 4 def) 'keymap) "keymap" + (if (nth 4 def) "Lisp macro" "Lisp function")) )) + ;; perhaps use keymapp here instead + ((eq (car-safe def) 'keymap) + (let ((is-full nil) + (elts (cdr-safe def))) + (while elts + (if (char-table-p (car-safe elts)) + (setq is-full t + elts nil)) + (setq elts (cdr-safe elts))) + (if is-full + "a full keymap" + "a sparse keymap"))) (t ""))) (when (and parens (not (equal string ""))) (setq need-close t) (princ "(")) (princ string) + (with-current-buffer "*Help*" + (save-excursion + (save-match-data + (if (re-search-backward "alias for `\\([^`']+\\)'" nil t) + (help-xref-button 1 #'describe-function def))))) (or file-name - (setq file-name (describe-function-find-file function))) + (setq file-name (symbol-file function))) (if file-name (progn (princ " in `") @@ -619,23 +691,25 @@ C-w Display information on absence of warranty for GNU Emacs." (help-xref-button 1 #'(lambda (arg) (let ((location (find-function-noselect arg))) - (display-buffer (nth 0 location)) - (goto-char (nth 1 location)))) + (pop-to-buffer (car location)) + (goto-char (cdr location)))) function))))) (if need-close (princ ")")) (princ ".") (terpri) - (let* ((inner-function (if (and (listp def) 'macro) - (cdr def) - def)) - (arglist (cond ((byte-code-function-p inner-function) - (car (append inner-function nil))) - ((eq (car-safe inner-function) 'lambda) - (nth 1 inner-function)) - (t t)))) + ;; Handle symbols aliased to other symbols. + (setq def (indirect-function def)) + ;; If definition is a macro, find the function inside it. + (if (eq (car-safe def) 'macro) + (setq def (cdr def))) + (let ((arglist (cond ((byte-code-function-p def) + (car (append def nil))) + ((eq (car-safe def) 'lambda) + (nth 1 def)) + (t t)))) (if (listp arglist) (progn - (princ (cons function + (princ (cons (if (symbolp function) function "anonymous") (mapcar (lambda (arg) (if (memq arg '(&optional &rest)) arg @@ -646,11 +720,12 @@ C-w Display information on absence of warranty for GNU Emacs." (if doc (progn (terpri) (princ doc) - (help-setup-xref (list #'describe-function function) (interactive-p))) + (help-setup-xref (list #'describe-function function) interactive-p)) (princ "not documented"))))) -;; We return 0 if we can't find a variable to return. (defun variable-at-point () + "Return the bound variable symbol found around point. +Return 0 if there is no such symbol." (condition-case () (let ((stab (syntax-table))) (unwind-protect @@ -723,10 +798,12 @@ Returns the documentation as a string, also." (help-setup-xref (list #'describe-variable variable) (interactive-p)) ;; Make a link to customize if this variable can be customized. - ;; Note, it is not reliable to test for a custom-type property + ;; Note, it is not reliable to test only for a custom-type property ;; because those are only present after the var's definition ;; has been loaded. - (if (user-variable-p variable) + (if (or (get variable 'custom-type) ; after defcustom + (get variable 'custom-loads) ; from loaddefs.el + (get variable 'standard-value)) ; from cus-start.el (let ((customize-label "customize")) (terpri) (terpri) @@ -738,6 +815,23 @@ Returns the documentation as a string, also." (help-xref-button 1 #'(lambda (v) (customize-variable v)) variable) )))) + ;; Make a hyperlink to the library if appropriate. (Don't + ;; change the format of the buffer's initial line in case + ;; anything expects the current format.) + (let ((file-name (symbol-file variable))) + (when file-name + (princ "\n\nDefined in `") + (princ file-name) + (princ "'.") + (with-current-buffer "*Help*" + (save-excursion + (re-search-backward "`\\([^`']+\\)'" nil t) + (help-xref-button 1 (lambda (arg) + (let ((location + (find-variable-noselect arg))) + (pop-to-buffer (car location)) + (goto-char (cdr location)))) + variable))))) (print-help-return-message) (save-excursion @@ -763,7 +857,7 @@ to display (default, the current buffer)." (interactive-p)))) (defun where-is (definition &optional insert) - "Print message listing key sequences that invoke specified command. + "Print message listing key sequences that invoke the command DEFINITION. Argument is a command definition, usually a symbol with a function definition. If INSERT (the prefix arg) is non-nil, insert the message in the buffer." (interactive @@ -797,7 +891,11 @@ Optional second arg NOSUFFIX non-nil means don't add suffixes `.elc' or `.el' to the specified name LIBRARY. If the optional third arg PATH is specified, that list of directories -is used instead of `load-path'." +is used instead of `load-path'. + +When called from a program, the file name is normaly returned as a +string. When run interactively, the argument INTERACTIVE-CALL is t, +and the file name is displayed in the echo area." (interactive (list (read-string "Locate library: ") nil nil t)) @@ -849,8 +947,7 @@ is used instead of `load-path'." (defcustom help-highlight-p t "*If non-nil, `help-make-xrefs' highlight cross-references. Under a window system it highlights them with face defined by -`help-highlight-face'. On a character terminal highlighted -references look like cross-references in info mode." +`help-highlight-face'." :group 'help :version "20.3" :type 'boolean) @@ -877,7 +974,7 @@ The words preceding the quoted symbol can be used in doc strings to distinguish references to variables, functions and symbols.") (defvar help-xref-info-regexp - "\\ (move-to-column col) 0) - (looking-at "\\(\\sw\\|\\s_\\)+$")) - ;; + (and (eolp) (forward-line)) + (end-of-line) + (skip-chars-backward "^\t\n") + (if (and (>= (current-column) col) + (looking-at "\\(\\sw\\|-\\)+$")) (let ((sym (intern-soft (match-string 0)))) (if (fboundp sym) (help-xref-button 0 #'describe-function sym)))) - t) - (zerop (forward-line)) - (move-to-column 0))))))) + (zerop (forward-line))))))))) (set-syntax-table stab)) ;; Make a back-reference in this buffer if appropriate. (when help-xref-stack @@ -1002,17 +1101,19 @@ MATCH-NUMBER is the subexpression of interest in the last matched regexp. FUNCTION is a function to invoke when the button is activated, applied to DATA. DATA may be a single value or a list. See `help-make-xrefs'." - (add-text-properties (match-beginning match-number) - (match-end match-number) - (list 'mouse-face 'highlight - 'help-xref (cons function - (if (listp data) - data - (list data))))) - (if help-highlight-p - (put-text-property (match-beginning match-number) - (match-end match-number) - 'face help-highlight-face))) + ;; Don't mung properties we've added specially in some instances. + (unless (get-text-property (match-beginning match-number) 'help-xref) + (add-text-properties (match-beginning match-number) + (match-end match-number) + (list 'mouse-face 'highlight + 'help-xref (cons function + (if (listp data) + data + (list data))))) + (if help-highlight-p + (put-text-property (match-beginning match-number) + (match-end match-number) + 'face help-highlight-face)))) ;; Additional functions for (re-)creating types of help buffers. @@ -1021,14 +1122,17 @@ See `help-make-xrefs'." Both variable and function documentation are extracted into a single help buffer." - (let ((fdoc (describe-function symbol))) - (describe-variable symbol) - ;; We now have a help buffer on the variable. Insert the function - ;; text after it. - (goto-char (point-max)) - (insert "\n\n" fdoc)) - (goto-char (point-min)) - (help-setup-xref (list #'help-xref-interned symbol) nil)) + (let ((fdoc (when (fboundp symbol) (describe-function symbol)))) + (when (or (boundp symbol) (not fdoc)) + (describe-variable symbol) + ;; We now have a help buffer on the variable. Insert the function + ;; text before it. + (when fdoc + (with-current-buffer "*Help*" + (goto-char (point-min)) + (let ((inhibit-read-only t)) + (insert fdoc "\n\n" (symbol-name symbol) " is also a variable.\n\n")) + (help-setup-xref (list #'help-xref-interned symbol) nil)))))) (defun help-xref-mode (buffer) "Do a `describe-mode' for the specified BUFFER." @@ -1048,8 +1152,7 @@ help buffer." (help-follow pos)))) (defun help-xref-go-back (buffer) - "Go back to the previous help buffer text using info on `help-xref-stack'." - (interactive) + "From BUFFER, go back to previous help buffer text using `help-xref-stack'." (let (item position method args) (with-current-buffer buffer (when help-xref-stack @@ -1063,6 +1166,7 @@ help buffer." (goto-char position))) (defun help-go-back () + "Invoke the [back] button (if any) in the Help mode buffer." (interactive) (help-follow (1- (point-max)))) @@ -1071,16 +1175,29 @@ help buffer." For the cross-reference format, see `help-make-xrefs'." (interactive "d") - (let* ((help-data (or (and (not (= pos (point-max))) - (get-text-property pos 'help-xref)) - (and (not (= pos (point-min))) - (get-text-property (1- pos) 'help-xref)))) + (unless pos + (setq pos (point))) + (let* ((help-data + (or (and (not (= pos (point-max))) + (get-text-property pos 'help-xref)) + (and (not (= pos (point-min))) + (get-text-property (1- pos) 'help-xref)) + ;; check if the symbol under point is a function or variable + (let ((sym + (intern + (save-excursion + (goto-char pos) (skip-syntax-backward "w_") + (buffer-substring (point) + (progn (skip-syntax-forward "w_") + (point))))))) + (when (or (boundp sym) (fboundp sym)) + (list #'help-xref-interned sym))))) (method (car help-data)) (args (cdr help-data))) - (setq help-xref-stack (cons (cons (point) help-xref-stack-item) - help-xref-stack)) - (setq help-xref-stack-item nil) (when help-data + (setq help-xref-stack (cons (cons (point) help-xref-stack-item) + help-xref-stack)) + (setq help-xref-stack-item nil) ;; There is a reference at point. Follow it. (apply method args)))) @@ -1117,4 +1234,73 @@ For the cross-reference format, see `help-make-xrefs'." (t ; be circular (goto-char (point-max))))))) + +;;; Automatic resizing of temporary buffers. + +(defcustom temp-buffer-resize-mode nil + "Non-nil means resize windows displaying temporary buffers. +This makes the window the right height for its contents, but never +more than `temp-buffer-max-height' nor less than `window-min-height'. +This applies to `help', `apropos' and `completion' buffers, and some others. + +Setting this variable directly does not take effect; +use either \\[customize] or the function `temp-buffer-resize-mode'." + :get (lambda (symbol) + (and (memq 'resize-temp-buffer-window temp-buffer-show-hook) t)) + :set (lambda (symbol value) + (temp-buffer-resize-mode (if value 1 -1))) + :initialize 'custom-initialize-default + :type 'boolean + :group 'help + :version "20.4") + +(defcustom temp-buffer-max-height (lambda (buffer) (/ (- (frame-height) 2) 2)) + "*Maximum height of a window displaying a temporary buffer. +This is the maximum height (in text lines) which `resize-temp-buffer-window' +will give to a window displaying a temporary buffer. +It can also be a function which will be called with the object corresponding +to the buffer to be displayed as argument and should return an integer +positive number." + :type '(choice integer function) + :group 'help + :version "20.4") + +(defun temp-buffer-resize-mode (arg) + "Toggle the mode which that makes windows smaller for temporary buffers. +With prefix argument ARG, turn the resizing of windows displaying temporary +buffers on if ARG is positive or off otherwise. +See the documentation of the variable `temp-buffer-resize-mode' for +more information." + (interactive "P") + (let ((turn-it-on + (if (null arg) + (not (memq 'resize-temp-buffer-window temp-buffer-show-hook)) + (> (prefix-numeric-value arg) 0)))) + (if turn-it-on + (progn + ;; `help-mode-maybe' may add a `back' button and thus increase the + ;; text size, so `resize-temp-buffer-window' must be run *after* it. + (add-hook 'temp-buffer-show-hook 'resize-temp-buffer-window 'append) + (setq temp-buffer-resize-mode t)) + (remove-hook 'temp-buffer-show-hook 'resize-temp-buffer-window) + (setq temp-buffer-resize-mode nil)))) + +(defun resize-temp-buffer-window () + "Resize the current window to fit its contents. +Will not make it higher than `temp-buffer-max-height' nor smaller than +`window-min-height'. Do nothing if it is the only window on its frame, if it +is not as wide as the frame or if some of the window's contents are scrolled +out of view." + (unless (or (one-window-p 'nomini) + (not (pos-visible-in-window-p (point-min))) + (/= (frame-width) (window-width))) + (let* ((max-height (if (functionp temp-buffer-max-height) + (funcall temp-buffer-max-height (current-buffer)) + temp-buffer-max-height)) + (win-height (1- (window-height))) + (min-height (1- window-min-height)) + (text-height (window-buffer-height(selected-window))) + (new-height (max (min text-height max-height) min-height))) + (enlarge-window (- new-height win-height))))) + ;;; help.el ends here