weiner@novavax.UUCP (Bob Weiner) (04/29/89)
;;!emacs ;; ;; FILE: smart-menu.el ;; SUMMARY: Display subsystem menu for use with 'smart-key.el' package. ;; USAGE: GNU Emacs Lisp Library ;; ;; AUTHOR: Bob Weiner, Applied Research, Motorola, Inc. ;; E-MAIL: USENET: weiner@novavax.UUCP ;; ORIG-DATE: 20-Apr-89 ;; LAST-MOD: 28-Apr-89 at 00:38:00 by Bob Weiner ;; ;; Copyright (C) 1989 Bob Weiner and Free Software Foundation, Inc. ;; Available for use and distribution under the same terms as GNU Emacs. ;; ;; This file is not part of GNU Emacs. ;; ;; DESCRIPTION: ;;; ;;; This code is machine independent. ;;; ;;; To install: ;;; ;;; See smart-key.el ;;; ;; DESCRIP-END. (defconst smart-menu-at-bottom t "Non-nil means display menu below current window, nil means above.") (defconst smart-menu-buffer "*Smart Menu*" "Name of the buffer used for the smart subsystem menu.") (defvar *smart-menu-window-config* nil "Window configuration prior to entry of smart menu mode.") (defvar *smart-menu-prev-mode* nil "Records major-mode prior to entry of smart-menu.") (defvar smart-menu-mode-map nil "Keymap containing smart-menu commands.") (if smart-menu-mode-map nil (setq smart-menu-mode-map (copy-keymap text-mode-map)) (define-key smart-menu-mode-map "h" 'smart-menu-help) (define-key smart-menu-mode-map "q" 'smart-menu-quit) (define-key smart-menu-mode-map " " 'smart-menu-select) (define-key smart-menu-mode-map "\C-m" 'smart-key) (define-key smart-menu-mode-map "\M-\C-m" 'smart-key-meta)) ;; Smart menu mode is suitable only for specially formatted data. (put 'smart-menu-mode 'mode-class 'special) (defun smart-menu-mode () "Smart-menu mode provides a menu of commands for entering subsystems. See also the documentation for 'smart-menu'. \\[smart-menu-select] or \\[smart-key] selects entries in the menu. \\[smart-menu-quit] or \\[smart-key-meta] quits from the menu." (kill-all-local-variables) (use-local-map smart-menu-mode-map) (setq major-mode 'smart-menu-mode) (setq mode-name "smart-menu") (set-syntax-table text-mode-syntax-table) (setq local-abbrev-table text-mode-abbrev-table) (setq case-fold-search t) (setq buffer-read-only t) ;; (smart-menu-set-mode-line) (run-hooks 'smart-menu-mode-hook)) (defun smart-menu () "Smart-menu pops up a window with a menu of commands for entering subsystems. \\[smart-menu-select] or \\[smart-key] selects entries in the menu. \\[smart-menu-quit] or \\[smart-key-meta] quits from the menu." (interactive) (setq *smart-menu-window-config* (current-window-configuration)) (let ((buf (get-buffer-create smart-menu-buffer)) (pop-up-windows t)) (setq *smart-menu-prev-mode* major-mode) (set-buffer buf) (or (eq major-mode 'smart-menu-mode) (smart-menu-mode)) (split-window-vertically) (if smart-menu-at-bottom (pop-to-buffer smart-menu-buffer) (switch-to-buffer smart-menu-buffer)) ;; Smallest size you can shrink a window (shrink-window (- (window-height) 4)) ;; If empty buffer (if (= (save-excursion (end-of-buffer) (point)) 1) (let ((buffer-read-only nil)) (insert "\nBuffer-Menu Calendar Dired-Home-Dir <Help> Info Rmail Mail Shell <Quit>") (center-line) (set-buffer-modified-p nil) (back-to-indentation))))) (defun smart-menu-select (&optional arg) "Select smart menu item that point is within and execute associated command. Also quits from smart menu mode. With prefix ARG, quits only." (interactive "P") (if arg (smart-menu-quit) (let ((cmd (extract-item-around-point))) (if (string= cmd "") (error "No command selected.") (let ((exec-cmd (cond ((string= cmd "Buffer-Menu") '(buffer-menu nil)) ((string= cmd "Calendar") '(calendar)) ((string= cmd "Dired-Home-Dir") '(dired "~")) ((string= cmd "<Help>") '(smart-menu-help)) ((string= cmd "Info") '(info)) ((string= cmd "Rmail") '(rmail)) ((string= cmd "Mail") '(mail)) ((string= cmd "Shell") '(shell)) ((string= cmd "<Quit>"))))) (if exec-cmd (progn (smart-menu-quit) (eval exec-cmd)) (beep) (message (format "Unimplemented command selected, '%s'." cmd)))))))) (defun smart-menu-help () "Displays description of major mode prior to smart-menu invocation." (interactive) (describe-function *smart-menu-prev-mode*)) (defun smart-menu-quit (&optional arg) "Quit from smart menu. Restore previous window configuration. Optional ARG kills the smart menu buffer rather than just burying it." (interactive "P") (let ((buf (get-buffer smart-menu-buffer))) (and buf (if arg (kill-buffer buf) (bury-buffer buf))) ;; Restore previous window configuration before entering smart menu. (if (and buf *smart-menu-window-config*) (progn (set-window-configuration *smart-menu-window-config*) (setq *smart-menu-window-config* nil))))) (defun extract-item-around-point () "Return whitespace separated menu item that point is within or before." (interactive) (save-excursion (skip-chars-backward "^ \t\n") (let ((start (point))) (skip-chars-forward "^ \t\n") (buffer-substring start (point))))) (provide 'smart-menu) -- Bob Weiner, Motorola, Inc., USENET: ...!gatech!uflorida!novavax!weiner (407) 738-2087