summaryrefslogtreecommitdiff
path: root/lisp/help.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/help.el')
-rw-r--r--lisp/help.el295
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)