X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/6016b6e4dc30a334ab130f21f5400d178ce863d3..73ea6d945d4af5352122e3a1470c4533187e9dcc:/lisp/help.el diff --git a/lisp/help.el b/lisp/help.el index 833239825e..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'. @@ -216,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." @@ -236,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)) @@ -317,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*" @@ -327,7 +347,7 @@ 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 () @@ -438,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." @@ -483,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. @@ -591,7 +614,7 @@ It can also be nil, if the definition is not associated with any file." ;; 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) @@ -599,7 +622,7 @@ It can also be nil, if the definition is not associated with any file." (buffer-string))) (message "You didn't specify a function"))) -(defun describe-function-1 (function parens) +(defun describe-function-1 (function parens interactive-p) (let* ((def (if (symbolp function) (symbol-function function) function)) @@ -630,6 +653,18 @@ It can also be nil, if the definition is not associated with any file." (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) @@ -674,7 +709,7 @@ It can also be nil, if the definition is not associated with any file." (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 @@ -685,7 +720,7 @@ It can also be nil, if the definition is not associated with any file." (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"))))) (defun variable-at-point () @@ -766,7 +801,9 @@ Returns the documentation as a string, also." ;; 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 (or (user-variable-p variable) (get variable 'custom-type)) + (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) @@ -910,8 +947,7 @@ and the file name is displayed in the echo area." (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) @@ -938,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\\|-\\)+$")) - ;; + (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) - (progn - (end-of-line) - (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 @@ -1092,15 +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)) - (let ((inhibit-read-only t)) - (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." @@ -1143,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)))) @@ -1198,7 +1243,8 @@ 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. -This variable must be modified via \\[customize] in order to have an effect." +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)