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