Mercurial > hg > xemacs-beta
comparison lisp/electric/ehelp.el @ 4:b82b59fe008d r19-15b3
Import from CVS: tag r19-15b3
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:46:56 +0200 |
parents | 376386a54a3c |
children | 131b0175ea99 |
comparison
equal
deleted
inserted
replaced
3:30df88044ec6 | 4:b82b59fe008d |
---|---|
1 ;;; ehelp.el --- bindings for electric-help mode | 1 ;;; ehelp.el --- bindings for electric-help mode |
2 | 2 |
3 ;; Copyright (C) 1986, 1995 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1986, 1995 Free Software Foundation, Inc. |
4 | 4 |
5 ;; Author: Richard Mlynarik <mly@ai.mit.edu> | 5 ;; Author: Richard Mlynarik <mly@ai.mit.edu> |
6 | |
7 ;; Maintainer: FSF | 6 ;; Maintainer: FSF |
8 ;; Keywords: help, extensions | 7 ;; Keywords: help, extensions |
9 | 8 |
10 ;; This file is part of XEmacs. | 9 ;; This file is part of XEmacs. |
11 | 10 |
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
20 ;; General Public License for more details. | 19 ;; General Public License for more details. |
21 | 20 |
22 ;; You should have received a copy of the GNU General Public License | 21 ;; You should have received a copy of the GNU General Public License |
23 ;; along with XEmacs; see the file COPYING. If not, write to the Free | 22 ;; along with XEmacs; see the file COPYING. If not, write to the Free |
24 ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | 23 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
25 | 24 ;; 02111-1307, USA. |
26 ;;; Synched up with: FSF 19.30. | 25 |
26 ;;; Synched up with: FSF 19.34. | |
27 | 27 |
28 ;;; Commentary: | 28 ;;; Commentary: |
29 | 29 |
30 ;; This package provides a pre-packaged `Electric Help Mode' for | 30 ;; This package provides a pre-packaged `Electric Help Mode' for |
31 ;; browsing on-line help screens. There is one entry point, | 31 ;; browsing on-line help screens. There is one entry point, |
40 ;; (define-key global-map [f1] 'ehelp-command) | 40 ;; (define-key global-map [f1] 'ehelp-command) |
41 | 41 |
42 ;;; Code: | 42 ;;; Code: |
43 | 43 |
44 (require 'electric) | 44 (require 'electric) |
45 | 45 (defvar electric-help-map () |
46 (defvar electric-help-map nil | |
47 "Keymap defining commands available in `electric-help-mode'.") | 46 "Keymap defining commands available in `electric-help-mode'.") |
47 | |
48 (defvar electric-help-form-to-execute nil) | |
48 | 49 |
49 (put 'electric-help-undefined 'suppress-keymap t) | 50 (put 'electric-help-undefined 'suppress-keymap t) |
50 (if electric-help-map | 51 (if electric-help-map |
51 () | 52 () |
52 (let ((map (make-keymap))) | 53 (let ((map (make-keymap))) |
53 (set-keymap-name map 'electric-help-map) | |
54 ;; allow all non-self-inserting keys - search, scroll, etc, but | 54 ;; allow all non-self-inserting keys - search, scroll, etc, but |
55 ;; let M-x and C-x exit ehelp mode and retain buffer: | 55 ;; let M-x and C-x exit ehelp mode and retain buffer: |
56 (suppress-keymap map) | 56 (suppress-keymap map) |
57 (define-key map "\C-u" 'electric-help-undefined) | 57 (define-key map "\C-u" 'electric-help-undefined) |
58 (define-key map [(control ?0)] 'electric-help-undefined) | 58 (define-key map [(control ?0)] 'electric-help-undefined) |
65 (define-key map [(control ?7)] 'electric-help-undefined) | 65 (define-key map [(control ?7)] 'electric-help-undefined) |
66 (define-key map [(control ?8)] 'electric-help-undefined) | 66 (define-key map [(control ?8)] 'electric-help-undefined) |
67 (define-key map [(control ?9)] 'electric-help-undefined) | 67 (define-key map [(control ?9)] 'electric-help-undefined) |
68 (define-key map (char-to-string help-char) 'electric-help-help) | 68 (define-key map (char-to-string help-char) 'electric-help-help) |
69 (define-key map "?" 'electric-help-help) | 69 (define-key map "?" 'electric-help-help) |
70 ;; XEmacs addition | |
70 (define-key map 'help 'electric-help-help) | 71 (define-key map 'help 'electric-help-help) |
71 (define-key map " " 'scroll-up) | 72 (define-key map " " 'scroll-up) |
72 (define-key map "\^?" 'scroll-down) | 73 (define-key map "\^?" 'scroll-down) |
73 (define-key map "." 'beginning-of-buffer) | 74 (define-key map "." 'beginning-of-buffer) |
74 (define-key map "<" 'beginning-of-buffer) | 75 (define-key map "<" 'beginning-of-buffer) |
84 | 85 |
85 (setq electric-help-map map))) | 86 (setq electric-help-map map))) |
86 | 87 |
87 (defun electric-help-mode () | 88 (defun electric-help-mode () |
88 "`with-electric-help' temporarily places its buffer in this mode. | 89 "`with-electric-help' temporarily places its buffer in this mode. |
89 \(On exit from `with-electric-help', the buffer is put in `default-major-mode'.\)" | 90 \(On exit from `with-electric-help', the buffer is put in `default-major-mode'.)" |
90 (setq buffer-read-only t) | 91 (setq buffer-read-only t) |
91 (setq mode-name "Help") | 92 (setq mode-name "Help") |
92 (setq major-mode 'help) | 93 (setq major-mode 'help) |
93 (setq modeline-buffer-identification '(" Help: %b")) | 94 (setq modeline-buffer-identification '(" Help: %b")) |
94 (use-local-map electric-help-map) | 95 (use-local-map electric-help-map) |
95 (setq mouse-leave-buffer-hook '(electric-help-retain)) | 96 (add-hook 'mouse-leave-buffer-hook 'electric-help-retain) |
97 (view-mode -1) | |
96 ;; this is done below in with-electric-help | 98 ;; this is done below in with-electric-help |
97 ;(run-hooks 'electric-help-mode-hook) | 99 ;(run-hooks 'electric-help-mode-hook) |
98 ) | 100 ) |
99 | 101 |
100 ;;;###autoload | 102 ;;;###autoload |
124 BUFFER is put into `default-major-mode' (or `fundamental-mode') when we exit." | 126 BUFFER is put into `default-major-mode' (or `fundamental-mode') when we exit." |
125 (setq buffer (get-buffer-create (or buffer "*Help*"))) | 127 (setq buffer (get-buffer-create (or buffer "*Help*"))) |
126 (let ((one (one-window-p t)) | 128 (let ((one (one-window-p t)) |
127 (config (current-window-configuration)) | 129 (config (current-window-configuration)) |
128 (bury nil) | 130 (bury nil) |
129 (to-be-executed nil)) | 131 (electric-help-form-to-execute nil)) |
130 (unwind-protect | 132 (unwind-protect |
131 (save-excursion | 133 (save-excursion |
132 (if one (goto-char (window-start (selected-window)))) | 134 (if one (goto-char (window-start (selected-window)))) |
133 (let ((pop-up-windows t)) | 135 (let ((pop-up-windows t)) |
134 (pop-to-buffer buffer)) | 136 (pop-to-buffer buffer)) |
136 (set-buffer buffer) | 138 (set-buffer buffer) |
137 (if (and minheight (< (window-height) minheight)) | 139 (if (and minheight (< (window-height) minheight)) |
138 (enlarge-window (- minheight (window-height)))) | 140 (enlarge-window (- minheight (window-height)))) |
139 (electric-help-mode) | 141 (electric-help-mode) |
140 (setq buffer-read-only nil) | 142 (setq buffer-read-only nil) |
141 (or noerase (erase-buffer))) | 143 (or noerase |
144 (erase-buffer))) | |
142 (let ((standard-output buffer)) | 145 (let ((standard-output buffer)) |
143 (if (not (funcall thunk)) | 146 (if (not (funcall thunk)) |
144 (progn | 147 (progn |
145 (set-buffer buffer) | 148 (set-buffer buffer) |
146 (set-buffer-modified-p nil) | 149 (set-buffer-modified-p nil) |
147 (goto-char (point-min)) | 150 (goto-char (point-min)) |
148 (if one (shrink-window-if-larger-than-buffer (selected-window)))))) | 151 (if one (shrink-window-if-larger-than-buffer (selected-window)))))) |
149 (set-buffer buffer) | 152 (set-buffer buffer) |
150 (run-hooks 'electric-help-mode-hook) | 153 (run-hooks 'electric-help-mode-hook) |
154 (setq buffer-read-only t) | |
151 (if (eq (car-safe | 155 (if (eq (car-safe |
152 ;; Don't be screwed by minor-modes (view-minor-mode) | 156 ;; XEmacs: Don't be screwed by minor-modes (view-minor-mode) |
153 (let ((overriding-local-map electric-help-map)) | 157 (let ((overriding-local-map electric-help-map)) |
154 (electric-help-command-loop))) | 158 (electric-help-command-loop))) |
155 'retain) | 159 'retain) |
156 (setq config (current-window-configuration)) | 160 (setq config (current-window-configuration)) |
157 (setq bury t))) | 161 (setq bury t))) |
158 (message nil) | 162 (message "") |
159 (set-buffer buffer) | 163 (set-buffer buffer) |
160 (setq buffer-read-only nil) | 164 (setq buffer-read-only nil) |
161 (condition-case () | 165 (condition-case () |
162 (funcall (or default-major-mode 'fundamental-mode)) | 166 (funcall (or default-major-mode 'fundamental-mode)) |
163 (error nil)) | 167 (error nil)) |
167 ;;>> Perhaps this shouldn't be done. | 171 ;;>> Perhaps this shouldn't be done. |
168 ;; so that when we say "Press space to bury" we mean it | 172 ;; so that when we say "Press space to bury" we mean it |
169 (replace-buffer-in-windows buffer) | 173 (replace-buffer-in-windows buffer) |
170 ;; must do this outside of save-window-excursion | 174 ;; must do this outside of save-window-excursion |
171 (bury-buffer buffer))) | 175 (bury-buffer buffer))) |
172 (eval to-be-executed)))) | 176 (eval electric-help-form-to-execute)))) |
173 | 177 |
174 (defun electric-help-command-loop () | 178 (defun electric-help-command-loop () |
175 (catch 'exit | 179 (catch 'exit |
176 (if (pos-visible-in-window-p (point-max)) | 180 (if (pos-visible-in-window-p (point-max)) |
177 (progn (message (substitute-command-keys "<<< Press Space to bury the help buffer, Press \\[electric-help-retain] to retain it >>>")) | 181 (progn (message "%s" (substitute-command-keys "<<< Press Space to bury the help buffer, Press \\[electric-help-retain] to retain it >>>")) |
182 ;; XEmacs change | |
178 (if (equal (setq unread-command-events | 183 (if (equal (setq unread-command-events |
179 (list (next-command-event))) | 184 (list (next-command-event))) |
180 '(?\ )) | 185 '(?\ )) |
181 (progn (setq unread-command-events nil) | 186 (progn (setq unread-command-events nil) |
182 (throw 'exit t))))) | 187 (throw 'exit t))))) |
217 t)))) | 222 t)))) |
218 | 223 |
219 | 224 |
220 | 225 |
221 ;(defun electric-help-scroll-up (arg) | 226 ;(defun electric-help-scroll-up (arg) |
222 ; "####Doc" | 227 ; ">>>Doc" |
223 ; (interactive "P") | 228 ; (interactive "P") |
224 ; (if (and (null arg) (pos-visible-in-window-p (point-max))) | 229 ; (if (and (null arg) (pos-visible-in-window-p (point-max))) |
225 ; (electric-help-exit) | 230 ; (electric-help-exit) |
226 ; (scroll-up arg))) | 231 ; (scroll-up arg))) |
227 | 232 |
228 (defun electric-help-exit () | 233 (defun electric-help-exit () |
229 "####Doc" | 234 ">>>Doc" |
230 (interactive) | 235 (interactive) |
231 (throw 'exit t)) | 236 (throw 'exit t)) |
232 | 237 |
233 (defun electric-help-retain () | 238 (defun electric-help-retain () |
234 "Exit `electric-help', retaining the current window/buffer configuration. | 239 "Exit `electric-help', retaining the current window/buffer configuration. |
235 \(The *Help* buffer will not be selected, but \\[switch-to-buffer-other-window] RET | 240 \(The *Help* buffer will not be selected, but \\[switch-to-buffer-other-window] RET |
236 will select it.)" | 241 will select it.)" |
237 (interactive) | 242 (interactive) |
238 ;; Make sure that we don't throw twice, even if two events cause | 243 ;; Make sure that we don't throw twice, even if two events cause |
239 ;; calling this function: | 244 ;; calling this function: |
240 (if mouse-leave-buffer-hook | 245 (if (memq 'electric-help-retain mouse-leave-buffer-hook) |
241 (progn | 246 (progn |
242 (setq mouse-leave-buffer-hook nil) | 247 (remove-hook 'mouse-leave-buffer-hook 'electric-help-retain) |
243 (throw 'exit '(retain))))) | 248 (throw 'exit '(retain))))) |
244 | 249 |
245 | |
246 ;(defun electric-help-undefined () | |
247 ; (interactive) | |
248 ; (let* ((keys (this-command-keys)) | |
249 ; (n (length keys))) | |
250 ; (if (or (= n 1) | |
251 ; (and (= n 2) | |
252 ; meta-flag | |
253 ; (eq (aref keys 0) meta-prefix-char))) | |
254 ; (setq unread-command-char last-input-char | |
255 ; current-prefix-arg prefix-arg) | |
256 ; ;;#### I don't care. | |
257 ; ;;#### The emacs command-loop is too much pure pain to | |
258 ; ;;#### duplicate | |
259 ; )) | |
260 ; (throw 'exit t)) | |
261 | 250 |
262 (defun electric-help-undefined () | 251 (defun electric-help-undefined () |
263 (interactive) | 252 (interactive) |
264 (error "%s is undefined -- Press %s to exit" | 253 (error "%s is undefined -- Press %s to exit" |
265 (mapconcat 'single-key-description (this-command-keys) " ") | 254 (mapconcat 'single-key-description (this-command-keys) " ") |
266 (if (eq (key-binding "q") 'electric-help-exit) | 255 (if (eq (key-binding "q") 'electric-help-exit) |
267 "q" | 256 "q" |
268 (substitute-command-keys "\\[electric-help-exit]")))) | 257 (substitute-command-keys "\\[electric-help-exit]")))) |
269 | 258 |
270 | 259 |
271 ;#### this needs to be hairified (recursive help, anybody?) | 260 ;>>> this needs to be hairified (recursive help, anybody?) |
272 (defun electric-help-help () | 261 (defun electric-help-help () |
273 (interactive) | 262 (interactive) |
274 (if (and (eq (key-binding "q") 'electric-help-exit) | 263 (if (and (eq (key-binding "q") 'electric-help-exit) |
275 (eq (key-binding " ") 'scroll-up) | 264 (eq (key-binding " ") 'scroll-up) |
276 (eq (key-binding "\^?") 'scroll-down) | 265 (eq (key-binding "\^?") 'scroll-down) |
279 (message "%s" (substitute-command-keys "\\[scroll-up] scrolls up, \\[scroll-down] scrolls down, \\[electric-help-exit] exits burying help buffer, \\[electric-help-retain] exits"))) | 268 (message "%s" (substitute-command-keys "\\[scroll-up] scrolls up, \\[scroll-down] scrolls down, \\[electric-help-exit] exits burying help buffer, \\[electric-help-retain] exits"))) |
280 (sit-for 2)) | 269 (sit-for 2)) |
281 | 270 |
282 | 271 |
283 ;;;###autoload | 272 ;;;###autoload |
284 (defun electric-helpify (fun &optional buffer-name) | 273 (defun electric-helpify (fun &optional name) |
285 (or buffer-name (setq buffer-name "*Help*")) | 274 (let ((name (or name "*Help*"))) |
286 (let* ((p (symbol-function 'print-help-return-message)) | 275 (if (save-window-excursion |
287 (b (get-buffer buffer-name)) | 276 ;; kludge-o-rama |
288 (tick (and b (buffer-modified-tick b)))) | 277 (let* ((p (symbol-function 'print-help-return-message)) |
289 (and b (not (get-buffer-window b)) | 278 (b (get-buffer name)) |
290 (setq b nil)) | 279 (m (buffer-modified-p b))) |
291 (if (unwind-protect | 280 (and b (not (get-buffer-window b)) |
292 (save-window-excursion | 281 (setq b nil)) |
293 (message "%s..." (capitalize (symbol-name fun))) | 282 (unwind-protect |
294 ;; kludge-o-rama | 283 (progn |
295 (fset 'print-help-return-message 'ignore) | 284 (message "%s..." (capitalize (symbol-name fun))) |
296 (let ((a (call-interactively fun 'lambda))) | 285 ;; with-output-to-temp-buffer marks the buffer as unmodified. |
297 (let ((temp-buffer-show-function 'ignore)) | 286 ;; kludging excessively and relying on that as some sort |
298 (apply fun a))) | 287 ;; of indication leads to the following abomination... |
299 (message nil) | 288 ;;>> This would be doable without such icky kludges if either |
300 ;; Was a non-empty help buffer created/modified? | 289 ;;>> (a) there were a function to read the interactive |
301 (let ((r (get-buffer buffer-name))) | 290 ;;>> args for a command and return a list of those args. |
302 (and r | 291 ;;>> (To which one would then just apply the command) |
303 ;(get-buffer-window r) | 292 ;;>> (The only problem with this is that interactive-p |
304 (or (not b) | 293 ;;>> would break, but that is such a misfeature in |
305 (not (eq b r)) | 294 ;;>> any case that I don't care) |
306 (not (eql tick (buffer-modified-tick b)))) | 295 ;;>> It is easy to do this for emacs-lisp functions; |
307 (save-excursion | 296 ;;>> the only problem is getting the interactive spec |
308 (set-buffer r) | 297 ;;>> for subrs |
309 (> (buffer-size) 0))))) | 298 ;;>> (b) there were a function which returned a |
310 (fset 'print-help-return-message p) | 299 ;;>> modification-tick for a buffer. One could tell |
311 ) | 300 ;;>> whether a buffer had changed by whether the |
312 (with-electric-help 'ignore buffer-name t)))) | 301 ;;>> modification-tick were different. |
302 ;;>> (Presumably there would have to be a way to either | |
303 ;;>> restore the tick to some previous value, or to | |
304 ;;>> suspend updating of the tick in order to allow | |
305 ;;>> things like momentary-string-display) | |
306 (and b | |
307 (save-excursion | |
308 (set-buffer b) | |
309 (set-buffer-modified-p t))) | |
310 (fset 'print-help-return-message 'ignore) | |
311 (call-interactively fun) | |
312 (and (get-buffer name) | |
313 (get-buffer-window (get-buffer name)) | |
314 (or (not b) | |
315 (not (eq b (get-buffer name))) | |
316 (not (buffer-modified-p b))))) | |
317 (fset 'print-help-return-message p) | |
318 (and b (buffer-name b) | |
319 (save-excursion | |
320 (set-buffer b) | |
321 (set-buffer-modified-p m)))))) | |
322 (with-electric-help 'ignore name t)))) | |
313 | 323 |
314 | 324 |
315 | 325 |
316 ;; This is to be bound to M-x in ehelp mode. Retains ehelp buffer and then | 326 ;; This is to be bound to M-x in ehelp mode. Retains ehelp buffer and then |
317 ;; continues with execute-extended-command. | 327 ;; continues with execute-extended-command. |
318 (defun electric-help-execute-extended (prefixarg) | 328 (defun electric-help-execute-extended (prefixarg) |
319 (interactive "p") | 329 (interactive "p") |
320 (setq to-be-executed '(execute-extended-command nil)) | 330 (setq electric-help-form-to-execute '(execute-extended-command nil)) |
321 (electric-help-retain)) | 331 (electric-help-retain)) |
322 | 332 |
323 ;; This is to be buond to C-x in ehelp mode. Retains ehelp buffer and then | 333 ;; This is to be buond to C-x in ehelp mode. Retains ehelp buffer and then |
324 ;; continues with ctrl-x prefix. | 334 ;; continues with ctrl-x prefix. |
325 (defun electric-help-ctrl-x-prefix (prefixarg) | 335 (defun electric-help-ctrl-x-prefix (prefixarg) |
326 (interactive "p") | 336 (interactive "p") |
327 (setq to-be-executed '(progn (message nil) (setq unread-command-char ?\C-x))) | 337 (setq electric-help-form-to-execute '(progn (message nil) (setq unread-command-char ?\C-x))) |
328 (electric-help-retain)) | 338 (electric-help-retain)) |
329 | 339 |
330 | 340 |
331 (defun electric-describe-key () | 341 (defun electric-describe-key () |
332 (interactive) | 342 (interactive) |
361 (interactive) | 371 (interactive) |
362 (electric-helpify 'describe-syntax)) | 372 (electric-helpify 'describe-syntax)) |
363 | 373 |
364 (defun electric-command-apropos () | 374 (defun electric-command-apropos () |
365 (interactive) | 375 (interactive) |
366 (electric-helpify 'command-apropos)) | 376 (electric-helpify 'command-apropos "*Apropos*")) |
367 | 377 |
368 ;(define-key help-map "a" 'electric-command-apropos) | 378 ;(define-key help-map "a" 'electric-command-apropos) |
369 | 379 |
370 (defun electric-apropos () | 380 (defun electric-apropos () |
371 (interactive) | 381 (interactive) |
372 (electric-helpify 'apropos)) | 382 (electric-helpify 'apropos)) |
373 | |
374 | 383 |
375 | 384 |
376 ;;;; ehelp-map | 385 ;;;; ehelp-map |
377 | 386 |
378 (defvar ehelp-map nil) | 387 (defvar ehelp-map ()) |
379 (if ehelp-map | 388 (if ehelp-map |
380 nil | 389 nil |
381 ;; #### WTF? Why don't we just use substitute-key-definition | 390 ;; #### WTF? Why don't we just use substitute-key-definition |
382 ;; like FSF does? | 391 ;; like FSF does? |
383 (let ((shadow '((apropos . electric-apropos) | 392 (let ((shadow '((apropos . electric-apropos) |