*** empty log message ***
[bpt/emacs.git] / lisp / help.el
CommitLineData
1a06eabd
ER
1;;; help.el --- help commands for Emacs
2
598ea453 3;; Copyright (C) 1985, 1986, 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2004
754084bb 4;; Free Software Foundation, Inc.
3a801d0c 5
e5167999 6;; Maintainer: FSF
fd7fa35a 7;; Keywords: help, internal
e5167999 8
433ae6f6
RS
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
e5167999 13;; the Free Software Foundation; either version 2, or (at your option)
433ae6f6
RS
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
b578f267
EN
22;; along with GNU Emacs; see the file COPYING. If not, write to the
23;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24;; Boston, MA 02111-1307, USA.
433ae6f6 25
d9ecc911
ER
26;;; Commentary:
27
a1c9f209 28;; This code implements GNU Emacs' on-line help system, the one invoked by
95ac0a6f 29;; `M-x help-for-help'.
d9ecc911 30
e5167999
ER
31;;; Code:
32
8aa3a187
RS
33;; Get the macro make-help-screen when this is compiled,
34;; or run interpreted, but not when the compiled code is loaded.
b1fe9304 35(eval-when-compile (require 'help-macro))
788d62cf
MB
36
37;; This makes `with-output-to-temp-buffer' buffers use `help-mode'.
38(add-hook 'temp-buffer-setup-hook 'help-mode-setup)
39(add-hook 'temp-buffer-show-hook 'help-mode-finish)
41b8542b 40
433ae6f6
RS
41(defvar help-map (make-sparse-keymap)
42 "Keymap for characters following the Help key.")
43
e17d2fd1 44(define-key global-map (char-to-string help-char) 'help-command)
0af3df1c
RS
45(define-key global-map [help] 'help-command)
46(define-key global-map [f1] 'help-command)
433ae6f6
RS
47(fset 'help-command help-map)
48
e17d2fd1 49(define-key help-map (char-to-string help-char) 'help-for-help)
0af3df1c
RS
50(define-key help-map [help] 'help-for-help)
51(define-key help-map [f1] 'help-for-help)
7ada28ac 52(define-key help-map "." 'display-local-help)
433ae6f6
RS
53(define-key help-map "?" 'help-for-help)
54
55(define-key help-map "\C-c" 'describe-copying)
56(define-key help-map "\C-d" 'describe-distribution)
4f16ea85
RS
57(define-key help-map "\C-e" 'view-emacs-problems)
58(define-key help-map "\C-f" 'view-emacs-FAQ)
4f16ea85
RS
59(define-key help-map "\C-m" 'view-order-manuals)
60(define-key help-map "\C-n" 'view-emacs-news)
76766f2d 61(define-key help-map "\C-p" 'describe-project)
1ebc1f01 62(define-key help-map "\C-t" 'view-todo)
4f16ea85
RS
63(define-key help-map "\C-w" 'describe-no-warranty)
64
65;; This does not fit the pattern, but it is natural given the C-\ command.
66(define-key help-map "\C-\\" 'describe-input-method)
67
68(define-key help-map "C" 'describe-coding-system)
69(define-key help-map "F" 'Info-goto-emacs-command-node)
70(define-key help-map "I" 'describe-input-method)
71(define-key help-map "K" 'Info-goto-emacs-key-command-node)
72(define-key help-map "L" 'describe-language-environment)
73(define-key help-map "S" 'info-lookup-symbol)
74
122955bf 75(define-key help-map "a" 'apropos-command)
433ae6f6
RS
76
77(define-key help-map "b" 'describe-bindings)
78
79(define-key help-map "c" 'describe-key-briefly)
433ae6f6 80
4f16ea85
RS
81(define-key help-map "e" 'view-echo-area-messages)
82
433ae6f6
RS
83(define-key help-map "f" 'describe-function)
84
4f16ea85 85(define-key help-map "h" 'view-hello-file)
7ee71cf1 86
433ae6f6 87(define-key help-map "i" 'info)
4b08b7ed 88(define-key help-map "4i" 'info-other-window)
4f16ea85
RS
89
90(define-key help-map "k" 'describe-key)
433ae6f6
RS
91
92(define-key help-map "l" 'view-lossage)
93
94(define-key help-map "m" 'describe-mode)
95
433ae6f6
RS
96(define-key help-map "n" 'view-emacs-news)
97
06b98c51 98(define-key help-map "p" 'finder-by-keyword)
3e9c095d
RS
99(autoload 'finder-by-keyword "finder"
100 "Find packages matching a given keyword." t)
06b98c51 101
d009b6e9
RS
102(define-key help-map "r" 'info-emacs-manual)
103
433ae6f6
RS
104(define-key help-map "s" 'describe-syntax)
105
106(define-key help-map "t" 'help-with-tutorial)
107
108(define-key help-map "w" 'where-is)
109
110(define-key help-map "v" 'describe-variable)
111
2fc9d9f4
RS
112(define-key help-map "q" 'help-quit)
113
e25e90b4
DP
114;; insert-button makes the action nil if it is not store somewhere
115(defvar help-button-cache nil)
116
0cf0d828 117\f
2fc9d9f4 118(defun help-quit ()
3120a677 119 "Just exit from the Help command's command loop."
2fc9d9f4
RS
120 (interactive)
121 nil)
122
01364a75
RS
123(defvar help-return-method nil
124 "What to do to \"exit\" the help buffer.
125This is a list
126 (WINDOW . t) delete the selected window, go to WINDOW.
127 (WINDOW . quit-window) do quit-window, then select WINDOW.
128 (WINDOW BUF START POINT) display BUF at START, POINT, then select WINDOW.")
129
433ae6f6
RS
130(defun print-help-return-message (&optional function)
131 "Display or return message saying how to restore windows after help command.
d009b6e9
RS
132This function assumes that `standard-output' is the help buffer.
133It computes a message, and applies the optional argument FUNCTION to it.
134If FUNCTION is nil, it applies `message', thus displaying the message."
433ae6f6 135 (and (not (get-buffer-window standard-output))
d536293f 136 (let ((first-message
a1c9f209 137 (cond ((special-display-p (buffer-name standard-output))
01364a75 138 (setq help-return-method (cons (selected-window) t))
d536293f
RS
139 ;; If the help output buffer is a special display buffer,
140 ;; don't say anything about how to get rid of it.
141 ;; First of all, the user will do that with the window
142 ;; manager, not with Emacs.
143 ;; Secondly, the buffer has not been displayed yet,
144 ;; so we don't know whether its frame will be selected.
d536293f 145 nil)
f3ad2fc8
GM
146 (display-buffer-reuse-frames
147 (setq help-return-method (cons (selected-window)
148 'quit-window))
149 nil)
d536293f 150 ((not (one-window-p t))
01364a75
RS
151 (setq help-return-method
152 (cons (selected-window) 'quit-window))
d536293f
RS
153 "Type \\[switch-to-buffer-other-window] RET to restore the other window.")
154 (pop-up-windows
01364a75 155 (setq help-return-method (cons (selected-window) t))
d536293f
RS
156 "Type \\[delete-other-windows] to remove help window.")
157 (t
01364a75
RS
158 (setq help-return-method
159 (list (selected-window) (window-buffer)
160 (window-start) (window-point)))
d536293f
RS
161 "Type \\[switch-to-buffer] RET to remove help window."))))
162 (funcall (or function 'message)
163 (concat
164 (if first-message
376b2a24
DL
165 (substitute-command-keys first-message))
166 (if first-message " ")
125a8d70
RS
167 ;; If the help buffer will go in a separate frame,
168 ;; it's no use mentioning a command to scroll, so don't.
a1c9f209 169 (if (special-display-p (buffer-name standard-output))
125a8d70 170 nil
a1c9f209 171 (if (same-window-p (buffer-name standard-output))
125a8d70
RS
172 ;; Say how to scroll this window.
173 (substitute-command-keys
174 "\\[scroll-up] to scroll the help.")
175 ;; Say how to scroll some other window.
6e7f5182 176 (substitute-command-keys
125a8d70 177 "\\[scroll-other-window] to scroll the help."))))))))
433ae6f6 178
433ae6f6
RS
179;; So keyboard macro definitions are documented correctly
180(fset 'defining-kbd-macro (symbol-function 'start-kbd-macro))
181
788d62cf
MB
182(defalias 'help 'help-for-help)
183(make-help-screen help-for-help
7ada28ac 184 "a b c C e f F i I k C-k l L m p s t v w C-c C-d C-f C-n C-p C-t C-w . or ? :"
788d62cf
MB
185 "You have typed %THIS-KEY%, the help character. Type a Help option:
186\(Use SPC or DEL to scroll through this text. Type \\<help-map>\\[help-quit] to exit the Help command.)
187
188a command-apropos. Give a substring, and see a list of commands
189 (functions interactively callable) that contain
190 that substring. See also the apropos command.
191b describe-bindings. Display table of all key bindings.
192c describe-key-briefly. Type a command key sequence;
193 it prints the function name that sequence runs.
194C describe-coding-system. This describes either a specific coding system
195 (if you type its name) or the coding systems currently in use
196 (if you type just RET).
4f16ea85 197e view-echo-area-messages. Show the `*Messages*' buffer.
788d62cf 198f describe-function. Type a function name and get documentation of it.
4f16ea85 199F Info-goto-emacs-command-node. Type a function name;
788d62cf 200 it takes you to the Info node for that command.
54391990 201h Display the HELLO file which illustrates various scripts.
788d62cf
MB
202i info. The info documentation reader.
203I describe-input-method. Describe a specific input method (if you type
204 its name) or the current input method (if you type just RET).
788d62cf
MB
205k describe-key. Type a command key sequence;
206 it displays the full documentation.
4f16ea85 207K Info-goto-emacs-key-command-node. Type a command key sequence;
788d62cf
MB
208 it takes you to the Info node for the command bound to that key.
209l view-lossage. Show last 100 characters you typed.
210L describe-language-environment. This describes either a
211 specific language environment (if you type its name)
212 or the current language environment (if you type just RET).
213m describe-mode. Print documentation of current minor modes,
214 and the current major mode, including their special commands.
788d62cf
MB
215p finder-by-keyword. Find packages matching a given topic keyword.
216s describe-syntax. Display contents of syntax table, plus explanations.
4f16ea85
RS
217S info-lookup-symbol. Display the definition of a specific symbol
218 as found in the manual for the language this buffer is written in.
788d62cf
MB
219t help-with-tutorial. Select the Emacs learn-by-doing tutorial.
220v describe-variable. Type name of a variable;
221 it displays the variable's documentation and value.
222w where-is. Type command name; it prints which keystrokes
223 invoke that command.
7ada28ac
LT
224. display-local-help. Display any available local help at point
225 in the echo area.
788d62cf 226
4f16ea85 227C-c Display Emacs copying permission (GNU General Public License).
788d62cf 228C-d Display Emacs ordering information.
4f16ea85
RS
229C-e Display info about Emacs problems.
230C-f Display the Emacs FAQ.
4f16ea85 231C-m Display how to order printed Emacs manuals.
788d62cf
MB
232C-n Display news of recent Emacs changes.
233C-p Display information about the GNU project.
1ebc1f01 234C-t Display the Emacs TODO list.
788d62cf
MB
235C-w Display information on absence of warranty for GNU Emacs."
236 help-map)
237
238\f
239
240(defun function-called-at-point ()
241 "Return a function around point or else called by the list containing point.
242If that doesn't give a function, return nil."
542e904c
JL
243 (or (with-syntax-table emacs-lisp-mode-syntax-table
244 (or (condition-case ()
245 (save-excursion
246 (or (not (zerop (skip-syntax-backward "_w")))
247 (eq (char-syntax (following-char)) ?w)
248 (eq (char-syntax (following-char)) ?_)
249 (forward-sexp -1))
250 (skip-chars-forward "'")
251 (let ((obj (read (current-buffer))))
252 (and (symbolp obj) (fboundp obj) obj)))
253 (error nil))
254 (condition-case ()
255 (save-excursion
256 (save-restriction
257 (narrow-to-region (max (point-min)
258 (- (point) 1000)) (point-max))
259 ;; Move up to surrounding paren, then after the open.
260 (backward-up-list 1)
261 (forward-char 1)
262 ;; If there is space here, this is probably something
263 ;; other than a real Lisp function call, so ignore it.
264 (if (looking-at "[ \t]")
265 (error "Probably not a Lisp function call"))
266 (let ((obj (read (current-buffer))))
267 (and (symbolp obj) (fboundp obj) obj))))
268 (error nil))))
269 (let* ((str (find-tag-default))
918f2e56
JL
270 (sym (if str (intern-soft str))))
271 (if (and sym (fboundp sym))
272 sym
273 (save-match-data
274 (when (and str (string-match "\\`\\W*\\(.*?\\)\\W*\\'" str))
275 (setq sym (intern-soft (match-string 1 str)))
276 (and (fboundp sym) sym)))))))
788d62cf
MB
277
278\f
279;;; `User' help functions
280
433ae6f6
RS
281(defun describe-distribution ()
282 "Display info on how to obtain the latest version of GNU Emacs."
283 (interactive)
9e0e631c 284 (view-file (expand-file-name "DISTRIB" data-directory)))
433ae6f6
RS
285
286(defun describe-copying ()
287 "Display info on how you may redistribute copies of GNU Emacs."
288 (interactive)
64f3b7d3 289 (view-file (expand-file-name "COPYING" data-directory))
433ae6f6
RS
290 (goto-char (point-min)))
291
76766f2d
RS
292(defun describe-project ()
293 "Display info on the GNU project."
294 (interactive)
64f3b7d3 295 (view-file (expand-file-name "THE-GNU-PROJECT" data-directory))
76766f2d
RS
296 (goto-char (point-min)))
297
433ae6f6
RS
298(defun describe-no-warranty ()
299 "Display info on all the kinds of warranty Emacs does NOT have."
300 (interactive)
301 (describe-copying)
302 (let (case-fold-search)
303 (search-forward "NO WARRANTY")
304 (recenter 0)))
305
61c6b658 306(defun describe-prefix-bindings ()
c7cba9cb
RS
307 "Describe the bindings of the prefix used to reach this command.
308The prefix described consists of all but the last event
309of the key sequence that ran this command."
61c6b658 310 (interactive)
ccc06dcc
KH
311 (let* ((key (this-command-keys)))
312 (describe-bindings
313 (if (stringp key)
314 (substring key 0 (1- (length key)))
315 (let ((prefix (make-vector (1- (length key)) nil))
316 (i 0))
317 (while (< i (length prefix))
318 (aset prefix i (aref key i))
319 (setq i (1+ i)))
320 prefix)))))
788d62cf 321;; Make C-h after a prefix, when not specifically bound,
c7cba9cb 322;; run describe-prefix-bindings.
61c6b658
RS
323(setq prefix-help-command 'describe-prefix-bindings)
324
382d018a
RS
325(defun view-emacs-news (&optional arg)
326 "Display info on recent changes to Emacs.
598ea453 327With argument, display info only for the selected version."
382d018a 328 (interactive "P")
598ea453
JL
329 (if (not arg)
330 (view-file (expand-file-name "NEWS" data-directory))
331 (let* ((map (sort
332 (delete-dups
333 (apply
334 'nconc
335 (mapcar
336 (lambda (file)
337 (with-temp-buffer
338 (insert-file-contents
339 (expand-file-name file data-directory))
340 (let (res)
341 (while (re-search-forward
342 (if (string-match "^ONEWS\\.[0-9]+$" file)
343 "Changes in \\(?:Emacs\\|version\\)?[ \t]*\\([0-9]+\\(?:\\.[0-9]+\\)?\\)"
344 "^\* [^0-9\n]*\\([0-9]+\\.[0-9]+\\)") nil t)
345 (setq res (cons (list (match-string-no-properties 1)
346 file) res)))
347 res)))
348 (append '("NEWS" "ONEWS")
349 (directory-files data-directory nil
350 "^ONEWS\\.[0-9]+$" nil)))))
351 (lambda (a b)
352 (string< (car b) (car a)))))
353 (current (caar map))
354 (version (completing-read
355 (format "Read NEWS for the version (default %s): " current)
356 (mapcar 'car map) nil nil nil nil current))
357 (file (cadr (assoc version map)))
358 res)
359 (if (not file)
360 (error "No news is good news")
361 (view-file (expand-file-name file data-directory))
362 (widen)
363 (goto-char (point-min))
364 (when (re-search-forward
365 (concat (if (string-match "^ONEWS\\.[0-9]+$" file)
366 "Changes in \\(?:Emacs\\|version\\)?[ \t]*"
367 "^\* [^0-9\n]*") version)
368 nil t)
369 (beginning-of-line)
370 (narrow-to-region
371 (point)
372 (save-excursion
373 (while (and (setq res
374 (re-search-forward
375 (if (string-match "^ONEWS\\.[0-9]+$" file)
376 "Changes in \\(?:Emacs\\|version\\)?[ \t]*\\([0-9]+\\(?:\\.[0-9]+\\)?\\)"
377 "^\* [^0-9\n]*\\([0-9]+\\.[0-9]+\\)") nil t))
378 (equal (match-string-no-properties 1) version)))
379 (or res (goto-char (point-max)))
380 (beginning-of-line)
381 (point))))))))
433ae6f6 382
1ebc1f01
RS
383(defun view-todo (&optional arg)
384 "Display the Emacs TODO list."
385 (interactive "P")
386 (view-file (expand-file-name "TODO" data-directory)))
387
4f16ea85
RS
388(defun view-echo-area-messages ()
389 "View the log of recent echo-area messages: the `*Messages*' buffer.
390The number of messages retained in that buffer
391is specified by the variable `message-log-max'."
392 (interactive)
393 (switch-to-buffer (get-buffer-create "*Messages*")))
394
754084bb
GM
395(defun view-order-manuals ()
396 "Display the Emacs ORDERS file."
397 (interactive)
64f3b7d3 398 (view-file (expand-file-name "ORDERS" data-directory))
38790755 399 (goto-address))
754084bb 400
7ee71cf1
RS
401(defun view-emacs-FAQ ()
402 "Display the Emacs Frequently Asked Questions (FAQ) file."
403 (interactive)
94ea540b 404 ;; (find-file-read-only (expand-file-name "FAQ" data-directory))
279b772d 405 (info "(efaq)"))
7ee71cf1 406
4cbff657
DL
407(defun view-emacs-problems ()
408 "Display info on known problems with Emacs and possible workarounds."
409 (interactive)
410 (view-file (expand-file-name "PROBLEMS" data-directory)))
411
433ae6f6 412(defun view-lossage ()
50b57199
EZ
413 "Display last 100 input keystrokes.
414
415To record all your input on a file, use `open-dribble-file'."
433ae6f6 416 (interactive)
3e5929af
SM
417 (help-setup-xref (list #'view-lossage) (interactive-p))
418 (with-output-to-temp-buffer (help-buffer)
02dfca16
SM
419 (princ (mapconcat (lambda (key)
420 (if (or (integerp key) (symbolp key) (listp key))
421 (single-key-description key)
422 (prin1-to-string key nil)))
298a7c8c
RS
423 (recent-keys)
424 " "))
b0fbf754 425 (with-current-buffer standard-output
433ae6f6
RS
426 (goto-char (point-min))
427 (while (progn (move-to-column 50) (not (eobp)))
428 (search-forward " " nil t)
3e5929af 429 (insert "\n")))
433ae6f6
RS
430 (print-help-return-message)))
431
788d62cf
MB
432\f
433;; Key bindings
433ae6f6 434
4c45295b 435(defun describe-bindings (&optional prefix buffer)
a8ad43aa
RS
436 "Show a list of all defined keys, and their definitions.
437We put that list in a buffer, and display the buffer.
438
439The optional argument PREFIX, if non-nil, should be a key sequence;
4c45295b
KH
440then we display only bindings that start with that prefix.
441The optional argument BUFFER specifies which buffer's bindings
abca4ad7
LT
442to display (default, the current buffer). BUFFER can be a buffer
443or a buffer name."
3e5929af 444 (interactive)
4c45295b 445 (or buffer (setq buffer (current-buffer)))
3e5929af 446 (help-setup-xref (list #'describe-bindings prefix buffer) (interactive-p))
4c45295b 447 (with-current-buffer buffer
3e5929af 448 (describe-bindings-internal nil prefix)))
a8ad43aa 449
94ea540b
SM
450;; This function used to be in keymap.c.
451(defun describe-bindings-internal (&optional menus prefix)
452 "Show a list of all defined keys, and their definitions.
453We put that list in a buffer, and display the buffer.
454
455The optional argument MENUS, if non-nil, says to mention menu bindings.
456\(Ordinarily these are omitted from the output.)
457The optional argument PREFIX, if non-nil, should be a key sequence;
458then we display only bindings that start with that prefix."
459 (interactive)
460 (let ((buf (current-buffer)))
461 (with-output-to-temp-buffer "*Help*"
462 (with-current-buffer standard-output
463 (describe-buffer-bindings buf prefix menus)))))
464
e88a2c59 465(defun where-is (definition &optional insert)
b2c85790 466 "Print message listing key sequences that invoke the command DEFINITION.
e88a2c59
RS
467Argument is a command definition, usually a symbol with a function definition.
468If INSERT (the prefix arg) is non-nil, insert the message in the buffer."
54c0b967
RS
469 (interactive
470 (let ((fn (function-called-at-point))
788d62cf 471 (enable-recursive-minibuffers t)
54c0b967 472 val)
3829bcc5
SM
473 (setq val (completing-read
474 (if fn
475 (format "Where is command (default %s): " fn)
476 "Where is command: ")
477 obarray 'commandp t))
478 (list (if (equal val "") fn (intern val)) current-prefix-arg)))
7a698dc1 479 (let ((func (indirect-function definition))
3829bcc5 480 (defs nil)
7a698dc1 481 (standard-output (if insert (current-buffer) t)))
3829bcc5
SM
482 (mapatoms (lambda (symbol)
483 (and (fboundp symbol)
484 (not (eq symbol definition))
d92c2757
RS
485 (eq func (condition-case ()
486 (indirect-function symbol)
487 (error symbol)))
3829bcc5 488 (push symbol defs))))
7a698dc1
JB
489 (princ (mapconcat
490 #'(lambda (symbol)
023b93f6 491 (let* ((remapped (command-remapping symbol))
3829bcc5
SM
492 (keys (where-is-internal
493 symbol overriding-local-map nil nil remapped))
494 (keys (mapconcat 'key-description keys ", ")))
7a698dc1
JB
495 (if insert
496 (if (> (length keys) 0)
497 (if remapped
498 (format "%s (%s) (remapped from %s)"
499 keys remapped symbol)
500 (format "%s (%s)" keys symbol))
501 (format "M-x %s RET" symbol))
502 (if (> (length keys) 0)
503 (if remapped
504 (format "%s is remapped to %s which is on %s"
505 definition symbol keys)
506 (format "%s is on %s" symbol keys))
507 (format "%s is not on any key" symbol)))))
3829bcc5 508 (cons definition defs)
7a698dc1 509 ";\nand ")))
54c0b967
RS
510 nil)
511
788d62cf
MB
512(defun string-key-binding (key)
513 "Value is the binding of KEY in a string.
514If KEY is an event on a string, and that string has a `local-map'
515or `keymap' property, return the binding of KEY in the string's keymap."
516 (let* ((defn nil)
517 (start (when (vectorp key)
f03b7c7d
GM
518 (if (memq (aref key 0)
519 '(mode-line header-line left-margin right-margin))
788d62cf
MB
520 (event-start (aref key 1))
521 (and (consp (aref key 0))
522 (event-start (aref key 0))))))
523 (string-info (and (consp start) (nth 4 start))))
524 (when string-info
525 (let* ((string (car string-info))
526 (pos (cdr string-info))
f03b7c7d 527 (local-map (and (>= pos 0)
788d62cf
MB
528 (< pos (length string))
529 (or (get-text-property pos 'local-map string)
530 (get-text-property pos 'keymap string)))))
531 (setq defn (and local-map (lookup-key local-map key)))))
532 defn))
1a06eabd 533
02dfca16
SM
534(defun help-key-description (key untranslated)
535 (let ((string (key-description key)))
ae1bb8ac
SM
536 (if (or (not untranslated)
537 (and (eq (aref untranslated 0) ?\e) (not (eq (aref key 0) ?\e))))
02dfca16
SM
538 string
539 (let ((otherstring (key-description untranslated)))
540 (if (equal string otherstring)
541 string
542 (format "%s (translated from %s)" string otherstring))))))
71296446 543
02dfca16 544(defun describe-key-briefly (key &optional insert untranslated)
788d62cf 545 "Print the name of the function KEY invokes. KEY is a string.
02dfca16
SM
546If INSERT (the prefix arg) is non-nil, insert the message in the buffer.
547If non-nil UNTRANSLATED is a vector of the untranslated events.
548It can also be a number in which case the untranslated events from
549the last key hit are used."
550 (interactive "kDescribe key briefly: \nP\np")
551 (if (numberp untranslated)
552 (setq untranslated (this-single-command-raw-keys)))
400a1b1f 553 (save-excursion
788d62cf
MB
554 (let ((modifiers (event-modifiers (aref key 0)))
555 (standard-output (if insert (current-buffer) t))
556 window position)
557 ;; For a mouse button event, go to the button it applies to
558 ;; to get the right key bindings. And go to the right place
559 ;; in case the keymap depends on where you clicked.
560 (if (or (memq 'click modifiers) (memq 'down modifiers)
561 (memq 'drag modifiers))
562 (setq window (posn-window (event-start (aref key 0)))
563 position (posn-point (event-start (aref key 0)))))
564 (if (windowp window)
565 (progn
566 (set-buffer (window-buffer window))
567 (goto-char position)))
568 ;; Ok, now look up the key and name the command.
569 (let ((defn (or (string-key-binding key)
570 (key-binding key)))
02dfca16 571 (key-desc (help-key-description key untranslated)))
d61ac4a6 572 (if (or (null defn) (integerp defn) (equal defn 'undefined))
788d62cf 573 (princ (format "%s is undefined" key-desc))
80d553d4
RS
574 (princ (format (if (windowp window)
575 "%s at that spot runs the command %s"
576 "%s runs the command %s")
788d62cf
MB
577 key-desc
578 (if (symbolp defn) defn (prin1-to-string defn)))))))))
96ede6b2 579
788d62cf 580
4cf9f027 581(defun describe-key (key &optional untranslated up-event)
a0d32c10
RS
582 "Display documentation of the function invoked by KEY.
583KEY should be a key sequence--when calling from a program,
02dfca16
SM
584pass a string or a vector.
585If non-nil UNTRANSLATED is a vector of the untranslated events.
586It can also be a number in which case the untranslated events from
587the last key hit are used."
4cf9f027 588 (interactive "kDescribe key: \np\nU")
02dfca16
SM
589 (if (numberp untranslated)
590 (setq untranslated (this-single-command-raw-keys)))
788d62cf
MB
591 (save-excursion
592 (let ((modifiers (event-modifiers (aref key 0)))
593 window position)
594 ;; For a mouse button event, go to the button it applies to
595 ;; to get the right key bindings. And go to the right place
596 ;; in case the keymap depends on where you clicked.
597 (if (or (memq 'click modifiers) (memq 'down modifiers)
598 (memq 'drag modifiers))
599 (setq window (posn-window (event-start (aref key 0)))
600 position (posn-point (event-start (aref key 0)))))
94ea540b 601 (when (windowp window)
788d62cf 602 (set-buffer (window-buffer window))
94ea540b 603 (goto-char position))
788d62cf 604 (let ((defn (or (string-key-binding key) (key-binding key))))
d61ac4a6 605 (if (or (null defn) (integerp defn) (equal defn 'undefined))
02dfca16 606 (message "%s is undefined" (help-key-description key untranslated))
3e5929af
SM
607 (help-setup-xref (list #'describe-function defn) (interactive-p))
608 (with-output-to-temp-buffer (help-buffer)
02dfca16 609 (princ (help-key-description key untranslated))
788d62cf
MB
610 (if (windowp window)
611 (princ " at that spot"))
612 (princ " runs the command ")
613 (prin1 defn)
614 (princ "\n which is ")
3e5929af 615 (describe-function-1 defn)
4cf9f027 616 (when up-event
72b64ad5
KS
617 (let ((ev (aref up-event 0))
618 (descr (key-description up-event))
619 (hdr "\n\n-------------- up event ---------------\n\n")
620 defn
621 mouse-1-tricky mouse-1-remapped)
622 (when (and (consp ev)
623 (eq (car ev) 'mouse-1)
624 (windowp window)
625 mouse-1-click-follows-link
626 (not (eq mouse-1-click-follows-link 'double))
627 (with-current-buffer (window-buffer window)
628 (mouse-on-link-p (posn-point (event-start ev)))))
629 (setq mouse-1-tricky (integerp mouse-1-click-follows-link)
630 mouse-1-remapped (or (not mouse-1-tricky)
631 (> mouse-1-click-follows-link 0)))
632 (if mouse-1-remapped
633 (setcar ev 'mouse-2)))
634 (setq defn (or (string-key-binding up-event) (key-binding up-event)))
4cf9f027 635 (unless (or (null defn) (integerp defn) (equal defn 'undefined))
72b64ad5
KS
636 (princ (if mouse-1-tricky
637 "\n\n----------------- up-event (short click) ----------------\n\n"
638 hdr))
639 (setq hdr nil)
640 (princ descr)
4cf9f027
KS
641 (if (windowp window)
642 (princ " at that spot"))
72b64ad5
KS
643 (if mouse-1-remapped
644 (princ " is remapped to <mouse-2>\n which" ))
4cf9f027
KS
645 (princ " runs the command ")
646 (prin1 defn)
647 (princ "\n which is ")
72b64ad5
KS
648 (describe-function-1 defn))
649 (when mouse-1-tricky
650 (setcar ev
651 (if (> mouse-1-click-follows-link 0) 'mouse-1 'mouse-2))
652 (setq defn (or (string-key-binding up-event) (key-binding up-event)))
653 (unless (or (null defn) (integerp defn) (equal defn 'undefined))
654 (princ (or hdr
655 "\n\n----------------- up-event (long click) ----------------\n\n"))
656 (princ "Pressing ")
657 (princ descr)
658 (if (windowp window)
659 (princ " at that spot"))
660 (princ (format " for longer than %d milli-seconds\n"
661 (abs mouse-1-click-follows-link)))
662 (if (not mouse-1-remapped)
663 (princ " remaps it to <mouse-2> which" ))
664 (princ " runs the command ")
665 (prin1 defn)
666 (princ "\n which is ")
667 (describe-function-1 defn))))
668 (print-help-return-message))))))))
400a1b1f 669
400a1b1f 670\f
788d62cf
MB
671(defun describe-mode (&optional buffer)
672 "Display documentation of current major mode and minor modes.
efde809a
JPW
673A brief summary of the minor modes comes first, followed by the
674major mode description. This is followed by detailed
675descriptions of the minor modes, each on a separate page.
676
677For this to work correctly for a minor mode, the mode's indicator
678variable \(listed in `minor-mode-alist') must also be a function
679whose documentation describes the minor mode."
400a1b1f 680 (interactive)
9639be74
RS
681 (help-setup-xref (list #'describe-mode (or buffer (current-buffer)))
682 (interactive-p))
683 ;; For the sake of help-do-xref and help-xref-go-back,
684 ;; don't switch buffers before calling `help-buffer'.
3e5929af 685 (with-output-to-temp-buffer (help-buffer)
9639be74
RS
686 (save-excursion
687 (when buffer (set-buffer buffer))
f6c57ef6
RS
688 (let (minor-modes)
689 ;; Find enabled minor mode we will want to mention.
690 (dolist (mode minor-mode-list)
691 ;; Document a minor mode if it is listed in minor-mode-alist,
692 ;; non-nil, and has a function definition.
693 (and (boundp mode) (symbol-value mode)
694 (fboundp mode)
695 (let ((pretty-minor-mode mode)
696 indicator)
697 (if (string-match "\\(-minor\\)?-mode\\'"
698 (symbol-name mode))
699 (setq pretty-minor-mode
700 (capitalize
701 (substring (symbol-name mode)
702 0 (match-beginning 0)))))
703 (setq indicator (cadr (assq mode minor-mode-alist)))
704 (while (and indicator (symbolp indicator)
705 (boundp indicator)
706 (not (eq indicator (symbol-value indicator))))
707 (setq indicator (symbol-value indicator)))
708 (push (list pretty-minor-mode mode indicator)
709 minor-modes))))
710 (if auto-fill-function
b0915a31
KS
711 ;; copy pure string so we can add face property to it below.
712 (push (list (copy-sequence "Auto Fill") 'auto-fill-mode " Fill")
f6c57ef6
RS
713 minor-modes))
714 (setq minor-modes
715 (sort minor-modes
716 (lambda (a b) (string-lessp (car a) (car b)))))
717 (when minor-modes
718 (princ "Summary of minor modes:\n")
e25e90b4
DP
719 (make-local-variable 'help-button-cache)
720 (with-current-buffer standard-output
721 (dolist (mode minor-modes)
722 (let ((pretty-minor-mode (nth 0 mode))
723 (mode-function (nth 1 mode))
724 (indicator (nth 2 mode)))
725 (add-text-properties 0 (length pretty-minor-mode)
726 '(face bold) pretty-minor-mode)
727 (save-excursion
728 (goto-char (point-max))
729 (princ "\n\f\n")
730 (push (point-marker) help-button-cache)
731 ;; Document the minor modes fully.
732 (insert pretty-minor-mode)
733 (princ (format " minor mode (%s):\n"
734 (if indicator
735 (format "indicator%s" indicator)
736 "no indicator")))
737 (princ (documentation mode-function)))
738 (princ " ")
739 (insert-button pretty-minor-mode
740 'action (car help-button-cache)
72b64ad5 741 'follow-link t
e25e90b4
DP
742 'help-echo "mouse-2, RET: show full information")
743 (princ (format " minor mode (%s):\n"
744 (if indicator
745 (format "indicator%s" indicator)
746 "no indicator"))))))
f6c57ef6
RS
747 (princ "\n(Full information about these minor modes
748follows the description of the major mode.)\n\n"))
749 ;; Document the major mode.
e25e90b4
DP
750 (let ((mode mode-name))
751 (with-current-buffer standard-output
752 (insert mode)
753 (add-text-properties (- (point) (length mode)) (point) '(face bold))))
f6c57ef6 754 (princ " mode:\n")
e25e90b4 755 (princ (documentation major-mode)))
9639be74 756 (print-help-return-message))))
400a1b1f 757
f6c57ef6 758
8e864068 759(defun describe-minor-mode (minor-mode)
335028c3
MY
760 "Display documentation of a minor mode given as MINOR-MODE.
761MINOR-MODE can be a minor mode symbol or a minor mode indicator string
762appeared on the mode-line."
7ada28ac 763 (interactive (list (completing-read
335028c3
MY
764 "Minor mode: "
765 (nconc
766 (describe-minor-mode-completion-table-for-symbol)
767 (describe-minor-mode-completion-table-for-indicator)
768 ))))
769 (if (symbolp minor-mode)
770 (setq minor-mode (symbol-name minor-mode)))
771 (let ((symbols (describe-minor-mode-completion-table-for-symbol))
772 (indicators (describe-minor-mode-completion-table-for-indicator)))
773 (cond
774 ((member minor-mode symbols)
775 (describe-minor-mode-from-symbol (intern minor-mode)))
776 ((member minor-mode indicators)
777 (describe-minor-mode-from-indicator minor-mode))
778 (t
779 (error "No such minor mode: %s" minor-mode)))))
780
7ada28ac 781;; symbol
335028c3
MY
782(defun describe-minor-mode-completion-table-for-symbol ()
783 ;; In order to list up all minor modes, minor-mode-list
784 ;; is used here instead of minor-mode-alist.
785 (delq nil (mapcar 'symbol-name minor-mode-list)))
786(defun describe-minor-mode-from-symbol (symbol)
787 "Display documentation of a minor mode given as a symbol, SYMBOL"
7ada28ac 788 (interactive (list (intern (completing-read
335028c3
MY
789 "Minor mode symbol: "
790 (describe-minor-mode-completion-table-for-symbol)))))
791 (if (fboundp symbol)
792 (describe-function symbol)
793 (describe-variable symbol)))
794
795;; indicator
796(defun describe-minor-mode-completion-table-for-indicator ()
7ada28ac 797 (delq nil
335028c3
MY
798 (mapcar (lambda (x)
799 (let ((i (format-mode-line x)))
800 ;; remove first space if existed
801 (cond
802 ((= 0 (length i))
803 nil)
804 ((eq (aref i 0) ?\ )
805 (substring i 1))
7ada28ac 806 (t
335028c3
MY
807 i))))
808 minor-mode-alist)))
8e864068 809(defun describe-minor-mode-from-indicator (indicator)
335028c3
MY
810 "Display documentation of a minor mode specified by INDICATOR.
811If you call this function interactively, you can give indicator which
812is currently activated with completion."
7ada28ac
LT
813 (interactive (list
814 (completing-read
8e864068 815 "Minor mode indicator: "
335028c3 816 (describe-minor-mode-completion-table-for-indicator))))
8e864068
JB
817 (let ((minor-mode (lookup-minor-mode-from-indicator indicator)))
818 (if minor-mode
335028c3 819 (describe-minor-mode-from-symbol minor-mode)
8e864068
JB
820 (error "Cannot find minor mode for `%s'" indicator))))
821
822(defun lookup-minor-mode-from-indicator (indicator)
823 "Return a minor mode symbol from its indicator on the modeline."
335028c3 824 ;; remove first space if existed
7ada28ac 825 (if (and (< 0 (length indicator))
335028c3
MY
826 (eq (aref indicator 0) ?\ ))
827 (setq indicator (substring indicator 1)))
8e864068
JB
828 (let ((minor-modes minor-mode-alist)
829 result)
830 (while minor-modes
831 (let* ((minor-mode (car (car minor-modes)))
7ada28ac 832 (anindicator (format-mode-line
335028c3
MY
833 (car (cdr (car minor-modes))))))
834 ;; remove first space if existed
7ada28ac 835 (if (and (stringp anindicator)
335028c3
MY
836 (> (length anindicator) 0)
837 (eq (aref anindicator 0) ?\ ))
838 (setq anindicator (substring anindicator 1)))
839 (if (equal indicator anindicator)
8e864068
JB
840 (setq result minor-mode
841 minor-modes nil)
842 (setq minor-modes (cdr minor-modes)))))
843 result))
844
48ce3c22
RS
845\f
846;;; Automatic resizing of temporary buffers.
847
4483ddc5 848(defcustom temp-buffer-max-height (lambda (buffer) (/ (- (frame-height) 2) 2))
48ce3c22
RS
849 "*Maximum height of a window displaying a temporary buffer.
850This is the maximum height (in text lines) which `resize-temp-buffer-window'
851will give to a window displaying a temporary buffer.
852It can also be a function which will be called with the object corresponding
853to the buffer to be displayed as argument and should return an integer
854positive number."
855 :type '(choice integer function)
856 :group 'help
857 :version "20.4")
858
4e1ede6c
SM
859(define-minor-mode temp-buffer-resize-mode
860 "Toggle the mode which makes windows smaller for temporary buffers.
48ce3c22
RS
861With prefix argument ARG, turn the resizing of windows displaying temporary
862buffers on if ARG is positive or off otherwise.
4e1ede6c
SM
863This makes the window the right height for its contents, but never
864more than `temp-buffer-max-height' nor less than `window-min-height'.
865This applies to `help', `apropos' and `completion' buffers, and some others."
b0fbf754 866 :global t :group 'help
4e1ede6c 867 (if temp-buffer-resize-mode
57f43907 868 ;; `help-make-xrefs' may add a `back' button and thus increase the
4e1ede6c
SM
869 ;; text size, so `resize-temp-buffer-window' must be run *after* it.
870 (add-hook 'temp-buffer-show-hook 'resize-temp-buffer-window 'append)
8304a3bb 871 (remove-hook 'temp-buffer-show-hook 'resize-temp-buffer-window)))
48ce3c22
RS
872
873(defun resize-temp-buffer-window ()
874 "Resize the current window to fit its contents.
4483ddc5 875Will not make it higher than `temp-buffer-max-height' nor smaller than
b2c85790 876`window-min-height'. Do nothing if it is the only window on its frame, if it
48ce3c22
RS
877is not as wide as the frame or if some of the window's contents are scrolled
878out of view."
879 (unless (or (one-window-p 'nomini)
880 (not (pos-visible-in-window-p (point-min)))
881 (/= (frame-width) (window-width)))
d9c30bdf
MB
882 (fit-window-to-buffer
883 (selected-window)
884 (if (functionp temp-buffer-max-height)
885 (funcall temp-buffer-max-height (current-buffer))
886 temp-buffer-max-height))))
48ce3c22 887
5fbeea74
GM
888;; Provide this for the sake of define-minor-mode which generates
889;; defcustoms which require 'help'.
5fbeea74
GM
890(provide 'help)
891
ab5796a9 892;;; arch-tag: cf427352-27e9-49b7-9a6f-741ebab02423
1a06eabd 893;;; help.el ends here