diff options
| author | Miles Bader | 2001-10-07 12:05:22 +0000 |
|---|---|---|
| committer | Miles Bader | 2001-10-07 12:05:22 +0000 |
| commit | 0cf0d8284d2ee2e3db936598ed1407c7c2d01eb5 (patch) | |
| tree | 2040961f38af85412b6eb4243864502e23ab2054 | |
| parent | d6af189ae7d4826e6f13ae825d41298195d06f58 (diff) | |
| download | emacs-0cf0d8284d2ee2e3db936598ed1407c7c2d01eb5.tar.gz emacs-0cf0d8284d2ee2e3db936598ed1407c7c2d01eb5.zip | |
(help-mode-map): Make button-buffer-map our parent.
Don't bind mouse events or tab/backtab.
(help-function, help-variable, help-face, help-coding-system)
(help-input-method, help-character-set, help-back, help-info)
(help-customize-variable, help-function-def, help-variable-def):
New button types.
(help-button-action): New function.
(describe-function-1): Pass help button-types to `help-xref-button'
rather than help function and help-echo string. Don't put multiple
help-function args in a list to pass them to help-xref-button, just pass
them as multiple arguments. Use `help-insert-xref-button' to make
[back]-button, rather than `help-xref-button'.
(help-xref-button): Take a button-type TYPE as a parameter rather than a
function. Remove HELP-ECHO parameter. Remove DATA parameter and add a
&rest parameter ARGS to serve the same purpose. Use `make-text-button'
to add the button.
(help-insert-xref-button): Use `insert-text-button' to add the button.
(help-follow-mouse, help-next-ref, help-previous-ref): Functions removed.
(help-do-xref): New function.
(help-follow): Use `push-button' and `help-do-xref' to do most of the work.
| -rw-r--r-- | lisp/help.el | 337 |
1 files changed, 142 insertions, 195 deletions
diff --git a/lisp/help.el b/lisp/help.el index d0b5edcf3c2..c8189d04783 100644 --- a/lisp/help.el +++ b/lisp/help.el | |||
| @@ -41,6 +41,8 @@ | |||
| 41 | (defvar help-mode-map (make-sparse-keymap) | 41 | (defvar help-mode-map (make-sparse-keymap) |
| 42 | "Keymap for help mode.") | 42 | "Keymap for help mode.") |
| 43 | 43 | ||
| 44 | (set-keymap-parent help-mode-map button-buffer-map) | ||
| 45 | |||
| 44 | (define-key global-map (char-to-string help-char) 'help-command) | 46 | (define-key global-map (char-to-string help-char) 'help-command) |
| 45 | (define-key global-map [help] 'help-command) | 47 | (define-key global-map [help] 'help-command) |
| 46 | (define-key global-map [f1] 'help-command) | 48 | (define-key global-map [f1] 'help-command) |
| @@ -97,12 +99,8 @@ | |||
| 97 | 99 | ||
| 98 | (define-key help-map "q" 'help-quit) | 100 | (define-key help-map "q" 'help-quit) |
| 99 | 101 | ||
| 100 | (define-key help-mode-map [mouse-2] 'help-follow-mouse) | ||
| 101 | (define-key help-mode-map "\C-c\C-b" 'help-go-back) | 102 | (define-key help-mode-map "\C-c\C-b" 'help-go-back) |
| 102 | (define-key help-mode-map "\C-c\C-c" 'help-follow) | 103 | (define-key help-mode-map "\C-c\C-c" 'help-follow) |
| 103 | (define-key help-mode-map "\t" 'help-next-ref) | ||
| 104 | (define-key help-mode-map [backtab] 'help-previous-ref) | ||
| 105 | (define-key help-mode-map [(shift tab)] 'help-previous-ref) | ||
| 106 | ;; Documentation only, since we use minor-mode-overriding-map-alist. | 104 | ;; Documentation only, since we use minor-mode-overriding-map-alist. |
| 107 | (define-key help-mode-map "\r" 'help-follow) | 105 | (define-key help-mode-map "\r" 'help-follow) |
| 108 | 106 | ||
| @@ -127,6 +125,70 @@ The format is (FUNCTION ARGS...).") | |||
| 127 | :type 'hook | 125 | :type 'hook |
| 128 | :group 'help) | 126 | :group 'help) |
| 129 | 127 | ||
| 128 | |||
| 129 | ;; Button types used by help | ||
| 130 | |||
| 131 | ;; Make some button types that all use the same naming conventions | ||
| 132 | (dolist (help-type '("function" "variable" "face" | ||
| 133 | "coding-system" "input-method" "character-set")) | ||
| 134 | (define-button-type (intern (purecopy (concat "help-" help-type))) | ||
| 135 | 'help-function (intern (concat "describe-" help-type)) | ||
| 136 | 'help-echo (purecopy (concat "mouse-2, RET: describe this " help-type)) | ||
| 137 | 'action #'help-button-action)) | ||
| 138 | |||
| 139 | ;; make some more ideosyncratic button types | ||
| 140 | |||
| 141 | (define-button-type 'help-symbol | ||
| 142 | 'help-function #'help-xref-interned | ||
| 143 | 'help-echo (purecopy "mouse-2, RET: describe this symbol") | ||
| 144 | 'action #'help-button-action) | ||
| 145 | |||
| 146 | (define-button-type 'help-back | ||
| 147 | 'help-function #'help-xref-go-back | ||
| 148 | 'help-echo (purecopy "mouse-2, RET: go back to previous help buffer") | ||
| 149 | 'action #'help-button-action) | ||
| 150 | |||
| 151 | (define-button-type 'help-info | ||
| 152 | 'help-function #'info | ||
| 153 | 'help-echo (purecopy"mouse-2, RET: read this Info node") | ||
| 154 | 'action #'help-button-action) | ||
| 155 | |||
| 156 | (define-button-type 'help-customize-variable | ||
| 157 | 'help-function (lambda (v) | ||
| 158 | (if help-xref-stack | ||
| 159 | (pop help-xref-stack)) | ||
| 160 | (customize-variable v)) | ||
| 161 | 'help-echo (purecopy "mouse-2, RET: customize variable") | ||
| 162 | 'action #'help-button-action) | ||
| 163 | |||
| 164 | (define-button-type 'help-function-def | ||
| 165 | 'help-function (lambda (fun file) | ||
| 166 | (require 'find-func) | ||
| 167 | ;; Don't use find-function-noselect because it follows | ||
| 168 | ;; aliases (which fails for built-in functions). | ||
| 169 | (let* ((location (find-function-search-for-symbol | ||
| 170 | fun nil file))) | ||
| 171 | (pop-to-buffer (car location)) | ||
| 172 | (goto-char (cdr location)))) | ||
| 173 | 'help-echo (purecopy "mouse-2, RET: find function's definition") | ||
| 174 | 'action #'help-button-action) | ||
| 175 | |||
| 176 | (define-button-type 'help-variable-def | ||
| 177 | 'help-function (lambda (arg) | ||
| 178 | (let ((location | ||
| 179 | (find-variable-noselect arg))) | ||
| 180 | (pop-to-buffer (car location)) | ||
| 181 | (goto-char (cdr location)))) | ||
| 182 | 'help-echo (purecopy"mouse-2, RET: find variable's definition") | ||
| 183 | 'action #'help-button-action) | ||
| 184 | |||
| 185 | (defun help-button-action (button) | ||
| 186 | "Call this button's help function." | ||
| 187 | (help-do-xref (button-start button) | ||
| 188 | (button-get button 'help-function) | ||
| 189 | (button-get button 'help-args))) | ||
| 190 | |||
| 191 | |||
| 130 | (defun help-mode () | 192 | (defun help-mode () |
| 131 | "Major mode for viewing help text and navigating references in it. | 193 | "Major mode for viewing help text and navigating references in it. |
| 132 | Entry to this mode runs the normal hook `help-mode-hook'. | 194 | Entry to this mode runs the normal hook `help-mode-hook'. |
| @@ -695,8 +757,7 @@ It can also be nil, if the definition is not associated with any file." | |||
| 695 | (save-excursion | 757 | (save-excursion |
| 696 | (save-match-data | 758 | (save-match-data |
| 697 | (if (re-search-backward "alias for `\\([^`']+\\)'" nil t) | 759 | (if (re-search-backward "alias for `\\([^`']+\\)'" nil t) |
| 698 | (help-xref-button 1 #'describe-function def | 760 | (help-xref-button 1 'help-function def))))) |
| 699 | "mouse-2, RET: describe this function"))))) | ||
| 700 | (or file-name | 761 | (or file-name |
| 701 | (setq file-name (symbol-file function))) | 762 | (setq file-name (symbol-file function))) |
| 702 | (if file-name | 763 | (if file-name |
| @@ -710,18 +771,7 @@ It can also be nil, if the definition is not associated with any file." | |||
| 710 | (with-current-buffer "*Help*" | 771 | (with-current-buffer "*Help*" |
| 711 | (save-excursion | 772 | (save-excursion |
| 712 | (re-search-backward "`\\([^`']+\\)'" nil t) | 773 | (re-search-backward "`\\([^`']+\\)'" nil t) |
| 713 | (help-xref-button | 774 | (help-xref-button 1 'help-function-def function file-name))))) |
| 714 | 1 | ||
| 715 | #'(lambda (fun file) | ||
| 716 | (require 'find-func) | ||
| 717 | ;; Don't use find-function-noselect because it follows | ||
| 718 | ;; aliases (which fails for built-in functions). | ||
| 719 | (let* ((location (find-function-search-for-symbol | ||
| 720 | fun nil file))) | ||
| 721 | (pop-to-buffer (car location)) | ||
| 722 | (goto-char (cdr location)))) | ||
| 723 | (list function file-name) | ||
| 724 | "mouse-2, RET: find function's definition"))))) | ||
| 725 | (if need-close (princ ")")) | 775 | (if need-close (princ ")")) |
| 726 | (princ ".") | 776 | (princ ".") |
| 727 | (terpri) | 777 | (terpri) |
| @@ -818,13 +868,13 @@ Return 0 if there is no such symbol." | |||
| 818 | ((looking-at "#<") (search-forward ">" nil 'move)) | 868 | ((looking-at "#<") (search-forward ">" nil 'move)) |
| 819 | ((looking-at "\\(\\(\\sw\\|\\s_\\)+\\)") | 869 | ((looking-at "\\(\\(\\sw\\|\\s_\\)+\\)") |
| 820 | (let* ((sym (intern-soft (match-string 1))) | 870 | (let* ((sym (intern-soft (match-string 1))) |
| 821 | (fn (cond ((fboundp sym) #'describe-function) | 871 | (type (cond ((fboundp sym) 'help-function) |
| 822 | ((or (memq sym '(t nil)) | 872 | ((or (memq sym '(t nil)) |
| 823 | (keywordp sym)) | 873 | (keywordp sym)) |
| 824 | nil) | 874 | nil) |
| 825 | ((and sym (boundp sym)) | 875 | ((and sym (boundp sym)) |
| 826 | #'describe-variable)))) | 876 | 'help-variable)))) |
| 827 | (when fn (help-xref-button 1 fn sym))) | 877 | (when type (help-xref-button 1 type sym))) |
| 828 | (goto-char (match-end 1))) | 878 | (goto-char (match-end 1))) |
| 829 | (t (forward-char 1)))))) | 879 | (t (forward-char 1)))))) |
| 830 | (set-syntax-table ost)))) | 880 | (set-syntax-table ost)))) |
| @@ -928,12 +978,7 @@ it is displayed along with the global value." | |||
| 928 | (save-excursion | 978 | (save-excursion |
| 929 | (re-search-backward | 979 | (re-search-backward |
| 930 | (concat "\\(" customize-label "\\)") nil t) | 980 | (concat "\\(" customize-label "\\)") nil t) |
| 931 | (help-xref-button 1 (lambda (v) | 981 | (help-xref-button 1 'help-customize-variable variable))))) |
| 932 | (if help-xref-stack | ||
| 933 | (pop help-xref-stack)) | ||
| 934 | (customize-variable v)) | ||
| 935 | variable | ||
| 936 | "mouse-2, RET: customize variable"))))) | ||
| 937 | ;; Make a hyperlink to the library if appropriate. (Don't | 982 | ;; Make a hyperlink to the library if appropriate. (Don't |
| 938 | ;; change the format of the buffer's initial line in case | 983 | ;; change the format of the buffer's initial line in case |
| 939 | ;; anything expects the current format.) | 984 | ;; anything expects the current format.) |
| @@ -945,13 +990,7 @@ it is displayed along with the global value." | |||
| 945 | (with-current-buffer "*Help*" | 990 | (with-current-buffer "*Help*" |
| 946 | (save-excursion | 991 | (save-excursion |
| 947 | (re-search-backward "`\\([^`']+\\)'" nil t) | 992 | (re-search-backward "`\\([^`']+\\)'" nil t) |
| 948 | (help-xref-button | 993 | (help-xref-button 1 'help-variable-def variable))))) |
| 949 | 1 (lambda (arg) | ||
| 950 | (let ((location | ||
| 951 | (find-variable-noselect arg))) | ||
| 952 | (pop-to-buffer (car location)) | ||
| 953 | (goto-char (cdr location)))) | ||
| 954 | variable "mouse-2, RET: find variable's definition"))))) | ||
| 955 | 994 | ||
| 956 | (print-help-return-message) | 995 | (print-help-return-message) |
| 957 | (save-excursion | 996 | (save-excursion |
| @@ -1158,8 +1197,7 @@ that." | |||
| 1158 | (save-match-data | 1197 | (save-match-data |
| 1159 | (unless (string-match "^([^)]+)" data) | 1198 | (unless (string-match "^([^)]+)" data) |
| 1160 | (setq data (concat "(emacs)" data)))) | 1199 | (setq data (concat "(emacs)" data)))) |
| 1161 | (help-xref-button 1 #'info data | 1200 | (help-xref-button 1 'help-info data)))) |
| 1162 | "mouse-2, RET: read this Info node")))) | ||
| 1163 | ;; Mule related keywords. Do this before trying | 1201 | ;; Mule related keywords. Do this before trying |
| 1164 | ;; `help-xref-symbol-regexp' because some of Mule | 1202 | ;; `help-xref-symbol-regexp' because some of Mule |
| 1165 | ;; keywords have variable or function definitions. | 1203 | ;; keywords have variable or function definitions. |
| @@ -1171,31 +1209,19 @@ that." | |||
| 1171 | (cond | 1209 | (cond |
| 1172 | ((match-string 3) ; coding system | 1210 | ((match-string 3) ; coding system |
| 1173 | (and sym (coding-system-p sym) | 1211 | (and sym (coding-system-p sym) |
| 1174 | (help-xref-button | 1212 | (help-xref-button 6 'help-coding-system sym))) |
| 1175 | 7 #'describe-coding-system sym | ||
| 1176 | "mouse-2, RET: describe this coding system"))) | ||
| 1177 | ((match-string 4) ; input method | 1213 | ((match-string 4) ; input method |
| 1178 | (and (assoc data input-method-alist) | 1214 | (and (assoc data input-method-alist) |
| 1179 | (help-xref-button | 1215 | (help-xref-button 7 'help-input-method data))) |
| 1180 | 7 #'describe-input-method data | ||
| 1181 | "mouse-2, RET: describe this input method"))) | ||
| 1182 | ((or (match-string 5) (match-string 6)) ; charset | 1216 | ((or (match-string 5) (match-string 6)) ; charset |
| 1183 | (and sym (charsetp sym) | 1217 | (and sym (charsetp sym) |
| 1184 | (help-xref-button | 1218 | (help-xref-button 7 'help-character-set sym))) |
| 1185 | 7 #'describe-character-set sym | ||
| 1186 | "mouse-2, RET: describe this character set"))) | ||
| 1187 | ((assoc data input-method-alist) | 1219 | ((assoc data input-method-alist) |
| 1188 | (help-xref-button | 1220 | (help-xref-button 7 'help-character-set data)) |
| 1189 | 7 #'describe-input-method data | ||
| 1190 | "mouse-2, RET: describe this input method")) | ||
| 1191 | ((and sym (coding-system-p sym)) | 1221 | ((and sym (coding-system-p sym)) |
| 1192 | (help-xref-button | 1222 | (help-xref-button 7 'help-coding-system sym)) |
| 1193 | 7 #'describe-coding-system sym | ||
| 1194 | "mouse-2, RET: describe this coding system")) | ||
| 1195 | ((and sym (charsetp sym)) | 1223 | ((and sym (charsetp sym)) |
| 1196 | (help-xref-button | 1224 | (help-xref-button 7 'help-character-set sym))))))) |
| 1197 | 7 #'describe-character-set sym | ||
| 1198 | "mouse-2, RET: describe this character set"))))))) | ||
| 1199 | ;; Quoted symbols | 1225 | ;; Quoted symbols |
| 1200 | (save-excursion | 1226 | (save-excursion |
| 1201 | (while (re-search-forward help-xref-symbol-regexp nil t) | 1227 | (while (re-search-forward help-xref-symbol-regexp nil t) |
| @@ -1206,46 +1232,32 @@ that." | |||
| 1206 | ((match-string 3) ; `variable' &c | 1232 | ((match-string 3) ; `variable' &c |
| 1207 | (and (boundp sym) ; `variable' doesn't ensure | 1233 | (and (boundp sym) ; `variable' doesn't ensure |
| 1208 | ; it's actually bound | 1234 | ; it's actually bound |
| 1209 | (help-xref-button | 1235 | (help-xref-button 8 'help-variable sym))) |
| 1210 | 8 #'describe-variable sym | ||
| 1211 | "mouse-2, RET: describe this variable"))) | ||
| 1212 | ((match-string 4) ; `function' &c | 1236 | ((match-string 4) ; `function' &c |
| 1213 | (and (fboundp sym) ; similarly | 1237 | (and (fboundp sym) ; similarly |
| 1214 | (help-xref-button | 1238 | (help-xref-button 8 'help-function sym))) |
| 1215 | 8 #'describe-function sym | ||
| 1216 | "mouse-2, RET: describe this function"))) | ||
| 1217 | ((match-string 5) ; `face' | 1239 | ((match-string 5) ; `face' |
| 1218 | (and (facep sym) | 1240 | (and (facep sym) |
| 1219 | (help-xref-button 8 #'describe-face sym | 1241 | (help-xref-button 8 'help-face sym))) |
| 1220 | "mouse-2, RET: describe this face"))) | ||
| 1221 | ((match-string 6)) ; nothing for `symbol' | 1242 | ((match-string 6)) ; nothing for `symbol' |
| 1222 | ((match-string 7) | 1243 | ((match-string 7) |
| 1223 | (help-xref-button | 1244 | ;; this used: |
| 1224 | 8 | 1245 | ;; #'(lambda (arg) |
| 1225 | #'(lambda (arg) | 1246 | ;; (let ((location |
| 1226 | (let ((location | 1247 | ;; (find-function-noselect arg))) |
| 1227 | (find-function-noselect arg))) | 1248 | ;; (pop-to-buffer (car location)) |
| 1228 | (pop-to-buffer (car location)) | 1249 | ;; (goto-char (cdr location)))) |
| 1229 | (goto-char (cdr location)))) | 1250 | (help-xref-button 8 'help-function-def sym)) |
| 1230 | sym | ||
| 1231 | "mouse-2, RET: find function's definition")) | ||
| 1232 | ((and (boundp sym) (fboundp sym)) | 1251 | ((and (boundp sym) (fboundp sym)) |
| 1233 | ;; We can't intuit whether to use the | 1252 | ;; We can't intuit whether to use the |
| 1234 | ;; variable or function doc -- supply both. | 1253 | ;; variable or function doc -- supply both. |
| 1235 | (help-xref-button | 1254 | (help-xref-button 8 'help-symbol sym)) |
| 1236 | 8 #'help-xref-interned sym | ||
| 1237 | "mouse-2, RET: describe this symbol")) | ||
| 1238 | ((boundp sym) | 1255 | ((boundp sym) |
| 1239 | (help-xref-button | 1256 | (help-xref-button 8 'help-variable sym)) |
| 1240 | 8 #'describe-variable sym | ||
| 1241 | "mouse-2, RET: describe this variable")) | ||
| 1242 | ((fboundp sym) | 1257 | ((fboundp sym) |
| 1243 | (help-xref-button | 1258 | (help-xref-button 8 'help-function sym)) |
| 1244 | 8 #'describe-function sym | ||
| 1245 | "mouse-2, RET: describe this function")) | ||
| 1246 | ((facep sym) | 1259 | ((facep sym) |
| 1247 | (help-xref-button | 1260 | (help-xref-button 8 'help-face sym))))))) |
| 1248 | 8 #'describe-face sym))))))) | ||
| 1249 | ;; An obvious case of a key substitution: | 1261 | ;; An obvious case of a key substitution: |
| 1250 | (save-excursion | 1262 | (save-excursion |
| 1251 | (while (re-search-forward | 1263 | (while (re-search-forward |
| @@ -1254,9 +1266,7 @@ that." | |||
| 1254 | "\\<M-x\\s-+\\(\\sw\\(\\sw\\|-\\)+\\)" nil t) | 1266 | "\\<M-x\\s-+\\(\\sw\\(\\sw\\|-\\)+\\)" nil t) |
| 1255 | (let ((sym (intern-soft (match-string 1)))) | 1267 | (let ((sym (intern-soft (match-string 1)))) |
| 1256 | (if (fboundp sym) | 1268 | (if (fboundp sym) |
| 1257 | (help-xref-button | 1269 | (help-xref-button 1 'help-function sym))))) |
| 1258 | 1 #'describe-function sym | ||
| 1259 | "mouse-2, RET: describe this command"))))) | ||
| 1260 | ;; Look for commands in whole keymap substitutions: | 1270 | ;; Look for commands in whole keymap substitutions: |
| 1261 | (save-excursion | 1271 | (save-excursion |
| 1262 | ;; Make sure to find the first keymap. | 1272 | ;; Make sure to find the first keymap. |
| @@ -1278,9 +1288,7 @@ that." | |||
| 1278 | (looking-at "\\(\\sw\\|-\\)+$")) | 1288 | (looking-at "\\(\\sw\\|-\\)+$")) |
| 1279 | (let ((sym (intern-soft (match-string 0)))) | 1289 | (let ((sym (intern-soft (match-string 0)))) |
| 1280 | (if (fboundp sym) | 1290 | (if (fboundp sym) |
| 1281 | (help-xref-button | 1291 | (help-xref-button 0 'help-function sym)))) |
| 1282 | 0 #'describe-function sym | ||
| 1283 | "mouse-2, RET: describe this function")))) | ||
| 1284 | (zerop (forward-line))))))))) | 1292 | (zerop (forward-line))))))))) |
| 1285 | (set-syntax-table stab)) | 1293 | (set-syntax-table stab)) |
| 1286 | ;; Delete extraneous newlines at the end of the docstring | 1294 | ;; Delete extraneous newlines at the end of the docstring |
| @@ -1289,11 +1297,9 @@ that." | |||
| 1289 | (delete-char -1)) | 1297 | (delete-char -1)) |
| 1290 | ;; Make a back-reference in this buffer if appropriate. | 1298 | ;; Make a back-reference in this buffer if appropriate. |
| 1291 | (when (and help-xref-following help-xref-stack) | 1299 | (when (and help-xref-following help-xref-stack) |
| 1292 | (save-excursion | 1300 | (insert "\n\n") |
| 1293 | (insert "\n\n" help-back-label)) | 1301 | (help-insert-xref-button help-back-label 'help-back |
| 1294 | ;; Just to provide the match data: | 1302 | (current-buffer)))) |
| 1295 | (looking-at (concat "\n\n\\(" (regexp-quote help-back-label) "\\)")) | ||
| 1296 | (help-xref-button 1 #'help-xref-go-back (current-buffer)))) | ||
| 1297 | ;; View mode steals RET from us. | 1303 | ;; View mode steals RET from us. |
| 1298 | (set (make-local-variable 'minor-mode-overriding-map-alist) | 1304 | (set (make-local-variable 'minor-mode-overriding-map-alist) |
| 1299 | (list (cons 'view-mode | 1305 | (list (cons 'view-mode |
| @@ -1303,44 +1309,25 @@ that." | |||
| 1303 | map)))) | 1309 | map)))) |
| 1304 | (set-buffer-modified-p old-modified)))) | 1310 | (set-buffer-modified-p old-modified)))) |
| 1305 | 1311 | ||
| 1306 | (defun help-xref-button (match-number function data &optional help-echo) | 1312 | (defun help-xref-button (match-number type &rest args) |
| 1307 | "Make a hyperlink for cross-reference text previously matched. | 1313 | "Make a hyperlink for cross-reference text previously matched. |
| 1308 | |||
| 1309 | MATCH-NUMBER is the subexpression of interest in the last matched | 1314 | MATCH-NUMBER is the subexpression of interest in the last matched |
| 1310 | regexp. FUNCTION is a function to invoke when the button is | 1315 | regexp. TYPE is the type of button to use. Any remaining arguments are |
| 1311 | activated, applied to DATA. DATA may be a single value or a list. | 1316 | passed to the button's help-function when it is invoked. |
| 1312 | See `help-make-xrefs'. | 1317 | See `help-make-xrefs'." |
| 1313 | If optional arg HELP-ECHO is supplied, it is used as a help string." | ||
| 1314 | ;; Don't mung properties we've added specially in some instances. | 1318 | ;; Don't mung properties we've added specially in some instances. |
| 1315 | (unless (get-text-property (match-beginning match-number) 'help-xref) | 1319 | (unless (button-at (match-beginning match-number)) |
| 1316 | (add-text-properties (match-beginning match-number) | 1320 | (make-text-button (match-beginning match-number) |
| 1317 | (match-end match-number) | 1321 | (match-end match-number) |
| 1318 | (list 'mouse-face 'highlight | 1322 | 'type type 'help-args args))) |
| 1319 | 'help-xref (cons function | ||
| 1320 | (if (listp data) | ||
| 1321 | data | ||
| 1322 | (list data))))) | ||
| 1323 | (if help-echo | ||
| 1324 | (put-text-property (match-beginning match-number) | ||
| 1325 | (match-end match-number) | ||
| 1326 | 'help-echo help-echo)) | ||
| 1327 | (if help-highlight-p | ||
| 1328 | (put-text-property (match-beginning match-number) | ||
| 1329 | (match-end match-number) | ||
| 1330 | 'face help-highlight-face)))) | ||
| 1331 | |||
| 1332 | (defun help-insert-xref-button (string function data &optional help-echo) | ||
| 1333 | "Insert STRING and make a hyperlink from cross-reference text on it. | ||
| 1334 | |||
| 1335 | FUNCTION is a function to invoke when the button is activated, applied | ||
| 1336 | to DATA. DATA may be a single value or a list. See `help-make-xrefs'. | ||
| 1337 | If optional arg HELP-ECHO is supplied, it is used as a help string." | ||
| 1338 | (let ((pos (point))) | ||
| 1339 | (insert string) | ||
| 1340 | (goto-char pos) | ||
| 1341 | (search-forward string) | ||
| 1342 | (help-xref-button 0 function data help-echo))) | ||
| 1343 | 1323 | ||
| 1324 | (defun help-insert-xref-button (string type &rest args) | ||
| 1325 | "Insert STRING and make a hyperlink from cross-reference text on it. | ||
| 1326 | TYPE is the type of button to use. Any remaining arguments are passed | ||
| 1327 | to the button's help-function when it is invoked. | ||
| 1328 | See `help-make-xrefs'." | ||
| 1329 | (unless (button-at (point)) | ||
| 1330 | (insert-text-button string 'type type 'help-args args))) | ||
| 1344 | 1331 | ||
| 1345 | 1332 | ||
| 1346 | ;; Additional functions for (re-)creating types of help buffers. | 1333 | ;; Additional functions for (re-)creating types of help buffers. |
| @@ -1373,18 +1360,10 @@ help buffer." | |||
| 1373 | (save-excursion | 1360 | (save-excursion |
| 1374 | (set-buffer buffer) | 1361 | (set-buffer buffer) |
| 1375 | (describe-mode))) | 1362 | (describe-mode))) |
| 1363 | |||
| 1376 | 1364 | ||
| 1377 | ;;; Navigation/hyperlinking with xrefs | 1365 | ;;; Navigation/hyperlinking with xrefs |
| 1378 | 1366 | ||
| 1379 | (defun help-follow-mouse (click) | ||
| 1380 | "Follow the cross-reference that you click on." | ||
| 1381 | (interactive "e") | ||
| 1382 | (let* ((start (event-start click)) | ||
| 1383 | (window (car start)) | ||
| 1384 | (pos (car (cdr start)))) | ||
| 1385 | (with-current-buffer (window-buffer window) | ||
| 1386 | (help-follow pos)))) | ||
| 1387 | |||
| 1388 | (defun help-xref-go-back (buffer) | 1367 | (defun help-xref-go-back (buffer) |
| 1389 | "From BUFFER, go back to previous help buffer text using `help-xref-stack'." | 1368 | "From BUFFER, go back to previous help buffer text using `help-xref-stack'." |
| 1390 | (let (item position method args) | 1369 | (let (item position method args) |
| @@ -1405,7 +1384,22 @@ help buffer." | |||
| 1405 | (defun help-go-back () | 1384 | (defun help-go-back () |
| 1406 | "Invoke the [back] button (if any) in the Help mode buffer." | 1385 | "Invoke the [back] button (if any) in the Help mode buffer." |
| 1407 | (interactive) | 1386 | (interactive) |
| 1408 | (help-follow (1- (point-max)))) | 1387 | (let ((back-button (button-at (1- (point-max))))) |
| 1388 | (if back-button | ||
| 1389 | (button-activate back-button) | ||
| 1390 | (error "No [back] button")))) | ||
| 1391 | |||
| 1392 | (defun help-do-xref (pos function args) | ||
| 1393 | "Call the help cross-reference function FUNCTION with args ARGS. | ||
| 1394 | Things are set up properly so that the resulting help-buffer has | ||
| 1395 | a proper [back] button." | ||
| 1396 | (setq help-xref-stack (cons (cons (cons pos (buffer-name)) | ||
| 1397 | help-xref-stack-item) | ||
| 1398 | help-xref-stack)) | ||
| 1399 | (setq help-xref-stack-item nil) | ||
| 1400 | ;; There is a reference at point. Follow it. | ||
| 1401 | (let ((help-xref-following t)) | ||
| 1402 | (apply function args))) | ||
| 1409 | 1403 | ||
| 1410 | (defun help-follow (&optional pos) | 1404 | (defun help-follow (&optional pos) |
| 1411 | "Follow cross-reference at POS, defaulting to point. | 1405 | "Follow cross-reference at POS, defaulting to point. |
| @@ -1414,64 +1408,17 @@ For the cross-reference format, see `help-make-xrefs'." | |||
| 1414 | (interactive "d") | 1408 | (interactive "d") |
| 1415 | (unless pos | 1409 | (unless pos |
| 1416 | (setq pos (point))) | 1410 | (setq pos (point))) |
| 1417 | (let* ((help-data | 1411 | (unless (push-button pos) |
| 1418 | (or (and (not (= pos (point-max))) | 1412 | ;; check if the symbol under point is a function or variable |
| 1419 | (get-text-property pos 'help-xref)) | 1413 | (let ((sym |
| 1420 | (and (not (= pos (point-min))) | 1414 | (intern |
| 1421 | (get-text-property (1- pos) 'help-xref)) | 1415 | (save-excursion |
| 1422 | ;; check if the symbol under point is a function or variable | 1416 | (goto-char pos) (skip-syntax-backward "w_") |
| 1423 | (let ((sym | 1417 | (buffer-substring (point) |
| 1424 | (intern | 1418 | (progn (skip-syntax-forward "w_") |
| 1425 | (save-excursion | 1419 | (point))))))) |
| 1426 | (goto-char pos) (skip-syntax-backward "w_") | 1420 | (when (or (boundp sym) (fboundp sym)) |
| 1427 | (buffer-substring (point) | 1421 | (help-do-xref pos #'help-xref-interned (list sym)))))) |
| 1428 | (progn (skip-syntax-forward "w_") | ||
| 1429 | (point))))))) | ||
| 1430 | (when (or (boundp sym) (fboundp sym)) | ||
| 1431 | (list #'help-xref-interned sym))))) | ||
| 1432 | (method (car help-data)) | ||
| 1433 | (args (cdr help-data))) | ||
| 1434 | (when help-data | ||
| 1435 | (setq help-xref-stack (cons (cons (cons pos (buffer-name)) | ||
| 1436 | help-xref-stack-item) | ||
| 1437 | help-xref-stack)) | ||
| 1438 | (setq help-xref-stack-item nil) | ||
| 1439 | ;; There is a reference at point. Follow it. | ||
| 1440 | (let ((help-xref-following t)) | ||
| 1441 | (apply method args))))) | ||
| 1442 | |||
| 1443 | ;; For tabbing through buffer. | ||
| 1444 | (defun help-next-ref () | ||
| 1445 | "Find the next help cross-reference in the buffer." | ||
| 1446 | (interactive) | ||
| 1447 | (let (pos) | ||
| 1448 | (while (not pos) | ||
| 1449 | (if (get-text-property (point) 'help-xref) ; move off reference | ||
| 1450 | (goto-char (or (next-single-property-change (point) 'help-xref) | ||
| 1451 | (point)))) | ||
| 1452 | (cond ((setq pos (next-single-property-change (point) 'help-xref)) | ||
| 1453 | (if pos (goto-char pos))) | ||
| 1454 | ((bobp) | ||
| 1455 | (message "No cross references in the buffer.") | ||
| 1456 | (setq pos t)) | ||
| 1457 | (t ; be circular | ||
| 1458 | (goto-char (point-min))))))) | ||
| 1459 | |||
| 1460 | (defun help-previous-ref () | ||
| 1461 | "Find the previous help cross-reference in the buffer." | ||
| 1462 | (interactive) | ||
| 1463 | (let (pos) | ||
| 1464 | (while (not pos) | ||
| 1465 | (if (get-text-property (point) 'help-xref) ; move off reference | ||
| 1466 | (goto-char (or (previous-single-property-change (point) 'help-xref) | ||
| 1467 | (point)))) | ||
| 1468 | (cond ((setq pos (previous-single-property-change (point) 'help-xref)) | ||
| 1469 | (if pos (goto-char pos))) | ||
| 1470 | ((bobp) | ||
| 1471 | (message "No cross references in the buffer.") | ||
| 1472 | (setq pos t)) | ||
| 1473 | (t ; be circular | ||
| 1474 | (goto-char (point-max))))))) | ||
| 1475 | 1422 | ||
| 1476 | 1423 | ||
| 1477 | ;;; Automatic resizing of temporary buffers. | 1424 | ;;; Automatic resizing of temporary buffers. |