Mercurial > hg > xemacs-beta
comparison lisp/hyperbole/hui-mini.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 4103f0995bd7 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 ;;!emacs | |
2 ;; | |
3 ;; FILE: hui-mini.el | |
4 ;; SUMMARY: One line command menus for Hyperbole | |
5 ;; USAGE: GNU Emacs Lisp Library | |
6 ;; KEYWORDS: hypermedia, mouse | |
7 ;; | |
8 ;; AUTHOR: Bob Weiner | |
9 ;; ORG: Brown U. | |
10 ;; | |
11 ;; ORIG-DATE: 15-Oct-91 at 20:13:17 | |
12 ;; LAST-MOD: 3-Nov-95 at 04:02:02 by Bob Weiner | |
13 ;; | |
14 ;; This file is part of Hyperbole. | |
15 ;; Available for use and distribution under the same terms as GNU Emacs. | |
16 ;; | |
17 ;; Copyright (C) 1991-1995, Free Software Foundation, Inc. | |
18 ;; Developed with support from Motorola Inc. | |
19 ;; | |
20 ;; DESCRIPTION: | |
21 ;; DESCRIP-END. | |
22 | |
23 ;;; ************************************************************************ | |
24 ;;; Other required Elisp libraries | |
25 ;;; ************************************************************************ | |
26 | |
27 (require 'hypb) | |
28 | |
29 ;;; ************************************************************************ | |
30 ;;; Public variables | |
31 ;;; ************************************************************************ | |
32 | |
33 (defvar hui:menu-select "\C-m" | |
34 "*Upper case char-string which selects the Hyperbole menu item at point.") | |
35 (defvar hui:menu-quit "Q" | |
36 "*Upper case char-string which quits selecting from a Hyperbole menu item.") | |
37 (defvar hui:menu-abort "\C-g" | |
38 "*Same function as 'hui:menu-quit'.") | |
39 (defvar hui:menu-top "\C-t" | |
40 "*Character which returns to top Hyperbole menu.") | |
41 | |
42 (defvar hui:menu-p nil | |
43 "Non-nil iff a current Hyperbole menu activation exists.") | |
44 | |
45 (defvar hui:menus nil | |
46 "Command menus for use with the default Hyperbole user interface.") | |
47 (setq | |
48 hui:menus | |
49 (delq nil | |
50 (list (cons | |
51 'hyperbole | |
52 (append | |
53 (let ((version (if (= (aref hyperb:version 0) ?0) | |
54 (substring hyperb:version 1) | |
55 hyperb:version))) | |
56 (list (list (concat "Hy" version ">")))) | |
57 (delq nil | |
58 (list | |
59 '("Act" hui:hbut-act | |
60 "Activates button at point or prompts for explicit button.") | |
61 '("Butfile/" (menu . butfile) | |
62 "Quick access button files menus.") | |
63 '("Doc/" (menu . doc) | |
64 "Quick access to Hyperbole documentation.") | |
65 '("Ebut/" (menu . ebut) | |
66 "Explicit button commands.") | |
67 '("Gbut/" (menu . gbut) | |
68 "Global button commands.") | |
69 '("Hist" (hhist:remove current-prefix-arg) | |
70 "Jumps back to location prior to last Hyperbole button follow.") | |
71 '("Ibut/" (menu . ibut) | |
72 "Implicit button and button type commands.") | |
73 '("Msg/" (menu . msg) | |
74 "Mail and News messaging facilities.") | |
75 (if hyperb:kotl-p | |
76 '("Otl/" (menu . otl) | |
77 "Autonumbered outlining and hyper-node facilities.")) | |
78 '("Rolo/" (menu . rolo) | |
79 "Hierarchical, multi-file rolodex lookup and edit commands.") | |
80 '("Win/" (menu . win) | |
81 "Window configuration management command.") | |
82 )))) | |
83 '(butfile . | |
84 (("Butfile>") | |
85 ("DirFile" (find-file hbmap:filename) | |
86 "Edits directory-specific button file.") | |
87 ("Info" | |
88 (id-info "(hyperbole.info)Button Files") | |
89 "Displays manual section on button files.") | |
90 ("PersonalFile" (find-file | |
91 (expand-file-name hbmap:filename hbmap:dir-user)) | |
92 "Edits user-specific button file.") | |
93 )) | |
94 '(doc . | |
95 (("Doc>") | |
96 ("Demo" (find-file-read-only | |
97 (expand-file-name "DEMO" hyperb:dir)) | |
98 "Demonstrates Hyperbole features.") | |
99 ("Files" (find-file-read-only | |
100 (expand-file-name "MANIFEST" hyperb:dir)) | |
101 "Summarizes Hyperbole system files. Click on an entry to view it.") | |
102 ("Glossary" | |
103 (id-info "(hyperbole.info)Glossary") | |
104 "Glossary of Hyperbole terms.") | |
105 ("HypbCopy" (id-info "(hyperbole.info)Top") | |
106 "Displays general Hyperbole copyright and license details.") | |
107 ("Info" (id-info "(hyperbole.info)Top") | |
108 "Online Info version of Hyperbole manual.") | |
109 ("MailLists" (id-info "(hyperbole.info)Mail Lists") | |
110 "Details on Hyperbole mail list subscriptions.") | |
111 ("New" (progn | |
112 (hact 'link-to-regexp-match | |
113 "\\*[ \t]+What's New" 2 | |
114 (expand-file-name "README" hyperb:dir)) | |
115 (setq buffer-read-only nil) | |
116 (toggle-read-only)) | |
117 "Recent changes to Hyperbole.") | |
118 ("SmartKy" (find-file-read-only (hypb:mouse-help-file)) | |
119 "Summarizes Smart Key mouse or keyboard handling.") | |
120 ("Types/" (menu . types) | |
121 "Provides documentation on Hyperbole types.") | |
122 )) | |
123 '(ebut . | |
124 (("EButton>") | |
125 ("Act" hui:hbut-act | |
126 "Activates button at point or prompts for explicit button.") | |
127 ("Create" hui:ebut-create) | |
128 ("Delete" hui:ebut-delete) | |
129 ("Edit" hui:ebut-modify "Modifies any desired button attributes.") | |
130 ("Help/" (menu . ebut-help) "Summarizes button attributes.") | |
131 ("Info" | |
132 (id-info "(hyperbole.info)Explicit Buttons") | |
133 "Displays manual section on explicit buttons.") | |
134 ("Modify" hui:ebut-modify "Modifies any desired button attributes.") | |
135 ("Rename" hui:ebut-rename "Relabels an explicit button.") | |
136 ("Search" hui:ebut-search | |
137 "Locates and displays personally created buttons in context.") | |
138 )) | |
139 '(ebut-help . | |
140 (("Help on>") | |
141 ("BufferButs" (hui:hbut-report -1) | |
142 "Summarizes all explicit buttons in buffer.") | |
143 ("CurrentBut" (hui:hbut-report) | |
144 "Summarizes only current button in buffer.") | |
145 ("OrderedButs" (hui:hbut-report 1) | |
146 "Summarizes explicit buttons in lexicographically order.") | |
147 )) | |
148 '(gbut . | |
149 (("GButton>") | |
150 ("Act" gbut:act "Activates global button by name.") | |
151 ("Create" hui:gbut-create "Adds a global button to gbut:file.") | |
152 ("Edit" hui:gbut-modify "Modifies global button attributes.") | |
153 ("Help" gbut:help "Reports on a global button by name.") | |
154 ("Info" (id-info "(hyperbole.info)Global Buttons") | |
155 "Displays manual section on global buttons.") | |
156 ("Modify" hui:gbut-modify "Modifies global button attributes.") | |
157 )) | |
158 '(ibut . | |
159 (("IButton>") | |
160 ("Act" hui:hbut-act "Activates implicit button at point.") | |
161 ("DeleteIButType" (hui:htype-delete 'ibtypes) | |
162 "Deletes specified button type.") | |
163 ("Help" hui:hbut-help "Reports on button's attributes.") | |
164 ("Info" (id-info "(hyperbole.info)Implicit Buttons") | |
165 "Displays manual section on implicit buttons.") | |
166 ("Types" (hui:htype-help 'ibtypes 'no-sort) | |
167 "Displays documentation for one or all implicit button types.") | |
168 )) | |
169 '(msg . | |
170 (("Msg>") | |
171 ("Compose-Hypb-Mail" | |
172 (hmail:compose "hyperbole@hub.ucsb.edu" '(hact 'hyp-config)) | |
173 "Send a message to the Hyperbole discussion list.") | |
174 ("Edit-Hypb-List-Entry" | |
175 (hmail:compose "hyperbole-request@hub.ucsb.edu" | |
176 '(hact 'hyp-request)) | |
177 "Add, remove or change your entry on a the Hyperbole mail list.") | |
178 ("Modify-Hypb-Announce-Entry" | |
179 (hmail:compose "hyperbole-announce-request@hub.ucsb.edu" | |
180 '(hact 'hyp-request)) | |
181 "Add, remove or change your entry on the Hyperbole Announce mail list.") | |
182 )) | |
183 (if hyperb:kotl-p | |
184 '(otl | |
185 . (("Otl>") | |
186 ("All" kotl-mode:show-all "Expand all collapsed cells.") | |
187 ("Blanks" kvspec:toggle-blank-lines | |
188 "Toggle blank lines between cells on or off.") | |
189 ("Create" kfile:find "Create or edit an outline file.") | |
190 ("Downto" kotl-mode:hide-sublevels | |
191 "Hide all cells in outline deeper than a particular level.") | |
192 ("Examp" (find-file-read-only | |
193 (expand-file-name | |
194 "EXAMPLE.kotl" (concat hyperb:dir "kotl/"))) | |
195 "Display a self-descriptive example outline file.") | |
196 ("Hide" (progn (kotl-mode:is-p) | |
197 (kotl-mode:hide-tree (kcell-view:label))) | |
198 "Collapse tree rooted at point.") | |
199 ("Info" | |
200 (id-info "(hyperbole.info)Outliner") | |
201 "Display manual section on Hyperbole outliner.") | |
202 ("Kill" kotl-mode:kill-tree | |
203 "Kill ARG following trees starting from point.") | |
204 ("Link" klink:create | |
205 "Create and insert an implicit link at point.") | |
206 ("Overvw" kotl-mode:overview | |
207 "Show first line of each cell.") | |
208 ("Show" (progn (kotl-mode:is-p) | |
209 (kotl-mode:show-tree (kcell-view:label))) | |
210 "Expand tree rooted at point.") | |
211 ("Top" kotl-mode:top-cells | |
212 "Hide all but top-level cells.") | |
213 ("Vspec" kvspec:activate | |
214 "Prompt for and activate a view specifiction.") | |
215 ))) | |
216 '(rolo . | |
217 (("Rolo>") | |
218 ("Add" rolo-add "Add a new rolo entry.") | |
219 ("Display" rolo-display-matches | |
220 "Display last found rolodex matches again.") | |
221 ("Edit" rolo-edit "Edit an existing rolo entry.") | |
222 ("Info" (id-info "(hyperbole.info)Rolodex") | |
223 "Displays manual section on Hyperbole rolodex.") | |
224 ("Kill" rolo-kill "Kill an existing rolo entry.") | |
225 ("Mail" rolo-mail-to "Mail to address following point.") | |
226 ("Order" rolo-sort "Order rolo entries in a file.") | |
227 ("RegexFind" rolo-grep "Find entries containing a regexp.") | |
228 ("StringFind" rolo-fgrep "Find entries containing a string.") | |
229 ("WordFind" rolo-word "Find entries containing words.") | |
230 ("Yank" rolo-yank | |
231 "Find an entry containing a string and insert it at point.") | |
232 )) | |
233 '(types . | |
234 (("Types>") | |
235 ("ActionTypes" (hui:htype-help 'actypes) | |
236 "Displays documentation for one or all action types.") | |
237 ("IButTypes" (hui:htype-help 'ibtypes 'no-sort) | |
238 "Displays documentation for one or all implicit button types.") | |
239 )) | |
240 '(win . | |
241 (("WinConfig>") | |
242 ("AddName" wconfig-add-by-name | |
243 "Name current window configuration.") | |
244 ("DeleteName" wconfig-delete-by-name | |
245 "Delete named window configuration.") | |
246 ("RestoreName" wconfig-restore-by-name | |
247 "Restore frame to window configuration given by name.") | |
248 ("PopRing" (progn (wconfig-delete-pop) | |
249 (hyperbole 'win)) | |
250 "Restores window configuration from ring and removes it from ring.") | |
251 ("SaveRing" (wconfig-ring-save) | |
252 "Saves current window configuration to ring.") | |
253 ("YankRing" (progn (call-interactively 'wconfig-yank-pop) | |
254 (hyperbole 'win)) | |
255 "Restores next window configuration from ring.") | |
256 )) | |
257 ))) | |
258 | |
259 ;;; ************************************************************************ | |
260 ;;; Public functions | |
261 ;;; ************************************************************************ | |
262 | |
263 ;;; Old name | |
264 (fset 'hui:menu 'hyperbole) | |
265 | |
266 ;;; Used as autoloaded main entry point to Hyperbole (but hsite.el) is the | |
267 ;;; file that is autoloaded when this is invoked. | |
268 ;;; It brings up a menu of commands. | |
269 (defun hyperbole (&optional menu menu-list) | |
270 "Invokes default Hyperbole menu user interface when not already active. | |
271 Suitable for binding to a key, e.g. {C-h h}. | |
272 Non-interactively, returns t if menu is actually invoked by call, else nil. | |
273 | |
274 Two optional arguments may be given to invoke alternative menus. | |
275 MENU (a symbol) specifies the menu to invoke from MENU-LIST, (a | |
276 Hyperbole menu list structure). MENU defaults to 'hyperbole and MENU-LIST | |
277 to `hui:menus'. See `hui:menus' definition for the format of the menu list | |
278 structure." | |
279 | |
280 (interactive) | |
281 (if (and hui:menu-p (> (minibuffer-depth) 0)) | |
282 (progn (beep) nil) | |
283 (unwind-protect | |
284 (progn | |
285 (require 'hsite) ;; Since "hui-mini" may be loaded without loading | |
286 ;; all of Hyperbole. | |
287 (hyperb:init-menubar) | |
288 (setq hui:menu-p t) | |
289 (hui:menu-act (or menu 'hyperbole) menu-list) | |
290 t) | |
291 (setq hui:menu-p nil)))) | |
292 | |
293 (defun hui:menu-act (menu &optional menu-list) | |
294 "Prompts user with Hyperbole MENU (a symbol) and performs selected item. | |
295 Optional second argument MENU-LIST is a Hyperbole menu list structure from | |
296 which to extract MENU. It defaults to `hui:menus'. See its definition for | |
297 the menu list structure." | |
298 (let ((set-menu '(or (and menu (symbolp menu) | |
299 (setq menu-alist | |
300 (cdr (assq menu (or menu-list hui:menus))))) | |
301 (hypb:error "(menu-act): Invalid menu symbol arg: %s" | |
302 menu))) | |
303 (show-menu t) | |
304 (rtn) | |
305 menu-alist act-form) | |
306 (while (and show-menu (eval set-menu)) | |
307 (cond ((and (consp (setq act-form (hui:menu-select menu-alist))) | |
308 (cdr act-form) | |
309 (symbolp (cdr act-form))) | |
310 ;; Display another menu | |
311 (setq menu (cdr act-form))) | |
312 (act-form | |
313 (let ((prefix-arg current-prefix-arg)) | |
314 (cond ((symbolp act-form) | |
315 (if (eq act-form t) | |
316 nil | |
317 (setq show-menu nil | |
318 rtn (call-interactively act-form)))) | |
319 ((stringp act-form) | |
320 (hui:menu-help act-form) | |
321 ;; Loop and show menu again. | |
322 ) | |
323 (t (setq show-menu nil | |
324 rtn (eval act-form)))))) | |
325 (t (setq show-menu nil)))) | |
326 rtn)) | |
327 | |
328 (defun hui:menu-enter (&optional char-str) | |
329 "Uses CHAR-STR or last input character as minibuffer argument." | |
330 (interactive) | |
331 (let ((input (or char-str (aref (recent-keys) (1- (length (recent-keys))))))) | |
332 (cond (hyperb:emacs19-p | |
333 (and (not (integerp input)) | |
334 (eventp input) | |
335 (setq input (event-basic-type input)))) | |
336 (hyperb:lemacs-p | |
337 (if (eventp input) | |
338 (setq input (event-to-character input))))) | |
339 (if (or (symbolp input) | |
340 (and (integerp input) | |
341 (= input ?\r))) | |
342 (setq input (hargs:at-p))) | |
343 (erase-buffer) | |
344 (or (symbolp input) (insert input))) | |
345 (exit-minibuffer)) | |
346 | |
347 (defun hui:menu-help (help-str) | |
348 "Displays HELP-STR in a small window. HELP-STR must be a string." | |
349 (let* ((window-min-height 2) | |
350 (owind (selected-window)) | |
351 (buf-name (hypb:help-buf-name "Menu"))) | |
352 (unwind-protect | |
353 (progn | |
354 (save-window-excursion | |
355 (hkey-help-show buf-name)) ;; Needed to save wconfig. | |
356 (if (eq (selected-window) (minibuffer-window)) | |
357 (other-window 1)) | |
358 (if (= (length (hypb:window-list 'no-mini)) 1) | |
359 (split-window-vertically nil)) | |
360 (select-window (hui:bottom-window)) | |
361 (switch-to-buffer (get-buffer-create buf-name)) | |
362 (setq buffer-read-only nil) | |
363 (erase-buffer) | |
364 (insert "\n" help-str) | |
365 (set-buffer-modified-p nil) | |
366 (shrink-window | |
367 (- (window-height) | |
368 (+ 3 (length | |
369 (delq nil | |
370 (mapcar (function | |
371 (lambda (chr) (= chr ?\n))) | |
372 help-str))))))) | |
373 (select-window owind)))) | |
374 | |
375 (defun hui:menu-xemacs (&optional menu menu-list) | |
376 "Returns an XEmacs menu built from Hyperbole type menus. | |
377 Optional MENU (a symbol) specifies a specific submenu of optional MENU-LIST. | |
378 a Hyperbole menu list structure. Otherwise, all menus are used. | |
379 MENU defaults to 'hyperbole and MENU-LIST to `hui:menus'. See `hui:menus' | |
380 definition for the format of the menu list structure." | |
381 (mapcar | |
382 (function | |
383 (lambda (entry) | |
384 (or (consp entry) | |
385 (error "(hui:menu-xemacs): Invalid menu entry: %s" entry)) | |
386 (let ((label (car entry)) | |
387 (content (car (cdr entry)))) | |
388 (cond ((null content) (hypb:replace-match-string ">$" label "" t)) | |
389 ((and (consp content) (eq (car content) 'menu)) | |
390 (hui:menu-xemacs (cdr content))) | |
391 (t (vector label content 't)))))) | |
392 (cdr (assq (or menu 'hyperbole) (or menu-list hui:menus))))) | |
393 | |
394 (defun hui:menu-select (menu-alist) | |
395 "Prompts user to choose the first character of any item from MENU-ALIST. | |
396 Case is not significant. If chosen by direct selection with the Assist Key, | |
397 returns any help string for item, else returns the action form for the item." | |
398 (let* ((menu-line (hui:menu-line menu-alist)) | |
399 (set:equal-op 'eq) | |
400 (select-char (string-to-char hui:menu-select)) | |
401 (quit-char (string-to-char hui:menu-quit)) | |
402 (abort-char (string-to-char hui:menu-abort)) | |
403 (top-char (string-to-char hui:menu-top)) | |
404 (item-keys (mapcar (function | |
405 (lambda (item) (aref item 0))) | |
406 (mapcar 'car (cdr menu-alist)))) | |
407 (keys (apply 'list select-char quit-char abort-char | |
408 top-char item-keys)) | |
409 (key 0) | |
410 (hargs:reading-p 'hmenu) | |
411 sublist) | |
412 (while (not (memq (setq key (upcase | |
413 (string-to-char | |
414 (read-from-minibuffer | |
415 "" menu-line hui:menu-mode-map)))) | |
416 keys)) | |
417 (beep) | |
418 (setq hargs:reading-p 'hmenu) | |
419 (discard-input)) | |
420 (cond ((eq key quit-char) nil) | |
421 ((eq key abort-char) (beep) nil) | |
422 ((eq key top-char) '(menu . hyperbole)) | |
423 ((and (eq key select-char) | |
424 (save-excursion | |
425 (if (search-backward " " nil t) | |
426 (progn (skip-chars-forward " ") | |
427 (setq key (following-char)) | |
428 nil) ;; Drop through. | |
429 t)))) | |
430 (t (if (setq sublist (memq key item-keys)) | |
431 (let* ((label-act-help-list | |
432 (nth (- (1+ (length item-keys)) (length sublist)) | |
433 menu-alist)) | |
434 (act-form (car (cdr label-act-help-list)))) | |
435 (if (eq hargs:reading-p 'hmenu-help) | |
436 (let ((help-str | |
437 (or (car (cdr (cdr label-act-help-list))) | |
438 "No help documentation for this item."))) | |
439 (concat (car label-act-help-list) "\n " | |
440 help-str "\n Action: " | |
441 (prin1-to-string act-form))) | |
442 act-form))))))) | |
443 | |
444 ;;; ************************************************************************ | |
445 ;;; Private functions | |
446 ;;; ************************************************************************ | |
447 | |
448 (if (fboundp 'window-lowest-p) | |
449 (defun hui:bottom-window () | |
450 "Return a window that is at the bottom of the selected frame." | |
451 (let ((winds (hypb:window-list 'no-mini)) | |
452 (window)) | |
453 (while (and (not window) winds) | |
454 (if (window-lowest-p (car winds)) | |
455 (setq window (car winds)) | |
456 (setq winds (cdr winds)))) | |
457 window)) | |
458 (defun hui:bottom-window () | |
459 "Return a window that is at the bottom of the selected frame." | |
460 (let* ((winds (hypb:window-list 'no-mini)) | |
461 (bot-list (mapcar | |
462 (function | |
463 (lambda (wind) | |
464 (nth 3 (window-edges wind)))) | |
465 winds)) | |
466 (bot (apply 'max bot-list))) | |
467 (nth (- (length winds) (length (memq bot bot-list))) winds)))) | |
468 | |
469 (defun hui:menu-line (menu-alist) | |
470 "Returns a menu line string built from MENU-ALIST." | |
471 (let ((menu-prompt (concat (car (car menu-alist)) " ")) | |
472 (menu-items (mapconcat 'car (cdr menu-alist) " ")) | |
473 menu-line) | |
474 (setq menu-line (concat menu-prompt menu-items)) | |
475 ;; Narrow menu by changing 2 spaces to 1 if too wide for current frame. | |
476 (if (>= (length menu-line) (1- (frame-width))) | |
477 (concat menu-prompt (mapconcat 'car (cdr menu-alist) " ")) | |
478 menu-line))) | |
479 | |
480 ;;; ************************************************************************ | |
481 ;;; Private variables | |
482 ;;; ************************************************************************ | |
483 | |
484 ;; Hyperbole menu mode is suitable only for specially formatted data. | |
485 (put 'hui:menu-mode 'mode-class 'special) | |
486 | |
487 (defvar hui:menu-mode-map nil | |
488 "Keymap containing hui:menu commands.") | |
489 (if hui:menu-mode-map | |
490 nil | |
491 (setq hui:menu-mode-map (make-keymap)) | |
492 (suppress-keymap hui:menu-mode-map) | |
493 (define-key hui:menu-mode-map hui:menu-quit 'hui:menu-enter) | |
494 (define-key hui:menu-mode-map hui:menu-abort 'hui:menu-enter) | |
495 (define-key hui:menu-mode-map hui:menu-top 'hui:menu-enter) | |
496 (define-key hui:menu-mode-map hui:menu-select 'hui:menu-enter) | |
497 ;; | |
498 ;; This next binding is necessary since the default button1 binding under | |
499 ;; XEmacs, mouse-track, is broken under XEmacs V19.8. | |
500 (and hyperb:lemacs-p window-system | |
501 (define-key hui:menu-mode-map 'button1 'mouse-set-point)) | |
502 (let ((i 32)) | |
503 (while (<= i 126) | |
504 (define-key hui:menu-mode-map (char-to-string i) 'hui:menu-enter) | |
505 (setq i (1+ i))))) | |
506 | |
507 (provide 'hui-mini) |