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)