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