Describe djgpp library replacement files.
[bpt/emacs.git] / lisp / help.el
CommitLineData
1a06eabd
ER
1;;; help.el --- help commands for Emacs
2
d733c5ec 3;; Copyright (C) 1985, 1986, 1993, 1994 Free Software Foundation, Inc.
3a801d0c 4
e5167999 5;; Maintainer: FSF
fd7fa35a 6;; Keywords: help, internal
e5167999 7
433ae6f6
RS
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
e5167999 12;; the Free Software Foundation; either version 2, or (at your option)
433ae6f6
RS
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
b578f267
EN
21;; along with GNU Emacs; see the file COPYING. If not, write to the
22;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.
433ae6f6 24
d9ecc911
ER
25;;; Commentary:
26
27;; This code implements GNU Emac's on-line help system, the one invoked by
28;;`M-x help-for-help'.
29
e5167999
ER
30;;; Code:
31
8aa3a187
RS
32;; Get the macro make-help-screen when this is compiled,
33;; or run interpreted, but not when the compiled code is loaded.
b1fe9304 34(eval-when-compile (require 'help-macro))
41b8542b 35
433ae6f6
RS
36(defvar help-map (make-sparse-keymap)
37 "Keymap for characters following the Help key.")
38
afaa65e4
KH
39(defvar help-mode-map (make-sparse-keymap)
40 "Keymap for help mode.")
41
e17d2fd1 42(define-key global-map (char-to-string help-char) 'help-command)
0af3df1c
RS
43(define-key global-map [help] 'help-command)
44(define-key global-map [f1] 'help-command)
433ae6f6
RS
45(fset 'help-command help-map)
46
e17d2fd1 47(define-key help-map (char-to-string help-char) 'help-for-help)
0af3df1c
RS
48(define-key help-map [help] 'help-for-help)
49(define-key help-map [f1] 'help-for-help)
433ae6f6
RS
50(define-key help-map "?" 'help-for-help)
51
52(define-key help-map "\C-c" 'describe-copying)
53(define-key help-map "\C-d" 'describe-distribution)
54(define-key help-map "\C-w" 'describe-no-warranty)
76766f2d 55(define-key help-map "\C-p" 'describe-project)
433ae6f6
RS
56(define-key help-map "a" 'command-apropos)
57
58(define-key help-map "b" 'describe-bindings)
59
60(define-key help-map "c" 'describe-key-briefly)
61(define-key help-map "k" 'describe-key)
62
63(define-key help-map "d" 'describe-function)
64(define-key help-map "f" 'describe-function)
65
7ee71cf1
RS
66(define-key help-map "F" 'view-emacs-FAQ)
67
433ae6f6 68(define-key help-map "i" 'info)
e5d77022
JB
69(define-key help-map "\C-f" 'Info-goto-emacs-command-node)
70(define-key help-map "\C-k" 'Info-goto-emacs-key-command-node)
433ae6f6
RS
71
72(define-key help-map "l" 'view-lossage)
73
74(define-key help-map "m" 'describe-mode)
75
76(define-key help-map "\C-n" 'view-emacs-news)
77(define-key help-map "n" 'view-emacs-news)
78
06b98c51 79(define-key help-map "p" 'finder-by-keyword)
3e9c095d
RS
80(autoload 'finder-by-keyword "finder"
81 "Find packages matching a given keyword." t)
06b98c51 82
433ae6f6
RS
83(define-key help-map "s" 'describe-syntax)
84
85(define-key help-map "t" 'help-with-tutorial)
86
87(define-key help-map "w" 'where-is)
88
89(define-key help-map "v" 'describe-variable)
90
2fc9d9f4
RS
91(define-key help-map "q" 'help-quit)
92
507fb916 93(defvar help-font-lock-keywords
0e0ee795
RS
94 (eval-when-compile
95 (let ((name-char "[-+a-zA-Z0-9_*]") (sym-char "[-+a-zA-Z0-9_:*]"))
96 (list
97 ;;
98 ;; The symbol itself.
99 (list (concat "\\`\\(" name-char "+\\)\\(\\(:\\)\\|\\('\\)\\)")
8743d4cb
RS
100 '(1 (if (match-beginning 3)
101 font-lock-function-name-face
102 font-lock-variable-name-face)
103 nil t))
0e0ee795
RS
104 ;;
105 ;; Words inside `' which tend to be symbol names.
106 (list (concat "`\\(" sym-char sym-char "+\\)'")
107 1 'font-lock-reference-face t)
108 ;;
109 ;; CLisp `:' keywords as references.
110 (list (concat "\\<:" sym-char "+\\>") 0 'font-lock-reference-face t))))
507fb916
SM
111 "Default expressions to highlight in Help mode.")
112
afaa65e4
KH
113(defun help-mode ()
114 "Major mode for viewing help text.
115Entry to this mode runs the normal hook `help-mode-hook'.
116Commands:
117\\{help-mode-map}"
118 (interactive)
119 (kill-all-local-variables)
120 (use-local-map help-mode-map)
121 (setq mode-name "Help")
122 (setq major-mode 'help-mode)
507fb916 123 (make-local-variable 'font-lock-defaults)
dd7d85ba 124 (setq font-lock-defaults '(help-font-lock-keywords))
42499979 125 (view-mode)
afaa65e4
KH
126 (run-hooks 'help-mode-hook))
127
2fc9d9f4
RS
128(defun help-quit ()
129 (interactive)
130 nil)
131
433ae6f6
RS
132(defun help-with-tutorial ()
133 "Select the Emacs learn-by-doing tutorial."
134 (interactive)
135 (let ((file (expand-file-name "~/TUTORIAL")))
136 (delete-other-windows)
137 (if (get-file-buffer file)
138 (switch-to-buffer (get-file-buffer file))
139 (switch-to-buffer (create-file-buffer file))
140 (setq buffer-file-name file)
141 (setq default-directory (expand-file-name "~/"))
79058860 142 (setq buffer-auto-save-file-name nil)
1e6dacf6 143 (insert-file-contents (expand-file-name "TUTORIAL" data-directory))
433ae6f6
RS
144 (goto-char (point-min))
145 (search-forward "\n<<")
146 (beginning-of-line)
147 (delete-region (point) (progn (end-of-line) (point)))
857a1de6 148 (let ((n (- (window-height (selected-window))
433ae6f6 149 (count-lines (point-min) (point))
857a1de6 150 6)))
d0da2301 151 (if (< n 12)
857a1de6
KH
152 (newline n)
153 ;; Some people get confused by the large gap.
154 (newline (/ n 2))
155 (insert "[Middle of page left blank for didactic purposes. "
156 "Text continues below]")
157 (newline (- n (/ n 2)))))
433ae6f6
RS
158 (goto-char (point-min))
159 (set-buffer-modified-p nil))))
160
161(defun describe-key-briefly (key)
162 "Print the name of the function KEY invokes. KEY is a string."
163 (interactive "kDescribe key briefly: ")
5f296b78
RS
164 ;; If this key seq ends with a down event, discard the
165 ;; following click or drag event. Otherwise that would
166 ;; erase the message.
167 (let ((type (aref key (1- (length key)))))
168 (if (listp type) (setq type (car type)))
169 (and (symbolp type)
170 (memq 'down (event-modifiers type))
fca4b775 171 (read-event)))
fc558e4d
RS
172 (save-excursion
173 (let ((modifiers (event-modifiers (aref key 0)))
174 window position)
175 ;; For a mouse button event, go to the button it applies to
176 ;; to get the right key bindings. And go to the right place
177 ;; in case the keymap depends on where you clicked.
178 (if (or (memq 'click modifiers) (memq 'down modifiers)
179 (memq 'drag modifiers))
180 (setq window (posn-window (event-start (aref key 0)))
181 position (posn-point (event-start (aref key 0)))))
182 (if (windowp window)
183 (progn
184 (set-buffer (window-buffer window))
185 (goto-char position)))
186 ;; Ok, now look up the key and name the command.
187 (let ((defn (key-binding key)))
188 (if (or (null defn) (integerp defn))
189 (message "%s is undefined" (key-description key))
190 (message (if (windowp window)
191 "%s at that spot runs the command %s"
192 "%s runs the command %s")
193 (key-description key)
194 (if (symbolp defn) defn (prin1-to-string defn))))))))
433ae6f6
RS
195
196(defun print-help-return-message (&optional function)
197 "Display or return message saying how to restore windows after help command.
198Computes a message and applies the optional argument FUNCTION to it.
199If FUNCTION is nil, applies `message' to it, thus printing it."
200 (and (not (get-buffer-window standard-output))
d536293f
RS
201 (let ((first-message
202 (cond ((or (member (buffer-name standard-output)
203 special-display-buffer-names)
34b0ef48
RS
204 (assoc (buffer-name standard-output)
205 special-display-buffer-names)
d536293f
RS
206 (let (found
207 (tail special-display-regexps)
208 (name (buffer-name standard-output)))
209 (while (and tail (not found))
afaa65e4 210 (if (or (and (consp (car tail))
34b0ef48
RS
211 (string-match (car (car tail)) name))
212 (and (stringp (car tail))
213 (string-match (car tail) name)))
d536293f
RS
214 (setq found t))
215 (setq tail (cdr tail)))
216 found))
217 ;; If the help output buffer is a special display buffer,
218 ;; don't say anything about how to get rid of it.
219 ;; First of all, the user will do that with the window
220 ;; manager, not with Emacs.
221 ;; Secondly, the buffer has not been displayed yet,
222 ;; so we don't know whether its frame will be selected.
223 ;; Even the message about scrolling the help
224 ;; might be wrong, but it seems worth showing it anyway.
225 nil)
226 ((not (one-window-p t))
227 "Type \\[switch-to-buffer-other-window] RET to restore the other window.")
228 (pop-up-windows
229 "Type \\[delete-other-windows] to remove help window.")
230 (t
231 "Type \\[switch-to-buffer] RET to remove help window."))))
232 (funcall (or function 'message)
233 (concat
234 (if first-message
235 (substitute-command-keys first-message)
236 "")
237 (if first-message " " "")
125a8d70
RS
238 ;; If the help buffer will go in a separate frame,
239 ;; it's no use mentioning a command to scroll, so don't.
6e7f5182 240 (if (or (member (buffer-name standard-output)
125a8d70 241 special-display-buffer-names)
5cabce21
RS
242 (assoc (buffer-name standard-output)
243 special-display-buffer-names)
6e7f5182 244 (memq t (mapcar '(lambda (elt)
5cabce21
RS
245 (if (consp elt)
246 (setq elt (car elt)))
6e7f5182 247 (string-match elt (buffer-name standard-output)))
125a8d70
RS
248 special-display-regexps)))
249 nil
250 (if (or (member (buffer-name standard-output)
251 same-window-buffer-names)
5cabce21
RS
252 (assoc (buffer-name standard-output)
253 same-window-buffer-names)
125a8d70 254 (memq t (mapcar '(lambda (elt)
5cabce21
RS
255 (if (consp elt)
256 (setq elt (car elt)))
125a8d70
RS
257 (string-match elt (buffer-name standard-output)))
258 same-window-regexps)))
259 ;; Say how to scroll this window.
260 (substitute-command-keys
261 "\\[scroll-up] to scroll the help.")
262 ;; Say how to scroll some other window.
6e7f5182 263 (substitute-command-keys
125a8d70 264 "\\[scroll-other-window] to scroll the help."))))))))
433ae6f6
RS
265
266(defun describe-key (key)
267 "Display documentation of the function invoked by KEY. KEY is a string."
268 (interactive "kDescribe key: ")
5f296b78
RS
269 ;; If this key seq ends with a down event, discard the
270 ;; following click or drag event. Otherwise that would
271 ;; erase the message.
272 (let ((type (aref key (1- (length key)))))
273 (if (listp type) (setq type (car type)))
274 (and (symbolp type)
275 (memq 'down (event-modifiers type))
276 (read-event)))
fc558e4d
RS
277 (save-excursion
278 (let ((modifiers (event-modifiers (aref key 0)))
279 window position)
280 ;; For a mouse button event, go to the button it applies to
281 ;; to get the right key bindings. And go to the right place
282 ;; in case the keymap depends on where you clicked.
283 (if (or (memq 'click modifiers) (memq 'down modifiers)
284 (memq 'drag modifiers))
285 (setq window (posn-window (event-start (aref key 0)))
286 position (posn-point (event-start (aref key 0)))))
287 (if (windowp window)
288 (progn
289 (set-buffer (window-buffer window))
290 (goto-char position)))
291 (let ((defn (key-binding key)))
292 (if (or (null defn) (integerp defn))
293 (message "%s is undefined" (key-description key))
294 (with-output-to-temp-buffer "*Help*"
295 (princ (key-description key))
296 (if (windowp window)
297 (princ " at that spot"))
298 (princ " runs the command ")
299 (prin1 defn)
300 (princ ":\n")
fb3fc9b8
RS
301 (let ((doc (documentation defn)))
302 (if doc
303 (progn (terpri)
304 (princ doc))
305 (princ "not documented")))
fc558e4d
RS
306 (save-excursion
307 (set-buffer standard-output)
308 (help-mode))
309 (print-help-return-message)))))))
433ae6f6 310
ad023904
RS
311(defun describe-mode ()
312 "Display documentation of current major mode and minor modes.
433ae6f6 313For this to work correctly for a minor mode, the mode's indicator variable
61c6b658 314\(listed in `minor-mode-alist') must also be a function whose documentation
433ae6f6 315describes the minor mode."
7192540b 316 (interactive)
433ae6f6 317 (with-output-to-temp-buffer "*Help*"
7192540b 318 (let ((minor-modes minor-mode-alist)
83f86594 319 (first t)
7192540b
RS
320 (locals (buffer-local-variables)))
321 (while minor-modes
322 (let* ((minor-mode (car (car minor-modes)))
323 (indicator (car (cdr (car minor-modes))))
324 (local-binding (assq minor-mode locals)))
325 ;; Document a minor mode if it is listed in minor-mode-alist,
326 ;; bound locally in this buffer, non-nil, and has a function
327 ;; definition.
328 (if (and local-binding
329 (cdr local-binding)
330 (fboundp minor-mode))
331 (let ((pretty-minor-mode minor-mode))
332 (if (string-match "-mode$" (symbol-name minor-mode))
333 (setq pretty-minor-mode
334 (capitalize
335 (substring (symbol-name minor-mode)
336 0 (match-beginning 0)))))
337 (while (and indicator (symbolp indicator))
338 (setq indicator (symbol-value indicator)))
83f86594
RS
339 (if first
340 (princ "The minor modes are described first,
341followed by the major mode, which is described on the last page.\n\f\n"))
342 (setq first nil)
2ef581f3
RS
343 (princ (format "%s minor mode (%s):\n"
344 pretty-minor-mode
345 (if indicator
346 (format "indicator%s" indicator)
347 "no indicator")))
7192540b 348 (princ (documentation minor-mode))
83f86594 349 (princ "\n\f\n"))))
7192540b 350 (setq minor-modes (cdr minor-modes))))
433ae6f6 351 (princ mode-name)
ad023904 352 (princ " mode:\n")
433ae6f6 353 (princ (documentation major-mode))
c46bbd92
KH
354 (save-excursion
355 (set-buffer standard-output)
356 (help-mode))
433ae6f6
RS
357 (print-help-return-message)))
358
359;; So keyboard macro definitions are documented correctly
360(fset 'defining-kbd-macro (symbol-function 'start-kbd-macro))
361
362(defun describe-distribution ()
363 "Display info on how to obtain the latest version of GNU Emacs."
364 (interactive)
365 (find-file-read-only
1e6dacf6 366 (expand-file-name "DISTRIB" data-directory)))
433ae6f6
RS
367
368(defun describe-copying ()
369 "Display info on how you may redistribute copies of GNU Emacs."
370 (interactive)
371 (find-file-read-only
1e6dacf6 372 (expand-file-name "COPYING" data-directory))
433ae6f6
RS
373 (goto-char (point-min)))
374
76766f2d
RS
375(defun describe-project ()
376 "Display info on the GNU project."
377 (interactive)
378 (find-file-read-only
379 (expand-file-name "GNU" data-directory))
380 (goto-char (point-min)))
381
433ae6f6
RS
382(defun describe-no-warranty ()
383 "Display info on all the kinds of warranty Emacs does NOT have."
384 (interactive)
385 (describe-copying)
386 (let (case-fold-search)
387 (search-forward "NO WARRANTY")
388 (recenter 0)))
389
61c6b658 390(defun describe-prefix-bindings ()
c7cba9cb
RS
391 "Describe the bindings of the prefix used to reach this command.
392The prefix described consists of all but the last event
393of the key sequence that ran this command."
61c6b658 394 (interactive)
ccc06dcc
KH
395 (let* ((key (this-command-keys)))
396 (describe-bindings
397 (if (stringp key)
398 (substring key 0 (1- (length key)))
399 (let ((prefix (make-vector (1- (length key)) nil))
400 (i 0))
401 (while (< i (length prefix))
402 (aset prefix i (aref key i))
403 (setq i (1+ i)))
404 prefix)))))
c7cba9cb
RS
405;; Make C-h after a prefix, when not specifically bound,
406;; run describe-prefix-bindings.
61c6b658
RS
407(setq prefix-help-command 'describe-prefix-bindings)
408
433ae6f6
RS
409(defun view-emacs-news ()
410 "Display info on recent changes to Emacs."
411 (interactive)
1e6dacf6 412 (find-file-read-only (expand-file-name "NEWS" data-directory)))
433ae6f6 413
7ee71cf1
RS
414(defun view-emacs-FAQ ()
415 "Display the Emacs Frequently Asked Questions (FAQ) file."
416 (interactive)
417 (find-file-read-only (expand-file-name "FAQ" data-directory)))
418
433ae6f6
RS
419(defun view-lossage ()
420 "Display last 100 input keystrokes."
421 (interactive)
422 (with-output-to-temp-buffer "*Help*"
298a7c8c
RS
423 (princ (mapconcat (function (lambda (key)
424 (if (or (integerp key)
425 (symbolp key)
426 (listp key))
427 (single-key-description key)
428 (prin1-to-string key nil))))
429 (recent-keys)
430 " "))
433ae6f6
RS
431 (save-excursion
432 (set-buffer standard-output)
433 (goto-char (point-min))
434 (while (progn (move-to-column 50) (not (eobp)))
435 (search-forward " " nil t)
c46bbd92
KH
436 (insert "\n"))
437 (help-mode))
433ae6f6
RS
438 (print-help-return-message)))
439
2fc9d9f4 440(defalias 'help 'help-for-help)
41b8542b 441(make-help-screen help-for-help
224d56a3 442 "a b c f C-f i k C-k l m n p s t v w C-c C-d C-n C-w, or ? for more help:"
76766f2d 443 "You have typed \\[help-command], the help character. Type a Help option:
efcce2d2 444\(Use SPC or DEL to scroll through this text. Type \\<help-map>\\[help-quit] to exit the Help command.)
433ae6f6 445
21ee8c42
RM
446a command-apropos. Give a substring, and see a list of commands
447 (functions interactively callable) that contain
448 that substring. See also the apropos command.
af6a9de9
RS
449b describe-bindings. Display table of all key bindings.
450c describe-key-briefly. Type a command key sequence;
21ee8c42 451 it prints the function name that sequence runs.
af6a9de9 452f describe-function. Type a function name and get documentation of it.
21ee8c42
RM
453C-f Info-goto-emacs-command-node. Type a function name;
454 it takes you to the Info node for that command.
7ee71cf1 455F view-emacs-FAQ. Shows emacs frequently asked questions file.
af6a9de9
RS
456i info. The info documentation reader.
457k describe-key. Type a command key sequence;
21ee8c42
RM
458 it displays the full documentation.
459C-k Info-goto-emacs-key-command-node. Type a command key sequence;
460 it takes you to the Info node for the command bound to that key.
af6a9de9
RS
461l view-lossage. Shows last 100 characters you typed.
462m describe-mode. Print documentation of current major mode,
21ee8c42 463 which describes the commands peculiar to it.
af6a9de9
RS
464n view-emacs-news. Shows emacs news file.
465p finder-by-keyword. Find packages matching a given topic keyword.
466s describe-syntax. Display contents of syntax table, plus explanations
467t help-with-tutorial. Select the Emacs learn-by-doing tutorial.
468v describe-variable. Type name of a variable;
21ee8c42 469 it displays the variable's documentation and value.
af6a9de9 470w where-is. Type command name; it prints which keystrokes
21ee8c42 471 invoke that command.
433ae6f6
RS
472C-c print Emacs copying permission (General Public License).
473C-d print Emacs ordering information.
474C-n print news of recent Emacs changes.
76766f2d 475C-p print information about the GNU project.
433ae6f6 476C-w print information on absence of warranty for GNU Emacs."
41b8542b 477 help-map)
433ae6f6
RS
478
479;; Return a function which is called by the list containing point.
480;; If that gives no function, return a function whose name is around point.
481;; If that doesn't give a function, return nil.
482(defun function-called-at-point ()
483 (or (condition-case ()
484 (save-excursion
485 (save-restriction
486 (narrow-to-region (max (point-min) (- (point) 1000)) (point-max))
487 (backward-up-list 1)
488 (forward-char 1)
489 (let (obj)
490 (setq obj (read (current-buffer)))
491 (and (symbolp obj) (fboundp obj) obj))))
492 (error nil))
493 (condition-case ()
914a48d0
RS
494 (let ((stab (syntax-table)))
495 (unwind-protect
496 (save-excursion
497 (set-syntax-table emacs-lisp-mode-syntax-table)
498 (or (not (zerop (skip-syntax-backward "_w")))
499 (eq (char-syntax (following-char)) ?w)
500 (eq (char-syntax (following-char)) ?_)
501 (forward-sexp -1))
502 (skip-chars-forward "'")
503 (let ((obj (read (current-buffer))))
504 (and (symbolp obj) (fboundp obj) obj)))
505 (set-syntax-table stab)))
433ae6f6
RS
506 (error nil))))
507
ca5ed196
RS
508(defun describe-function-find-file (function)
509 (let ((files load-history)
510 file functions)
511 (while files
512 (if (memq function (cdr (car files)))
513 (setq file (car (car files)) files nil))
514 (setq files (cdr files)))
515 file))
516
433ae6f6
RS
517(defun describe-function (function)
518 "Display the full documentation of FUNCTION (a symbol)."
519 (interactive
520 (let ((fn (function-called-at-point))
521 (enable-recursive-minibuffers t)
522 val)
523 (setq val (completing-read (if fn
524 (format "Describe function (default %s): " fn)
525 "Describe function: ")
526 obarray 'fboundp t))
527 (list (if (equal val "")
528 fn (intern val)))))
529 (with-output-to-temp-buffer "*Help*"
530 (prin1 function)
531 (princ ": ")
532 (let* ((def (symbol-function function))
ad3ec252 533 file-name
433ae6f6 534 (beg (if (commandp def) "an interactive " "a ")))
7f26b180
RM
535 (princ (cond ((or (stringp def)
536 (vectorp def))
6f6bfb85 537 "a keyboard macro")
433ae6f6 538 ((subrp def)
6f6bfb85 539 (concat beg "built-in function"))
dbc4e1c1 540 ((byte-code-function-p def)
6f6bfb85 541 (concat beg "compiled Lisp function"))
433ae6f6 542 ((symbolp def)
6f6bfb85 543 (format "alias for `%s'" def))
433ae6f6 544 ((eq (car-safe def) 'lambda)
6f6bfb85 545 (concat beg "Lisp function"))
433ae6f6 546 ((eq (car-safe def) 'macro)
6f6bfb85 547 "a Lisp macro")
433ae6f6 548 ((eq (car-safe def) 'mocklisp)
6f6bfb85 549 "a mocklisp function")
433ae6f6 550 ((eq (car-safe def) 'autoload)
ad3ec252 551 (setq file-name (nth 1 def))
6f6bfb85 552 (format "%s autoloaded Lisp %s"
762435dd 553 (if (commandp def) "an interactive" "an")
433ae6f6 554 (if (nth 4 def) "macro" "function")
ab67260b 555 ))
433ae6f6 556 (t "")))
ad3ec252
RS
557 (or file-name
558 (setq file-name (describe-function-find-file function)))
559 (if file-name
560 (progn
561 (princ " in `")
562 ;; We used to add .el to the file name,
563 ;; but that's completely wrong when the user used load-file.
564 (princ file-name)
565 (princ "'")))
6f6bfb85 566 (princ ".")
4591cb90 567 (terpri)
7f26b180
RM
568 (let ((arglist (cond ((byte-code-function-p def)
569 (car (append def nil)))
570 ((eq (car-safe def) 'lambda)
571 (nth 1 def))
572 (t t))))
573 (if (listp arglist)
574 (progn
575 (princ (cons function
576 (mapcar (lambda (arg)
577 (if (memq arg '(&optional &rest))
578 arg
579 (intern (upcase (symbol-name arg)))))
580 arglist)))
581 (terpri))))
fb3fc9b8
RS
582 (let ((doc (documentation function)))
583 (if doc
584 (progn (terpri)
585 (princ doc))
586 (princ "not documented"))))
433ae6f6 587 (print-help-return-message)
c46bbd92
KH
588 (save-excursion
589 (set-buffer standard-output)
590 (help-mode)
591 ;; Return the text we displayed.
592 (buffer-string))))
433ae6f6
RS
593
594(defun variable-at-point ()
595 (condition-case ()
914a48d0
RS
596 (let ((stab (syntax-table)))
597 (unwind-protect
598 (save-excursion
599 (set-syntax-table emacs-lisp-mode-syntax-table)
600 (or (not (zerop (skip-syntax-backward "_w")))
601 (eq (char-syntax (following-char)) ?w)
602 (eq (char-syntax (following-char)) ?_)
603 (forward-sexp -1))
604 (skip-chars-forward "'")
605 (let ((obj (read (current-buffer))))
606 (and (symbolp obj) (boundp obj) obj)))
607 (set-syntax-table stab)))
433ae6f6
RS
608 (error nil)))
609
610(defun describe-variable (variable)
611 "Display the full documentation of VARIABLE (a symbol).
612Returns the documentation as a string, also."
613 (interactive
614 (let ((v (variable-at-point))
615 (enable-recursive-minibuffers t)
616 val)
617 (setq val (completing-read (if v
618 (format "Describe variable (default %s): " v)
619 "Describe variable: ")
620 obarray 'boundp t))
621 (list (if (equal val "")
622 v (intern val)))))
623 (with-output-to-temp-buffer "*Help*"
624 (prin1 variable)
433ae6f6 625 (if (not (boundp variable))
3e483e01
RS
626 (princ " is void")
627 (princ "'s value is ")
433ae6f6 628 (prin1 (symbol-value variable)))
7e76ae23 629 (terpri)
b872e1da 630 (if (local-variable-p variable)
3e483e01
RS
631 (progn
632 (princ (format "Local in buffer %s; " (buffer-name)))
633 (if (not (default-boundp variable))
634 (princ "globally void")
635 (princ "global value is ")
636 (prin1 (default-value variable)))
637 (terpri)))
7e76ae23 638 (terpri)
433ae6f6
RS
639 (princ "Documentation:")
640 (terpri)
641 (let ((doc (documentation-property variable 'variable-documentation)))
c8f98e6d 642 (princ (or doc "not documented as a variable.")))
433ae6f6 643 (print-help-return-message)
c46bbd92
KH
644 (save-excursion
645 (set-buffer standard-output)
646 (help-mode)
647 ;; Return the text we displayed.
648 (buffer-string))))
433ae6f6 649
54c0b967
RS
650(defun where-is (definition)
651 "Print message listing key sequences that invoke specified command.
652Argument is a command definition, usually a symbol with a function definition."
653 (interactive
654 (let ((fn (function-called-at-point))
655 (enable-recursive-minibuffers t)
656 val)
657 (setq val (completing-read (if fn
658 (format "Where is command (default %s): " fn)
659 "Where is command: ")
660 obarray 'fboundp t))
661 (list (if (equal val "")
662 fn (intern val)))))
663 (let* ((keys (where-is-internal definition overriding-local-map nil nil))
664 (keys1 (mapconcat 'key-description keys ", ")))
665 (if (> (length keys1) 0)
666 (message "%s is on %s" definition keys1)
667 (message "%s is not on any key" definition)))
668 nil)
669
433ae6f6
RS
670(defun locate-library (library &optional nosuffix)
671 "Show the full path name of Emacs library LIBRARY.
672This command searches the directories in `load-path' like `M-x load-library'
673to find the file that `M-x load-library RET LIBRARY RET' would load.
674Optional second arg NOSUFFIX non-nil means don't add suffixes `.elc' or `.el'
675to the specified name LIBRARY (a la calling `load' instead of `load-library')."
676 (interactive "sLocate library: ")
677 (catch 'answer
678 (mapcar
679 '(lambda (dir)
680 (mapcar
681 '(lambda (suf)
682 (let ((try (expand-file-name (concat library suf) dir)))
683 (and (file-readable-p try)
684 (null (file-directory-p try))
685 (progn
686 (message "Library is file %s" try)
687 (throw 'answer try)))))
688 (if nosuffix '("") '(".elc" ".el" ""))))
689 load-path)
690 (message "No library %s in search path" library)
691 nil))
1a06eabd
ER
692
693;;; help.el ends here