diff options
| author | Richard M. Stallman | 1991-08-25 21:47:10 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1991-08-25 21:47:10 +0000 |
| commit | 433ae6f6e191af1d1bc67025200ea54a08761e68 (patch) | |
| tree | 2000034c91a4dea6c222a45a68e96e8a2f00d9ea | |
| parent | d47099af4a72b4f804ce83948549f9728b8a3ced (diff) | |
| download | emacs-433ae6f6e191af1d1bc67025200ea54a08761e68.tar.gz emacs-433ae6f6e191af1d1bc67025200ea54a08761e68.zip | |
Initial revision
| -rw-r--r-- | lisp/help.el | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/lisp/help.el b/lisp/help.el new file mode 100644 index 00000000000..d2d65a5fa94 --- /dev/null +++ b/lisp/help.el | |||
| @@ -0,0 +1,385 @@ | |||
| 1 | ;; Help commands for Emacs | ||
| 2 | ;; Copyright (C) 1985, 1986 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | ;; This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | ;; it under the terms of the GNU General Public License as published by | ||
| 8 | ;; the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | ;; any later version. | ||
| 10 | |||
| 11 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | ;; GNU General Public License for more details. | ||
| 15 | |||
| 16 | ;; You should have received a copy of the GNU General Public License | ||
| 17 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | |||
| 20 | ;;;###autoload | ||
| 21 | (defvar help-map (make-sparse-keymap) | ||
| 22 | "Keymap for characters following the Help key.") | ||
| 23 | |||
| 24 | (define-key global-map "\C-h" 'help-command) | ||
| 25 | (fset 'help-command help-map) | ||
| 26 | |||
| 27 | (define-key help-map "\C-h" 'help-for-help) | ||
| 28 | (define-key help-map "?" 'help-for-help) | ||
| 29 | |||
| 30 | (define-key help-map "\C-c" 'describe-copying) | ||
| 31 | (define-key help-map "\C-d" 'describe-distribution) | ||
| 32 | (define-key help-map "\C-w" 'describe-no-warranty) | ||
| 33 | (define-key help-map "a" 'command-apropos) | ||
| 34 | |||
| 35 | (define-key help-map "b" 'describe-bindings) | ||
| 36 | |||
| 37 | (define-key help-map "c" 'describe-key-briefly) | ||
| 38 | (define-key help-map "k" 'describe-key) | ||
| 39 | |||
| 40 | (define-key help-map "d" 'describe-function) | ||
| 41 | (define-key help-map "f" 'describe-function) | ||
| 42 | |||
| 43 | (define-key help-map "i" 'info) | ||
| 44 | |||
| 45 | (define-key help-map "l" 'view-lossage) | ||
| 46 | |||
| 47 | (define-key help-map "m" 'describe-mode) | ||
| 48 | |||
| 49 | (define-key help-map "\C-n" 'view-emacs-news) | ||
| 50 | (define-key help-map "n" 'view-emacs-news) | ||
| 51 | |||
| 52 | (define-key help-map "s" 'describe-syntax) | ||
| 53 | |||
| 54 | (define-key help-map "t" 'help-with-tutorial) | ||
| 55 | |||
| 56 | (define-key help-map "w" 'where-is) | ||
| 57 | |||
| 58 | (define-key help-map "v" 'describe-variable) | ||
| 59 | |||
| 60 | (defun help-with-tutorial () | ||
| 61 | "Select the Emacs learn-by-doing tutorial." | ||
| 62 | (interactive) | ||
| 63 | (let ((file (expand-file-name "~/TUTORIAL"))) | ||
| 64 | (delete-other-windows) | ||
| 65 | (if (get-file-buffer file) | ||
| 66 | (switch-to-buffer (get-file-buffer file)) | ||
| 67 | (switch-to-buffer (create-file-buffer file)) | ||
| 68 | (setq buffer-file-name file) | ||
| 69 | (setq default-directory (expand-file-name "~/")) | ||
| 70 | (setq auto-save-file-name nil) | ||
| 71 | (insert-file-contents (expand-file-name "TUTORIAL" exec-directory)) | ||
| 72 | (goto-char (point-min)) | ||
| 73 | (search-forward "\n<<") | ||
| 74 | (beginning-of-line) | ||
| 75 | (delete-region (point) (progn (end-of-line) (point))) | ||
| 76 | (newline (- (window-height (selected-window)) | ||
| 77 | (count-lines (point-min) (point)) | ||
| 78 | 6)) | ||
| 79 | (goto-char (point-min)) | ||
| 80 | (set-buffer-modified-p nil)))) | ||
| 81 | |||
| 82 | (defun describe-key-briefly (key) | ||
| 83 | "Print the name of the function KEY invokes. KEY is a string." | ||
| 84 | (interactive "kDescribe key briefly: ") | ||
| 85 | (let ((defn (key-binding key))) | ||
| 86 | (if (or (null defn) (integerp defn)) | ||
| 87 | (message "%s is undefined" (key-description key)) | ||
| 88 | (message "%s runs the command %s" | ||
| 89 | (key-description key) | ||
| 90 | (if (symbolp defn) defn (prin1-to-string defn)))))) | ||
| 91 | |||
| 92 | (defun print-help-return-message (&optional function) | ||
| 93 | "Display or return message saying how to restore windows after help command. | ||
| 94 | Computes a message and applies the optional argument FUNCTION to it. | ||
| 95 | If FUNCTION is nil, applies `message' to it, thus printing it." | ||
| 96 | (and (not (get-buffer-window standard-output)) | ||
| 97 | (funcall (or function 'message) | ||
| 98 | (concat | ||
| 99 | (substitute-command-keys | ||
| 100 | (if (one-window-p t) | ||
| 101 | (if pop-up-windows | ||
| 102 | "Type \\[delete-other-windows] to remove help window." | ||
| 103 | "Type \\[switch-to-buffer] RET to remove help window.") | ||
| 104 | "Type \\[switch-to-buffer-other-window] RET to restore the other window.")) | ||
| 105 | (substitute-command-keys | ||
| 106 | " \\[scroll-other-window] to scroll the help."))))) | ||
| 107 | |||
| 108 | (defun describe-key (key) | ||
| 109 | "Display documentation of the function invoked by KEY. KEY is a string." | ||
| 110 | (interactive "kDescribe key: ") | ||
| 111 | (let ((defn (key-binding key))) | ||
| 112 | (if (or (null defn) (integerp defn)) | ||
| 113 | (message "%s is undefined" (key-description key)) | ||
| 114 | (with-output-to-temp-buffer "*Help*" | ||
| 115 | (prin1 defn) | ||
| 116 | (princ ":\n") | ||
| 117 | (if (documentation defn) | ||
| 118 | (princ (documentation defn)) | ||
| 119 | (princ "not documented")) | ||
| 120 | (print-help-return-message))))) | ||
| 121 | |||
| 122 | (defun describe-mode (&optional minor) | ||
| 123 | "Display documentation of current major mode. | ||
| 124 | If optional MINOR is non-nil (or prefix argument is given if interactive), | ||
| 125 | display documentation of active minor modes as well. | ||
| 126 | For this to work correctly for a minor mode, the mode's indicator variable | ||
| 127 | (listed in `minor-mode-alist') must also be a function whose documentation | ||
| 128 | describes the minor mode." | ||
| 129 | (interactive) | ||
| 130 | (with-output-to-temp-buffer "*Help*" | ||
| 131 | (princ mode-name) | ||
| 132 | (princ " Mode:\n") | ||
| 133 | (princ (documentation major-mode)) | ||
| 134 | (let ((minor-modes minor-mode-alist) | ||
| 135 | (locals (buffer-local-variables))) | ||
| 136 | (while minor-modes | ||
| 137 | (let* ((minor-mode (car (car minor-modes))) | ||
| 138 | (indicator (car (cdr (car minor-modes)))) | ||
| 139 | (local-binding (assq minor-mode locals))) | ||
| 140 | ;; Document a minor mode if it is listed in minor-mode-alist, | ||
| 141 | ;; bound locally in this buffer, non-nil, and has a function | ||
| 142 | ;; definition. | ||
| 143 | (if (and local-binding | ||
| 144 | (cdr local-binding) | ||
| 145 | (fboundp minor-mode)) | ||
| 146 | (progn | ||
| 147 | (princ (format "\n\n\n%s minor mode (indicator%s):\n" | ||
| 148 | minor-mode indicator)) | ||
| 149 | (princ (documentation minor-mode))))) | ||
| 150 | (setq minor-modes (cdr minor-modes)))) | ||
| 151 | (print-help-return-message))) | ||
| 152 | |||
| 153 | ;; So keyboard macro definitions are documented correctly | ||
| 154 | (fset 'defining-kbd-macro (symbol-function 'start-kbd-macro)) | ||
| 155 | |||
| 156 | (defun describe-distribution () | ||
| 157 | "Display info on how to obtain the latest version of GNU Emacs." | ||
| 158 | (interactive) | ||
| 159 | (find-file-read-only | ||
| 160 | (expand-file-name "DISTRIB" exec-directory))) | ||
| 161 | |||
| 162 | (defun describe-copying () | ||
| 163 | "Display info on how you may redistribute copies of GNU Emacs." | ||
| 164 | (interactive) | ||
| 165 | (find-file-read-only | ||
| 166 | (expand-file-name "COPYING" exec-directory)) | ||
| 167 | (goto-char (point-min))) | ||
| 168 | |||
| 169 | (defun describe-no-warranty () | ||
| 170 | "Display info on all the kinds of warranty Emacs does NOT have." | ||
| 171 | (interactive) | ||
| 172 | (describe-copying) | ||
| 173 | (let (case-fold-search) | ||
| 174 | (search-forward "NO WARRANTY") | ||
| 175 | (recenter 0))) | ||
| 176 | |||
| 177 | (defun view-emacs-news () | ||
| 178 | "Display info on recent changes to Emacs." | ||
| 179 | (interactive) | ||
| 180 | (find-file-read-only (expand-file-name "NEWS" exec-directory))) | ||
| 181 | |||
| 182 | (defun view-lossage () | ||
| 183 | "Display last 100 input keystrokes." | ||
| 184 | (interactive) | ||
| 185 | (with-output-to-temp-buffer "*Help*" | ||
| 186 | (princ (key-description (recent-keys))) | ||
| 187 | (save-excursion | ||
| 188 | (set-buffer standard-output) | ||
| 189 | (goto-char (point-min)) | ||
| 190 | (while (progn (move-to-column 50) (not (eobp))) | ||
| 191 | (search-forward " " nil t) | ||
| 192 | (insert "\n"))) | ||
| 193 | (print-help-return-message))) | ||
| 194 | |||
| 195 | (defun help-for-help () | ||
| 196 | "You have typed C-h, the help character. Type a Help option: | ||
| 197 | |||
| 198 | A command-apropos. Give a substring, and see a list of commands | ||
| 199 | (functions interactively callable) that contain | ||
| 200 | that substring. See also the apropos command. | ||
| 201 | B describe-bindings. Display table of all key bindings. | ||
| 202 | C describe-key-briefly. Type a command key sequence; | ||
| 203 | it prints the function name that sequence runs. | ||
| 204 | F describe-function. Type a function name and get documentation of it. | ||
| 205 | I info. The info documentation reader. | ||
| 206 | K describe-key. Type a command key sequence; | ||
| 207 | it displays the full documentation. | ||
| 208 | L view-lossage. Shows last 100 characters you typed. | ||
| 209 | M describe-mode. Print documentation of current major mode, | ||
| 210 | which describes the commands peculiar to it. | ||
| 211 | N view-emacs-news. Shows emacs news file. | ||
| 212 | S describe-syntax. Display contents of syntax table, plus explanations | ||
| 213 | T help-with-tutorial. Select the Emacs learn-by-doing tutorial. | ||
| 214 | V describe-variable. Type name of a variable; | ||
| 215 | it displays the variable's documentation and value. | ||
| 216 | W where-is. Type command name; it prints which keystrokes | ||
| 217 | invoke that command. | ||
| 218 | C-c print Emacs copying permission (General Public License). | ||
| 219 | C-d print Emacs ordering information. | ||
| 220 | C-n print news of recent Emacs changes. | ||
| 221 | C-w print information on absence of warranty for GNU Emacs." | ||
| 222 | (interactive) | ||
| 223 | (message | ||
| 224 | "A B C F I K L M N S T V W C-c C-d C-n C-w. Type C-h again for more help: ") | ||
| 225 | (let ((char (read-char))) | ||
| 226 | (if (or (= char ?\C-h) (= char ??)) | ||
| 227 | (save-window-excursion | ||
| 228 | (switch-to-buffer "*Help*") | ||
| 229 | (delete-other-windows) | ||
| 230 | (erase-buffer) | ||
| 231 | (insert (documentation 'help-for-help)) | ||
| 232 | (goto-char (point-min)) | ||
| 233 | (while (memq char '(?\C-h ?? ?\C-v ?\ ?\177 ?\M-v)) | ||
| 234 | (if (memq char '(?\C-v ?\ )) | ||
| 235 | (scroll-up)) | ||
| 236 | (if (memq char '(?\177 ?\M-v)) | ||
| 237 | (scroll-down)) | ||
| 238 | (message "A B C F I K L M N S T V W C-c C-d C-n C-w%s: " | ||
| 239 | (if (pos-visible-in-window-p (point-max)) | ||
| 240 | "" " or Space to scroll")) | ||
| 241 | (let ((cursor-in-echo-area t)) | ||
| 242 | (setq char (read-char)))))) | ||
| 243 | (let ((defn (cdr (assq (downcase char) (cdr help-map))))) | ||
| 244 | (if defn (call-interactively defn) (ding))))) | ||
| 245 | |||
| 246 | |||
| 247 | ;; Return a function which is called by the list containing point. | ||
| 248 | ;; If that gives no function, return a function whose name is around point. | ||
| 249 | ;; If that doesn't give a function, return nil. | ||
| 250 | (defun function-called-at-point () | ||
| 251 | (or (condition-case () | ||
| 252 | (save-excursion | ||
| 253 | (save-restriction | ||
| 254 | (narrow-to-region (max (point-min) (- (point) 1000)) (point-max)) | ||
| 255 | (backward-up-list 1) | ||
| 256 | (forward-char 1) | ||
| 257 | (let (obj) | ||
| 258 | (setq obj (read (current-buffer))) | ||
| 259 | (and (symbolp obj) (fboundp obj) obj)))) | ||
| 260 | (error nil)) | ||
| 261 | (condition-case () | ||
| 262 | (save-excursion | ||
| 263 | (forward-sexp -1) | ||
| 264 | (skip-chars-forward "'") | ||
| 265 | (let ((obj (read (current-buffer)))) | ||
| 266 | (and (symbolp obj) (fboundp obj) obj))) | ||
| 267 | (error nil)))) | ||
| 268 | |||
| 269 | (defun describe-function (function) | ||
| 270 | "Display the full documentation of FUNCTION (a symbol)." | ||
| 271 | (interactive | ||
| 272 | (let ((fn (function-called-at-point)) | ||
| 273 | (enable-recursive-minibuffers t) | ||
| 274 | val) | ||
| 275 | (setq val (completing-read (if fn | ||
| 276 | (format "Describe function (default %s): " fn) | ||
| 277 | "Describe function: ") | ||
| 278 | obarray 'fboundp t)) | ||
| 279 | (list (if (equal val "") | ||
| 280 | fn (intern val))))) | ||
| 281 | (with-output-to-temp-buffer "*Help*" | ||
| 282 | (prin1 function) | ||
| 283 | (princ ": ") | ||
| 284 | (let* ((def (symbol-function function)) | ||
| 285 | (beg (if (commandp def) "an interactive " "a "))) | ||
| 286 | (princ (cond ((stringp def) "a keyboard macro.") | ||
| 287 | ((subrp def) | ||
| 288 | (concat beg "built-in function.")) | ||
| 289 | ((compiled-function-p def) | ||
| 290 | (concat beg "compiled Lisp function.")) | ||
| 291 | ((symbolp def) | ||
| 292 | (format "alias for `%s'." def)) | ||
| 293 | ((eq (car-safe def) 'lambda) | ||
| 294 | (concat beg "Lisp function.")) | ||
| 295 | ((eq (car-safe def) 'macro) | ||
| 296 | "a Lisp macro.") | ||
| 297 | ((eq (car-safe def) 'mocklisp) | ||
| 298 | "a mocklisp function.") | ||
| 299 | ((eq (car-safe def) 'autoload) | ||
| 300 | (format "%sLisp %s to autoload from `%s'." | ||
| 301 | beg | ||
| 302 | (if (nth 4 def) "macro" "function") | ||
| 303 | (nth 1 def))) | ||
| 304 | (t ""))) | ||
| 305 | (terpri)) | ||
| 306 | (if (documentation function) | ||
| 307 | (princ (documentation function)) | ||
| 308 | (princ "not documented")) | ||
| 309 | (print-help-return-message) | ||
| 310 | ;; Return the text we displayed. | ||
| 311 | (save-excursion (set-buffer standard-output) (buffer-string)))) | ||
| 312 | |||
| 313 | (defun variable-at-point () | ||
| 314 | (condition-case () | ||
| 315 | (save-excursion | ||
| 316 | (forward-sexp -1) | ||
| 317 | (skip-chars-forward "'") | ||
| 318 | (let ((obj (read (current-buffer)))) | ||
| 319 | (and (symbolp obj) (boundp obj) obj))) | ||
| 320 | (error nil))) | ||
| 321 | |||
| 322 | (defun describe-variable (variable) | ||
| 323 | "Display the full documentation of VARIABLE (a symbol). | ||
| 324 | Returns the documentation as a string, also." | ||
| 325 | (interactive | ||
| 326 | (let ((v (variable-at-point)) | ||
| 327 | (enable-recursive-minibuffers t) | ||
| 328 | val) | ||
| 329 | (setq val (completing-read (if v | ||
| 330 | (format "Describe variable (default %s): " v) | ||
| 331 | "Describe variable: ") | ||
| 332 | obarray 'boundp t)) | ||
| 333 | (list (if (equal val "") | ||
| 334 | v (intern val))))) | ||
| 335 | (with-output-to-temp-buffer "*Help*" | ||
| 336 | (prin1 variable) | ||
| 337 | (princ "'s value is ") | ||
| 338 | (if (not (boundp variable)) | ||
| 339 | (princ "void.") | ||
| 340 | (prin1 (symbol-value variable))) | ||
| 341 | (terpri) (terpri) | ||
| 342 | (princ "Documentation:") | ||
| 343 | (terpri) | ||
| 344 | (let ((doc (documentation-property variable 'variable-documentation))) | ||
| 345 | (if doc | ||
| 346 | (princ (substitute-command-keys doc)) | ||
| 347 | (princ "not documented as a variable."))) | ||
| 348 | (print-help-return-message) | ||
| 349 | ;; Return the text we displayed. | ||
| 350 | (save-excursion (set-buffer standard-output) (buffer-string)))) | ||
| 351 | |||
| 352 | (defun command-apropos (string) | ||
| 353 | "Like apropos but lists only symbols that are names of commands | ||
| 354 | \(interactively callable functions). Argument REGEXP is a regular expression | ||
| 355 | that is matched against command symbol names. Returns list of symbols and | ||
| 356 | documentation found." | ||
| 357 | (interactive "sCommand apropos (regexp): ") | ||
| 358 | (let ((message | ||
| 359 | (let ((standard-output (get-buffer-create "*Help*"))) | ||
| 360 | (print-help-return-message 'identity)))) | ||
| 361 | (apropos string 'commandp) | ||
| 362 | (and message (message message)))) | ||
| 363 | |||
| 364 | (defun locate-library (library &optional nosuffix) | ||
| 365 | "Show the full path name of Emacs library LIBRARY. | ||
| 366 | This command searches the directories in `load-path' like `M-x load-library' | ||
| 367 | to find the file that `M-x load-library RET LIBRARY RET' would load. | ||
| 368 | Optional second arg NOSUFFIX non-nil means don't add suffixes `.elc' or `.el' | ||
| 369 | to the specified name LIBRARY (a la calling `load' instead of `load-library')." | ||
| 370 | (interactive "sLocate library: ") | ||
| 371 | (catch 'answer | ||
| 372 | (mapcar | ||
| 373 | '(lambda (dir) | ||
| 374 | (mapcar | ||
| 375 | '(lambda (suf) | ||
| 376 | (let ((try (expand-file-name (concat library suf) dir))) | ||
| 377 | (and (file-readable-p try) | ||
| 378 | (null (file-directory-p try)) | ||
| 379 | (progn | ||
| 380 | (message "Library is file %s" try) | ||
| 381 | (throw 'answer try))))) | ||
| 382 | (if nosuffix '("") '(".elc" ".el" "")))) | ||
| 383 | load-path) | ||
| 384 | (message "No library %s in search path" library) | ||
| 385 | nil)) | ||