PageRenderTime 26ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/old-archive/misc/auc-menu.el

https://github.com/emacsmirror/ohio-archive
Emacs Lisp | 313 lines | 169 code | 54 blank | 90 comment | 2 complexity | 9a550d30153fb5f760000986ce97d437 MD5 | raw file
  1. ;;; auc-menu.el - Easy menu support for GNU Emacs and XEmacs.
  2. ;;
  3. ;; $Id: auc-menu.el,v 5.8 1995/01/24 22:52:29 amanda Exp $
  4. ;;
  5. ;; LCD Archive Entry:
  6. ;; auc-menu|Per Abrahamsen|abraham@iesd.auc.dk|
  7. ;; Easy menu support for GNU Emacs and XEmacs|
  8. ;; 24-Jan-1995|5.8|~/misc/auc-menu.el.gz|
  9. ;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
  10. ;; Copyright (C) 1994 Per Abrahamsen <abraham@iesd.auc.dk>
  11. ;;
  12. ;; This program is free software; you can redistribute it and/or modify
  13. ;; it under the terms of the GNU General Public License as published by
  14. ;; the Free Software Foundation; either version 2, or (at your option)
  15. ;; any later version.
  16. ;;
  17. ;; This program is distributed in the hope that it will be useful,
  18. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. ;; GNU General Public License for more details.
  21. ;;
  22. ;; You should have received a copy of the GNU General Public License
  23. ;; along with this program; if not, write to the Free Software
  24. ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25. ;; Commentary:
  26. ;;
  27. ;; Easymenu allows you to define menus for both Emacs 19 and XEmacs.
  28. ;; The advantages of using easymenu are:
  29. ;;
  30. ;; - Easier to use than either the Emacs 19 and XEmacs menu syntax.
  31. ;;
  32. ;; - Common interface for Emacs 18, Emacs 19, and XEmacs.
  33. ;; (The code does nothing when run under Emacs 18).
  34. ;;
  35. ;; The public functions are:
  36. ;;
  37. ;; - Function: easy-menu-define SYMBOL MAPS DOC MENU
  38. ;; SYMBOL is both the name of the variable that holds the menu and
  39. ;; the name of a function that will present a the menu.
  40. ;; MAPS is a list of keymaps where the menu should appear in the menubar.
  41. ;; DOC is the documentation string for the variable.
  42. ;; MENU is an XEmacs style menu description.
  43. ;;
  44. ;; See the documentation for easy-menu-define for details.
  45. ;;
  46. ;; - Function: easy-menu-change PATH NAME ITEMS
  47. ;; Change an existing menu.
  48. ;; The menu must already exist an be visible on the menu bar.
  49. ;; PATH is a list of strings used for locating the menu on the menu bar.
  50. ;; NAME is the name of the menu.
  51. ;; ITEMS is a list of menu items, as defined in `easy-menu-define'.
  52. ;;
  53. ;; - Function: easy-menu-add MENU [ MAP ]
  54. ;; Add MENU to the current menubar in MAP.
  55. ;;
  56. ;; - Function: easy-menu-remove MENU
  57. ;; Remove MENU from the current menubar.
  58. ;;
  59. ;; GNU Emacs 19 never uses `easy-menu-add' or `easy-menu-remove',
  60. ;; menus automatically appear and disappear when the keymaps
  61. ;; specified by the MAPS argument to `easy-menu-define' are
  62. ;; activated.
  63. ;;
  64. ;; XEmacs will bind the map to button3 in each MAPS, but you must
  65. ;; explicitly call `easy-menu-add' and `easy-menu-remove' to add and
  66. ;; remove menus from the menu bar.
  67. ;; auc-menu.el defines the easymenu API included in Emacs 19.29.
  68. ;; In fact, the Emacs 19 specific code should be identical.
  69. ;;; Code:
  70. ;;;###autoload
  71. (defmacro easy-menu-define (symbol maps doc menu)
  72. "Define a menu bar submenu in maps MAPS, according to MENU.
  73. The arguments SYMBOL and DOC are ignored; they are present for
  74. compatibility only. SYMBOL is not evaluated. In other Emacs versions
  75. these arguments may be used as a variable to hold the menu data, and a
  76. doc string for that variable.
  77. The first element of MENU must be a string. It is the menu bar item name.
  78. The rest of the elements are menu items.
  79. A menu item is usually a vector of three elements: [NAME CALLBACK ENABLE]
  80. NAME is a string--the menu item name.
  81. CALLBACK is a command to run when the item is chosen,
  82. or a list to evaluate when the item is chosen.
  83. ENABLE is an expression; the item is enabled for selection
  84. whenever this expression's value is non-nil.
  85. Alternatively, a menu item may have the form:
  86. [ NAME CALLBACK [ KEYWORD ARG ] ... ]
  87. Where KEYWORD is one of the symbol defined below.
  88. :keys KEYS
  89. KEYS is a string; a complex keyboard equivalent to this menu item.
  90. :active ENABLE
  91. ENABLE is an expression; the item is enabled for selection
  92. whenever this expression's value is non-nil.
  93. :suffix NAME
  94. NAME is a string; the name of an argument to CALLBACK.
  95. :style STYLE
  96. STYLE is a symbol describing the type of menu item. The following are
  97. defined:
  98. toggle: A checkbox.
  99. Currently just prepend the name with the string \"Toggle \".
  100. radio: A radio button.
  101. nil: An ordinary menu item.
  102. :selected SELECTED
  103. SELECTED is an expression; the checkbox or radio button is selected
  104. whenever this expression's value is non-nil.
  105. Currently just disable radio buttons, no effect on checkboxes.
  106. A menu item can be a string. Then that string appears in the menu as
  107. unselectable text. A string consisting solely of hyphens is displayed
  108. as a solid horizontal line.
  109. A menu item can be a list. It is treated as a submenu.
  110. The first element should be the submenu name. That's used as the
  111. menu item in the top-level menu. The cdr of the submenu list
  112. is a list of menu items, as above."
  113. (` (progn
  114. (defvar (, symbol) nil (, doc))
  115. (easy-menu-do-define (quote (, symbol)) (, maps) (, doc) (, menu)))))
  116. (cond
  117. ;;; Emacs 18
  118. ((< (string-to-int emacs-version) 19)
  119. (defun easy-menu-do-define (symbol maps doc menu)
  120. (fset symbol (symbol-function 'ignore)))
  121. (defun easy-menu-remove (menu))
  122. (defun easy-menu-add (menu &optional map))
  123. (defun easy-menu-change (path name items))
  124. ) ;Emacs 18
  125. ;;; XEmacs
  126. ((string-match "XEmacs\\|Lucid" emacs-version)
  127. (defun easy-menu-do-define (symbol maps doc menu)
  128. (set symbol menu)
  129. (fset symbol (list 'lambda '(e)
  130. doc
  131. '(interactive "@e")
  132. '(run-hooks 'activate-menubar-hook)
  133. '(setq zmacs-region-stays 't)
  134. (list 'popup-menu symbol)))
  135. (mapcar (function (lambda (map) (define-key map 'button3 symbol)))
  136. (if (keymapp maps) (list maps) maps)))
  137. (fset 'easy-menu-change (symbol-function 'add-menu))
  138. (defun easy-menu-add (menu &optional map)
  139. "Add MENU to the current menu bar."
  140. (cond ((null current-menubar)
  141. ;; Don't add it to a non-existing menubar.
  142. nil)
  143. ((assoc (car menu) current-menubar)
  144. ;; Already present.
  145. nil)
  146. ((equal current-menubar '(nil))
  147. ;; Set at left if only contains right marker.
  148. (set-buffer-menubar (list menu nil)))
  149. (t
  150. ;; Add at right.
  151. (set-buffer-menubar (copy-sequence current-menubar))
  152. (add-menu nil (car menu) (cdr menu)))))
  153. (defun easy-menu-remove (menu)
  154. "Remove MENU from the current menu bar."
  155. (and current-menubar
  156. (assoc (car menu) current-menubar)
  157. (delete-menu-item (list (car menu)))))
  158. ) ;XEmacs
  159. ;;; GNU Emacs 19
  160. (t
  161. (defun easy-menu-do-define (symbol maps doc menu)
  162. ;; We can't do anything that might differ between Emacs dialects in
  163. ;; `easy-menu-define' in order to make byte compiled files
  164. ;; compatible. Therefore everything interesting is done in this
  165. ;; function.
  166. (set symbol (easy-menu-create-keymaps (car menu) (cdr menu)))
  167. (fset symbol (` (lambda (event) (, doc) (interactive "@e")
  168. (easy-popup-menu event (, symbol)))))
  169. (mapcar (function (lambda (map)
  170. (define-key map (vector 'menu-bar (intern (car menu)))
  171. (cons (car menu) (symbol-value symbol)))))
  172. (if (keymapp maps) (list maps) maps)))
  173. (defvar easy-menu-item-count 0)
  174. ;; Return a menu keymap corresponding to a XEmacs style menu list
  175. ;; MENU-ITEMS, and with name MENU-NAME.
  176. (defun easy-menu-create-keymaps (menu-name menu-items)
  177. (let ((menu (make-sparse-keymap menu-name)))
  178. ;; Process items in reverse order,
  179. ;; since the define-key loop reverses them again.
  180. (setq menu-items (reverse menu-items))
  181. (while menu-items
  182. (let* ((item (car menu-items))
  183. (callback (if (vectorp item) (aref item 1)))
  184. command enabler name)
  185. (cond ((stringp item)
  186. (setq command nil)
  187. (setq name (if (string-match "^-+$" item) "" item)))
  188. ((consp item)
  189. (setq command (easy-menu-create-keymaps (car item) (cdr item)))
  190. (setq name (car item)))
  191. ((vectorp item)
  192. (setq command (make-symbol (format "menu-function-%d"
  193. easy-menu-item-count)))
  194. (setq easy-menu-item-count (1+ easy-menu-item-count))
  195. (setq name (aref item 0))
  196. (let ((keyword (aref item 2)))
  197. (if (and (symbolp keyword)
  198. (= ?: (aref (symbol-name keyword) 0)))
  199. (let ((count 2)
  200. style selected active keys
  201. arg)
  202. (while (> (length item) count)
  203. (setq keyword (aref item count))
  204. (setq arg (aref item (1+ count)))
  205. (setq count (+ 2 count))
  206. (cond ((eq keyword ':keys)
  207. (setq keys arg))
  208. ((eq keyword ':active)
  209. (setq active arg))
  210. ((eq keyword ':suffix)
  211. (setq name (concat name " " arg)))
  212. ((eq keyword ':style)
  213. (setq style arg))
  214. ((eq keyword ':selected)
  215. (setq selected arg))))
  216. (if keys
  217. (setq name (concat name " (" keys ")")))
  218. (if (eq style 'toggle)
  219. ;; Simulate checkboxes.
  220. (setq name (concat "Toggle " name)))
  221. (if active
  222. (put command 'menu-enable active)
  223. (and (eq style 'radio)
  224. selected
  225. ;; Simulate radio buttons with menu-enable.
  226. (put command 'menu-enable
  227. (list 'not selected)))))))
  228. (if (keymapp callback)
  229. (setq name (concat name " ...")))
  230. (if (symbolp callback)
  231. (fset command callback)
  232. (fset command (list 'lambda () '(interactive) callback)))))
  233. (if (null command)
  234. ;; Handle inactive strings specially--allow any number
  235. ;; of identical ones.
  236. (setcdr menu (cons (list nil name) (cdr menu)))
  237. (if name
  238. (define-key menu (vector (intern name)) (cons name command)))))
  239. (setq menu-items (cdr menu-items)))
  240. menu))
  241. (defun easy-menu-change (path name items)
  242. "Change menu found at PATH as item NAME to contain ITEMS.
  243. PATH is a list of strings for locating the menu containing NAME in the
  244. menu bar. ITEMS is a list of menu items, as in `easy-menu-define'.
  245. These items entirely replace the previous items in that map.
  246. Call this from `activate-menubar-hook' to implement dynamic menus."
  247. (let ((map (key-binding (apply 'vector
  248. 'menu-bar
  249. (mapcar 'intern (append path (list name)))))))
  250. (if (keymapp map)
  251. (setcdr map (cdr (easy-menu-create-keymaps name items)))
  252. (error "Malformed menu in `easy-menu-change'"))))
  253. (defun easy-menu-remove (menu))
  254. (defun easy-menu-add (menu &optional map))
  255. ) ;GNU Emacs 19
  256. ) ;cond
  257. (provide 'easymenu)
  258. (provide 'auc-menu)
  259. ;;; auc-menu.el ends here