Mercurial > hg > xemacs-beta
comparison lisp/help.el @ 442:abe6d1db359e r21-2-36
Import from CVS: tag r21-2-36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:35:02 +0200 |
parents | 8de8e3f6228a |
children | 576fb035e263 |
comparison
equal
deleted
inserted
replaced
441:72a7cfa4a488 | 442:abe6d1db359e |
---|---|
238 "Exit from help mode, possibly restoring the previous window configuration. | 238 "Exit from help mode, possibly restoring the previous window configuration. |
239 If the optional argument BURY is non-nil, the help buffer is buried, | 239 If the optional argument BURY is non-nil, the help buffer is buried, |
240 otherwise it is killed." | 240 otherwise it is killed." |
241 (interactive) | 241 (interactive) |
242 (let ((buf (current-buffer))) | 242 (let ((buf (current-buffer))) |
243 (cond ((frame-property (selected-frame) 'help-window-config) | 243 (cond (help-window-config |
244 (set-window-configuration | 244 (set-window-configuration help-window-config)) |
245 (frame-property (selected-frame) 'help-window-config)) | |
246 (set-frame-property (selected-frame) 'help-window-config nil)) | |
247 ((not (one-window-p)) | 245 ((not (one-window-p)) |
248 (delete-window))) | 246 (delete-window))) |
249 (if bury | 247 (if bury |
250 (bury-buffer buf) | 248 (bury-buffer buf) |
251 (kill-buffer buf)))) | 249 (kill-buffer buf)))) |
478 ;; #### BEFORE you rush to make this a macro, think about backward | 476 ;; #### BEFORE you rush to make this a macro, think about backward |
479 ;; compatibility. The right way would be to create a macro with | 477 ;; compatibility. The right way would be to create a macro with |
480 ;; another name (which is a shame, because w-d-h-b is a perfect name | 478 ;; another name (which is a shame, because w-d-h-b is a perfect name |
481 ;; for a macro) that uses with-displaying-help-buffer internally. | 479 ;; for a macro) that uses with-displaying-help-buffer internally. |
482 | 480 |
481 (defcustom mode-for-help 'help-mode | |
482 "*Mode that help buffers are put into.") | |
483 | |
484 (defvar help-sticky-window nil | |
485 ;; Window into which help buffers will be displayed, rather than | |
486 ;; always searching for a new one. This is INTERNAL and liable to | |
487 ;; change its interface and/or name at any moment. It should be | |
488 ;; bound, not set. | |
489 ) | |
490 | |
491 (defvar help-window-config nil) | |
492 | |
493 (make-variable-buffer-local 'help-window-config) | |
494 (put 'help-window-config 'permanent-local t) | |
495 | |
483 (defun with-displaying-help-buffer (thunk &optional name) | 496 (defun with-displaying-help-buffer (thunk &optional name) |
484 "Form which makes a help buffer with given NAME and evaluates BODY there. | 497 "Form which makes a help buffer with given NAME and evaluates BODY there. |
485 The actual name of the buffer is generated by the function `help-buffer-name'." | 498 The actual name of the buffer is generated by the function `help-buffer-name'." |
486 (let* ((winconfig (current-window-configuration)) | 499 (let* ((winconfig (current-window-configuration)) |
487 (was-one-window (one-window-p)) | 500 (was-one-window (one-window-p)) |
490 (not (and (windows-of-buffer buffer-name) ;shortcut | 503 (not (and (windows-of-buffer buffer-name) ;shortcut |
491 (memq (selected-frame) | 504 (memq (selected-frame) |
492 (mapcar 'window-frame | 505 (mapcar 'window-frame |
493 (windows-of-buffer buffer-name))))))) | 506 (windows-of-buffer buffer-name))))))) |
494 (help-register-and-maybe-prune-excess buffer-name) | 507 (help-register-and-maybe-prune-excess buffer-name) |
495 (prog1 (with-output-to-temp-buffer buffer-name | 508 ;; if help-sticky-window is bogus or deleted, get rid of it. |
496 (prog1 (funcall thunk) | 509 (if (and help-sticky-window (or (not (windowp help-sticky-window)) |
497 (save-excursion | 510 (not (window-live-p help-sticky-window)))) |
498 (set-buffer standard-output) | 511 (setq help-sticky-window nil)) |
499 (help-mode)))) | 512 (prog1 |
513 (let ((temp-buffer-show-function | |
514 (if help-sticky-window | |
515 #'(lambda (buffer) | |
516 (set-window-buffer help-sticky-window buffer)) | |
517 temp-buffer-show-function))) | |
518 (with-output-to-temp-buffer buffer-name | |
519 (prog1 (funcall thunk) | |
520 (save-excursion | |
521 (set-buffer standard-output) | |
522 (funcall mode-for-help))))) | |
500 (let ((helpwin (get-buffer-window buffer-name))) | 523 (let ((helpwin (get-buffer-window buffer-name))) |
501 (when helpwin | 524 (when helpwin |
502 (with-current-buffer (window-buffer helpwin) | 525 ;; If the *Help* buffer is already displayed on this |
503 ;; If the *Help* buffer is already displayed on this | 526 ;; frame, don't override the previous configuration |
504 ;; frame, don't override the previous configuration | 527 (when help-not-visible |
505 (when help-not-visible | 528 (with-current-buffer (window-buffer helpwin) |
506 (set-frame-property (selected-frame) | 529 (setq help-window-config winconfig))) |
507 'help-window-config winconfig))) | |
508 (when help-selects-help-window | 530 (when help-selects-help-window |
509 (select-window helpwin)) | 531 (select-window helpwin)) |
510 (cond ((eq helpwin (selected-window)) | 532 (cond ((eq helpwin (selected-window)) |
511 (display-message 'command | 533 (display-message 'command |
512 (substitute-command-keys "Type \\[help-mode-quit] to remove help window, \\[scroll-up] to scroll the help."))) | 534 (substitute-command-keys "Type \\[help-mode-quit] to remove help window, \\[scroll-up] to scroll the help."))) |
728 (interactive) | 750 (interactive) |
729 (if (and (boundp 'Installation-string) | 751 (if (and (boundp 'Installation-string) |
730 (stringp Installation-string)) | 752 (stringp Installation-string)) |
731 (with-displaying-help-buffer | 753 (with-displaying-help-buffer |
732 (lambda () | 754 (lambda () |
733 (princ Installation-string)) | 755 (princ |
756 (if (fboundp 'decode-coding-string) | |
757 (decode-coding-string Installation-string 'automatic-conversion) | |
758 Installation-string))) | |
734 "Installation") | 759 "Installation") |
735 (error "No Installation information available."))) | 760 (error "No Installation information available."))) |
736 | 761 |
737 (defun view-emacs-news () | 762 (defun view-emacs-news () |
738 "Display info on recent changes to XEmacs." | 763 "Display info on recent changes to XEmacs." |
740 (find-file (locate-data-file "NEWS"))) | 765 (find-file (locate-data-file "NEWS"))) |
741 | 766 |
742 (defun xemacs-www-page () | 767 (defun xemacs-www-page () |
743 "Go to the XEmacs World Wide Web page." | 768 "Go to the XEmacs World Wide Web page." |
744 (interactive) | 769 (interactive) |
745 (if (boundp 'browse-url-browser-function) | 770 (if (fboundp 'browse-url) |
746 (funcall browse-url-browser-function "http://www.xemacs.org/") | 771 (browse-url "http://www.xemacs.org/") |
747 (error "xemacs-www-page requires browse-url"))) | 772 (error "xemacs-www-page requires browse-url"))) |
748 | 773 |
749 (defun xemacs-www-faq () | 774 (defun xemacs-www-faq () |
750 "View the latest and greatest XEmacs FAQ using the World Wide Web." | 775 "View the latest and greatest XEmacs FAQ using the World Wide Web." |
751 (interactive) | 776 (interactive) |
752 (if (boundp 'browse-url-browser-function) | 777 (if (fboundp 'browse-url) |
753 (funcall browse-url-browser-function | 778 (browse-url "http://www.xemacs.org/faq/index.html") |
754 "http://www.xemacs.org/faq/index.html") | |
755 (error "xemacs-www-faq requires browse-url"))) | 779 (error "xemacs-www-faq requires browse-url"))) |
756 | 780 |
757 (defun xemacs-local-faq () | 781 (defun xemacs-local-faq () |
758 "View the local copy of the XEmacs FAQ. | 782 "View the local copy of the XEmacs FAQ. |
759 If you have access to the World Wide Web, you should use `xemacs-www-faq' | 783 If you have access to the World Wide Web, you should use `xemacs-www-faq' |
917 (forward-char 1) | 941 (forward-char 1) |
918 (let (obj) | 942 (let (obj) |
919 (setq obj (read (current-buffer))) | 943 (setq obj (read (current-buffer))) |
920 (and (symbolp obj) (fboundp obj) obj))))))) | 944 (and (symbolp obj) (fboundp obj) obj))))))) |
921 | 945 |
946 (defun function-at-event (event) | |
947 "Return the function whose name is around the position of EVENT. | |
948 EVENT should be a mouse event. When calling from a popup or context menu, | |
949 use `last-popup-menu-event' to find out where the mouse was clicked. | |
950 \(You cannot use (interactive \"e\"), unfortunately. This returns a | |
951 misc-user event.) | |
952 | |
953 If the event contains no position, or the position is not over text, or | |
954 there is no function around that point, nil is returned." | |
955 (if (and event (event-buffer event) (event-point event)) | |
956 (save-excursion | |
957 (set-buffer (event-buffer event)) | |
958 (goto-char (event-point event)) | |
959 (function-at-point)))) | |
960 | |
922 ;; Default to nil for the non-hackers? Not until we find a way to | 961 ;; Default to nil for the non-hackers? Not until we find a way to |
923 ;; distinguish hackers from non-hackers automatically! | 962 ;; distinguish hackers from non-hackers automatically! |
924 (defcustom describe-function-show-arglist t | 963 (defcustom describe-function-show-arglist t |
925 "*If non-nil, describe-function will show its arglist, | 964 "*If non-nil, describe-function will show its arglist, |
926 unless the function is autoloaded." | 965 unless the function is autoloaded." |
1060 (void-function "")))) | 1099 (void-function "")))) |
1061 (if (and strip-arglist | 1100 (if (and strip-arglist |
1062 (string-match "[\n\t ]*\narguments: ?(\\(.*\\))\n?\\'" doc)) | 1101 (string-match "[\n\t ]*\narguments: ?(\\(.*\\))\n?\\'" doc)) |
1063 (setq doc (substring doc 0 (match-beginning 0)))) | 1102 (setq doc (substring doc 0 (match-beginning 0)))) |
1064 doc)) | 1103 doc)) |
1104 ; (let ((name-char "[-+a-zA-Z0-9_*]") (sym-char "[-+a-zA-Z0-9_:*]")) | |
1105 ; (list | |
1106 ; ;; | |
1107 ; ;; The symbol itself. | |
1108 ; (list (concat "\\`\\(" name-char "+\\)\\(:\\)?") | |
1109 ; '(1 (if (match-beginning 2) | |
1110 ; 'font-lock-function-name-face | |
1111 ; 'font-lock-variable-name-face) | |
1112 ; nil t)) | |
1113 ; ;; | |
1114 ; ;; Words inside `' which tend to be symbol names. | |
1115 ; (list (concat "`\\(" sym-char sym-char "+\\)'") | |
1116 ; 1 '(prog1 | |
1117 ; 'font-lock-reference-face | |
1118 ; (add-list-mode-item (match-beginning 1) | |
1119 ; (match-end 1) | |
1120 ; nil | |
1121 ; 'help-follow-reference)) | |
1122 ; t) | |
1123 ; ;; | |
1124 ; ;; CLisp `:' keywords as references. | |
1125 ; (list (concat "\\<:" sym-char "+\\>") 0 'font-lock-reference-face t))) | |
1126 | |
1127 (defvar help-symbol-regexp | |
1128 (let ((sym-char "[+a-zA-Z0-9_:*]") | |
1129 (sym-char-no-dash "[-+a-zA-Z0-9_:*]")) | |
1130 (concat "\\(" | |
1131 ;; a symbol with a - in it. | |
1132 "\\<\\(" sym-char-no-dash "+\\(-" sym-char-no-dash "+\\)+\\)\\>" | |
1133 "\\|" | |
1134 "`\\(" sym-char "+\\)'" | |
1135 "\\)"))) | |
1136 | |
1137 (defun help-symbol-run-function-1 (ev ex fun) | |
1138 (let ((help-sticky-window | |
1139 ;; if we were called from a help buffer, make sure the new help | |
1140 ;; goes in the same window. | |
1141 (if (and (event-buffer ev) | |
1142 (symbol-value-in-buffer 'help-window-config | |
1143 (event-buffer ev))) | |
1144 (event-window ev) | |
1145 help-sticky-window))) | |
1146 (funcall fun (extent-property ex 'help-symbol)))) | |
1147 | |
1148 (defun help-symbol-run-function (fun) | |
1149 (let ((ex (extent-at-event last-popup-menu-event 'help-symbol))) | |
1150 (when ex | |
1151 (help-symbol-run-function-1 last-popup-menu-event ex fun)))) | |
1152 | |
1153 (defvar help-symbol-function-context-menu | |
1154 '("---" | |
1155 ["View %_Documentation" (help-symbol-run-function 'describe-function)] | |
1156 ["Find %_Function Source" (help-symbol-run-function 'find-function)] | |
1157 )) | |
1158 | |
1159 (defvar help-symbol-variable-context-menu | |
1160 '("---" | |
1161 ["View %_Documentation" (help-symbol-run-function 'describe-variable)] | |
1162 ["Find %_Variable Source" (help-symbol-run-function 'find-variable)] | |
1163 )) | |
1164 | |
1165 (defvar help-symbol-function-and-variable-context-menu | |
1166 '("---" | |
1167 ["View Function %_Documentation" (help-symbol-run-function | |
1168 'describe-function)] | |
1169 ["View Variable D%_ocumentation" (help-symbol-run-function | |
1170 'describe-variable)] | |
1171 ["Find %_Function Source" (help-symbol-run-function 'find-function)] | |
1172 ["Find %_Variable Source" (help-symbol-run-function 'find-variable)] | |
1173 )) | |
1174 | |
1175 (defun frob-help-extents (buffer) | |
1176 ;; Look through BUFFER, starting at the buffer's point and continuing | |
1177 ;; till end of file, and find documented functions and variables. | |
1178 ;; any such symbol found is tagged with an extent, that sets up these | |
1179 ;; properties: | |
1180 ;; 1. mouse-face is 'highlight (so the extent gets highlighted on mouse over) | |
1181 ;; 2. help-symbol is the name of the symbol. | |
1182 ;; 3. context-menu is a list of context menu items, specific to whether | |
1183 ;; the symbol is a function, variable, or both. | |
1184 ;; 4. activate-function will cause the function or variable to be described, | |
1185 ;; replacing the existing help contents. | |
1186 (save-excursion | |
1187 (set-buffer buffer) | |
1188 (let (b e name) | |
1189 (while (re-search-forward help-symbol-regexp nil t) | |
1190 (setq b (or (match-beginning 2) (match-beginning 4))) | |
1191 (setq e (or (match-end 2) (match-end 4))) | |
1192 (setq name (buffer-substring b e)) | |
1193 (let* ((sym (intern-soft name)) | |
1194 (var (and sym (boundp sym) | |
1195 (documentation-property sym | |
1196 'variable-documentation t))) | |
1197 (fun (and sym (fboundp sym) | |
1198 (documentation sym t)))) | |
1199 (when (or var fun) | |
1200 (let ((ex (make-extent b e))) | |
1201 (set-extent-property ex 'mouse-face 'highlight) | |
1202 (set-extent-property ex 'help-symbol sym) | |
1203 (set-extent-property | |
1204 ex 'context-menu | |
1205 (cond ((and var fun) | |
1206 help-symbol-function-and-variable-context-menu) | |
1207 (var help-symbol-variable-context-menu) | |
1208 (fun help-symbol-function-context-menu))) | |
1209 (set-extent-property | |
1210 ex 'activate-function | |
1211 (if fun | |
1212 #'(lambda (ev ex) | |
1213 (help-symbol-run-function-1 ev ex 'describe-function)) | |
1214 #'(lambda (ev ex) | |
1215 (help-symbol-run-function-1 ev ex 'describe-variable)))) | |
1216 ))))))) ;; 11 parentheses! | |
1065 | 1217 |
1066 (defun describe-function-1 (function &optional nodoc) | 1218 (defun describe-function-1 (function &optional nodoc) |
1067 "This function does the work for `describe-function'." | 1219 "This function does the work for `describe-function'." |
1068 (princ (format "`%s' is " function)) | 1220 (princ (format "`%s' is " function)) |
1069 (let* ((def function) | 1221 (let* ((def function) |
1156 (terpri) | 1308 (terpri) |
1157 (terpri)) | 1309 (terpri)) |
1158 (unless (and obsolete aliases) | 1310 (unless (and obsolete aliases) |
1159 (let ((doc (function-documentation function t))) | 1311 (let ((doc (function-documentation function t))) |
1160 (princ "Documentation:\n") | 1312 (princ "Documentation:\n") |
1161 (princ doc) | 1313 (let ((oldp (point standard-output)) |
1314 newp) | |
1315 (princ doc) | |
1316 (setq newp (point standard-output)) | |
1317 (goto-char oldp standard-output) | |
1318 (frob-help-extents standard-output) | |
1319 (goto-char newp standard-output)) | |
1162 (unless (or (equal doc "") | 1320 (unless (or (equal doc "") |
1163 (eq ?\n (aref doc (1- (length doc))))) | 1321 (eq ?\n (aref doc (1- (length doc))))) |
1164 (terpri))))))))) | 1322 (terpri))))))))) |
1165 | 1323 |
1166 | 1324 |
1169 (defun describe-function-arglist (function) | 1327 (defun describe-function-arglist (function) |
1170 (interactive (list (or (function-at-point) | 1328 (interactive (list (or (function-at-point) |
1171 (error "no function call at point")))) | 1329 (error "no function call at point")))) |
1172 (message nil) | 1330 (message nil) |
1173 (message (function-arglist function))) | 1331 (message (function-arglist function))) |
1174 | |
1175 | 1332 |
1176 (defun variable-at-point () | 1333 (defun variable-at-point () |
1177 (ignore-errors | 1334 (ignore-errors |
1178 (with-syntax-table emacs-lisp-mode-syntax-table | 1335 (with-syntax-table emacs-lisp-mode-syntax-table |
1179 (save-excursion | 1336 (save-excursion |
1182 (eq (char-syntax (char-after (point))) ?_) | 1339 (eq (char-syntax (char-after (point))) ?_) |
1183 (forward-sexp -1)) | 1340 (forward-sexp -1)) |
1184 (skip-chars-forward "'") | 1341 (skip-chars-forward "'") |
1185 (let ((obj (read (current-buffer)))) | 1342 (let ((obj (read (current-buffer)))) |
1186 (and (symbolp obj) (boundp obj) obj)))))) | 1343 (and (symbolp obj) (boundp obj) obj)))))) |
1344 | |
1345 (defun variable-at-event (event) | |
1346 "Return the variable whose name is around the position of EVENT. | |
1347 EVENT should be a mouse event. When calling from a popup or context menu, | |
1348 use `last-popup-menu-event' to find out where the mouse was clicked. | |
1349 \(You cannot use (interactive \"e\"), unfortunately. This returns a | |
1350 misc-user event.) | |
1351 | |
1352 If the event contains no position, or the position is not over text, or | |
1353 there is no variable around that point, nil is returned." | |
1354 (if (and event (event-buffer event) (event-point event)) | |
1355 (save-excursion | |
1356 (set-buffer (event-buffer event)) | |
1357 (goto-char (event-point event)) | |
1358 (variable-at-point)))) | |
1187 | 1359 |
1188 (defun variable-obsolete-p (variable) | 1360 (defun variable-obsolete-p (variable) |
1189 "Return non-nil if VARIABLE is obsolete." | 1361 "Return non-nil if VARIABLE is obsolete." |
1190 (not (null (get variable 'byte-obsolete-variable)))) | 1362 (not (null (get variable 'byte-obsolete-variable)))) |
1191 | 1363 |
1311 (terpri)) | 1483 (terpri)) |
1312 ;; don't bother to print anything if variable is obsolete and aliased. | 1484 ;; don't bother to print anything if variable is obsolete and aliased. |
1313 (when (or (not obsolete) (not aliases)) | 1485 (when (or (not obsolete) (not aliases)) |
1314 (if doc | 1486 (if doc |
1315 ;; note: documentation-property calls substitute-command-keys. | 1487 ;; note: documentation-property calls substitute-command-keys. |
1316 (princ doc) | 1488 (let ((oldp (point standard-output)) |
1489 newp) | |
1490 (princ doc) | |
1491 (setq newp (point standard-output)) | |
1492 (goto-char oldp standard-output) | |
1493 (frob-help-extents standard-output) | |
1494 (goto-char newp standard-output)) | |
1317 (princ "not documented as a variable.")))) | 1495 (princ "not documented as a variable.")))) |
1318 (terpri))) | 1496 (terpri))) |
1319 (format "variable `%s'" variable))) | 1497 (format "variable `%s'" variable))) |
1320 | 1498 |
1321 (defun sorted-key-descriptions (keys &optional separator) | 1499 (defun sorted-key-descriptions (keys &optional separator) |
1444 (let ((string (eval form))) | 1622 (let ((string (eval form))) |
1445 (if (stringp string) | 1623 (if (stringp string) |
1446 (with-displaying-help-buffer | 1624 (with-displaying-help-buffer |
1447 (insert string))))) | 1625 (insert string))))) |
1448 | 1626 |
1449 | |
1450 ;;; help.el ends here | 1627 ;;; help.el ends here |