diff lisp/vm/vm-menu.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children 859a2309aef8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/vm/vm-menu.el	Mon Aug 13 08:45:50 2007 +0200
@@ -0,0 +1,1155 @@
+;;; Menu related functions and commands
+;;; Copyright (C) 1995 Kyle E. Jones
+;;;
+;;; Folders menu derived from
+;;;     vm-folder-menu.el
+;;;     v1.10; 03-May-1994
+;;;     Copyright (C) 1994 Heiko Muenkel
+;;;     email: muenkel@tnt.uni-hannover.de
+;;;  Used with permission and my thanks.
+;;;  Changed 18-May-1995, Kyle Jones
+;;;     Cosmetic string changes, changed some variable names
+;;;     and interfaced it with FSF Emacs via easymenu.el.
+;;;   
+;;; Tree menu code is essentially tree-menu.el with renamed functions
+;;;     tree-menu.el
+;;;     v1.20; 10-May-1994
+;;;     Copyright (C) 1994 Heiko Muenkel
+;;;     email: muenkel@tnt.uni-hannover.de
+;;;
+;;;  Changed 18-May-1995, Kyle Jones
+;;;    Removed the need for the utils.el package and references thereto.
+;;;    Changed file-truename calls to tree-menu-file-truename so
+;;;    the calls could be made compatible with FSF Emacs 19's
+;;;    file-truename function.
+;;;  Changed 30-May-1995, Kyle Jones
+;;;    Renamed functions: tree- -> vm-menu-hm-tree.
+;;;  Changed 5-July-1995, Kyle Jones
+;;;    Removed the need for -A in ls flags.
+;;;    Some systems' ls don't support -A.
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 1, or (at your option)
+;;; any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+(provide 'vm-menu)
+
+(defun vm-menu-fsfemacs-menus-p ()
+  (and (vm-fsfemacs-19-p)
+       (fboundp 'menu-bar-mode)))
+
+(defun vm-menu-xemacs-menus-p ()
+  (and (vm-xemacs-p)
+       (fboundp 'set-buffer-menubar)))
+
+;; defined again in vm-misc.el but we need it here for some
+;; initializations.  The "noautoload" vm.elc won't work without
+;; this.
+(defun vm-fsfemacs-19-p ()
+  (and (string-match "^19" emacs-version)
+       (not (string-match "XEmacs\\|Lucid" emacs-version))))
+
+(defvar vm-menu-folders-menu 
+  '("Manipulate Folders"
+    ["Make Folders Menu" vm-menu-hm-make-folder-menu vm-folder-directory])
+  "VM folder menu list.")
+
+(defconst vm-menu-folder-menu
+  (list
+   "Folder"
+   (if (vm-fsfemacs-19-p)
+       ["Manipulate Folders" ignore (ignore)]
+     vm-menu-folders-menu)
+   "---"
+   ["Display Summary" vm-summarize t]
+   ["Toggle Threading" vm-toggle-threads-display t]
+   "---"
+   ["Get New Mail" vm-get-new-mail (vm-menu-can-get-new-mail-p)]
+   "---"
+   ["Search" vm-isearch-forward vm-message-list]
+   "---"
+   ["Auto-Archive" vm-auto-archive-messages vm-message-list]
+   ["Expunge" vm-expunge-folder vm-message-list]
+   "---"
+   ["Visit Folder" vm-visit-folder t]
+   ["Revert Folder (back to disk version)" revert-buffer (vm-menu-can-revert-p)]
+   ["Recover Folder (from auto-save file)" recover-file (vm-menu-can-recover-p)]
+   ["Save" vm-save-folder (vm-menu-can-save-p)]
+   ["Save As..." vm-write-file t]
+   ["Quit" vm-quit-no-change t]
+   ["Save & Quit" vm-quit t]
+   "---"
+   "---"
+   ;; special string that marks the tail of this menu for
+   ;; vm-menu-install-visited-folders-menu.
+   "-------"
+   ))
+
+(defconst vm-menu-dispose-menu
+  (let ((title (if (vm-menu-fsfemacs-menus-p)
+		   (list "Dispose"
+			 "Dispose"
+			 "---"
+			 "---")
+		 (list "Dispose"))))
+    (append
+     title
+     (list
+      ["Reply to Author" vm-reply vm-message-list]
+      ["Reply to All" vm-followup vm-message-list]
+      ["Reply to Author (citing original)" vm-reply-include-text vm-message-list]
+      ["Reply to All (citing original)" vm-followup-include-text vm-message-list]
+      ["Forward" vm-forward-message vm-message-list]
+      ["Resend" vm-resend-message vm-message-list]
+      ["Retry Bounce" vm-resend-bounced-message vm-message-list]
+      "---"
+      ["File" vm-save-message vm-message-list]
+      ["Delete" vm-delete-message vm-message-list]
+      ["Undelete"	vm-undelete-message vm-message-list]
+      ["Kill Current Subject" vm-kill-subject vm-message-list]
+      ["Mark Unread" vm-unread-message vm-message-list]
+      ["Edit" vm-edit-message vm-message-list]
+      ["Print" vm-print-message vm-message-list]
+      ["Pipe to Command" vm-pipe-message-to-command vm-message-list]
+      "---"
+      ["Burst Message as Digest" (vm-burst-digest "guess") vm-message-list]
+      ))))
+
+(defconst vm-menu-motion-menu
+  '("Motion"
+    ["Page Up" vm-scroll-backward vm-message-list]
+    ["Page Down" vm-scroll-forward vm-message-list]
+    "----"
+    ["Beginning" vm-beginning-of-message vm-message-list]
+    ["End" vm-end-of-message vm-message-list]
+    "----"
+    ["Expose/Hide Headers" vm-expose-hidden-headers vm-message-list]
+    "----"
+    "----"
+    ["Next Message" vm-next-message t]
+    ["Previous Message"	vm-previous-message t]
+    "---"
+    ["Next, Same Subject" vm-next-message-same-subject t]
+    ["Previous, Same Subject" vm-previous-message-same-subject t]
+    "---"
+    ["Next Unread" vm-next-unread-message t]
+    ["Previous Unread" vm-previous-unread-message t]
+    "---"
+    ["Next Message (no skip)" vm-next-message-no-skip t]
+    ["Previous Message (no skip)" vm-previous-message-no-skip t]
+    "---"
+    ["Go to Last Seen Message" vm-goto-message-last-seen t]
+    ["Go to Message" vm-goto-message t]
+    ["Go to Parent Message" vm-goto-parent-message t]
+    ))
+
+(defconst vm-menu-virtual-menu
+  '("Virtual"
+    ["Visit Virtual Folder" vm-visit-virtual-folder t]
+    ["Create Virtual Folder" vm-create-virtual-folder t]
+    ["Apply Virtual Folder" vm-apply-virtual-folder t]
+    "---"
+    "---"
+    ;; special string that marks the tail of this menu for
+    ;; vm-menu-install-known-virtual-folders-menu.
+    "-------"
+    ))
+
+(defconst vm-menu-send-menu
+  '("Send"
+    ["Compose" vm-mail t]
+    ["Continue Composing" vm-continue-composing-message vm-message-list]
+    ["Reply to Author" vm-reply vm-message-list]
+    ["Reply to All" vm-followup vm-message-list]
+    ["Reply to Author (citing original)" vm-reply-include-text vm-message-list]
+    ["Reply to All (citing original)" vm-followup-include-text vm-message-list]
+    ["Forward Message" vm-forward-message vm-message-list]
+    ["Resend Message" vm-resend-message vm-message-list]
+    ["Retry Bounced Message" vm-resend-bounced-message vm-message-list]
+    ["Send Digest (RFC934)" vm-send-rfc934-digest vm-message-list]
+    ["Send Digest (RFC1153)" vm-send-rfc1153-digest vm-message-list]
+    ))
+
+(defconst vm-menu-mark-menu
+  '("Mark"
+    ["Next Command Uses Marks..." vm-next-command-uses-marks
+     :active vm-message-list
+     :style radio
+     :selected (eq last-command 'vm-next-command-uses-marks)]
+    "----"
+    ["Mark" vm-mark-message vm-message-list]
+    ["Unmark" vm-unmark-message vm-message-list]
+    ["Mark All" vm-mark-all-messages vm-message-list]
+    ["Clear All Marks" vm-clear-all-marks vm-message-list]
+    "----"
+    ["Mark Same Subject" vm-mark-messages-same-subject vm-message-list]
+    ["Unmark Same Subject" vm-unmark-messages-same-subject vm-message-list]
+    ["Mark Same Author" vm-mark-messages-same-author vm-message-list]
+    ["Unmark Same Author" vm-unmark-messages-same-author vm-message-list]
+    ["Mark Messages Matching..." vm-mark-matching-messages vm-message-list]
+    ["Unmark Messages Matching..." vm-unmark-matching-messages vm-message-list]
+    ["Mark Thread Subtree" vm-mark-thread-subtree vm-message-list]
+    ["Unmark Thread Subtree" vm-unmark-thread-subtree vm-message-list]
+    ))
+
+(defconst vm-menu-label-menu
+  '("Label"
+    ["Add Label" vm-add-message-labels vm-message-list]
+    ["Remove Label" vm-delete-message-labels vm-message-list]
+    ))
+
+(defconst vm-menu-sort-menu
+  '("Sort"
+    ["By Multiple Fields..." vm-sort-messages vm-message-list]
+    "---"
+    ["By Date" (vm-sort-messages "date") vm-message-list]
+    ["By Subject" (vm-sort-messages "subject") vm-message-list]
+    ["By Author" (vm-sort-messages "author") vm-message-list]
+    ["By Recipients" (vm-sort-messages "recipients") vm-message-list]
+    ["By Lines" (vm-sort-messages "line-count") vm-message-list]
+    ["By Bytes" (vm-sort-messages "byte-count") vm-message-list]
+    "---"
+    ["By Date (backward)" (vm-sort-messages "reversed-date") vm-message-list]
+    ["By Subject (backward)" (vm-sort-messages "reversed-subject") vm-message-list]
+    ["By Author (backward)" (vm-sort-messages "reversed-author") vm-message-list]
+    ["By Recipients (backward)" (vm-sort-messages "reversed-recipients") vm-message-list]
+    ["By Lines (backwards)" (vm-sort-messages "reversed-line-count") vm-message-list]
+    ["By Bytes (backward)" (vm-sort-messages "reversed-byte-count") vm-message-list]
+    "---"
+    ["Toggle Threading" vm-toggle-threads-display t]
+    "---"
+    ["Revert to Physical Order" (vm-sort-messages "physical-order" t) vm-message-list]
+    ))
+
+(defconst vm-menu-help-menu
+  '("Help!"
+    ["What Now?" vm-help t]
+    ["Describe Mode" describe-mode t]
+    ["Revert Folder (back to disk version)" revert-buffer (vm-menu-can-revert-p)]
+    ["Recover Folder (from auto-save file)" recover-file (vm-menu-can-recover-p)]
+    "---"
+    ["Save Folder & Quit" vm-quit t]
+    ["Quit Without Saving" vm-quit-no-change t]
+    ))
+
+(defconst vm-menu-undo-menu
+  ["Undo" vm-undo (vm-menu-can-undo-p)]
+  )
+
+(defconst vm-menu-emacs-button
+  ["XEmacs" vm-menu-toggle-menubar t]
+  )
+
+(defconst vm-menu-vm-button
+  ["VM" vm-menu-toggle-menubar t]
+  )
+
+(defconst vm-menu-mail-menu
+  (let ((title (if (vm-menu-fsfemacs-menus-p)
+		   (list "Mail Commands"
+			 "Mail Commands"
+			 "---"
+			 "---")
+		 (list "Mail Commands"))))
+    (append
+     title
+     (list ["Send and Exit" vm-mail-send-and-exit (vm-menu-can-send-mail-p)]
+	   ["Send, Keep Composing" vm-mail-send (vm-menu-can-send-mail-p)]
+	   ["Cancel" kill-buffer t]
+	   "----"
+	   "Go to Field:"
+	   "----"
+	   ["      To:" mail-to t]
+	   ["      Subject:" mail-subject	t]
+	   ["      CC:" mail-cc t]
+	   ["      BCC:" mail-bcc t]
+	   ["      Reply-To:" mail-replyto t]
+	   ["      Text" mail-text t]
+	   "----"
+	   ["Yank Original" vm-menu-yank-original vm-reply-list]
+	   ["Fill Yanked Message" mail-fill-yanked-message t]
+	   ["Insert Signature"	mail-signature t]
+	   ["Insert File..." insert-file t]
+	   ["Insert Buffer..."	insert-buffer t]
+	   ))))
+
+(defconst vm-menu-url-browser-menu
+  (let ((title (if (vm-menu-fsfemacs-menus-p)
+		   (list "Send URL to ..."
+			 "Send URL to ..."
+			 "---"
+			 "---")
+		 (list "Send URL to ...")))
+	(w3 (cond ((fboundp 'w3-fetch-other-frame)
+		   'w3-fetch-other-frame)
+		  ((fboundp 'w3-fetch)
+		   'w3-fetch)
+		  (t 'w3-fetch-other-frame))))
+    (append
+     title
+     (list (vector "Emacs W3"
+		   (list 'vm-mouse-send-url-at-position
+			 '(point)
+			 (list 'quote w3))
+		   (list 'fboundp (list 'quote w3)))
+	   ["Mosaic"
+	    (vm-mouse-send-url-at-position (point)
+					   'vm-mouse-send-url-to-mosaic)
+	    t]
+	   ["Netscape"
+	    (vm-mouse-send-url-at-position (point)
+					   'vm-mouse-send-url-to-netscape)
+	    t]))))
+
+(defconst vm-menu-subject-menu
+  (let ((title (if (vm-menu-fsfemacs-menus-p)
+		   (list "Take Action on Subject..."
+			 "Take Action on Subject..."
+			 "---"
+			 "---")
+		 (list "Take Action on Subject..."))))
+    (append
+     title
+     (list
+      ["Kill Subject" vm-kill-subject vm-message-list]
+      ["Next Message, Same Subject" vm-next-message-same-subject
+       vm-message-list]
+      ["Previous Message, Same Subject" vm-previous-message-same-subject
+       vm-message-list]
+      ["Mark Messages, Same Subject" vm-mark-messages-same-subject
+       vm-message-list]
+      ["Unmark Messages, Same Subject" vm-unmark-messages-same-subject
+       vm-message-list]
+      ["Virtual Folder, Matching Subject" vm-menu-create-subject-virtual-folder
+       vm-message-list]
+      ))))
+
+(defconst vm-menu-author-menu
+  (let ((title (if (vm-menu-fsfemacs-menus-p)
+		   (list "Take Action on Author..."
+			 "Take Action on Author..."
+			 "---"
+			 "---")
+		 (list "Take Action on Author..."))))
+    (append
+     title
+     (list
+      ["Mark Messages, Same Author" vm-mark-messages-same-author
+       vm-message-list]
+      ["Unmark Messages, Same Author" vm-unmark-messages-same-author
+       vm-message-list]
+      ["Virtual Folder, Matching Author" vm-menu-create-author-virtual-folder
+       vm-message-list]
+      ))))
+
+(defvar vm-menu-vm-menubar nil)
+
+(defconst vm-menu-vm-menu
+  (let ((title (if (vm-menu-fsfemacs-menus-p)
+		   (list "VM"
+			 "VM"
+			 "---"
+			 "---")
+		 (list "VM"))))
+    (append title
+	    (list vm-menu-folder-menu
+		  vm-menu-motion-menu
+		  vm-menu-send-menu
+		  vm-menu-mark-menu
+		  vm-menu-label-menu
+		  vm-menu-sort-menu
+		  vm-menu-virtual-menu
+		  vm-menu-undo-menu
+		  vm-menu-dispose-menu
+		  "---"
+		  "---"
+		  vm-menu-help-menu))))
+
+(defvar vm-mode-menu-map nil)
+
+(defun vm-menu-run-command (command &rest args)
+  "Run COMMAND almost interactively, with ARGS.
+call-interactive can't be used unfortunately, but this-command is
+set to the command name so that window configuration will be done."
+  (setq this-command command)
+  (apply command args))
+
+(defun vm-menu-can-revert-p ()
+  (save-excursion
+    (vm-check-for-killed-folder)
+    (vm-select-folder-buffer)
+    (and (buffer-modified-p) buffer-file-name)))
+
+(defun vm-menu-can-recover-p ()
+  (save-excursion
+    (vm-check-for-killed-folder)
+    (vm-select-folder-buffer)
+    (and buffer-file-name
+	 buffer-auto-save-file-name
+	 (file-newer-than-file-p
+	  buffer-auto-save-file-name
+	  buffer-file-name))))
+
+(defun vm-menu-can-save-p ()
+  (save-excursion
+    (vm-check-for-killed-folder)
+    (vm-select-folder-buffer)
+    (or (eq major-mode 'vm-virtual-mode)
+	(buffer-modified-p))))
+
+(defun vm-menu-can-get-new-mail-p ()
+  (save-excursion
+    (vm-check-for-killed-folder)
+    (vm-select-folder-buffer)
+    (or (eq major-mode 'vm-virtual-mode)
+	(and (not vm-block-new-mail) (not vm-folder-read-only)))))
+
+(defun vm-menu-can-undo-p ()
+  (save-excursion
+    (vm-check-for-killed-folder)
+    (vm-select-folder-buffer)
+    vm-undo-record-list))
+
+(defun vm-menu-yank-original ()
+  (interactive)
+  (save-excursion
+    (let ((mlist vm-reply-list))
+      (while mlist
+	(vm-yank-message (car mlist))
+	(goto-char (point-max))
+	(setq mlist (cdr mlist))))))
+
+(defun vm-menu-can-send-mail-p ()
+  (save-match-data
+    (catch 'done
+      (let ((headers '("to" "cc" "bcc" "resent-to" "resent-cc" "resent-bcc"))
+	    h)
+	(while headers
+	  (setq h (mail-fetch-field (car headers)))
+	  (and (stringp h) (string-match "[^ \t\n,]" h)
+	       (throw 'done t))
+	  (setq headers (cdr headers)))
+	nil ))))
+
+(defun vm-menu-create-subject-virtual-folder ()
+  (interactive)
+  (vm-select-folder-buffer)
+  (setq this-command 'vm-create-virtual-folder)
+  (vm-create-virtual-folder 'subject (regexp-quote
+				      (vm-so-sortable-subject
+				       (car vm-message-pointer)))))
+
+(defun vm-menu-create-author-virtual-folder ()
+  (interactive)
+  (vm-select-folder-buffer)
+  (setq this-command 'vm-create-virtual-folder)
+  (vm-create-virtual-folder 'author (regexp-quote
+				     (vm-su-from (car vm-message-pointer)))))
+
+(defun vm-menu-xemacs-global-menubar ()
+  (save-excursion
+    (set-buffer (get-buffer-create "*scratch*"))
+    current-menubar))
+
+(defun vm-menu-fsfemacs-global-menubar ()
+  (lookup-key (current-global-map) [menu-bar]))
+
+(defun vm-menu-initialize-vm-mode-menu-map ()
+  (if (null vm-mode-menu-map)
+      (let ((map (make-sparse-keymap))
+	    (dummy (make-sparse-keymap)))
+	;; initialize all the vm-menu-fsfemacs-*-menu variables
+	;; with the menus.
+	(vm-easy-menu-define vm-menu-fsfemacs-help-menu (list dummy) nil
+			     vm-menu-help-menu)
+	(vm-easy-menu-define vm-menu-fsfemacs-dispose-menu (list dummy) nil
+			     (cons "Dispose" (nthcdr 4 vm-menu-dispose-menu)))
+	(vm-easy-menu-define vm-menu-fsfemacs-dispose-popup-menu (list dummy) nil
+			     vm-menu-dispose-menu)
+;;	(vm-easy-menu-define vm-menu-fsfemacs-undo-menu (list dummy) nil
+;;			     (list "Undo" vm-menu-undo-menu))
+	(vm-easy-menu-define vm-menu-fsfemacs-virtual-menu (list dummy) nil
+			     vm-menu-virtual-menu)
+	(vm-easy-menu-define vm-menu-fsfemacs-sort-menu (list dummy) nil
+			     vm-menu-sort-menu)
+	(vm-easy-menu-define vm-menu-fsfemacs-label-menu (list dummy) nil
+			     vm-menu-label-menu)
+	(vm-easy-menu-define vm-menu-fsfemacs-mark-menu (list dummy) nil
+			     vm-menu-mark-menu)
+	(vm-easy-menu-define vm-menu-fsfemacs-send-menu (list dummy) nil
+			     vm-menu-send-menu)
+	(vm-easy-menu-define vm-menu-fsfemacs-motion-menu (list dummy) nil
+			     vm-menu-motion-menu)
+;;	(vm-easy-menu-define vm-menu-fsfemacs-folders-menu (list dummy) nil
+;;			     vm-menu-folders-menu)
+	(vm-easy-menu-define vm-menu-fsfemacs-folder-menu (list dummy) nil
+			     vm-menu-folder-menu)
+	(vm-easy-menu-define vm-menu-fsfemacs-vm-menu (list dummy) nil
+			     vm-menu-vm-menu)
+	;; for mail mode
+	(vm-easy-menu-define vm-menu-fsfemacs-mail-menu (list dummy) nil
+			     vm-menu-mail-menu)
+	;; subject menu
+	(vm-easy-menu-define vm-menu-fsfemacs-subject-menu (list dummy) nil
+			     vm-menu-subject-menu)
+	;; author menu
+	(vm-easy-menu-define vm-menu-fsfemacs-author-menu (list dummy) nil
+			     vm-menu-author-menu)
+	;; url browser menu
+	(vm-easy-menu-define vm-menu-fsfemacs-url-browser-menu (list dummy) nil
+			     vm-menu-url-browser-menu)
+	;; block the global menubar entries in the map so that VM
+	;; can take over the menubar if necessary.
+	(define-key map [rootmenu] (make-sparse-keymap))
+	(define-key map [rootmenu vm] (cons "VM" (make-sparse-keymap "VM")))
+	(define-key map [rootmenu vm file] 'undefined)
+	(define-key map [rootmenu vm files] 'undefined)
+	(define-key map [rootmenu vm search] 'undefined)
+	(define-key map [rootmenu vm edit] 'undefined)
+	(define-key map [rootmenu vm options] 'undefined)
+	(define-key map [rootmenu vm buffer] 'undefined)
+	(define-key map [rootmenu vm tools] 'undefined)
+	(define-key map [rootmenu vm help] 'undefined)
+	;; 19.29 changed the tag for the Help menu.
+	(define-key map [rootmenu vm help-menu] 'undefined)
+	;; now build VM's menu tree.
+	(let ((menu-alist
+	       '((dispose
+		  (cons "Dispose" vm-menu-fsfemacs-dispose-menu))
+		 (folder
+		  (cons "Folder" vm-menu-fsfemacs-folder-menu))
+		 (help
+		  (cons "Help!" vm-menu-fsfemacs-help-menu))
+		 (label
+		  (cons "Label" vm-menu-fsfemacs-label-menu))
+		 (mark
+		  (cons "Mark" vm-menu-fsfemacs-mark-menu))
+		 (motion
+		  (cons "Motion" vm-menu-fsfemacs-motion-menu))
+		 (send
+		  (cons "Send" vm-menu-fsfemacs-send-menu))
+		 (sort
+		  (cons "Sort" vm-menu-fsfemacs-sort-menu))
+		 (virtual
+		  (cons "Virtual" vm-menu-fsfemacs-virtual-menu))
+		 (emacs
+		  (cons "[Emacs]" 'vm-menu-toggle-menubar))
+		 (undo
+		  (cons "[Undo]" 'vm-undo))))
+	      cons
+	      (vec (vector 'rootmenu 'vm nil))
+	      ;; menus appear in the opposite order that we
+	      ;; define-key them.
+	      (menu-list 
+	       (if (consp vm-use-menus)
+		   (reverse vm-use-menus)
+		 (list 'help nil 'dispose 'undo 'virtual 'sort
+		       'label 'mark 'send 'motion 'folder))))
+	  (while menu-list
+	    (if (null (car menu-list))
+		nil;; no flushright support in FSF Emacs
+	      (aset vec 2 (intern (concat "vm-menubar-"
+					  (symbol-name
+					   (car menu-list)))))
+	      (setq cons (assq (car menu-list) menu-alist))
+	      (if cons
+		  (define-key map vec (eval (car (cdr cons))))))
+	    (setq menu-list (cdr menu-list))))
+	(setq vm-mode-menu-map map)
+	(run-hooks 'vm-menu-setup-hook))))
+
+(defun vm-menu-make-xemacs-menubar ()
+  (let ((menu-alist
+	 '((dispose . vm-menu-dispose-menu)
+	   (folder . vm-menu-folder-menu)
+	   (help . vm-menu-help-menu)
+	   (label . vm-menu-label-menu)
+	   (mark . vm-menu-mark-menu)
+	   (motion . vm-menu-motion-menu)
+	   (send . vm-menu-send-menu)
+	   (sort . vm-menu-sort-menu)
+	   (virtual . vm-menu-virtual-menu)
+	   (emacs . vm-menu-emacs-button)
+	   (undo . vm-menu-undo-menu)))
+	cons
+	(menubar nil)
+	(menu-list vm-use-menus))
+    (while menu-list
+      (if (null (car menu-list))
+	  (setq menubar (cons nil menubar))
+	(setq cons (assq (car menu-list) menu-alist))
+	(if cons
+	    (setq menubar (cons (symbol-value (cdr cons)) menubar))))
+      (setq menu-list (cdr menu-list)))
+    (nreverse menubar) ))
+
+(defun vm-menu-popup-mode-menu (event)
+  (interactive "e")
+  (cond ((and (vm-menu-xemacs-menus-p) vm-use-menus)
+	 (set-buffer (window-buffer (event-window event)))
+	 (and (event-point event) (goto-char (event-point event)))
+	 (popup-mode-menu))
+	((and (vm-menu-fsfemacs-menus-p) vm-use-menus)
+	 (set-buffer (window-buffer (posn-window (event-start event))))
+	 (goto-char (posn-point (event-start event)))
+	 (vm-menu-popup-fsfemacs-menu event))))
+
+(defun vm-menu-popup-context-menu (event)
+  (interactive "e")
+  ;; We should not need to do anything here for XEmacs.  The
+  ;; default binding of mouse-3 is popup-mode-menu which does
+  ;; what we want for the normal case.  For special contexts,
+  ;; like when the mouse is over an URL, XEmacs has local keymap
+  ;; support for extents.  Any context sensitive area should be
+  ;; contained in an extent with a keymap that has mouse-3 bound
+  ;; to a function that will pop up a context sensitive menu.
+  (cond ((and (vm-menu-fsfemacs-menus-p) vm-use-menus)
+	 (set-buffer (window-buffer (posn-window (event-start event))))
+	 (goto-char (posn-point (event-start event)))
+	 (let (o-list o menu (found nil))
+	   (setq o-list (overlays-at (point)))
+	   (while (and o-list (not found))
+	     (cond ((overlay-get (car o-list) 'vm-url)
+		    (setq found t)
+		    (vm-menu-popup-url-browser-menu event))
+		   ((setq menu (overlay-get (car o-list) 'vm-header))
+		    (setq found t)
+		    (vm-menu-popup-fsfemacs-menu event menu)))
+	     (setq o-list (cdr o-list)))
+	   (and (not found) (vm-menu-popup-fsfemacs-menu event))))))
+
+;; to quiet the byte-compiler
+(defvar vm-menu-fsfemacs-url-browser-menu)
+
+(defun vm-menu-popup-url-browser-menu (event)
+  (interactive "e")
+  (cond ((and (vm-menu-xemacs-menus-p) vm-use-menus)
+	 ;; Must select window instead of just set-buffer because
+	 ;; popup-menu returns before the user has made a
+	 ;; selection.  This will cause the command loop to
+	 ;; resume which might undo what set-buffer does.
+	 (select-window (event-window event))
+	 (and (event-point event) (goto-char (event-point event)))
+	 (popup-menu vm-menu-url-browser-menu))
+	((and (vm-menu-fsfemacs-menus-p) vm-use-menus)
+	 (set-buffer (window-buffer (posn-window (event-start event))))
+	 (goto-char (posn-point (event-start event)))
+	 (vm-menu-popup-fsfemacs-menu
+	  event vm-menu-fsfemacs-url-browser-menu))))
+
+;; to quiet the byte-compiler
+(defvar vm-menu-fsfemacs-mail-menu)
+(defvar vm-menu-fsfemacs-dispose-popup-menu)
+(defvar vm-menu-fsfemacs-vm-menu)
+
+(defun vm-menu-popup-fsfemacs-menu (event &optional menu)
+  (interactive "e")
+  (set-buffer (window-buffer (posn-window (event-start event))))
+  (goto-char (posn-point (event-start event)))
+  (let ((map (or menu mode-popup-menu))
+	key command func)
+    (setq key (x-popup-menu event map)
+	  key (apply 'vector key)
+          command (lookup-key map key)
+	  func (and (symbolp command) (symbol-function command)))
+    (cond ((null func) (setq this-command last-command))
+	  ((symbolp func)
+	   (setq this-command func)
+	   (call-interactively this-command))
+	  (t
+	   (call-interactively command)))))
+
+(defun vm-menu-mode-menu ()
+  (if (vm-menu-xemacs-menus-p)
+      (cond ((eq major-mode 'mail-mode)
+	     vm-menu-mail-menu)
+	    ((memq major-mode '(vm-mode vm-summary-mode vm-virtual-mode))
+	     vm-menu-dispose-menu)
+	    (t vm-menu-vm-menu))
+    (cond ((eq major-mode 'mail-mode)
+	   vm-menu-fsfemacs-mail-menu)
+	  ((memq major-mode '(vm-mode vm-summary-mode vm-virtual-mode))
+	   vm-menu-fsfemacs-dispose-popup-menu)
+	  (t vm-menu-fsfemacs-vm-menu))))
+
+(defun vm-menu-set-menubar-dirty-flag ()
+  (cond ((vm-menu-xemacs-menus-p)
+	 (set-menubar-dirty-flag))
+	((vm-menu-fsfemacs-menus-p)
+	 (force-mode-line-update))))
+
+(defun vm-menu-toggle-menubar (&optional buffer)
+  (interactive)
+  (if buffer
+      (set-buffer buffer)
+    (vm-select-folder-buffer))
+  (cond ((vm-menu-xemacs-menus-p)
+	 (if (null (car (find-menu-item current-menubar '("XEmacs"))))
+	     (set-buffer-menubar vm-menu-vm-menubar)
+	   (set-buffer-menubar (copy-sequence (vm-menu-xemacs-global-menubar)))
+	   (condition-case nil
+	       (add-menu-button nil vm-menu-vm-button nil)
+	     (void-function
+	      (add-menu-item nil "VM" 'vm-menu-toggle-menubar t))))
+	 (vm-menu-set-menubar-dirty-flag)
+	 (vm-check-for-killed-summary)
+	 (and vm-summary-buffer
+	      (vm-menu-toggle-menubar vm-summary-buffer)))
+	((vm-menu-fsfemacs-menus-p)
+	 (if (not (eq (lookup-key vm-mode-map [menu-bar])
+		      (lookup-key vm-mode-menu-map [rootmenu vm])))
+	     (define-key vm-mode-map [menu-bar]
+	       (lookup-key vm-mode-menu-map [rootmenu vm]))
+	   (define-key vm-mode-map [menu-bar]
+	     (make-sparse-keymap))
+	   (define-key vm-mode-map [menu-bar vm]
+	     (cons "[VM]" 'vm-menu-toggle-menubar)))
+	 (vm-menu-set-menubar-dirty-flag))))
+
+(defun vm-menu-install-menubar ()
+  (cond ((vm-menu-xemacs-menus-p)
+	 (setq vm-menu-vm-menubar (vm-menu-make-xemacs-menubar))
+	 (set-buffer-menubar vm-menu-vm-menubar))
+	((and (vm-menu-fsfemacs-menus-p)
+	      ;; menus only need to be installed once for FSF Emacs
+	      (not (fboundp 'vm-menu-undo-menu)))
+	 (vm-menu-initialize-vm-mode-menu-map)
+	 (define-key vm-mode-map [menu-bar]
+	   (lookup-key vm-mode-menu-map [rootmenu vm])))))
+
+(defun vm-menu-install-menubar-item ()
+  (cond ((and (vm-menu-xemacs-menus-p) (vm-menu-xemacs-global-menubar))
+	 (set-buffer-menubar (copy-sequence (vm-menu-xemacs-global-menubar)))
+	 (add-menu nil "VM" (cdr vm-menu-vm-menu)))
+	((and (vm-menu-fsfemacs-menus-p)
+	      ;; menus only need to be installed once for FSF Emacs
+	      (not (fboundp 'vm-menu-undo-menu)))
+	 (vm-menu-initialize-vm-mode-menu-map)
+	 (define-key vm-mode-map [menu-bar]
+	   (lookup-key vm-mode-menu-map [rootmenu])))))
+
+(defun vm-menu-install-vm-mode-menu ()
+  ;; nothing to do here.
+  ;; handled in vm-mouse.el
+  (cond ((vm-menu-xemacs-menus-p)
+	 t )
+	((vm-menu-fsfemacs-menus-p)
+	 t )))
+
+(defun vm-menu-install-mail-mode-menu ()
+  (cond ((vm-menu-xemacs-menus-p)
+	 ;; mail-mode doesn't have mode-popup-menu bound to
+	 ;; mouse-3 by default.  fix that.
+	 (define-key vm-mail-mode-map 'button3 'popup-mode-menu)
+	 ;; put menu on menubar also.
+	 (if (vm-menu-xemacs-global-menubar)
+	     (progn
+	       (set-buffer-menubar
+		(copy-sequence (vm-menu-xemacs-global-menubar)))
+	       (add-menu nil "Mail" (cdr vm-menu-mail-menu))))
+	 t )
+	((vm-menu-fsfemacs-menus-p)
+	 ;; I'd like to do this, but the result is a combination
+	 ;; of the Emacs and VM Mail menus glued together.
+	 ;; Poorly.
+	 ;;(define-key vm-mail-mode-map [menu-bar mail]
+	 ;;  (cons "Mail" vm-menu-fsfemacs-mail-menu))
+	 (define-key vm-mail-mode-map [down-mouse-3]
+	   'vm-menu-popup-mode-menu))))
+
+(defun vm-menu-install-menus ()
+  (cond ((consp vm-use-menus)
+	 (vm-menu-install-vm-mode-menu)
+	 (vm-menu-install-menubar)
+	 (vm-menu-install-known-virtual-folders-menu))
+	((eq vm-use-menus 1)
+	 (vm-menu-install-vm-mode-menu)
+	 (vm-menu-install-menubar-item)
+	 (vm-menu-install-known-virtual-folders-menu))
+	(t nil)))
+
+(defun vm-menu-install-known-virtual-folders-menu ()
+  (let ((folders (sort (mapcar 'car vm-virtual-folder-alist)
+		       (function string-lessp)))
+	(menu nil)
+	tail
+	;; special string indicating tail of Virtual menu
+	(special "-------"))
+    (while folders
+      (setq menu (cons (vector "    "
+			       (list 'vm-menu-run-command
+				     ''vm-visit-virtual-folder (car folders))
+			       t
+			       (car folders))
+		       menu)
+	    folders (cdr folders)))
+    (and menu (setq menu (nreverse menu)
+		    menu (nconc (list "Visit:" "---") menu)))
+    (setq tail (vm-member special vm-menu-virtual-menu))
+    (if (and menu tail)
+	(progn
+	  (setcdr tail menu)
+	  (vm-menu-set-menubar-dirty-flag)
+	  (cond ((vm-menu-fsfemacs-menus-p)
+		 (makunbound 'vm-menu-fsfemacs-virtual-menu)
+		 (vm-easy-menu-define vm-menu-fsfemacs-virtual-menu
+				      (list (make-sparse-keymap))
+				      nil
+				      vm-menu-virtual-menu)
+		 (define-key vm-mode-menu-map [rootmenu vm vm-menubar-virtual]
+		   (cons "Virtual" vm-menu-fsfemacs-virtual-menu))))))))
+
+(defun vm-menu-install-visited-folders-menu ()
+  (let ((folders (vm-delete-duplicates (copy-sequence vm-folder-history)))
+	(menu nil)
+	tail
+	spool-files
+	(i 0)
+	;; special string indicating tail of Folder menu
+	(special "-------"))
+    (while (and folders (< i 10))
+      (setq menu (cons (vector "    "
+			       (list 'vm-menu-run-command
+				     ''vm-visit-folder (car folders))
+			       t
+			       (car folders))
+		       menu)
+	    folders (cdr folders)
+	    i (1+ i)))
+    (and menu (setq menu (nreverse menu)
+		    menu (nconc (list "Visit:" "---") menu)))
+    (setq spool-files (vm-spool-files)
+	  folders (cond ((and (consp spool-files)
+			      (consp (car spool-files)))
+			 (mapcar (function car) spool-files))
+			((and (consp spool-files)
+			      (stringp (car spool-files))
+			      (stringp vm-primary-inbox))
+			 (list vm-primary-inbox))
+			(t nil)))
+    (if (and menu folders)
+	(nconc menu (list "---" "---")))
+    (while folders
+      (setq menu (nconc menu
+			(list (vector "    "
+				      (list 'vm-menu-run-command
+					    ''vm-visit-folder (car folders))
+				      t
+				      (car folders))))
+	    folders (cdr folders)))
+    (setq tail (vm-member special vm-menu-folder-menu))
+    (if (and menu tail)
+	(progn
+	  (setcdr tail menu)
+	  (vm-menu-set-menubar-dirty-flag)
+	  (cond ((vm-menu-fsfemacs-menus-p)
+		 (makunbound 'vm-menu-fsfemacs-folder-menu)
+		 (vm-easy-menu-define vm-menu-fsfemacs-folder-menu
+				      (list (make-sparse-keymap))
+				      nil
+				      vm-menu-folder-menu)
+		 (define-key vm-mode-menu-map [rootmenu vm vm-menubar-folder]
+		   (cons "Folder" vm-menu-fsfemacs-folder-menu))))))))
+
+
+;;; Muenkel Folders menu code
+
+(defvar vm-menu-hm-no-hidden-dirs t
+  "*Hidden directories are suppressed in the folder menus, if non nil.")
+
+(defvar vm-menu-hm-hidden-file-list '("^\\..*" ".*\\.~[0-9]+~"))
+
+(defun vm-menu-hm-delete-folder (folder)
+  "Query deletes a folder."
+  (interactive "fDelete folder: ")
+  (if (file-exists-p folder)
+      (if (y-or-n-p (concat "Delete the folder " folder " ? "))
+	  (progn
+	    (if (file-directory-p folder)
+		(delete-directory folder)
+	      (delete-file folder))
+	    (message "Folder deleted.")
+	    (vm-menu-hm-make-folder-menu)
+	    (vm-menu-hm-install-menu)
+	    )
+	(message "Aborted"))
+    (error "Folder %s does not exist." folder)
+    (vm-menu-hm-make-folder-menu)
+    (vm-menu-hm-install-menu)
+    ))
+	
+
+(defun vm-menu-hm-rename-folder (folder)
+  "Rename a folder."
+  (interactive "fRename folder: ")
+  (if (file-exists-p folder)
+      (rename-file folder
+		   (read-file-name (concat "Rename "
+					   folder
+					   " to ")
+				   (directory-file-name folder)
+				   folder))
+    (error "Folder %s does not exist." folder))
+  (vm-menu-hm-make-folder-menu)
+  (vm-menu-hm-install-menu)
+  )
+
+
+(defun vm-menu-hm-create-dir (parent-dir)
+  "Create a subdir in PARENT-DIR."
+  (interactive "DCreate new directory in: ")
+  (make-directory 
+   (expand-file-name (read-file-name "Create directory in %s called: "
+				     (concat parent-dir
+					     "/")))
+   t)
+  (vm-menu-hm-make-folder-menu)
+  (vm-menu-hm-install-menu)
+  )
+
+
+(defun vm-menu-hm-make-folder-menu ()
+  "Makes a menu with the mail folders of the directory `vm-folder-directory'."
+  (interactive)
+  (vm-unsaved-message "Building folders menu...")
+  (let ((folder-list (vm-menu-hm-tree-make-file-list vm-folder-directory))
+	(inbox-list (if (listp (car vm-spool-files))
+			(mapcar 'car vm-spool-files)
+		      (list vm-primary-inbox))))
+    (setq vm-menu-folders-menu
+	  (cons "Manipulate Folders"
+		(list (cons "Visit Inboxes  "
+			    (vm-menu-hm-tree-make-menu 
+			     inbox-list
+			     'vm-visit-folder
+			     t))
+		      (cons "Visit Folder   "
+			    (vm-menu-hm-tree-make-menu 
+			     folder-list
+			     'vm-visit-folder
+			     t
+			     vm-menu-hm-no-hidden-dirs
+			     vm-menu-hm-hidden-file-list))
+		      (cons "Save Message   "
+			    (vm-menu-hm-tree-make-menu 
+			     folder-list
+			     'vm-save-message
+			     t
+			     vm-menu-hm-no-hidden-dirs
+			     vm-menu-hm-hidden-file-list))
+		      "----"
+		      (cons "Delete Folder  "
+			    (vm-menu-hm-tree-make-menu 
+			     folder-list
+			     'vm-menu-hm-delete-folder
+			     t
+			     nil
+			     nil
+			     t
+			     ))
+		      (cons "Rename Folder  "
+			    (vm-menu-hm-tree-make-menu 
+			     folder-list
+			     'vm-menu-hm-rename-folder
+			     t
+			     nil
+			     nil
+			     t
+			     ))
+		      (cons "Make New Directory in..."
+			    (vm-menu-hm-tree-make-menu 
+			     (cons (list ".") folder-list)
+			     'vm-menu-hm-create-dir
+			     t
+			     nil
+			     '(".*")
+			     t
+			     ))
+		      "----"
+		      ["Rebuild Folders Menu" vm-menu-hm-make-folder-menu vm-folder-directory]
+		      ))))
+  (vm-unsaved-message "Building folders menu... done")
+  (vm-menu-hm-install-menu))
+
+(defun vm-menu-hm-install-menu ()
+  (cond ((vm-menu-xemacs-menus-p)
+	 (cond ((car (find-menu-item current-menubar '("VM")))
+		(add-menu '("VM") "Folders"
+			  (cdr vm-menu-folders-menu) "Motion"))
+	       ((car (find-menu-item current-menubar
+				     '("Folder" "Manipulate Folders")))
+		(add-menu '("Folder") "Manipulate Folders"
+			  (cdr vm-menu-folders-menu) "Motion"))))
+	((vm-menu-fsfemacs-menus-p)
+	 (vm-easy-menu-define vm-menu-fsfemacs-folders-menu
+			      (list (make-sparse-keymap))
+			      nil
+			      vm-menu-folders-menu)
+	 (define-key vm-mode-menu-map [rootmenu vm folder folders]
+	   (cons "Manipulate Folders" vm-menu-fsfemacs-folders-menu)))))
+
+
+;;; Muenkel tree-menu code
+
+(defvar vm-menu-hm-tree-ls-flags "-aFLR" 
+  "*A String with the flags used in the function
+vm-menu-hm-tree-ls-in-temp-buffer for the ls command.
+Be careful if you want to change this variable. 
+The ls command must append a / on all files which are directories. 
+The original flags are -aFLR.")
+
+
+(defun vm-menu-hm-tree-ls-in-temp-buffer (dir temp-buffer)
+"List the directory DIR in the TEMP-BUFFER."
+  (switch-to-buffer temp-buffer)
+  (erase-buffer)
+  (let ((process-connection-type nil))
+    (call-process "ls" nil temp-buffer nil vm-menu-hm-tree-ls-flags dir))
+  (goto-char (point-min))
+  (while (search-forward "//" nil t)
+    (replace-match "/"))
+  (goto-char (point-min))
+  (while (re-search-forward "\\.\\.?/\n" nil t)
+    (replace-match ""))
+  (goto-char (point-min)))
+
+
+(defvar vm-menu-hm-tree-temp-buffername "*tree*"
+  "Name of the temp buffers in tree.")
+
+
+(defun vm-menu-hm-tree-make-file-list-1 (root list)
+  (let ((filename (buffer-substring (point) (progn
+					      (end-of-line)
+					      (point)))))
+    (while (not (string= filename ""))
+      (setq 
+       list 
+       (append
+	list
+	(list
+	 (cond ((char-equal (char-after (- (point) 1)) ?/)
+		;; Directory
+		(setq filename (substring filename 0 (1- (length filename))))
+		(save-excursion
+		  (search-forward (concat root filename ":"))
+		  (forward-line)
+		  (vm-menu-hm-tree-make-file-list-1 (concat root filename "/")
+						(list (vm-menu-hm-tree-menu-file-truename 
+						       filename
+						       root)))))
+	       ((char-equal (char-after (- (point) 1)) ?*)
+		;; Executable
+		(setq filename (substring filename 0 (1- (length filename))))
+		(vm-menu-hm-tree-menu-file-truename filename root))
+	       (t (vm-menu-hm-tree-menu-file-truename filename root))))))
+      (forward-line)
+      (setq filename (buffer-substring (point) (progn
+						 (end-of-line)
+						 (point)))))
+    list))
+
+
+(defun vm-menu-hm-tree-menu-file-truename (file &optional root)
+  (file-truename (expand-file-name file root)))
+
+(defun vm-menu-hm-tree-make-file-list (dir)
+  "Makes a list with the files and subdirectories of DIR.
+The list looks like: ((dirname1 file1 file2) 
+                      file3
+                      (dirname2 (dirname3 file4 file5) file6))"
+  (save-window-excursion
+    (setq dir (expand-file-name dir))
+    (if (not (string= (substring dir -1) "/"))
+	(setq dir (concat dir "/")))
+;;    (while (string-match "/$" dir)
+;;      (setq dir (substring dir 0 -1)))
+    (vm-menu-hm-tree-ls-in-temp-buffer dir
+				 (generate-new-buffer-name 
+				  vm-menu-hm-tree-temp-buffername))
+    (let ((list nil))
+      (setq list (vm-menu-hm-tree-make-file-list-1 dir nil))
+      (kill-buffer (current-buffer))
+      list)))
+
+
+(defun vm-menu-hm-tree-hide-file-p (filename re-hidden-file-list)
+  "t, if one of the regexps in RE-HIDDEN-FILE-LIST matches the FILENAME."
+  (cond ((not re-hidden-file-list) nil)
+	((string-match (car re-hidden-file-list) 
+		       (vm-menu-hm-tree-menu-file-truename filename)))
+	(t (vm-menu-hm-tree-hide-file-p filename (cdr re-hidden-file-list)))))
+
+
+(defun vm-menu-hm-tree-make-menu (dirlist 
+		       function 
+		       selectable 
+		       &optional 
+		       no-hidden-dirs
+		       re-hidden-file-list
+		       include-current-dir)
+  "Returns a menu list.
+Each item of the menu list has the form 
+ [\"subdir\" (FUNCTION \"dir\") SELECTABLE].
+Hidden directories (with a leading point) are suppressed, 
+if NO-HIDDEN-DIRS are non nil. Also all files which are
+matching a regexp in RE-HIDDEN-FILE-LIST are suppressed.
+If INCLUDE-CURRENT-DIR non nil, then an additional command
+for the current directory (.) is inserted."
+  (let ((subdir nil)
+	(menulist nil))
+    (while (setq subdir (car dirlist))
+      (setq dirlist (cdr dirlist))
+      (cond ((and (stringp subdir)
+		  (not (vm-menu-hm-tree-hide-file-p subdir re-hidden-file-list)))
+	     (setq menulist
+		   (append menulist
+			   (list
+			    (vector (file-name-nondirectory subdir)
+				    (list function subdir)
+				    selectable)))))
+	    ((and (listp subdir)
+		  (or (not no-hidden-dirs)
+		      (not (char-equal 
+			    ?.
+			    (string-to-char 
+			     (file-name-nondirectory (car subdir))))))
+		  (setq menulist
+			(append 
+			 menulist
+			 (list
+			  (cons (file-name-nondirectory (car subdir))
+				(if include-current-dir
+				    (cons
+				     (vector "."
+					     (list function
+						   (car subdir))
+					     selectable)
+				     (vm-menu-hm-tree-make-menu (cdr subdir)
+						     function
+						     selectable
+						     no-hidden-dirs
+						     re-hidden-file-list
+						     include-current-dir
+						     ))
+				  (vm-menu-hm-tree-make-menu (cdr subdir)
+						  function
+						  selectable
+						  no-hidden-dirs
+						  re-hidden-file-list
+						  ))))))))
+	    (t nil))
+      )
+    menulist
+    )
+  )