comparison lisp/prim/help.el @ 183:e121b013d1f0 r20-3b18

Import from CVS: tag r20-3b18
author cvs
date Mon, 13 Aug 2007 09:54:23 +0200
parents 9ad43877534d
children 3d6bfa290dbd
comparison
equal deleted inserted replaced
182:f07455f06202 183:e121b013d1f0
26 26
27 ;;; Commentary: 27 ;;; Commentary:
28 28
29 ;; This code implements XEmacs's on-line help system, the one invoked by 29 ;; This code implements XEmacs's on-line help system, the one invoked by
30 ;;`M-x help-for-help'. 30 ;;`M-x help-for-help'.
31 31
32 ;; 06/11/1997 -- Converted to use char-after instead of broken 32 ;; 06/11/1997 -- Converted to use char-after instead of broken
33 ;; following-char. -slb 33 ;; following-char. -slb
34 34
35 ;;; Code: 35 ;;; Code:
36 36
407 (let ((defn (key-or-menu-binding key))) 407 (let ((defn (key-or-menu-binding key)))
408 (if (or (null defn) (integerp defn)) 408 (if (or (null defn) (integerp defn))
409 (message "%s is undefined" (key-description key)) 409 (message "%s is undefined" (key-description key))
410 (with-displaying-help-buffer 410 (with-displaying-help-buffer
411 (lambda () 411 (lambda ()
412 ; (princ (key-description key)) 412 (princ (key-description key))
413 ; (princ " runs the command ") 413 (princ " runs ")
414 (prin1 defn) 414 (princ (format "`%s'" defn))
415 (princ ":\n") 415 (princ "\n\n")
416 (cond ((or (stringp defn) (vectorp defn)) 416 (cond ((or (stringp defn) (vectorp defn))
417 (let ((cmd (key-binding defn))) 417 (let ((cmd (key-binding defn)))
418 (if (not cmd) 418 (if (not cmd)
419 (princ "a keyboard macro") 419 (princ "a keyboard macro")
420 (progn 420 (progn
776 unless the function is autoloaded." 776 unless the function is autoloaded."
777 :type 'boolean 777 :type 'boolean
778 :group 'help-appearance) 778 :group 'help-appearance)
779 779
780 (defun describe-function-find-file (function) 780 (defun describe-function-find-file (function)
781 (and (boundp 'load-history) ; not standardly bound in XEmacs 781 (let ((files load-history)
782 (let ((files load-history)
783 file) 782 file)
784 (while files 783 (while files
785 (if (memq function (cdr (car files))) 784 (if (memq function (cdr (car files)))
786 (setq file (car (car files)) files nil)) 785 (setq file (car (car files)) files nil))
787 (setq files (cdr files))) 786 (setq files (cdr files)))
788 file))) 787 file))
789 788
790 (defun describe-function (function) 789 (defun describe-function (function)
791 "Display the full documentation of FUNCTION (a symbol)." 790 "Display the full documentation of FUNCTION (a symbol)."
792 (interactive 791 (interactive
793 (let* ((fn (function-called-at-point)) 792 (let* ((fn (funcall find-function-function))
794 (val (let ((enable-recursive-minibuffers t)) 793 (val (let ((enable-recursive-minibuffers t))
795 (completing-read 794 (completing-read
796 (if fn 795 (if fn
797 (format (gettext "Describe function (default %s): ") 796 (format (gettext "Describe function (default %s): ")
798 fn) 797 fn)
856 ;(gettext "an interactive autoloaded Lisp function") 855 ;(gettext "an interactive autoloaded Lisp function")
857 ;(gettext "an autoloaded Lisp macro") 856 ;(gettext "an autoloaded Lisp macro")
858 ;(gettext "an interactive autoloaded Lisp macro") 857 ;(gettext "an interactive autoloaded Lisp macro")
859 858
860 (defun describe-function-1 (function stream &optional nodoc) 859 (defun describe-function-1 (function stream &optional nodoc)
861 (prin1 function stream) 860 (princ (format "`%S' is " function) stream)
862 (princ ": " stream)
863 (let* ((def function) 861 (let* ((def function)
864 file-name 862 file-name
865 (doc (or (documentation function) 863 (doc (or (documentation function)
866 (gettext "not documented"))) 864 (gettext "not documented")))
867 aliases home kbd-macro-p fndef macrop) 865 aliases home kbd-macro-p fndef macrop)
868 (while (symbolp def) 866 (while (symbolp def)
869 (or (eq def function) 867 (or (eq def function)
870 (if aliases 868 (if aliases
871 ;; I18N3 Need gettext due to concat 869 ;; I18N3 Need gettext due to concat
872 (setq aliases (concat aliases 870 (setq aliases (concat aliases
873 (format "\n which is an alias for %s, " 871 (format
872 "\n which is an alias for `%s', "
874 (symbol-name def)))) 873 (symbol-name def))))
875 (setq aliases (format "an alias for %s, " (symbol-name def))))) 874 (setq aliases (format "an alias for `%s', "
875 (symbol-name def)))))
876 (setq def (symbol-function def))) 876 (setq def (symbol-function def)))
877 (if (compiled-function-p def) 877 (if (compiled-function-p def)
878 (setq home (compiled-function-annotation def))) 878 (setq home (compiled-function-annotation def)))
879 (if (eq 'macro (car-safe def)) 879 (if (eq 'macro (car-safe def))
880 (setq fndef (cdr def) 880 (setq fndef (cdr def)
881 macrop t) 881 macrop t)
882 (setq fndef def)) 882 (setq fndef def))
883 (if describe-function-show-arglist
884 (if (cond ((eq 'autoload (car-safe fndef))
885 nil)
886 ((eq 'lambda (car-safe fndef))
887 (princ (or (nth 1 fndef) "()") stream)
888 t)
889 ((compiled-function-p fndef)
890 (princ (or (compiled-function-arglist fndef) "()") stream)
891 t)
892 ((and (subrp fndef)
893 (string-match "[\n\t ]*\narguments: ?\\((.*)\\)\n?\\'"
894 doc))
895 (princ (substring doc (match-beginning 1) (match-end 1))
896 stream)
897 (setq doc (substring doc 0 (match-beginning 0)))
898 t)
899 (t
900 nil))
901 (princ "\n -- " stream)))
902 (if aliases (princ aliases stream)) 883 (if aliases (princ aliases stream))
903 (let ((int #'(lambda (string an-p macro-p) 884 (let ((int #'(lambda (string an-p macro-p)
904 (princ (format 885 (princ (format
905 (gettext (concat 886 (gettext (concat
906 (cond ((commandp def) 887 (cond ((commandp def)
929 ((eq (car-safe def) 'autoload) 910 ((eq (car-safe def) 'autoload)
930 (setq file-name (elt def 1)) 911 (setq file-name (elt def 1))
931 (funcall int "autoloaded Lisp" t (elt def 4))) 912 (funcall int "autoloaded Lisp" t (elt def 4)))
932 (t 913 (t
933 nil))) 914 nil)))
915 (princ "\n")
934 (or file-name 916 (or file-name
935 (setq file-name (describe-function-find-file function))) 917 (setq file-name (describe-function-find-file function)))
936 (if file-name 918 (if file-name
937 (princ (format ".\n -- loads from \"%s\"" file-name) stream)) 919 (princ (format " -- loads from \"%s\"\n" file-name) stream))
938 (if home 920 (if home
939 (princ (format ".\n -- loaded from %s" home))) 921 (princ (format " -- loaded from \"%s\"\n" home)) stream)
940 (princ "." stream) 922 ;; (terpri stream)
923 (if describe-function-show-arglist
924 (let ((arglist
925 (cond ((compiled-function-p fndef)
926 (compiled-function-arglist fndef))
927 ((eq (car-safe fndef) 'lambda)
928 (nth 1 fndef))
929 ((and (subrp fndef)
930 (string-match
931 "[\n\t ]*\narguments: ?(\\(.*\\))\n?\\'"
932 doc))
933 (prog1
934 (substring doc (match-beginning 1) (match-end 1))
935 (setq doc (substring doc 0 (match-beginning 0)))))
936 (t t))))
937 (if (listp arglist)
938 (progn
939 ;; (princ " ")
940 (princ (cons function
941 (mapcar (lambda (arg)
942 (if (memq arg '(&optional &rest))
943 arg
944 (intern (upcase (symbol-name arg)))))
945 arglist)) stream)
946 (terpri stream)))
947 (if (stringp arglist)
948 (princ (format "(%s %s)\n" function arglist) stream))))
941 (terpri stream) 949 (terpri stream)
942 (cond (kbd-macro-p 950 (cond (kbd-macro-p
943 (princ "These characters are executed:\n\n\t" stream) 951 (princ "These characters are executed:\n\n\t" stream)
944 (princ (key-description def) stream) 952 (princ (key-description def) stream)
945 (cond ((setq def (key-binding def)) 953 (cond ((setq def (key-binding def))
946 (princ (format "\n\nwhich executes the command %s.\n\n" def) stream) 954 (princ (format "\n\nwhich executes the command %S.\n\n" def) stream)
947 (describe-function-1 def stream)))) 955 (describe-function-1 def stream))))
948 (nodoc nil) 956 (nodoc nil)
949 (t 957 (t
950 ;; tell the user about obsoleteness. 958 ;; tell the user about obsoleteness.
951 ;; If the function is obsolete and is aliased, don't 959 ;; If the function is obsolete and is aliased, don't
1069 (with-displaying-help-buffer 1077 (with-displaying-help-buffer
1070 (lambda () 1078 (lambda ()
1071 (let ((origvar variable) 1079 (let ((origvar variable)
1072 aliases) 1080 aliases)
1073 (let ((print-escape-newlines t)) 1081 (let ((print-escape-newlines t))
1082 (princ (format "`%s' is " (symbol-name variable)))
1074 (while (variable-alias variable) 1083 (while (variable-alias variable)
1075 (let ((newvar (variable-alias variable))) 1084 (let ((newvar (variable-alias variable)))
1076 (if aliases 1085 (if aliases
1077 ;; I18N3 Need gettext due to concat 1086 ;; I18N3 Need gettext due to concat
1078 (setq aliases 1087 (setq aliases
1079 (concat aliases 1088 (concat aliases
1080 (format ",\n which is an alias for %s" 1089 (format "\n which is an alias for `%s',"
1081 (symbol-name newvar)))) 1090 (symbol-name newvar))))
1082 (setq aliases 1091 (setq aliases
1083 (format "%s is an alias for %s" 1092 (format "an alias for `%s',"
1084 (symbol-name variable)
1085 (symbol-name newvar)))) 1093 (symbol-name newvar))))
1086 (setq variable newvar))) 1094 (setq variable newvar)))
1087 (if aliases 1095 (if aliases
1088 (princ (format "%s.\n" aliases))) 1096 (princ (format "%s" aliases)))
1097 (princ (built-in-variable-doc variable))
1098 (princ ".\n\n")
1099 (princ "Value: ")
1089 (if (not (boundp variable)) 1100 (if (not (boundp variable))
1090 (princ (format "%s is void" variable)) 1101 (princ "void")
1091 (princ (format "%s's value is " variable))
1092 (prin1 (symbol-value variable))) 1102 (prin1 (symbol-value variable)))
1093 (terpri)
1094 (princ " -- ")
1095 (princ (built-in-variable-doc variable))
1096 (princ ".")
1097 (terpri) 1103 (terpri)
1098 (cond ((local-variable-p variable (current-buffer)) 1104 (cond ((local-variable-p variable (current-buffer))
1099 (let* ((void (cons nil nil)) 1105 (let* ((void (cons nil nil))
1100 (def (condition-case nil 1106 (def (condition-case nil
1101 (default-value variable) 1107 (default-value variable)
1114 (if (eq def void) 1120 (if (eq def void)
1115 (princ "void.") 1121 (princ "void.")
1116 (prin1 def)) 1122 (prin1 def))
1117 (terpri))))) 1123 (terpri)))))
1118 ((local-variable-p variable (current-buffer) t) 1124 ((local-variable-p variable (current-buffer) t)
1119 (princ "Setting it would make its value buffer-local.\n") 1125 (princ "Setting it would make its value buffer-local.\n"))))
1120 (terpri))))
1121 (terpri) 1126 (terpri)
1122 (princ "Documentation:") 1127 (princ "Documentation:")
1123 (terpri) 1128 (terpri)
1124 (let ((doc (documentation-property variable 'variable-documentation)) 1129 (let ((doc (documentation-property variable 'variable-documentation))
1125 (obsolete (variable-obsoleteness-doc origvar)) 1130 (obsolete (variable-obsoleteness-doc origvar))
1157 1162
1158 (defun where-is (definition) 1163 (defun where-is (definition)
1159 "Print message listing key sequences that invoke specified command. 1164 "Print message listing key sequences that invoke specified command.
1160 Argument is a command definition, usually a symbol with a function definition." 1165 Argument is a command definition, usually a symbol with a function definition."
1161 (interactive 1166 (interactive
1162 (let ((fn (function-called-at-point)) 1167 (let ((fn (funcall find-function-function))
1163 (enable-recursive-minibuffers t) 1168 (enable-recursive-minibuffers t)
1164 val) 1169 val)
1165 (setq val (read-command 1170 (setq val (read-command
1166 (if fn (format "Where is command (default %s): " fn) 1171 (if fn (format "Where is command (default %s): " fn)
1167 "Where is command: "))) 1172 "Where is command: ")))
1291 (princ (car cmd) stream) 1296 (princ (car cmd) stream)
1292 (setq cmd (cdr cmd)) 1297 (setq cmd (cdr cmd))
1293 (if cmd (princ " " stream))))) 1298 (if cmd (princ " " stream)))))
1294 (terpri stream))))))) 1299 (terpri stream)))))))
1295 1300
1296 (defvar find-function-function 'ff-function-at-point 1301
1297 "The function used by `find-function' to select the function near 1302 ;; find-function stuff
1303
1304 (defvar find-function-function 'function-at-point
1305 "*The function used by `find-function' to select the function near
1298 point. 1306 point.
1299 1307
1300 For example `ff-function-at-point' or `function-called-at-point'.") 1308 For example `function-at-point' or `function-called-at-point'.")
1301 1309
1302 (defvar find-function-source-path nil 1310 (defvar find-function-source-path nil
1303 "The default list of directories where find-function searches. 1311 "The default list of directories where find-function searches.
1304 1312
1305 If this variable is `nil' then find-function searches `load-path' by 1313 If this variable is `nil' then find-function searches `load-path' by
1306 default.") 1314 default.")
1307 1315
1308 ;;; Code:
1309 1316
1310 (defun find-function-noselect (function &optional path) 1317 (defun find-function-noselect (function &optional path)
1311 "Put point at the definition of the function at point and return the buffer. 1318 "Returns list `(buffer point)' pointing to the definition of FUNCTION.
1312 1319
1313 Finds the emacs-lisp package containing the definition of FUNCTION 1320 Finds the emacs-lisp library containing the definition of FUNCTION
1314 into a buffer and place point before the definition. The buffer is 1321 in a buffer and places point before the definition. The buffer is
1315 not selected. 1322 not selected.
1316 1323
1317 If the optional argument PATH is given, the package where FUNCTION is 1324 If the optional argument PATH is given, the library where FUNCTION is
1318 defined is searched in PATH instead of `load-path' (see 1325 defined is searched in PATH instead of `load-path' (see
1319 `find-function-source-path')." 1326 `find-function-source-path')."
1320 (and (subrp (symbol-function function)) 1327 (and (subrp (symbol-function function))
1321 (error "%s is a primitive function" function)) 1328 (error "%s is a primitive function" function))
1322 (if (not function) 1329 (if (not function)
1323 (error "You didn't specify a function")) 1330 (error "You didn't specify a function"))
1324 (let ((def (symbol-function function)) 1331 (let ((def (symbol-function function))
1325 package aliases) 1332 library aliases)
1326 (while (symbolp def) 1333 (while (symbolp def)
1327 (or (eq def function) 1334 (or (eq def function)
1328 (if aliases 1335 (if aliases
1329 (setq aliases (concat aliases 1336 (setq aliases (concat aliases
1330 (format ", which is an alias for %s" 1337 (format ", which is an alias for %s"
1333 def))))) 1340 def)))))
1334 (setq function (symbol-function function) 1341 (setq function (symbol-function function)
1335 def (symbol-function function))) 1342 def (symbol-function function)))
1336 (if aliases 1343 (if aliases
1337 (message aliases)) 1344 (message aliases))
1338 (setq package 1345 (setq library
1339 (cond ((eq (car-safe def) 'autoload) 1346 (cond ((eq (car-safe def) 'autoload)
1340 (nth 1 def)) 1347 (nth 1 def))
1341 ((describe-function-find-file function)) 1348 ((describe-function-find-file function))
1342 ((and (compiled-function-p def) 1349 ((compiled-function-p def)
1343 (fboundp 'compiled-function-annotation))
1344 (substring (compiled-function-annotation def) 0 -4)))) 1350 (substring (compiled-function-annotation def) 0 -4))))
1345 (if (null package) 1351 (if (null library)
1346 (error "Can't find package")) 1352 (error "Can't find library"))
1347 (if (string-match "\\(\\.elc?\\'\\)" package) 1353 (if (string-match "\\(\\.elc?\\'\\)" library)
1348 (setq package (substring package 0 (match-beginning 1)))) 1354 (setq library (substring library 0 (match-beginning 1))))
1349 (setq package (concat package ".el")) 1355 (let* ((path (or path find-function-source-path))
1350 (let ((filename (locate-library package t 1356 (compression (or (rassq 'jka-compr-handler file-name-handler-alist)
1351 (if path 1357 (member 'crypt-find-file-hook find-file-hooks)))
1352 path 1358 (filename (or (locate-library (concat library ".el")
1353 find-function-source-path))) 1359 t path)
1354 (calling-buffer (current-buffer))) 1360 (locate-library library t path)
1361 (if compression
1362 (or (locate-library (concat library ".el.gz")
1363 t path)
1364 (locate-library (concat library ".gz")
1365 t path))))))
1355 (if (not filename) 1366 (if (not filename)
1356 (error "The package \"%s\" is not in the path." package)) 1367 (error "The library \"%s\" is not in the path." library))
1357 (set-buffer (find-file-noselect filename)) 1368 (save-excursion
1358 (save-match-data 1369 (set-buffer (find-file-noselect filename))
1359 (let ((p (point)) 1370 (save-match-data
1360 ;; avoid defconst, defgroup, defvar (any others?) 1371 (let (;; avoid defconst, defgroup, defvar (any others?)
1361 (re (format "^(def[^cgv\W]\\w+\\s-+%s\\s-" function)) 1372 (re (format "^\\s-*(def[^cgv\W]\\w+\\s-+%s\\s-" function))
1362 (syntable (syntax-table))) 1373 (syntable (syntax-table)))
1363 (set-syntax-table emacs-lisp-mode-syntax-table) 1374 (set-syntax-table emacs-lisp-mode-syntax-table)
1364 (goto-char (point-min)) 1375 (goto-char (point-min))
1365 (if (prog1 1376 (if (prog1
1366 (re-search-forward re nil t) 1377 (re-search-forward re nil t)
1367 (set-syntax-table syntable)) 1378 (set-syntax-table syntable))
1368 (prog2 1379 (progn
1369 (beginning-of-line) 1380 (beginning-of-line)
1370 (current-buffer) 1381 (list (current-buffer) (point)))
1371 (set-buffer calling-buffer)) 1382 (error "Cannot find definition of %s" function))))))))
1372 (goto-char p) 1383
1373 (set-buffer calling-buffer) 1384 (defun function-at-point ()
1374 (error "Cannot find definition of %s" function))))))) 1385 (or (condition-case ()
1375 1386 (let ((stab (syntax-table)))
1376 (defun ff-function-at-point () 1387 (unwind-protect
1377 (condition-case () 1388 (save-excursion
1378 (let ((stab (syntax-table))) 1389 (set-syntax-table emacs-lisp-mode-syntax-table)
1379 (unwind-protect 1390 (or (not (zerop (skip-syntax-backward "_w")))
1380 (save-excursion 1391 (eq (char-syntax (char-after (point))) ?w)
1381 (set-syntax-table emacs-lisp-mode-syntax-table) 1392 (eq (char-syntax (char-after (point))) ?_)
1382 (or (not (zerop (skip-syntax-backward "_w"))) 1393 (forward-sexp -1))
1383 (eq (char-syntax (char-after (point))) ?w) 1394 (skip-chars-forward "`'")
1384 (eq (char-syntax (char-after (point))) ?_) 1395 (let ((obj (read (current-buffer))))
1385 (forward-sexp -1)) 1396 (and (symbolp obj) (fboundp obj) obj)))
1386 (skip-chars-forward "'") 1397 (set-syntax-table stab)))
1387 (let ((obj (read (current-buffer)))) 1398 (error nil))
1388 (and (symbolp obj) (fboundp obj) obj))) 1399 (condition-case ()
1389 (set-syntax-table stab))) 1400 (save-excursion
1390 (error nil))) 1401 (save-restriction
1391 1402 (narrow-to-region (max (point-min) (- (point) 1000)) (point-max))
1392 (defun ff-read-function () 1403 (backward-up-list 1)
1404 (forward-char 1)
1405 (let (obj)
1406 (setq obj (read (current-buffer)))
1407 (and (symbolp obj) (fboundp obj) obj))))
1408 (error nil))))
1409
1410 (defun find-function-read-function ()
1393 "Read and return a function, defaulting to the one near point. 1411 "Read and return a function, defaulting to the one near point.
1394 1412
1395 The function named by `find-function-function' is used to select the 1413 The function named by `find-function-function' is used to select the
1396 default function." 1414 default function."
1397 (let ((fn (funcall find-function-function)) 1415 (let ((fn (funcall find-function-function))
1407 1425
1408 1426
1409 (defun find-function (function &optional path) 1427 (defun find-function (function &optional path)
1410 "Find the definition of the function near point in the current window. 1428 "Find the definition of the function near point in the current window.
1411 1429
1412 Finds the emacs-lisp package containing the definition of the function 1430 Finds the emacs-lisp library containing the definition of the function
1413 near point (selected by `find-function-function') and places point 1431 near point (selected by `find-function-function') and places point
1414 before the definition. 1432 before the definition.
1415 1433
1416 If the optional argument PATH is given, the package where FUNCTION is 1434 If the optional argument PATH is given, the library where FUNCTION is
1417 defined is searched in PATH instead of `load-path'" 1435 defined is searched in PATH instead of `load-path'"
1418 (interactive (ff-read-function)) 1436 (interactive (ff-read-function))
1419 (switch-to-buffer 1437 (let ((buffer-point (find-function-noselect function path)))
1420 (find-function-noselect function path))) 1438 (if buffer-point
1439 (progn
1440 (switch-to-buffer (car buffer-point))
1441 (goto-char (cadr buffer-point))
1442 (recenter 0)))))
1421 1443
1422 (defun find-function-other-window (function &optional path) 1444 (defun find-function-other-window (function &optional path)
1423 "Find the definition of the function near point in the other window. 1445 "Find the definition of the function near point in the other window.
1424 1446
1425 Finds the emacs-lisp package containing the definition of the function 1447 Finds the emacs-lisp library containing the definition of the function
1426 near point (selected by `find-function-function') and places point 1448 near point (selected by `find-function-function') and places point
1427 before the definition. 1449 before the definition.
1428 1450
1429 If the optional argument PATH is given, the package where FUNCTION is 1451 If the optional argument PATH is given, the library where FUNCTION is
1430 defined is searched in PATH instead of `load-path'" 1452 defined is searched in PATH instead of `load-path'"
1431 (interactive (ff-read-function)) 1453 (interactive (ff-read-function))
1432 (switch-to-buffer-other-window 1454 (let ((buffer-point (find-function-noselect function path)))
1433 (find-function-noselect function path))) 1455 (if buffer-point
1456 (progn
1457 (switch-to-buffer-other-window (car buffer-point))
1458 (goto-char (cadr buffer-point))
1459 (recenter 0)))))
1434 1460
1435 (defun find-function-other-frame (function &optional path) 1461 (defun find-function-other-frame (function &optional path)
1436 "Find the definition of the function near point in the another frame. 1462 "Find the definition of the function near point in the another frame.
1437 1463
1438 Finds the emacs-lisp package containing the definition of the function 1464 Finds the emacs-lisp library containing the definition of the function
1439 near point (selected by `find-function-function') and places point 1465 near point (selected by `find-function-function') and places point
1440 before the definition. 1466 before the definition.
1441 1467
1442 If the optional argument PATH is given, the package where FUNCTION is 1468 If the optional argument PATH is given, the library where FUNCTION is
1443 defined is searched in PATH instead of `load-path'" 1469 defined is searched in PATH instead of `load-path'"
1444 (interactive (ff-read-function)) 1470 (interactive (ff-read-function))
1445 (switch-to-buffer-other-frame 1471 (let ((buffer-point (find-function-noselect function path)))
1446 (find-function-noselect function path))) 1472 (if buffer-point
1447 1473 (progn
1448 (define-key mode-specific-map "f" 'find-function) 1474 (switch-to-buffer-other-frame (car buffer-point))
1475 (goto-char (cadr buffer-point))
1476 (recenter 0)))))
1477
1478 (defun find-function-on-key (key)
1479 "Find the function that KEY invokes. KEY is a string."
1480 (interactive "kFind function on key: ")
1481 (let ((defn (key-or-menu-binding key)))
1482 (if (or (null defn) (integerp defn))
1483 (message "%s is undefined" (key-description key))
1484 (if (and (consp defn) (not (eq 'lambda (car-safe defn))))
1485 (message "runs %s" (prin1-to-string defn))
1486 (find-function-other-window defn)))))
1487
1488 (define-key ctl-x-map "F" 'find-function)
1449 (define-key ctl-x-4-map "F" 'find-function-other-window) 1489 (define-key ctl-x-4-map "F" 'find-function-other-window)
1450 (define-key ctl-x-5-map "F" 'find-function-other-frame) 1490 (define-key ctl-x-5-map "F" 'find-function-other-frame)
1451 1491
1452 ;;; help.el ends here 1492 ;;; help.el ends here