(command-line): Extract arg value properly for -u.
[bpt/emacs.git] / lisp / menu-bar.el
CommitLineData
235aa29b
ER
1;;; menu-bar.el --- define a default menu bar.
2
3;; Author: RMS
b7f66977 4;; Keywords: internal
235aa29b 5
f8c25f1b 6;; Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
1db87953
RS
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs; see the file COPYING. If not, write to
22;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
235aa29b 24;;; Code:
1db87953 25
b132f2b1
RM
26;; Don't clobber an existing menu-bar keymap, to preserve any menu-bar key
27;; definitions made in loaddefs.el.
28(or (lookup-key global-map [menu-bar])
29 (define-key global-map [menu-bar] (make-sparse-keymap "menu-bar")))
22390f50 30(defvar menu-bar-help-menu (make-sparse-keymap "Help"))
ffbdd83d
RS
31
32;; Force Help item to come last, after the major mode's own items.
0d31efcd
KH
33;; The symbol used to be called `help', but that gets confused with the
34;; help key.
35(setq menu-bar-final-items '(help-menu))
ffbdd83d 36
0d31efcd 37(define-key global-map [menu-bar help-menu] (cons "Help" menu-bar-help-menu))
ffbdd83d
RS
38(defvar menu-bar-search-menu (make-sparse-keymap "Search"))
39(define-key global-map [menu-bar search] (cons "Search" menu-bar-search-menu))
22390f50 40(defvar menu-bar-edit-menu (make-sparse-keymap "Edit"))
40954111 41(define-key global-map [menu-bar edit] (cons "Edit" menu-bar-edit-menu))
ffbdd83d
RS
42(defvar menu-bar-tools-menu (make-sparse-keymap "Tools"))
43(define-key global-map [menu-bar tools] (cons "Tools" menu-bar-tools-menu))
44(defvar menu-bar-files-menu (make-sparse-keymap "Files"))
45(define-key global-map [menu-bar files] (cons "Files" menu-bar-files-menu))
1b009b97
RS
46
47;; This alias is for compatibility with 19.28 and before.
48(defvar menu-bar-file-menu menu-bar-files-menu)
9bb8e471 49\f
9dcdc43d
RS
50(defvar vc-menu-map (make-sparse-keymap "Version Control"))
51
e1726722 52(define-key menu-bar-tools-menu [calendar] '("Display Calendar" . calendar))
ffbdd83d
RS
53(define-key menu-bar-tools-menu [rmail] '("Read Mail" . rmail))
54(define-key menu-bar-tools-menu [gnus] '("Read Net News" . gnus))
55
56(define-key menu-bar-tools-menu [separator-vc]
57 '("--"))
58
59(define-key menu-bar-tools-menu [vc-menu]
60 (cons "Version Control" vc-menu-map))
9bb8e471 61
ffbdd83d 62(define-key menu-bar-tools-menu [separator-compare]
9bb8e471
RS
63 '("--"))
64
ffbdd83d 65(define-key menu-bar-tools-menu [epatch]
080ac1ac 66 '("Apply Patch" . menu-bar-epatch-menu))
ffbdd83d 67(define-key menu-bar-tools-menu [ediff-merge]
5438ecd3 68 '("Merge" . menu-bar-ediff-merge-menu))
57eed34a 69(define-key menu-bar-tools-menu [compare]
40a8cde1 70 '("Compare" . menu-bar-ediff-menu))
9bb8e471 71
ffbdd83d 72(define-key menu-bar-tools-menu [separator-print]
9bb8e471
RS
73 '("--"))
74
ffbdd83d
RS
75(put 'print-region 'menu-enable 'mark-active)
76(put 'ps-print-region-with-faces 'menu-enable 'mark-active)
77
78(define-key menu-bar-tools-menu [ps-print-region]
79 '("Postscript Print Region" . ps-print-region-with-faces))
80(define-key menu-bar-tools-menu [ps-print-buffer]
81 '("Postscript Print Buffer" . ps-print-buffer-with-faces))
82(define-key menu-bar-tools-menu [print-region]
83 '("Print Region" . print-region))
84(define-key menu-bar-tools-menu [print-buffer]
85 '("Print Buffer" . print-buffer))
86\f
87(define-key menu-bar-files-menu [exit-emacs]
88 '("Exit Emacs" . save-buffers-kill-emacs))
89
90(define-key menu-bar-files-menu [separator-exit]
91 '("--"))
92
93(define-key menu-bar-files-menu [one-window]
94 '("One Window" . delete-other-windows))
95
96(define-key menu-bar-files-menu [split-window]
97 '("Split Window" . split-window-vertically))
9bb8e471 98
ca1a9692
RS
99(if (fboundp 'delete-frame)
100 (progn
ffbdd83d 101 (define-key menu-bar-files-menu [delete-frame]
ca1a9692 102 '("Delete Frame" . delete-frame))
ffbdd83d
RS
103 (define-key menu-bar-files-menu [make-frame-on-display]
104 '("Open New Display..." . make-frame-on-display))
105 (define-key menu-bar-files-menu [make-frame]
ca1a9692 106 '("Make New Frame" . make-frame))))
9bb8e471 107
ffbdd83d 108(define-key menu-bar-files-menu [separator-buffers]
9bb8e471
RS
109 '("--"))
110
ffbdd83d
RS
111(define-key menu-bar-files-menu [kill-buffer]
112 '("Kill Current Buffer" . kill-this-buffer))
113(define-key menu-bar-files-menu [insert-file]
1f50590a 114 '("Insert File..." . insert-file))
ffbdd83d 115(define-key menu-bar-files-menu [revert-buffer]
2f1139a4 116 '("Revert Buffer" . revert-buffer))
ffbdd83d 117(define-key menu-bar-files-menu [write-file]
2f1139a4 118 '("Save Buffer As..." . write-file))
ffbdd83d
RS
119(define-key menu-bar-files-menu [save-buffer] '("Save Buffer" . save-buffer))
120(define-key menu-bar-files-menu [dired] '("Open Directory..." . dired))
121(define-key menu-bar-files-menu [open-file] '("Open File..." . find-file))
40a8cde1
RS
122
123;; This is just one element of the ediff menu--the first.
124(define-key menu-bar-ediff-menu [window]
125 '("This Window And Next Window" . compare-windows))
9bb8e471 126\f
ffbdd83d
RS
127(defun nonincremental-search-forward (string)
128 "Read a string and search for it nonincrementally."
129 (interactive "sSearch for string: ")
130 (if (equal string "")
131 (search-forward (car search-ring))
132 (isearch-update-ring string nil)
133 (search-forward string)))
134
135(defun nonincremental-search-backward (string)
136 "Read a string and search backward for it nonincrementally."
137 (interactive "sSearch for string: ")
138 (if (equal string "")
139 (search-backward (car search-ring))
140 (isearch-update-ring string nil)
141 (search-backward string)))
142
143(defun nonincremental-re-search-forward (string)
144 "Read a regular expression and search for it nonincrementally."
145 (interactive "sSearch for regexp: ")
146 (if (equal string "")
147 (re-search-forward (car regexp-search-ring))
148 (isearch-update-ring string t)
149 (re-search-forward string)))
150
151(defun nonincremental-re-search-backward (string)
152 "Read a regular expression and search backward for it nonincrementally."
153 (interactive "sSearch for regexp: ")
154 (if (equal string "")
155 (re-search-backward (car regexp-search-ring))
156 (isearch-update-ring string t)
157 (re-search-backward string)))
158
1f50590a 159(defun nonincremental-repeat-search-forward ()
ffbdd83d
RS
160 "Search forward for the previous search string."
161 (interactive)
162 (search-forward (car search-ring)))
163
1f50590a 164(defun nonincremental-repeat-search-backward ()
ffbdd83d
RS
165 "Search backward for the previous search string."
166 (interactive)
167 (search-backward (car search-ring)))
168
1f50590a 169(defun nonincremental-repeat-re-search-forward ()
ffbdd83d
RS
170 "Search forward for the previous regular expression."
171 (interactive)
172 (re-search-forward (car regexp-search-ring)))
173
1f50590a 174(defun nonincremental-repeat-re-search-backward ()
ffbdd83d
RS
175 "Search backward for the previous regular expression."
176 (interactive)
177 (re-search-backward (car regexp-search-ring)))
178
1f50590a
RS
179(define-key menu-bar-search-menu [query-replace-regexp]
180 '("Query Replace Regexp..." . query-replace-regexp))
ffbdd83d 181(define-key menu-bar-search-menu [query-replace]
1f50590a 182 '("Query Replace..." . query-replace))
ffbdd83d 183(define-key menu-bar-search-menu [find-tag]
1f50590a 184 '("Find Tag..." . find-tag))
ffbdd83d
RS
185(put 'find-tag 'menu-enable 'tags-table-list)
186(define-key menu-bar-search-menu [bookmark]
187 '("Bookmarks" . menu-bar-bookmark-map))
188
189(define-key menu-bar-search-menu [separator-search]
190 '("--"))
191
192(define-key menu-bar-search-menu [nonincremental-repeat-re-search-back]
193 '("Repeat Regexp Backwards" . nonincremental-repeat-re-search-backward))
194(define-key menu-bar-search-menu [nonincremental-repeat-search-back]
195 '("Repeat Backwards" . nonincremental-repeat-search-backward))
196(define-key menu-bar-search-menu [nonincremental-repeat-re-search-fwd]
197 '("Repeat Regexp" . nonincremental-repeat-re-search-forward))
198(define-key menu-bar-search-menu [nonincremental-repeat-search-fwd]
199 '("Repeat Search" . nonincremental-repeat-search-forward))
200
201(define-key menu-bar-search-menu [separator-repeat]
9bb8e471
RS
202 '("--"))
203
ffbdd83d 204(define-key menu-bar-search-menu [re-search-back]
1f50590a 205 '("Regexp Search Backwards..." . nonincremental-re-search-backward))
ffbdd83d 206(define-key menu-bar-search-menu [search-back]
1f50590a 207 '("Search Backwards..." . nonincremental-search-backward))
ffbdd83d 208(define-key menu-bar-search-menu [re-search-fwd]
1f50590a 209 '("Regexp Search..." . nonincremental-re-search-forward))
ffbdd83d 210(define-key menu-bar-search-menu [search-fwd]
1f50590a 211 '("Search..." . nonincremental-search-forward))
ffbdd83d 212\f
5b42ec2b
RS
213(if (fboundp 'start-process)
214 (define-key menu-bar-edit-menu [spell] '("Spell" . ispell-menu-map)))
9bb8e471 215(define-key menu-bar-edit-menu [fill] '("Fill" . fill-region))
6507ffb1 216(define-key menu-bar-edit-menu [props] '("Text Properties" . facemenu-menu))
9bb8e471
RS
217
218(define-key menu-bar-edit-menu [separator-edit]
219 '("--"))
220
221(define-key menu-bar-edit-menu [clear] '("Clear" . delete-region))
3dd92899 222
e1726722 223(define-key menu-bar-edit-menu [paste] '("Paste Most Recent" . yank))
3dd92899
KH
224
225(defvar yank-menu (cons "Select Yank" nil))
226(fset 'yank-menu (cons 'keymap yank-menu))
227(define-key menu-bar-edit-menu [select-paste] '("Select and Paste" . yank-menu))
4c0317b1 228(define-key menu-bar-edit-menu [copy] '("Copy" . menu-bar-kill-ring-save))
057d49d1
RS
229(define-key menu-bar-edit-menu [cut] '("Cut" . kill-region))
230(define-key menu-bar-edit-menu [undo] '("Undo" . undo))
231
4c0317b1
RS
232(defun menu-bar-kill-ring-save (beg end)
233 (interactive "r")
234 (if (mouse-region-match)
235 (message "Select a region with the mouse does `copy' automatically")
236 (kill-ring-save beg end)))
237
057d49d1
RS
238(put 'fill-region 'menu-enable 'mark-active)
239(put 'kill-region 'menu-enable 'mark-active)
4c0317b1 240(put 'menu-bar-kill-ring-save 'menu-enable 'mark-active)
057d49d1 241(put 'yank 'menu-enable '(x-selection-exists-p))
3dd92899 242(put 'yank-menu 'menu-enable '(cdr yank-menu))
4c0317b1
RS
243(put 'delete-region 'menu-enable '(and mark-active
244 (not (mouse-region-match))))
057d49d1
RS
245(put 'undo 'menu-enable '(if (eq last-command 'undo)
246 pending-undo-list
247 (consp buffer-undo-list)))
3a841b0b 248(put 'query-replace 'menu-enable '(not buffer-read-only))
db774a16 249
9e18f0a0
RS
250(autoload 'ispell-menu-map "ispell" nil t 'keymap)
251
f9cf0be2 252;; These are alternative definitions for the cut, paste and copy
4c0317b1 253;; menu items. Use them if your system expects these to use the clipboard.
f9cf0be2 254
f9cf0be2
RS
255(put 'clipboard-kill-region 'menu-enable 'mark-active)
256(put 'clipboard-kill-ring-save 'menu-enable 'mark-active)
257(put 'clipboard-yank 'menu-enable
258 '(or (x-selection-exists-p) (x-selection-exists-p 'CLIPBOARD)))
259
260(defun clipboard-yank ()
261 "Reinsert the last stretch of killed text, or the clipboard contents."
262 (interactive)
263 (let ((x-select-enable-clipboard t))
264 (yank)))
265
266(defun clipboard-kill-ring-save (beg end)
267 "Copy region to kill ring, and save in the X clipboard."
268 (interactive "r")
269 (let ((x-select-enable-clipboard t))
270 (kill-ring-save beg end)))
271
272(defun clipboard-kill-region (beg end)
273 "Kill the region, and save it in the X clipboard."
274 (interactive "r")
275 (let ((x-select-enable-clipboard t))
276 (kill-region beg end)))
277
278(defun menu-bar-enable-clipboard ()
5cbdeb30
RS
279 "Make CUT, PASTE and COPY (keys and menu bar items) use the clipboard.
280Do the same for the keys of the same name."
f9cf0be2 281 (interactive)
5754d7f2
RS
282 ;; We can't use constant list structure here because it becomes pure,
283 ;; and because it gets modified with cache data.
284 (define-key menu-bar-edit-menu [paste]
285 (cons "Paste" 'clipboard-yank))
286 (define-key menu-bar-edit-menu [copy]
287 (cons "Copy" 'clipboard-kill-ring-save))
288 (define-key menu-bar-edit-menu [cut]
5cbdeb30
RS
289 (cons "Cut" 'clipboard-kill-region))
290
291 (define-key global-map [f20] 'clipboard-kill-region)
292 (define-key global-map [f16] 'clipboard-kill-ring-save)
293 (define-key global-map [f18] 'clipboard-yank)
294 ;; X11R6 versions
295 (define-key global-map [cut] 'clipboard-kill-region)
296 (define-key global-map [copy] 'clipboard-kill-ring-save)
297 (define-key global-map [paste] 'clipboard-yank))
f9cf0be2 298\f
efb166ff
RS
299(define-key menu-bar-help-menu [emacs-version]
300 '("Show Version" . emacs-version))
48433a65 301(define-key menu-bar-help-menu [report-emacs-bug]
1c6e18f6 302 '("Send Bug Report..." . report-emacs-bug))
ca9b40a1 303(define-key menu-bar-help-menu [emacs-tutorial]
db774a16 304 '("Emacs Tutorial" . help-with-tutorial))
2f1139a4
RS
305(define-key menu-bar-help-menu [man] '("Man..." . manual-entry))
306(define-key menu-bar-help-menu [describe-variable]
307 '("Describe Variable..." . describe-variable))
308(define-key menu-bar-help-menu [describe-function]
309 '("Describe Function..." . describe-function))
310(define-key menu-bar-help-menu [describe-key]
311 '("Describe Key..." . describe-key))
312(define-key menu-bar-help-menu [list-keybindings]
313 '("List Keybindings" . describe-bindings))
314(define-key menu-bar-help-menu [command-apropos]
315 '("Command Apropos..." . command-apropos))
316(define-key menu-bar-help-menu [describe-mode]
317 '("Describe Mode" . describe-mode))
e1726722 318(define-key menu-bar-help-menu [info] '("Browse Manuals" . info))
889560ed 319(define-key menu-bar-help-menu [emacs-faq] '("Emacs FAQ" . view-emacs-FAQ))
2f1139a4 320(define-key menu-bar-help-menu [emacs-news] '("Emacs News" . view-emacs-news))
889560ed 321
db774a16
RS
322(defun kill-this-buffer () ; for the menubar
323 "Kills the current buffer."
324 (interactive)
325 (kill-buffer (current-buffer)))
326
2f1139a4
RS
327(defun kill-this-buffer-enabled-p ()
328 (let ((count 0)
329 (buffers (buffer-list)))
330 (while buffers
331 (or (string-match "^ " (buffer-name (car buffers)))
332 (setq count (1+ count)))
333 (setq buffers (cdr buffers)))
1f50590a
RS
334 (and (not (window-minibuffer-p (selected-window)))
335 (> count 1))))
336
337(put 'kill-this-buffer 'menu-enable '(kill-this-buffer-enabled-p))
338
339(put 'save-buffer 'menu-enable
340 '(and (buffer-modified-p)
341 (not (window-minibuffer-p (selected-window)))))
342
343(put 'write-file 'menu-enable
344 '(not (window-minibuffer-p (selected-window))))
345
346(put 'find-file 'menu-enable
347 '(not (window-minibuffer-p (selected-window))))
348
349(put 'dired 'menu-enable
350 '(not (window-minibuffer-p (selected-window))))
351
352(put 'insert-file 'menu-enable
353 '(not (window-minibuffer-p (selected-window))))
2f1139a4 354
da183f87
RS
355(put 'revert-buffer 'menu-enable
356 '(or revert-buffer-function revert-buffer-insert-file-contents-function
357 (and (buffer-file-name)
660fa562
RM
358 (or (buffer-modified-p)
359 (not (verify-visited-file-modtime (current-buffer)))))))
82a74107 360
a0213a97
RS
361;; Permit deleting frame if it would leave a visible or iconified frame.
362(put 'delete-frame 'menu-enable
82a74107
KH
363 '(delete-frame-enabled-p))
364
365(defun delete-frame-enabled-p ()
366 "Return non-nil if `delete-frame' should be enabled in the menu bar."
367 (let ((frames (frame-list))
368 (count 0))
369 (while frames
370 (if (frame-visible-p (car frames))
371 (setq count (1+ count)))
372 (setq frames (cdr frames)))
373 (> count 1)))
2f1139a4 374
db774a16
RS
375(put 'advertised-undo 'menu-enable
376 '(and (not (eq t buffer-undo-list))
377 (if (eq last-command 'undo)
2f1139a4
RS
378 (and (boundp 'pending-undo-list)
379 pending-undo-list)
380 buffer-undo-list)))
2877eac2 381
c3e1d435 382(defvar yank-menu-length 20
3dd92899
KH
383 "*Maximum length to display in the yank-menu.")
384
385(defun menu-bar-update-yank-menu (string old)
386 (let ((front (car (cdr yank-menu)))
387 (menu-string (if (<= (length string) yank-menu-length)
388 string
c3e1d435
RS
389 (concat
390 (substring string 0 (/ yank-menu-length 2))
391 "..."
392 (substring string (- (/ yank-menu-length 2)))))))
3dd92899
KH
393 ;; If we're supposed to be extending an existing string, and that
394 ;; string really is at the front of the menu, then update it in place.
395 (if (and old (or (eq old (car front))
396 (string= old (car front))))
dfabc98f 397 (progn
3dd92899
KH
398 (setcar front string)
399 (setcar (cdr front) menu-string))
400 (setcdr yank-menu
401 (cons
402 (cons string (cons menu-string 'menu-bar-select-yank))
403 (cdr yank-menu)))))
404 (if (> (length (cdr yank-menu)) kill-ring-max)
405 (setcdr (nthcdr kill-ring-max yank-menu) nil)))
406
407(defun menu-bar-select-yank ()
408 (interactive "*")
409 (push-mark (point))
410 (insert last-command-event))
40954111 411\f
09642d97
RS
412(define-key global-map [menu-bar buffer] '("Buffers" . menu-bar-buffers))
413
414(defalias 'menu-bar-buffers (make-sparse-keymap "Buffers"))
40954111 415
40954111
RS
416(defvar buffers-menu-max-size 10
417 "*Maximum number of entries which may appear on the Buffers menu.
418If this is 10, then only the ten most-recently-selected buffers are shown.
419If this is nil, then all buffers are shown.
420A large number or nil slows down menu responsiveness.")
421
d0690d12
RS
422(defvar list-buffers-directory nil)
423
08e8171f
RS
424(defvar menu-bar-update-buffers-maxbuf)
425
09642d97
RS
426(defun menu-bar-select-buffer ()
427 (interactive)
428 (switch-to-buffer last-command-event))
429
430(defun menu-bar-select-frame ()
431 (interactive)
432 (make-frame-visible last-command-event)
433 (raise-frame last-command-event)
434 (select-frame last-command-event))
435
c171b42f
RS
436(defun menu-bar-update-buffers-1 (elt)
437 (cons (format
08e8171f 438 (format "%%%ds %%s%%s %%s" menu-bar-update-buffers-maxbuf)
c171b42f
RS
439 (cdr elt)
440 (if (buffer-modified-p (car elt))
441 "*" " ")
442 (save-excursion
443 (set-buffer (car elt))
444 (if buffer-read-only "%" " "))
445 (let ((file
446 (or (buffer-file-name (car elt))
447 (save-excursion
448 (set-buffer (car elt))
449 list-buffers-directory)
450 "")))
451 (setq file (or (file-name-directory file)
452 ""))
453 (if (> (length file) 20)
454 (setq file (concat "..." (substring file -17))))
455 file))
456 (car elt)))
457
06ff7539
RS
458(defvar menu-bar-buffers-menu-list-buffers-entry nil)
459
09642d97 460(defun menu-bar-update-buffers ()
29397c58 461 ;; If user discards the Buffers item, play along.
4d587a6c 462 (and (lookup-key (current-global-map) [menu-bar buffer])
29397c58
RS
463 (frame-or-buffer-changed-p)
464 (let ((buffers (buffer-list))
465 (frames (frame-list))
466 buffers-menu frames-menu)
467 ;; If requested, list only the N most recently selected buffers.
468 (if (and (integerp buffers-menu-max-size)
469 (> buffers-menu-max-size 1))
470 (if (> (length buffers) buffers-menu-max-size)
471 (setcdr (nthcdr buffers-menu-max-size buffers) nil)))
472
473 ;; Make the menu of buffers proper.
474 (setq buffers-menu
475 (cons "Select Buffer"
c171b42f
RS
476 (let* ((buffer-list
477 (mapcar 'list buffers))
478 tail
08e8171f 479 (menu-bar-update-buffers-maxbuf 0)
c171b42f
RS
480 (maxlen 0)
481 alist
482 head)
483 ;; Put into each element of buffer-list
484 ;; the name for actual display,
485 ;; perhaps truncated in the middle.
486 (setq tail buffer-list)
487 (while tail
488 (let ((name (buffer-name (car (car tail)))))
489 (setcdr (car tail)
490 (if (> (length name) 27)
491 (concat (substring name 0 12)
492 "..."
493 (substring name -12))
494 name)))
495 (setq tail (cdr tail)))
496 ;; Compute the maximum length of any name.
497 (setq tail buffer-list)
29397c58 498 (while tail
c171b42f 499 (or (eq ?\ (aref (cdr (car tail)) 0))
08e8171f
RS
500 (setq menu-bar-update-buffers-maxbuf
501 (max menu-bar-update-buffers-maxbuf
c171b42f 502 (length (cdr (car tail))))))
29397c58 503 (setq tail (cdr tail)))
c171b42f
RS
504 ;; Set ALIST to an alist of the form
505 ;; ITEM-STRING . BUFFER
506 (setq tail buffer-list)
29397c58
RS
507 (while tail
508 (let ((elt (car tail)))
c171b42f 509 (or (eq ?\ (aref (cdr elt) 0))
29397c58 510 (setq alist (cons
c171b42f 511 (menu-bar-update-buffers-1 elt)
29397c58
RS
512 alist)))
513 (and alist (> (length (car (car alist))) maxlen)
514 (setq maxlen (length (car (car alist))))))
515 (setq tail (cdr tail)))
516 (setq alist (nreverse alist))
06ff7539
RS
517 ;; Make the menu item for list-buffers
518 ;; or reuse the one we already have.
519 ;; The advantage in reusing one
520 ;; is that it already has the keyboard equivalent
521 ;; cached, so we save the time to look that up again.
522 (or menu-bar-buffers-menu-list-buffers-entry
523 (setq menu-bar-buffers-menu-list-buffers-entry
524 (cons
525 'list-buffers
526 (cons
527 ""
528 'list-buffers))))
529 ;; Update the item string for menu's new width.
530 (setcar (cdr menu-bar-buffers-menu-list-buffers-entry)
531 (concat (make-string (max (- (/ maxlen 2) 8) 0)
532 ?\ )
533 "List All Buffers"))
534 ;; Now make the actual list of items,
535 ;; ending with the list-buffers item.
29397c58
RS
536 (nconc (mapcar '(lambda (pair)
537 ;; This is somewhat risque, to use
538 ;; the buffer name itself as the event
539 ;; type to define, but it works.
540 ;; It would not work to use the buffer
541 ;; since a buffer as an event has its
542 ;; own meaning.
543 (nconc (list (buffer-name (cdr pair))
544 (car pair)
545 (cons nil nil))
546 'menu-bar-select-buffer))
547 alist)
06ff7539 548 (list menu-bar-buffers-menu-list-buffers-entry)))))
29397c58
RS
549
550
551 ;; Make a Frames menu if we have more than one frame.
552 (if (cdr frames)
553 (setq frames-menu
554 (cons "Select Frame"
555 (mapcar '(lambda (frame)
556 (nconc (list frame
557 (cdr (assq 'name
558 (frame-parameters frame)))
559 (cons nil nil))
560 'menu-bar-select-frame))
561 frames))))
562 (if buffers-menu
563 (setq buffers-menu (cons 'keymap buffers-menu)))
564 (if frames-menu
565 (setq frames-menu (cons 'keymap frames-menu)))
4d587a6c 566 (define-key (current-global-map) [menu-bar buffer]
29397c58
RS
567 (cons "Buffers"
568 (if (and buffers-menu frames-menu)
569 (list 'keymap "Buffers and Frames"
570 (cons 'buffers (cons "Buffers" buffers-menu))
571 (cons 'frames (cons "Frames" frames-menu)))
572 (or buffers-menu frames-menu 'undefined)))))))
09642d97
RS
573
574(add-hook 'menu-bar-update-hook 'menu-bar-update-buffers)
2f1139a4 575
40954111
RS
576;; this version is too slow
577;;;(defun format-buffers-menu-line (buffer)
578;;; "Returns a string to represent the given buffer in the Buffer menu.
579;;;nil means the buffer shouldn't be listed. You can redefine this."
580;;; (if (string-match "\\` " (buffer-name buffer))
581;;; nil
582;;; (save-excursion
583;;; (set-buffer buffer)
584;;; (let ((size (buffer-size)))
585;;; (format "%s%s %-19s %6s %-15s %s"
586;;; (if (buffer-modified-p) "*" " ")
587;;; (if buffer-read-only "%" " ")
588;;; (buffer-name)
589;;; size
590;;; mode-name
591;;; (or (buffer-file-name) ""))))))
592\f
7b7d6615
RS
593(defvar menu-bar-mode nil)
594
057d49d1 595(defun menu-bar-mode (flag)
dfd29450 596 "Toggle display of a menu bar on each frame.
057d49d1
RS
597This command applies to all frames that exist and frames to be
598created in the future.
599With a numeric argument, if the argument is negative,
dfd29450 600turn off menu bars; otherwise, turn on menu bars."
dad8e392 601 (interactive "P")
dad8e392 602
7b7d6615
RS
603 ;; Make menu-bar-mode and default-frame-alist consistent.
604 (let ((default (assq 'menu-bar-lines default-frame-alist)))
605 (if default
606 (setq menu-bar-mode (not (eq (cdr default) 0)))
607 (setq default-frame-alist
608 (cons (cons 'menu-bar-lines (if menu-bar-mode 1 0))
609 default-frame-alist))))
610
611 ;; Toggle or set the mode, according to FLAG.
612 (setq menu-bar-mode (if (null flag) (not menu-bar-mode)
613 (> (prefix-numeric-value flag) 0)))
614
615 ;; Apply it to default-frame-alist.
616 (let ((parameter (assq 'menu-bar-lines default-frame-alist)))
617 (if (consp parameter)
618 (setcdr parameter (if menu-bar-mode 1 0))
619 (setq default-frame-alist
620 (cons (cons 'menu-bar-lines (if menu-bar-mode 1 0))
621 default-frame-alist))))
622
623 ;; Apply it to existing frames.
624 (let ((frames (frame-list)))
625 (while frames
626 (let ((height (cdr (assq 'height (frame-parameters (car frames))))))
627 (modify-frame-parameters (car frames)
628 (list (cons 'menu-bar-lines
629 (if menu-bar-mode 1 0))))
630 (modify-frame-parameters (car frames)
631 (list (cons 'height height))))
632 (setq frames (cdr frames)))))
1db87953 633
bffa5d4d
RS
634(provide 'menu-bar)
635
235aa29b 636;;; menu-bar.el ends here