comparison lisp/prim/help.el @ 203:850242ba4a81 r20-3b28

Import from CVS: tag r20-3b28
author cvs
date Mon, 13 Aug 2007 10:02:21 +0200
parents acd284d43ca1
children e45d5e7c476e
comparison
equal deleted inserted replaced
202:61eefc8fc970 203:850242ba4a81
259 (setq default-directory (expand-file-name "~/")) 259 (setq default-directory (expand-file-name "~/"))
260 (setq buffer-auto-save-file-name nil) 260 (setq buffer-auto-save-file-name nil)
261 (insert-file-contents (expand-file-name tutorial data-directory)) 261 (insert-file-contents (expand-file-name tutorial data-directory))
262 (goto-char (point-min)) 262 (goto-char (point-min))
263 (search-forward "\n<<") 263 (search-forward "\n<<")
264 (beginning-of-line) 264 (delete-region (point-at-bol) (point-at-eol))
265 (delete-region (point) (progn (end-of-line) (point)))
266 (let ((n (- (window-height (selected-window)) 265 (let ((n (- (window-height (selected-window))
267 (count-lines (point-min) (point)) 266 (count-lines (point-min) (point))
268 6))) 267 6)))
269 (if (< n 12) 268 (if (< n 12)
270 (newline n) 269 (newline n)
274 "Text continues below]") 273 "Text continues below]")
275 (newline (- n (/ n 2))))) 274 (newline (- n (/ n 2)))))
276 (goto-char (point-min)) 275 (goto-char (point-min))
277 (set-buffer-modified-p nil)))) 276 (set-buffer-modified-p nil))))
278 277
279 ;; used by describe-key and describe-key-briefly 278 ;; used by describe-key, describe-key-briefly, insert-key-binding, etc.
280 279
281 (defun key-or-menu-binding (key &optional menu-flag) 280 (defun key-or-menu-binding (key &optional menu-flag)
282 ;; KEY is any value returned by next-command-event 281 "Return the command invoked by KEY.
283 ;; MENU-FLAG is a symbol that should be set to T if KEY is a menu event, 282 Like `key-binding', but handles menu events and toolbar presses correctly.
284 ;; or NIL otherwise 283 KEY is any value returned by `next-command-event'.
284 MENU-FLAG is a symbol that should be set to T if KEY is a menu event,
285 or NIL otherwise"
285 (let (defn) 286 (let (defn)
286 (and menu-flag (set menu-flag nil)) 287 (and menu-flag (set menu-flag nil))
287 ;; If the key typed was really a menu selection, grab the form out 288 ;; If the key typed was really a menu selection, grab the form out
288 ;; of the event object and intuit the function that would be called, 289 ;; of the event object and intuit the function that would be called,
289 ;; and describe that instead. 290 ;; and describe that instead.
293 (let ((event (aref key 0))) 294 (let ((event (aref key 0)))
294 (setq defn (if (eventp event) 295 (setq defn (if (eventp event)
295 (list (event-function event) (event-object event)) 296 (list (event-function event) (event-object event))
296 (cdr event))) 297 (cdr event)))
297 (and menu-flag (set menu-flag t)) 298 (and menu-flag (set menu-flag t))
298 (if (eq (car defn) 'eval) 299 (when (eq (car defn) 'eval)
299 (setq defn (car (cdr defn)))) 300 (setq defn (car (cdr defn))))
300 (if (eq (car-safe defn) 'call-interactively) 301 (when (eq (car-safe defn) 'call-interactively)
301 (setq defn (car (cdr defn)))) 302 (setq defn (car (cdr defn))))
302 (if (and (consp defn) (null (cdr defn))) 303 (when (and (consp defn) (null (cdr defn)))
303 (setq defn (car defn)))) 304 (setq defn (car defn))))
304 ;; else 305 ;; else
305 (setq defn (key-binding key))) 306 (setq defn (key-binding key)))
306 ;; kludge: if a toolbar button was pressed on, try to find the 307 ;; kludge: if a toolbar button was pressed on, try to find the
307 ;; binding of the toolbar button. 308 ;; binding of the toolbar button.
308 (if (and (eq defn 'press-toolbar-button) 309 (if (and (eq defn 'press-toolbar-button)
403 (prog1 (funcall thunk) 404 (prog1 (funcall thunk)
404 (save-excursion 405 (save-excursion
405 (set-buffer standard-output) 406 (set-buffer standard-output)
406 (help-mode)))) 407 (help-mode))))
407 (let ((helpwin (get-buffer-window "*Help*"))) 408 (let ((helpwin (get-buffer-window "*Help*")))
408 (if helpwin 409 (when helpwin
409 (progn 410 (with-current-buffer (window-buffer helpwin)
410 (save-excursion 411 ;; If the *Help* buffer is already displayed on this
411 (set-buffer (window-buffer helpwin)) 412 ;; frame, don't override the previous configuration
412 ;;If the *Help* buffer is already displayed on this 413 (when help-not-visible
413 ;; frame, don't override the previous configuration 414 (set-frame-property (selected-frame)
414 (if help-not-visible 415 'help-window-config winconfig)))
415 (set-frame-property (selected-frame) 416 (when help-selects-help-window
416 'help-window-config winconfig))) 417 (select-window helpwin))
417 (if help-selects-help-window 418 (cond ((eq helpwin (selected-window))
418 (select-window helpwin)) 419 (display-message 'command
419 (cond ((eq helpwin (selected-window)) 420 (substitute-command-keys "Type \\[help-mode-quit] to remove help window, \\[scroll-up] to scroll the help.")))
420 (display-message 'command 421 (was-one-window
421 (substitute-command-keys "Type \\[help-mode-quit] to remove help window, \\[scroll-up] to scroll the help."))) 422 (display-message 'command
422 (was-one-window 423 (substitute-command-keys "Type \\[delete-other-windows] to remove help window, \\[scroll-other-window] to scroll the help.")))
423 (display-message 'command 424 (t
424 (substitute-command-keys "Type \\[delete-other-windows] to remove help window, \\[scroll-other-window] to scroll the help."))) 425 (display-message 'command
425 (t 426 (substitute-command-keys "Type \\[switch-to-buffer-other-window] to restore the other window, \\[scroll-other-window] to scroll the help.")))))))))
426 (display-message 'command
427 (substitute-command-keys "Type \\[switch-to-buffer-other-window] to restore the other window, \\[scroll-other-window] to scroll the help."))))))))))
428 427
429 (defun describe-key (key) 428 (defun describe-key (key)
430 "Display documentation of the function invoked by KEY. 429 "Display documentation of the function invoked by KEY.
431 KEY is a string, or vector of events. 430 KEY is a string, or vector of events.
432 When called interactively, KEY may also be a menu selection." 431 When called interactively, KEY may also be a menu selection."
738 (insert (documentation 'help-for-help))) 737 (insert (documentation 'help-for-help)))
739 (goto-char (point-min)) 738 (goto-char (point-min))
740 (while (or (equal event help-key) 739 (while (or (equal event help-key)
741 (eq char ??) 740 (eq char ??)
742 (eq 'help-command (key-binding event)) 741 (eq 'help-command (key-binding event))
743 (eq char ? ) 742 (eq char ?\ )
744 (eq 'scroll-up (key-binding event)) 743 (eq 'scroll-up (key-binding event))
745 (eq char ?\177) 744 (eq char ?\177)
746 (and (not (eq char ?b)) 745 (and (not (eq char ?b))
747 (eq 'scroll-down (key-binding event)))) 746 (eq 'scroll-down (key-binding event))))
748 (if (or (eq char ? ) 747 (if (or (eq char ?\ )
749 (eq 'scroll-up (key-binding event))) 748 (eq 'scroll-up (key-binding event)))
750 (scroll-up)) 749 (scroll-up))
751 (if (or (eq char ?\177) 750 (if (or (eq char ?\177)
752 (and (not (eq char ?b)) 751 (and (not (eq char ?b))
753 (eq 'scroll-down (key-binding event)))) 752 (eq 'scroll-down (key-binding event))))
765 (message nil) 764 (message nil)
766 (if defn 765 (if defn
767 (call-interactively defn) 766 (call-interactively defn)
768 (ding))))) 767 (ding)))))
769 768
770 ;; Return a function which is called by the list containing point.
771 ;; If that gives no function, return a function whose name is around point.
772 ;; If that doesn't give a function, return nil.
773 (defun function-called-at-point () 769 (defun function-called-at-point ()
770 "Return the function which is called by the list containing point.
771 If that gives no function, return the function whose name is around point.
772 If that doesn't give a function, return nil."
774 (or (condition-case () 773 (or (condition-case ()
775 (save-excursion 774 (save-excursion
776 (save-restriction 775 (save-restriction
777 (narrow-to-region (max (point-min) (- (point) 1000)) (point-max)) 776 (narrow-to-region (max (point-min) (- (point) 1000)) (point-max))
778 (backward-up-list 1) 777 (backward-up-list 1)
794 (let ((obj (read (current-buffer)))) 793 (let ((obj (read (current-buffer))))
795 (and (symbolp obj) (fboundp obj) obj))) 794 (and (symbolp obj) (fboundp obj) obj)))
796 (set-syntax-table stab))) 795 (set-syntax-table stab)))
797 (error nil)))) 796 (error nil))))
798 797
799 ;; default to nil for the non-hackers? 798 (defun function-at-point ()
799 "Return the function whose name is around point.
800 If that gives no function, return the function which is called by the
801 list containing point. If that doesn't give a function, return nil."
802 (or (condition-case ()
803 (let ((stab (syntax-table)))
804 (unwind-protect
805 (save-excursion
806 (set-syntax-table emacs-lisp-mode-syntax-table)
807 (or (not (zerop (skip-syntax-backward "_w")))
808 (eq (char-syntax (char-after (point))) ?w)
809 (eq (char-syntax (char-after (point))) ?_)
810 (forward-sexp -1))
811 (skip-chars-forward "`'")
812 (let ((obj (read (current-buffer))))
813 (and (symbolp obj) (fboundp obj) obj)))
814 (set-syntax-table stab)))
815 (error nil))
816 (condition-case ()
817 (save-excursion
818 (save-restriction
819 (narrow-to-region (max (point-min) (- (point) 1000)) (point-max))
820 (backward-up-list 1)
821 (forward-char 1)
822 (let (obj)
823 (setq obj (read (current-buffer)))
824 (and (symbolp obj) (fboundp obj) obj))))
825 (error nil))))
826
827 ;; Default to nil for the non-hackers? Not until we find a way to
828 ;; distinguish hackers from non-hackers automatically!
800 (defcustom describe-function-show-arglist t 829 (defcustom describe-function-show-arglist t
801 "*If non-nil, describe-function will show its arglist, 830 "*If non-nil, describe-function will show its arglist,
802 unless the function is autoloaded." 831 unless the function is autoloaded."
803 :type 'boolean 832 :type 'boolean
804 :group 'help-appearance) 833 :group 'help-appearance)
805 834
835 (defcustom find-function-function 'function-at-point
836 "*The function used by `describe-function', `where-is' and
837 `find-function' to select the function near point.
838
839 For example `function-at-point' or `function-called-at-point'."
840 :type 'function
841 :group 'help)
842
806 (defun describe-function-find-file (function) 843 (defun describe-function-find-file (function)
807 (let ((files load-history) 844 (let ((files load-history)
808 file) 845 file)
809 (while files 846 (while files
810 (if (memq function (cdr (car files))) 847 (if (memq function (cdr (car files)))
811 (setq file (car (car files)) 848 (setq file (car (car files))
812 files nil)) 849 files nil))
813 (setq files (cdr files))) 850 (setq files (cdr files)))
814 file)) 851 file))
815 852
816 (defun describe-function (function) 853 (defun describe-function (function)
817 "Display the full documentation of FUNCTION (a symbol). 854 "Display the full documentation of FUNCTION (a symbol).
818 When run interactively, it defaults to any function found by the 855 When run interactively, it defaults to any function found by the
819 value of `find-function-function'." 856 value of `find-function-function'."
828 obarray 'fboundp t nil 'function-history)))) 865 obarray 'fboundp t nil 'function-history))))
829 (list (if (equal val "") fn (intern val))))) 866 (list (if (equal val "") fn (intern val)))))
830 (with-displaying-help-buffer 867 (with-displaying-help-buffer
831 (lambda () 868 (lambda ()
832 (describe-function-1 function standard-output) 869 (describe-function-1 function standard-output)
833 (save-excursion 870 ;; Return the text we displayed.
834 (set-buffer standard-output) 871 (buffer-string nil nil standard-output))))
835 ;; Return the text we displayed.
836 (buffer-string)))))
837 872
838 (defun function-obsolete-p (function) 873 (defun function-obsolete-p (function)
839 "Return non-nil if FUNCTION is obsolete." 874 "Return non-nil if FUNCTION is obsolete."
840 (not (null (get function 'byte-obsolete-info)))) 875 (not (null (get function 'byte-obsolete-info))))
841 876
906 (setq def (symbol-function def))) 941 (setq def (symbol-function def)))
907 (if (compiled-function-p def) 942 (if (compiled-function-p def)
908 (setq file-name (compiled-function-annotation def))) 943 (setq file-name (compiled-function-annotation def)))
909 (if (eq 'macro (car-safe def)) 944 (if (eq 'macro (car-safe def))
910 (setq fndef (cdr def) 945 (setq fndef (cdr def)
911 home (and (compiled-function-p (cdr def)) 946 file-name (and (compiled-function-p (cdr def))
912 (compiled-function-annotation (cdr def))) 947 (compiled-function-annotation (cdr def)))
913 macrop t) 948 macrop t)
914 (setq fndef def)) 949 (setq fndef def))
915 (if aliases (princ aliases stream)) 950 (if aliases (princ aliases stream))
916 (let ((int #'(lambda (string an-p macro-p) 951 (let ((int #'(lambda (string an-p macro-p)
917 (princ (format 952 (princ (format
1008 (unless (or (equal doc "") 1043 (unless (or (equal doc "")
1009 (eq ?\n (aref doc (1- (length doc))))) 1044 (eq ?\n (aref doc (1- (length doc)))))
1010 (terpri stream)))))))) 1045 (terpri stream))))))))
1011 1046
1012 1047
1013 (defun describe-function-arglist (function) 1048 ;;; ## this doesn't seem to be used for anything
1014 (interactive (list (or (function-called-at-point) 1049 ;; (defun describe-function-arglist (function)
1015 (error "no function call at point")))) 1050 ;; (interactive (list (or (function-called-at-point)
1016 (let ((b nil)) 1051 ;; (error "no function call at point"))))
1017 (unwind-protect 1052 ;; (let ((b nil))
1018 (save-excursion 1053 ;; (unwind-protect
1019 (set-buffer (setq b (get-buffer-create " *arglist*"))) 1054 ;; (save-excursion
1020 (buffer-disable-undo b) 1055 ;; (set-buffer (setq b (get-buffer-create " *arglist*")))
1021 (erase-buffer) 1056 ;; (buffer-disable-undo b)
1022 (describe-function-1 function b t) 1057 ;; (erase-buffer)
1023 (goto-char (point-min)) 1058 ;; (describe-function-1 function b t)
1024 (end-of-line) 1059 ;; (goto-char (point-min))
1025 (or (eobp) (delete-char 1)) 1060 ;; (end-of-line)
1026 (just-one-space) 1061 ;; (or (eobp) (delete-char 1))
1027 (end-of-line) 1062 ;; (just-one-space)
1028 (message (buffer-substring (point-min) (point)))) 1063 ;; (end-of-line)
1029 (and b (kill-buffer b))))) 1064 ;; (message (buffer-substring (point-min) (point))))
1065 ;; (and b (kill-buffer b)))))
1030 1066
1031 1067
1032 (defun variable-at-point () 1068 (defun variable-at-point ()
1033 (ignore-errors 1069 (ignore-errors
1034 (let ((stab (syntax-table))) 1070 (let ((stab (syntax-table)))
1071 (format "use `%s' instead." compatible)))))) 1107 (format "use `%s' instead." compatible))))))
1072 1108
1073 (defun built-in-variable-doc (variable) 1109 (defun built-in-variable-doc (variable)
1074 "Return a string describing whether VARIABLE is built-in." 1110 "Return a string describing whether VARIABLE is built-in."
1075 (let ((type (built-in-variable-type variable))) 1111 (let ((type (built-in-variable-type variable)))
1076 (cond ((eq type 'integer) "a built-in integer variable") 1112 (case type
1077 ((eq type 'const-integer) "a built-in constant integer variable") 1113 (integer "a built-in integer variable")
1078 ((eq type 'boolean) "a built-in boolean variable") 1114 (const-integer "a built-in constant integer variable")
1079 ((eq type 'const-boolean) "a built-in constant boolean variable") 1115 (boolean "a built-in boolean variable")
1080 ((eq type 'object) "a simple built-in variable") 1116 (const-boolean "a built-in constant boolean variable")
1081 ((eq type 'const-object) "a simple built-in constant variable") 1117 (object "a simple built-in variable")
1082 ((eq type 'const-specifier) "a built-in constant specifier variable") 1118 (const-object "a simple built-in constant variable")
1083 ((eq type 'current-buffer) "a built-in buffer-local variable") 1119 (const-specifier "a built-in constant specifier variable")
1084 ((eq type 'const-current-buffer) 1120 (current-buffer "a built-in buffer-local variable")
1085 "a built-in constant buffer-local variable") 1121 (const-current-buffer "a built-in constant buffer-local variable")
1086 ((eq type 'default-buffer) 1122 (default-buffer "a built-in default buffer-local variable")
1087 "a built-in default buffer-local variable") 1123 (selected-console "a built-in console-local variable")
1088 ((eq type 'selected-console) "a built-in console-local variable") 1124 (const-selected-console "a built-in constant console-local variable")
1089 ((eq type 'const-selected-console) 1125 (default-console "a built-in default console-local variable")
1090 "a built-in constant console-local variable") 1126 (t
1091 ((eq type 'default-console) 1127 (if type "an unknown type of built-in variable?"
1092 "a built-in default console-local variable") 1128 "a variable declared in Lisp")))))
1093 (type "an unknown type of built-in variable?")
1094 (t "a variable declared in Lisp"))))
1095 1129
1096 (defun describe-variable (variable) 1130 (defun describe-variable (variable)
1097 "Display the full documentation of VARIABLE (a symbol)." 1131 "Display the full documentation of VARIABLE (a symbol)."
1098 (interactive 1132 (interactive
1099 (let* ((v (variable-at-point)) 1133 (let* ((v (variable-at-point))
1157 (princ "Documentation:") 1191 (princ "Documentation:")
1158 (terpri) 1192 (terpri)
1159 (let ((doc (documentation-property variable 'variable-documentation)) 1193 (let ((doc (documentation-property variable 'variable-documentation))
1160 (obsolete (variable-obsoleteness-doc origvar)) 1194 (obsolete (variable-obsoleteness-doc origvar))
1161 (compatible (variable-compatibility-doc origvar))) 1195 (compatible (variable-compatibility-doc origvar)))
1162 (if obsolete 1196 (when obsolete
1163 (progn 1197 (princ obsolete)
1164 (princ obsolete) 1198 (terpri)
1165 (terpri) 1199 (terpri))
1166 (terpri))) 1200 (when compatible
1167 (if compatible 1201 (princ compatible)
1168 (progn 1202 (terpri)
1169 (princ compatible) 1203 (terpri))
1170 (terpri)
1171 (terpri)))
1172 ;; don't bother to print anything if variable is obsolete and aliased. 1204 ;; don't bother to print anything if variable is obsolete and aliased.
1173 (when (or (not obsolete) (not aliases)) 1205 (when (or (not obsolete) (not aliases))
1174 (if doc 1206 (if doc
1175 ;; note: documentation-property calls substitute-command-keys. 1207 ;; note: documentation-property calls substitute-command-keys.
1176 (princ doc) 1208 (princ doc)
1177 (princ "not documented as a variable.")) 1209 (princ "not documented as a variable."))
1178 (terpri))) 1210 (terpri)))
1179 (save-excursion 1211 ;; Return the text we displayed.
1180 (set-buffer standard-output) 1212 (buffer-string nil nil standard-output)))))
1181 ;; Return the text we displayed.
1182 (buffer-string))))))
1183 1213
1184 (defun sorted-key-descriptions (keys &optional separator) 1214 (defun sorted-key-descriptions (keys &optional separator)
1185 "Sort and separate the key descriptions for KEYS. 1215 "Sort and separate the key descriptions for KEYS.
1186 The sorting is done by length (shortest bindings first), and the bindings 1216 The sorting is done by length (shortest bindings first), and the bindings
1187 are separated with SEPARATOR (`, ' by default)." 1217 are separated with SEPARATOR (\", \" by default)."
1188 (mapconcat 'key-description 1218 (mapconcat 'key-description
1189 (sort keys #'(lambda (x y) 1219 (sort keys #'(lambda (x y)
1190 (< (length x) (length y)))) 1220 (< (length x) (length y))))
1191 (or separator ", "))) 1221 (or separator ", ")))
1192 1222
1208 (if keys 1238 (if keys
1209 (message "%s is on %s" definition (sorted-key-descriptions keys)) 1239 (message "%s is on %s" definition (sorted-key-descriptions keys))
1210 (message "%s is not on any keys" definition))) 1240 (message "%s is not on any keys" definition)))
1211 nil) 1241 nil)
1212 1242
1213 ;; Synched with Emacs 19.35 1243 ;; `locate-library' moved to "packages.el"
1214 ;; Moved to packages.el 1244
1215 ;(defun locate-library (library &optional nosuffix path interactive-call)
1216 ; "Show the precise file name of Emacs library LIBRARY.
1217 ;This command searches the directories in `load-path' like `M-x load-library'
1218 ;to find the file that `M-x load-library RET LIBRARY RET' would load.
1219 ;Optional second arg NOSUFFIX non-nil means don't add suffixes `.elc' or `.el'
1220 ;to the specified name LIBRARY.
1221
1222 ;If the optional third arg PATH is specified, that list of directories
1223 ;is used instead of `load-path'."
1224 ; (interactive (list (read-string "Locate library: ")
1225 ; nil nil
1226 ; t))
1227 ; (let (result)
1228 ; (catch 'answer
1229 ; (mapcar
1230 ; (lambda (dir)
1231 ; (mapcar
1232 ; (lambda (suf)
1233 ; (let ((try (expand-file-name (concat library suf) dir)))
1234 ; (and (file-readable-p try)
1235 ; (null (file-directory-p try))
1236 ; (progn
1237 ; (setq result try)
1238 ; (throw 'answer try)))))
1239 ; (if nosuffix
1240 ; '("")
1241 ; (let ((basic '(".elc" ".el" ""))
1242 ; (compressed '(".Z" ".gz" "")))
1243 ; ;; If autocompression mode is on,
1244 ; ;; consider all combinations of library suffixes
1245 ; ;; and compression suffixes.
1246 ; (if (rassq 'jka-compr-handler file-name-handler-alist)
1247 ; (apply 'nconc
1248 ; (mapcar (lambda (compelt)
1249 ; (mapcar (lambda (baselt)
1250 ; (concat baselt compelt))
1251 ; basic))
1252 ; compressed))
1253 ; basic)))))
1254 ; (or path load-path)))
1255 ; (and interactive-call
1256 ; (if result
1257 ; (message "Library is file %s" result)
1258 ; (message "No library %s in search path" library)))
1259 ; result))
1260 1245
1261 ;; Functions ported from C into Lisp in XEmacs 1246 ;; Functions ported from C into Lisp in XEmacs
1262 1247
1263 (defun describe-syntax () 1248 (defun describe-syntax ()
1264 "Describe the syntax specifications in the syntax table. 1249 "Describe the syntax specifications in the syntax table.
1321 (progn 1306 (progn
1322 (princ "network stream connection " stream) 1307 (princ "network stream connection " stream)
1323 (princ (car pid) stream) 1308 (princ (car pid) stream)
1324 (princ "@" stream) 1309 (princ "@" stream)
1325 (princ (cdr pid) stream)) 1310 (princ (cdr pid) stream))
1326 (let ((cmd (process-command p))) 1311 (let ((cmd (process-command p)))
1327 (while cmd 1312 (while cmd
1328 (princ (car cmd) stream) 1313 (princ (car cmd) stream)
1329 (setq cmd (cdr cmd)) 1314 (setq cmd (cdr cmd))
1330 (if cmd (princ " " stream))))) 1315 (if cmd (princ " " stream)))))
1331 (terpri stream))))))) 1316 (terpri stream)))))))
1332 1317
1333 1318 ;; `find-function' et al moved to "find-func.el"
1334 ;; find-function stuff
1335
1336 (defvar find-function-function 'function-at-point
1337 "*The function used by `describe-function', `where-is' and
1338 `find-function' to select the function near point.
1339
1340 For example `function-at-point' or `function-called-at-point'.")
1341
1342 (defvar find-function-source-path nil
1343 "The default list of directories where find-function searches.
1344
1345 If this variable is `nil' then find-function searches `load-path' by
1346 default.")
1347
1348
1349 (defun find-function-noselect (function)
1350 "Returns a pair `(buffer . point)' pointing to the definition of FUNCTION.
1351
1352 Finds the Emacs Lisp library containing the definition of FUNCTION
1353 in a buffer and the point of the definition. The buffer is
1354 not selected.
1355
1356 The library where FUNCTION is defined is searched for in
1357 `find-function-source-path', if non `nil', otherwise in `load-path'."
1358 (and (subrp (symbol-function function))
1359 (error "%s is a primitive function" function))
1360 (if (not function)
1361 (error "You didn't specify a function"))
1362 (let ((def (symbol-function function))
1363 library aliases)
1364 (while (symbolp def)
1365 (or (eq def function)
1366 (if aliases
1367 (setq aliases (concat aliases
1368 (format ", which is an alias for %s"
1369 (symbol-name def))))
1370 (setq aliases (format "an alias for %s" (symbol-name def)))))
1371 (setq function (symbol-function function)
1372 def (symbol-function function)))
1373 (if aliases
1374 (message aliases))
1375 (setq library
1376 (cond ((eq (car-safe def) 'autoload)
1377 (nth 1 def))
1378 ((describe-function-find-file function))
1379 ((compiled-function-p def)
1380 (substring (compiled-function-annotation def) 0 -4))))
1381 (if (null library)
1382 (error (format "Don't know where `%s' is defined" function)))
1383 (if (string-match "\\.el\\(c\\)\\'" library)
1384 (setq library (substring library 0 (match-beginning 1))))
1385 (let* ((path find-function-source-path)
1386 (filename (if (file-exists-p library)
1387 library
1388 (if (string-match "\\(\\.el\\)\\'" library)
1389 (setq library (substring library 0
1390 (match-beginning
1391 1))))
1392 (or (locate-library (concat library ".el") t path)
1393 (locate-library library t path)))))
1394 (if (not filename)
1395 (error "The library \"%s\" is not in the path." library))
1396 (with-current-buffer (find-file-noselect filename)
1397 (save-match-data
1398 (let (;; avoid defconst, defgroup, defvar (any others?)
1399 (regexp
1400 (format "^\\s-*(def[^cgv\W]\\w+\\*?\\s-+%s\\s-" function))
1401 (syntable (syntax-table)))
1402 (set-syntax-table emacs-lisp-mode-syntax-table)
1403 (goto-char (point-min))
1404 (if (prog1
1405 (re-search-forward regexp nil t)
1406 (set-syntax-table syntable))
1407 (progn
1408 (beginning-of-line)
1409 (cons (current-buffer) (point)))
1410 (error "Cannot find definition of `%s'" function))))))))
1411
1412 (defun function-at-point ()
1413 (or (condition-case ()
1414 (let ((stab (syntax-table)))
1415 (unwind-protect
1416 (save-excursion
1417 (set-syntax-table emacs-lisp-mode-syntax-table)
1418 (or (not (zerop (skip-syntax-backward "_w")))
1419 (eq (char-syntax (char-after (point))) ?w)
1420 (eq (char-syntax (char-after (point))) ?_)
1421 (forward-sexp -1))
1422 (skip-chars-forward "`'")
1423 (let ((obj (read (current-buffer))))
1424 (and (symbolp obj) (fboundp obj) obj)))
1425 (set-syntax-table stab)))
1426 (error nil))
1427 (condition-case ()
1428 (save-excursion
1429 (save-restriction
1430 (narrow-to-region (max (point-min) (- (point) 1000)) (point-max))
1431 (backward-up-list 1)
1432 (forward-char 1)
1433 (let (obj)
1434 (setq obj (read (current-buffer)))
1435 (and (symbolp obj) (fboundp obj) obj))))
1436 (error nil))))
1437
1438 (defun find-function-read-function ()
1439 "Read and return a function, defaulting to the one near point.
1440
1441 The function named by `find-function-function' is used to select the
1442 default function."
1443 (let ((fn (funcall find-function-function))
1444 (enable-recursive-minibuffers t)
1445 val)
1446 (setq val (completing-read
1447 (if fn
1448 (format "Find function (default %s): " fn)
1449 "Find function: ")
1450 obarray 'fboundp t nil 'function-history))
1451 (list (if (equal val "")
1452 fn (intern val)))))
1453
1454 (defun find-function-do-it (function switch-fn)
1455 "find elisp FUNCTION in a buffer and display it with SWITCH-FN.
1456 Point is saved in the buffer if it is one of the current buffers."
1457 (let ((orig-point (point))
1458 (orig-buffers (buffer-list))
1459 (buffer-point (find-function-noselect function)))
1460 (if buffer-point
1461 (progn
1462 (funcall switch-fn (car buffer-point))
1463 (if (memq (car buffer-point) orig-buffers)
1464 (push-mark orig-point))
1465 (goto-char (cdr buffer-point))
1466 (recenter 0)))))
1467
1468 (defun find-function (function)
1469 "Find the definition of the function near point in the current window.
1470
1471 Finds the Emacs Lisp library containing the definition of the function
1472 near point (selected by `find-function-function') in a buffer and
1473 places point before the definition. Point is saved in the buffer if
1474 it is one of the current buffers.
1475
1476 The library where FUNCTION is defined is searched for in
1477 `find-function-source-path', if non `nil', otherwise in `load-path'."
1478 (interactive (find-function-read-function))
1479 (find-function-do-it function 'switch-to-buffer))
1480
1481 (defun find-function-other-window (function)
1482 "Find the definition of the function near point in the other window.
1483
1484 Finds the Emacs Lisp library containing the definition of the function
1485 near point (selected by `find-function-function') in a buffer and
1486 places point before the definition. Point is saved in the buffer if
1487 it is one of the current buffers.
1488
1489 The library where FUNCTION is defined is searched for in
1490 `find-function-source-path', if non `nil', otherwise in `load-path'."
1491 (interactive (find-function-read-function))
1492 (find-function-do-it function 'switch-to-buffer-other-window))
1493
1494 (defun find-function-other-frame (function)
1495 "Find the definition of the function near point in the another frame.
1496
1497 Finds the Emacs Lisp library containing the definition of the function
1498 near point (selected by `find-function-function') in a buffer and
1499 places point before the definition. Point is saved in the buffer if
1500 it is one of the current buffers.
1501
1502 The library where FUNCTION is defined is searched for in
1503 `find-function-source-path', if non `nil', otherwise in `load-path'."
1504 (interactive (find-function-read-function))
1505 (find-function-do-it function 'switch-to-buffer-other-frame))
1506
1507 (defun find-function-on-key (key)
1508 "Find the function that KEY invokes. KEY is a string.
1509 Point is saved if FUNCTION is in the current buffer."
1510 (interactive "kFind function on key: ")
1511 (let ((defn (key-or-menu-binding key)))
1512 (if (or (null defn) (integerp defn))
1513 (message "%s is undefined" (key-description key))
1514 (if (and (consp defn) (not (eq 'lambda (car-safe defn))))
1515 (message "runs %s" (prin1-to-string defn))
1516 (find-function-other-window defn)))))
1517
1518 (defun find-function-at-point ()
1519 "Find directly the function at point in the other window."
1520 (interactive)
1521 (let ((symb (function-at-point)))
1522 (when symb
1523 (find-function-other-window symb))))
1524
1525 (define-key ctl-x-map "F" 'find-function)
1526 (define-key ctl-x-4-map "F" 'find-function-other-window)
1527 (define-key ctl-x-5-map "F" 'find-function-other-frame)
1528 1319
1529 ;;; help.el ends here 1320 ;;; help.el ends here