diff options
Diffstat (limited to 'lisp/help.el')
-rw-r--r-- | lisp/help.el | 295 |
1 files changed, 194 insertions, 101 deletions
diff --git a/lisp/help.el b/lisp/help.el index 084e941549e..29ae3404813 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -104,8 +104,9 @@ (define-key map "R" 'info-display-manual) (define-key map "s" 'describe-syntax) (define-key map "t" 'help-with-tutorial) - (define-key map "w" 'where-is) (define-key map "v" 'describe-variable) + (define-key map "w" 'where-is) + (define-key map "x" 'describe-command) (define-key map "q" 'help-quit) map) "Keymap for characters following the Help key.") @@ -187,65 +188,124 @@ Do not call this in the scope of `with-help-window'." ;; So keyboard macro definitions are documented correctly (fset 'defining-kbd-macro (symbol-function 'start-kbd-macro)) -(defalias 'help 'help-for-help-internal) -;; find-function can find this. -(defalias 'help-for-help 'help-for-help-internal) -;; It can't find this, but nobody will look. -(make-help-screen help-for-help-internal + +;;; Help for help. (a.k.a. `C-h C-h') + +(defvar help-for-help-buffer-name " *Metahelp*" + "Name of the `help-for-help' buffer.") + +(defface help-for-help-header '((t :height 1.26)) + "Face used for headers in the `help-for-help' buffer." + :group 'help) + +(defun help--for-help-make-commands (commands) + "Create commands for `help-for-help' screen from COMMANDS." + (mapconcat + (lambda (cmd) + (if (listp cmd) + (let ((name (car cmd)) (desc (cadr cmd))) + (concat + " " + (if (string-match (rx string-start "C-" word string-end) name) + ;; `help--key-description-fontified' would convert "C-m" to + ;; "RET" so we can't use it here. + (propertize name 'face 'help-key-binding) + (concat "\\[" name "]")) + " " ; ensure we have some whitespace before the description + (propertize "\t" 'display '(space :align-to 8)) + desc)) + "")) + commands "\n")) + +(defun help--for-help-make-sections (sections) + "Create sections for `help-for-help' screen from SECTIONS." + (mapconcat + (lambda (section) + (let ((title (car section)) (commands (cdr section))) + (concat + "\n\n" + (propertize title 'face 'help-for-help-header) + "\n\n" + (help--for-help-make-commands commands)))) + sections "")) + +(defalias 'help 'help-for-help) +(make-help-screen help-for-help (purecopy "Type a help option: [abcCdefFgiIkKlLmnprstvw.] C-[cdefmnoptw] or ?") - ;; Don't purecopy this one, because it's not evaluated (it's - ;; directly used as a docstring in a function definition, so it'll - ;; be moved to the DOC file anyway: no need for purecopying it). - "You have typed %THIS-KEY%, the help character. Type a Help option: -\(Use SPC or DEL to scroll through this text. Type \\<help-map>\\[help-quit] to exit the Help command.) - -a PATTERN Show commands whose name matches the PATTERN (a list of words - or a regexp). See also the `apropos' command. -b Display all key bindings. -c KEYS Display the command name run by the given key sequence. -C CODING Describe the given coding system, or RET for current ones. -d PATTERN Show a list of functions, variables, and other items whose - documentation matches the PATTERN (a list of words or a regexp). -e Go to the *Messages* buffer which logs echo-area messages. -f FUNCTION Display documentation for the given function. -F COMMAND Show the Emacs manual's section that describes the command. -g Display information about the GNU project. -h Display the HELLO file which illustrates various scripts. -i Start the Info documentation reader: read included manuals. -I METHOD Describe a specific input method, or RET for current. -k KEYS Display the full documentation for the key sequence. -K KEYS Show the Emacs manual's section for the command bound to KEYS. -l Show last 300 input keystrokes (lossage). -L LANG-ENV Describes a specific language environment, or RET for current. -m Display documentation of current minor modes and current major mode, - including their special commands. -n Display news of recent Emacs changes. -o SYMBOL Display the given function or variable's documentation and value. -p TOPIC Find packages matching a given topic keyword. -P PACKAGE Describe the given Emacs Lisp package. -r Display the Emacs manual in Info mode. -R Prompt for a manual and then display it in Info mode. -s Display contents of current syntax table, plus explanations. -S SYMBOL Show the section for the given symbol in the Info manual - for the programming language used in this buffer. -t Start the Emacs learn-by-doing tutorial. -v VARIABLE Display the given variable's documentation and value. -w COMMAND Display which keystrokes invoke the given command (where-is). -. Display any available local help at point in the echo area. - -C-a Information about Emacs. -C-c Emacs copying permission (GNU General Public License). -C-d Instructions for debugging GNU Emacs. -C-e External packages and information about Emacs. -C-f Emacs FAQ. -C-m How to order printed Emacs manuals. -C-n News of recent Emacs changes. -C-o Emacs ordering and distribution information. -C-p Info about known Emacs problems. -C-s Search forward \"help window\". -C-t Emacs TODO list. -C-w Information on absence of warranty for GNU Emacs." - help-map) + (concat + "(Type " + (help--key-description-fontified (kbd "<PageDown>")) + " or " + (help--key-description-fontified (kbd "<PageUp>")) + " to scroll, " + (help--key-description-fontified "\C-s") + " to search, or \\<help-map>\\[help-quit] to exit.)" + (help--for-help-make-sections + `(("Commands, Keys and Functions" + ("describe-mode" + "Show help for current major and minor modes and their commands") + ("describe-bindings" "Show all key bindings") + ("describe-key" "Show help for key") + ("describe-key-briefly" "Show help for key briefly") + ("where-is" "Show which key runs a specific command") + "" + ("apropos-command" + "Search for commands (see also \\[apropos])") + ("apropos-documentation" + "Search documentation of functions, variables, and other items") + ("describe-command" "Show help for command") + ("describe-function" "Show help for function") + ("describe-variable" "Show help for variable") + ("describe-symbol" "Show help for function or variable")) + ("Manuals" + ("info-emacs-manual" "Show Emacs manual") + ("Info-goto-emacs-command-node" + "Show Emacs manual section for command") + ("Info-goto-emacs-key-command-node" + "Show Emacs manual section for a key sequence") + ("info" "Show all installed manuals") + ("info-display-manual" "Show a specific manual") + ("info-lookup-symbol" "Show description of symbol in pertinent manual")) + ("Other Help Commands" + ("view-external-packages" + "Extending Emacs with external packages") + ("finder-by-keyword" + "Search for Emacs packages (see also \\[list-packages])") + ("describe-package" "Describe a specific Emacs package") + "" + ("help-with-tutorial" "Start the Emacs tutorial") + ("view-echo-area-messages" + "Show recent messages (from echo area)") + ("view-lossage" ,(format "Show last %d input keystrokes (lossage)" + (lossage-size))) + ("display-local-help" "Show local help at point")) + ("Miscellaneous" + ("about-emacs" "About Emacs") + ("view-emacs-FAQ" "Emacs FAQ") + ("C-n" "News of recent changes") + ("view-emacs-problems" "Known problems") + ("view-emacs-debugging" "Debugging Emacs") + "" + ("describe-gnu-project" "About the GNU project") + ("describe-copying" + "Emacs copying permission (GNU General Public License)") + ("describe-distribution" + "Emacs ordering and distribution information") + ("C-m" "Order printed manuals") + ("view-emacs-todo" "Emacs TODO") + ("describe-no-warranty" + "Information on absence of warranty")) + ("Internationalization and Coding Systems" + ("describe-input-method" "Describe input method") + ("describe-coding-system" "Describe coding system") + ("describe-language-environment" + "Describe language environment") + ("describe-syntax" "Show current syntax table") + ("view-hello-file" + "Display the HELLO file illustrating various scripts")))) + "\n") + help-map + help-for-help-buffer-name) @@ -492,6 +552,21 @@ To record all your input, use `open-dribble-file'." ;; Key bindings +(defun help--key-description-fontified (keys &optional prefix) + "Like `key-description' but add face for \"*Help*\" buffers." + ;; We add both the `font-lock-face' and `face' properties here, as this + ;; seems to be the only way to get this to work reliably in any + ;; buffer. + (propertize (key-description keys prefix) + 'font-lock-face 'help-key-binding + 'face 'help-key-binding)) + +(defcustom describe-bindings-outline nil + "Non-nil enables outlines in the output buffer of `describe-bindings'." + :type 'boolean + :group 'help + :version "28.1") + (defun describe-bindings (&optional prefix buffer) "Display a buffer showing a list of all defined keys, and their definitions. The keys are displayed in order of precedence. @@ -509,24 +584,26 @@ or a buffer name." ;; Be aware that `describe-buffer-bindings' puts its output into ;; the current buffer. (with-current-buffer (help-buffer) - (describe-buffer-bindings buffer prefix)))) - -;; This function used to be in keymap.c. -(defun describe-bindings-internal (&optional menus prefix) - "Show a list of all defined keys, and their definitions. -We put that list in a buffer, and display the buffer. - -The optional argument MENUS, if non-nil, says to mention menu bindings. -\(Ordinarily these are omitted from the output.) -The optional argument PREFIX, if non-nil, should be a key sequence; -then we display only bindings that start with that prefix." - (declare (obsolete describe-buffer-bindings "24.4")) - (let ((buf (current-buffer))) - (with-help-window (help-buffer) - ;; Be aware that `describe-buffer-bindings' puts its output into - ;; the current buffer. - (with-current-buffer (help-buffer) - (describe-buffer-bindings buf prefix menus))))) + (describe-buffer-bindings buffer prefix) + + (when describe-bindings-outline + (setq-local outline-regexp ".*:$") + (setq-local outline-heading-end-regexp ":\n") + (setq-local outline-level (lambda () 1)) + (setq-local outline-minor-mode-cycle t + outline-minor-mode-highlight t) + (outline-minor-mode 1) + (save-excursion + (let ((inhibit-read-only t)) + (goto-char (point-min)) + (insert (substitute-command-keys + (concat "\\<outline-mode-cycle-map>Type " + "\\[outline-cycle] or \\[outline-cycle-buffer] " + "on headings to cycle their visibility.\n\n"))) + ;; Hide the longest body + (when (and (re-search-forward "Key translations" nil t) + (fboundp 'outline-cycle)) + (outline-cycle)))))))) (defun where-is (definition &optional insert) "Print message listing key sequences that invoke the command DEFINITION. @@ -559,7 +636,8 @@ If INSERT (the prefix arg) is non-nil, insert the message in the buffer." (let* ((remapped (command-remapping symbol)) (keys (where-is-internal symbol overriding-local-map nil nil remapped)) - (keys (mapconcat 'key-description keys ", ")) + (keys (mapconcat #'help--key-description-fontified + keys ", ")) string) (setq string (if insert @@ -587,11 +665,11 @@ If INSERT (the prefix arg) is non-nil, insert the message in the buffer." nil) (defun help-key-description (key untranslated) - (let ((string (key-description key))) + (let ((string (help--key-description-fontified key))) (if (or (not untranslated) (and (eq (aref untranslated 0) ?\e) (not (eq (aref key 0) ?\e)))) string - (let ((otherstring (key-description untranslated))) + (let ((otherstring (help--key-description-fontified untranslated))) (if (equal string otherstring) string (format "%s (translated from %s)" string otherstring)))))) @@ -865,12 +943,7 @@ current buffer." (when defn (when (> (length info-list) 1) (with-current-buffer standard-output - (insert "\n\n" - ;; FIXME: Can't use eval-when-compile because purified - ;; strings lose their text properties :-( - (propertize "\n" 'face - '(:height 0.1 :inverse-video t :extend t)) - "\n"))) + (insert "\n\n" (make-separator-line) "\n"))) (princ brief-desc) (when locus @@ -882,7 +955,7 @@ current buffer." "Search forward \"help window\"." (interactive) ;; Move cursor to the "help window". - (pop-to-buffer " *Metahelp*") + (pop-to-buffer help-for-help-buffer-name) ;; Do incremental search forward. (isearch-forward nil t)) @@ -979,7 +1052,7 @@ is currently activated with completion." "Substitute key descriptions for command names in STRING. Each substring of the form \\\\=[COMMAND] is replaced by either a keystroke sequence that invokes COMMAND, or \"M-x COMMAND\" if COMMAND -is not on any keys. +is not on any keys. Keybindings will use the face `help-key-binding'. Each substring of the form \\\\={MAPVAR} is replaced by a summary of the value of MAPVAR as a keymap. This summary is similar to the one @@ -999,7 +1072,7 @@ into the output, \\\\==\\[ puts \\[ into the output, and \\\\==\\=` puts \\=` in output. Return the original STRING if no substitutions are made. -Otherwise, return a new string (without any text properties)." +Otherwise, return a new string." (when (not (null string)) ;; KEYMAP is either nil (which means search all the active ;; keymaps) or a specified local map (which means search just that @@ -1053,12 +1126,16 @@ Otherwise, return a new string (without any text properties)." (where-is-internal fun keymap t)))) (if (not key) ;; Function is not on any key. - (progn (insert "M-x ") - (goto-char (+ end-point 3)) - (delete-char 1)) + (let ((op (point))) + (insert "M-x ") + (goto-char (+ end-point 3)) + (add-text-properties op (point) + '( face help-key-binding + font-lock-face help-key-binding)) + (delete-char 1)) ;; Function is on a key. (delete-char (- end-point (point))) - (insert (key-description key))))) + (insert (help--key-description-fontified key))))) ;; 1D. \{foo} is replaced with a summary of the keymap ;; (symbol-value foo). ;; \<foo> just sets the keymap used for \[cmd]. @@ -1172,7 +1249,7 @@ Any inserted text ends in two newlines (used by (concat title (if prefix (concat " Starting With " - (key-description prefix))) + (help--key-description-fontified prefix))) ":\n")) "key binding\n" "--- -------\n"))) @@ -1228,7 +1305,11 @@ Return nil if the key sequence is too long." (= help--previous-description-column 32))) 32) (t 16)))) - (indent-to description-column 1) + ;; Avoid using the `help-keymap' face. + (let ((op (point))) + (indent-to description-column 1) + (set-text-properties op (point) '( face nil + font-lock-face nil))) (setq help--previous-description-column description-column) (cond ((symbolp definition) (insert (symbol-name definition) "\n")) @@ -1240,7 +1321,11 @@ Return nil if the key sequence is too long." (defun help--describe-translation (definition) ;; Converted from describe_translation in keymap.c. - (indent-to 16 1) + ;; Avoid using the `help-keymap' face. + (let ((op (point))) + (indent-to 16 1) + (set-text-properties op (point) '( face nil + font-lock-face nil))) (cond ((symbolp definition) (insert (symbol-name definition) "\n")) ((or (stringp definition) (vectorp definition)) @@ -1351,9 +1436,9 @@ TRANSL, PARTIAL, SHADOW, NOMENU, MENTION-SHADOW are as in (setq end (caar vect)))) ;; Now START .. END is the range to describe next. ;; Insert the string to describe the event START. - (insert (key-description (vector start) prefix)) + (insert (help--key-description-fontified (vector start) prefix)) (when (not (eq start end)) - (insert " .. " (key-description (vector end) prefix))) + (insert " .. " (help--key-description-fontified (vector end) prefix))) ;; Print a description of the definition of this character. ;; Called function will take care of spacing out far enough ;; for alignment purposes. @@ -1420,7 +1505,7 @@ TRANSL, PARTIAL, SHADOW, NOMENU, MENTION-SHADOW are as in ;; (setq first nil)) ;; (when (and prefix (> (length prefix) 0)) ;; (insert (format "%s" prefix))) -;; (insert (key-description (vector start-idx) prefix)) +;; (insert (help--key-description-fontified (vector start-idx) prefix)) ;; ;; Find all consecutive characters or rows that have the ;; ;; same definition. ;; (while (equal (keymap--get-keyelt (aref vector (1+ idx)) nil) @@ -1433,7 +1518,7 @@ TRANSL, PARTIAL, SHADOW, NOMENU, MENTION-SHADOW are as in ;; (insert " .. ") ;; (when (and prefix (> (length prefix) 0)) ;; (insert (format "%s" prefix))) -;; (insert (key-description (vector idx) prefix))) +;; (insert (help--key-description-fontified (vector idx) prefix))) ;; (if transl ;; (help--describe-translation definition) ;; (help--describe-command definition)) @@ -1792,6 +1877,8 @@ ARGLIST can also be t or a string of the form \"(FUN ARG1 ARG2 ...)\"." (error "Unrecognized usage format")) (help--make-usage-docstring 'fn arglist))))) +(declare-function subr-native-lambda-list "data.c") + (defun help-function-arglist (def &optional preserve-names) "Return a formal argument list for the function DEF. If PRESERVE-NAMES is non-nil, return a formal arglist that uses @@ -1807,6 +1894,10 @@ the same names as used in the original source code, when possible." ((and (byte-code-function-p def) (listp (aref def 0))) (aref def 0)) ((eq (car-safe def) 'lambda) (nth 1 def)) ((eq (car-safe def) 'closure) (nth 2 def)) + ((and (featurep 'native-compile) + (subrp def) + (listp (subr-native-lambda-list def))) + (subr-native-lambda-list def)) ((or (and (byte-code-function-p def) (integerp (aref def 0))) (subrp def) (module-function-p def)) (or (when preserve-names @@ -1821,7 +1912,7 @@ the same names as used in the original source code, when possible." (let ((name (symbol-name arg))) (if (eq (aref name 0) ?&) (memq arg '(&rest &optional)) - (not (string-match "\\." name))))) + (not (string-search "." name))))) (setq valid nil))) (when valid arglist))) (let* ((arity (func-arity def)) @@ -1924,6 +2015,8 @@ the suggested string to use instead. See (add-function :after command-error-function #'help-command-error-confusable-suggestions) +(define-obsolete-function-alias 'help-for-help-internal #'help-for-help "28.1") + (provide 'help) |