Doc fixes.
[bpt/emacs.git] / lisp / bookmark.el
CommitLineData
b3bf02fa
RS
1;;; bookmark.el --- set bookmarks, jump to them later.
2
3;; Copyright (C) 1993 Free Software Foundation, Inc.
4
5;; Author: Karl Fogel <kfogel@cs.oberlin.edu>
8027e2ad 6;; Maintainer: Karl Fogel <kfogel@cs.oberlin.edu>
b3bf02fa 7;; Created: July, 1993
11eb4275 8;; Version: 1.7.3 (interim)
b3bf02fa
RS
9;; Keywords: bookmarks, placeholders
10
11;; This file is part of GNU Emacs.
12
13;; GNU Emacs is free software; you can redistribute it and/or modify
14;; it under the terms of the GNU General Public License as published by
15;; the Free Software Foundation; either version 2, or (at your option)
16;; any later version.
17
18;; GNU Emacs is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
24;; along with GNU Emacs; see the file COPYING. If not, write to
25;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
26
27;; Thanks to David Bremner <bremner@cs.sfu.ca> for thinking of and
28;; then implementing the bookmark-current-bookmark idea. He even
29;; sent *patches*, bless his soul...
30
31;; Thanks to Gregory M. Saunders <saunders@cis.ohio-state.edu> for
32;; fixing and improving bookmark-time-to-save-p.
33
34;; Based on info-bookmark.el, by Karl Fogel and Ken Olstad
35;; <olstad@msc.edu>.
36
37;; LCD Archive Entry:
38;; bookmark|Karl Fogel|kfogel@cs.oberlin.edu|
39;; Setting bookmarks in files or directories, jumping to them later.|
40;; 16-July-93|Version: 1.7.2|~/misc/bookmark.el.Z|
41
42;; FAVORITE CHINESE RESTAURANT:
43;; Boy, that's a tough one. Probably Hong Min, or maybe Emperor's
44;; Choice (both in Chicago's Chinatown). Well, both. How about you?
45
46;;; Commentary on code:
47
48;; bookmark alist format:
49;; (...
50;; (bookmark-name (filename
51;; string-in-front
52;; string-behind
53;; point))
54;; ...)
55;;
56;; bookmark-name is the string the user gives the bookmark and
57;; accesses it by from then on. filename is the location of the file
58;; in which the bookmark is set. string-in-front is a string of
59;; `bookmark-search-size' chars of context in front of the point the
60;; bookmark is set at, string-behind is the same thing after the
61;; point. bookmark-jump will search for string-behind and
62;; string-in-front in case the file has changed since the bookmark was
63;; set. It will attempt to place the user before the changes, if
64;; there were any.
11eb4275
RS
65;;
66;; It is not advisable to sort the bookmark list when it is presented
67;; to the user, because it is already sorted in what is probably the
68;; most useful way: order of creation, with most recently created
69;; bookmarks coming first and older ones toward the end (renaming does
70;; not count as creating) -- which is what we want, most of the time.
b3bf02fa
RS
71
72;;; Code:
73
74;; Added for lucid emacs compatibility, db
75(or (fboundp 'defalias) (fset 'defalias 'fset))
76
77;; these are the distribution keybindings suggested by RMS, everything
78;; else will be done with M-x or the menubar:
79(define-key ctl-x-map "rb" 'bookmark-jump)
80(define-key ctl-x-map "rm" 'bookmark-set)
81(define-key ctl-x-map "rl" 'bookmark-locate)
82
83;; define the map, so it can be bound by those who desire to do so:
84
9aef3b21
RS
85(defvar bookmark-map nil
86 "Keymap containing bindings to bookmark functions.
87It is not bound to any key by default: to bind it
88so that you have a bookmark prefix, just use `global-set-key' and bind a
89key of your choice to `bookmark-map'. All interactive bookmark
b3bf02fa
RS
90functions have a binding in this keymap.")
91
92(define-prefix-command 'bookmark-map)
93
94;; Read the help on all of these functions for details...
95;; "x" marks the spot!
96(define-key bookmark-map "x" 'bookmark-set)
97(define-key bookmark-map "j" 'bookmark-jump)
98(define-key bookmark-map "i" 'bookmark-insert)
99(define-key bookmark-map "f" 'bookmark-locate) ; "f" for "find"
9aef3b21 100(define-key bookmark-map "r" 'bookmark-rename)
b3bf02fa
RS
101;; deletes bookmarks
102(define-key bookmark-map "d" 'bookmark-delete)
103;; loads new file
104(define-key bookmark-map "l" 'bookmark-load)
105;; saves them in file
106(define-key bookmark-map "w" 'bookmark-write)
107(define-key bookmark-map "s" 'bookmark-save)
108
109;; just add the hook to make sure that people don't lose bookmarks
110;; when they kill Emacs, unless they don't want to save them.
111
112(add-hook 'kill-emacs-hook
113 (function
114 (lambda ()
115 (and (featurep 'bookmark)
116 bookmark-alist
117 (bookmark-time-to-save-p t)
118 (bookmark-save)))))
119
120;; more stuff added by db.
121(defvar bookmark-current-bookmark nil
9aef3b21
RS
122 "Name of bookmark most recently used in the current file.
123It is buffer local, used to make moving a bookmark forward
8027e2ad 124through a file easier.")
b3bf02fa
RS
125
126(make-variable-buffer-local 'bookmark-current-bookmark)
127
128(defvar bookmark-save-flag t
9aef3b21
RS
129 "*Controls when Emacs saves bookmarks to a file.
130--> Nil means never save bookmarks, except when `bookmark-save' is
131 explicitly called \(\\[bookmark-save]\).
132--> t means save bookmarks when Emacs is killed.
133--> Otherise, it should be a number that is the frequency with which
134 the bookmark list is saved \(i.e.: the number of times which
135 Emacs' bookmark list may be modified before it is automatically
136 saved.\). If it is a number, Emacs will also automatically save
137 bookmarks when it is killed.
b3bf02fa
RS
138
139Therefore, the way to get it to save every time you make or delete a
140bookmark is to set this variable to 1 \(or 0, which produces the same
141behavior.\)
142
143To specify the file in which to save them, modify the variable
9aef3b21 144bookmark-file, which is `~/.emacs-bkmrks' by default.")
b3bf02fa
RS
145
146(defvar bookmark-alist-modification-count 0
9aef3b21 147 "Number of modifications to bookmark list since it was last saved.")
b3bf02fa
RS
148
149(defvar bookmark-file "~/.emacs-bkmrks"
150 "*File in which to save bookmarks by default.")
151
152(defvar bookmark-completion-ignore-case t
9aef3b21 153 "*Non-nil means bookmark functions ignore case in completion.")
b3bf02fa 154
9aef3b21
RS
155(defvar bookmark-search-size 500
156 "Length of the context strings recorded on either side of a bookmark.")
b3bf02fa
RS
157
158(defvar bookmark-alist ()
159 "Association list of bookmarks.
160You probably don't want to change the value of this alist yourself;
161instead, let the various bookmark functions do it for you.")
162
163(defvar bookmark-current-point 0)
164(defvar bookmark-yank-point 0)
165(defvar bookmark-current-buffer nil)
166
167(defun bookmark-set (&optional parg)
9aef3b21
RS
168
169 "Set a bookmark named NAME inside a file.
170With prefix arg, will not overwrite a bookmark that has the same name
171as NAME if such a bookmark already exists, but instead will \"push\"
172the new bookmark onto the bookmark alist. Thus the most recently set
173bookmark with name NAME would be the one in effect at any given time,
174but the others are still there, should you decide to delete the most
175recent one.
b3bf02fa
RS
176
177To yank words from the text of the buffer and use them as part of the
9aef3b21 178bookmark name, type C-w while setting a bookmark. Successive C-w's
b3bf02fa
RS
179yank successive words.
180
181Typing C-v inserts the name of the current file being visited. Typing
182C-u inserts the name of the last bookmark used in the buffer \(as an
183aid in using a single bookmark name to track your progress through a
184large file\). If no bookmark was used, then C-u behaves like C-v and
185inserts the name of the file being visited.
186
187Use \\[bookmark-delete] to remove bookmarks \(you give it a name,
188and it removes only the first instance of a bookmark with that name from
189the list of bookmarks.\)"
190 (interactive "P")
191 (if (not (bookmark-buffer-file-name))
192 (error "Buffer not visiting a file or directory."))
193 (setq bookmark-current-point (point))
194 (setq bookmark-yank-point (point))
195 (setq bookmark-current-buffer (current-buffer))
196 (let ((str
197 (read-from-minibuffer
198 "Set bookmark: "
199 nil
200 (let ((now-map (copy-keymap minibuffer-local-map)))
201 (progn (define-key now-map "\C-w"
202 'bookmark-yank-word)
203 (define-key now-map "\C-v"
204 'bookmark-insert-current-file-name)
205 (define-key now-map "\C-u"
206 'bookmark-insert-current-bookmark))
207 now-map))))
208 (progn
209 (bookmark-make parg str)
210 (setq bookmark-current-bookmark str)
211 (goto-char bookmark-current-point))))
212
213(defun bookmark-insert-current-bookmark ()
214 ;; insert this buffer's value of bookmark-current-bookmark, default
215 ;; to file name if it's nil.
216 (interactive)
217 (let ((str
218 (save-excursion
219 (set-buffer bookmark-current-buffer)
220 bookmark-current-bookmark)))
221 (if str (insert str) (bookmark-insert-current-file-name))))
222
223(defun bookmark-insert-current-file-name ()
224 ;; insert the name (sans path) of the current file into the bookmark
225 ;; name that is being set.
226 (interactive)
227 (let ((str (save-excursion
228 (set-buffer bookmark-current-buffer)
229 (bookmark-buffer-file-name))))
230 (insert (substring
231 str
232 (1+ (string-match
233 "\\(/[^/]*\\)/*$"
234 str))))))
235
236(defun bookmark-yank-word ()
237 (interactive)
238 ;; get the next word from the buffer and append it to the name of
239 ;; the bookmark currently being set.
240 (let ((string (save-excursion
241 (set-buffer bookmark-current-buffer)
242 (goto-char bookmark-yank-point)
243 (buffer-substring
244 (point)
245 (save-excursion
246 (forward-word 1)
247 (setq bookmark-yank-point (point)))))))
248 (insert string)))
249
250(defun bookmark-make (parg str)
251 (if (and (assoc str bookmark-alist) (not parg))
252 ;; already existing boookmark under that name and
253 ;; no prefix arg means just overwrite old bookmark
254 (setcdr (assoc str bookmark-alist)
255 (list (bookmark-make-cell)))
256
257 ;; otherwise just cons it onto the front (either the bookmark
258 ;; doesn't exist already, or there is no prefix arg. In either
259 ;; case, we want the new bookmark consed onto the alist...)
260
261 (setq bookmark-alist
262 (cons
263 (list str
264 (bookmark-make-cell))
265 bookmark-alist)))
266 ;; Added by db
267 (setq bookmark-current-bookmark str)
268 (setq bookmark-alist-modification-count
269 (1+ bookmark-alist-modification-count))
270 (if (bookmark-time-to-save-p)
271 (bookmark-save)))
272
273(defun bookmark-make-cell ()
274 ;; make the cell that is the cdr of a bookmark alist element. It
275 ;; looks like this:
276 ;; (filename search-forward-str search-back-str point)
277 (list
278 (bookmark-buffer-file-name)
279 (if (>= (- (point-max) (point)) bookmark-search-size)
280 (buffer-substring
281 (point)
282 (+ (point) bookmark-search-size))
283 nil)
284 (if (>= (- (point) (point-min)) bookmark-search-size)
285 (buffer-substring
286 (point)
287 (- (point) bookmark-search-size))
288 nil)
289 (point)))
290
291(defun bookmark-buffer-file-name ()
292 (or
293 buffer-file-name
294 (if (and (boundp 'dired-directory) dired-directory)
295 (if (stringp dired-directory)
296 dired-directory
297 (car dired-directory)))))
298
299(defun bookmark-try-default-file ()
300 (if (and (null bookmark-alist)
301 (file-readable-p (expand-file-name bookmark-file)))
302 (bookmark-load bookmark-file)))
8027e2ad 303
b3bf02fa 304(defun bookmark-jump (str)
9aef3b21
RS
305 "Jump to bookmark BOOKMARK (a point in some file).
306You may have a problem using this function if the value of variable
307`bookmark-alist' is nil. If that happens, you need to load in some
308bookmarks. See help on function `bookmark-load' for more about
8027e2ad 309this."
11eb4275 310 (interactive (let ((completion-ignore-case
b3bf02fa
RS
311 bookmark-completion-ignore-case))
312 (list (completing-read
313 "Jump to bookmark: "
314 bookmark-alist
315 nil
11eb4275
RS
316 0))))
317 (let ((whereto-list (car (cdr (assoc str bookmark-alist)))))
318 (let ((file (car whereto-list))
319 (forward-str (car (cdr whereto-list)))
320 (behind-str (car (cdr (cdr whereto-list))))
321 (place (car (cdr (cdr (cdr whereto-list))))))
322 (if (file-exists-p (expand-file-name file))
323 (progn
324 (find-file (expand-file-name file))
325 (goto-char place)
326 ;; Go searching forward first. Then, if forward-str exists and
327 ;; was found in the file, we can search backward for behind-str.
328 ;; Rationale is that if text was inserted between the two in the
329 ;; file, it's better to be put before it so you can read it,
330 ;; rather than after and remain perhaps unaware of the changes.
331 (if forward-str
332 (if (search-forward forward-str (point-max) t)
333 (backward-char bookmark-search-size)))
334 (if behind-str
335 (if (search-backward behind-str (point-min) t)
336 (forward-char bookmark-search-size)))
337 ;; added by db
338 (setq bookmark-current-bookmark str))
339 (error
340 (concat "File "
341 file
342 " does not exist. Suggest deleting bookmark \""
343 str
344 "\""))))))
b3bf02fa
RS
345
346(defun bookmark-locate (str)
9aef3b21
RS
347 "Insert the name of the file associated with BOOKMARK.
348\(This is not the same as the contents of that file\)."
11eb4275
RS
349 (interactive (let ((completion-ignore-case
350 bookmark-completion-ignore-case))
351 (list (completing-read
352 "Insert bookmark location: "
353 bookmark-alist
354 nil
355 0))))
b3bf02fa
RS
356 (insert (car (car (cdr (assoc str bookmark-alist))))))
357
9aef3b21
RS
358(defun bookmark-rename (old &optional new)
359 "Change the name of BOOKMARK to NEWNAME.
360If called from keyboard, prompts for OLD and NEWNAME.
361If called from menubar, prompts for NEWNAME.
362If called from Lisp, prompts for NEWNAME if only BOOKMARK was passed
363as an argument. If called with two strings, then no prompting is
364done. You must pass at least BOOKMARK when calling from Lisp.
365
366While you are entering the new name, consecutive C-w's insert
367consectutive words from the text of the buffer into the new bookmark
368name, and C-v inserts the name of the file."
369
11eb4275
RS
370 (interactive (let ((completion-ignore-case
371 bookmark-completion-ignore-case))
372 (list (completing-read "Old bookmark name: "
373 bookmark-alist
374 nil
375 0))))
b3bf02fa
RS
376 (progn
377 (setq bookmark-current-point (point))
378 (setq bookmark-yank-point (point))
379 (setq bookmark-current-buffer (current-buffer))
380 (let ((cell (assoc old bookmark-alist))
381 (str
9aef3b21
RS
382 (or new ; use second arg, if non-nil
383 (read-from-minibuffer
384 "New name: "
385 nil
386 (let ((now-map (copy-keymap minibuffer-local-map)))
387 (progn (define-key now-map "\C-w"
388 'bookmark-yank-word)
389 (define-key now-map "\C-v"
390 'bookmark-insert-current-file-name))
391 now-map)))))
b3bf02fa
RS
392 (progn
393 (setcar cell str)
394 (setq bookmark-current-bookmark str)
395 (setq bookmark-alist-modification-count
396 (1+ bookmark-alist-modification-count))
397 (if (bookmark-time-to-save-p)
398 (bookmark-save))))))
399
400(defun bookmark-insert (str)
9aef3b21
RS
401 "Insert the text of the file pointed to by bookmark BOOKMARK.
402You may have a problem using this function if the value of variable
403`bookmark-alist' is nil. If that happens, you need to load in some
404bookmarks. See help on function `bookmark-load' for more about
8027e2ad 405this."
11eb4275
RS
406 (interactive (let ((completion-ignore-case
407 bookmark-completion-ignore-case))
408 (list (completing-read
409 "Insert bookmark contents: "
410 bookmark-alist
411 nil
412 0))))
b3bf02fa
RS
413 (let ((whereto-list (car (cdr (assoc str bookmark-alist)))))
414 (let ((file (car whereto-list)))
415 (if (file-readable-p (expand-file-name file))
416 (let ((str-to-insert
417 (save-excursion
418 (find-file (expand-file-name file))
419 (prog1
420 (buffer-substring (point-min) (point-max))
421 (bury-buffer))))
422 (orig-point (point)))
423 (insert str-to-insert)
424 (push-mark)
425 (goto-char orig-point))
426 (error
427 (concat "File "
428 file
429 " does not exist. Suggest deleting bookmark \""
430 str
431 "\""))))))
432
433(defun bookmark-delete (str)
9aef3b21
RS
434 "Delete the bookmark named NAME from the bookmark list.
435Removes only the first instance of a bookmark with that name. If
436there are one or more other bookmarks with the same name, they will
437not be deleted. Defaults to the \"current\" bookmark \(that is, the
438one most recently used in this file, if any\)."
439
b3bf02fa
RS
440 (interactive (let ((completion-ignore-case
441 bookmark-completion-ignore-case))
442 (list
11eb4275
RS
443 (completing-read
444 "Delete bookmark: "
445 bookmark-alist
446 nil
447 0
448 bookmark-current-bookmark))))
449 (let ((will-go (assoc str bookmark-alist)))
450 (setq bookmark-alist (delq will-go bookmark-alist))
451 ;; Added by db, nil bookmark-current-bookmark if the last
452 ;; occurence has been deleted
b3bf02fa 453 (or (assoc bookmark-current-bookmark bookmark-alist)
11eb4275
RS
454 (setq bookmark-current-bookmark nil)))
455 (setq bookmark-alist-modification-count
456 (1+ bookmark-alist-modification-count))
457 (if (bookmark-time-to-save-p)
458 (bookmark-save)))
b3bf02fa
RS
459
460(defun bookmark-time-to-save-p (&optional last-time)
461 ;; By Gregory M. Saunders <saunders@cis.ohio-state.edu>
462 ;; finds out whether it's time to save bookmarks to a file, by
463 ;; examining the value of variable bookmark-save-flag, and maybe
464 ;; bookmark-alist-modification-count. Returns t if they should be
465 ;; saved, nil otherwise. if last-time is non-nil, then this is
466 ;; being called when emacs is killed.
467 (cond (last-time
468 (and (> bookmark-alist-modification-count 0)
469 bookmark-save-flag))
470 ((numberp bookmark-save-flag)
471 (>= bookmark-alist-modification-count bookmark-save-flag))
472 (t
473 nil)))
474
475(defun bookmark-write ()
476 (interactive)
477 (bookmark-save t))
478
11eb4275 479(defun bookmark-save (&optional parg file)
9aef3b21
RS
480 "Save currently defined bookmarks.
481Saves by default in the file defined by the variable
482`bookmark-file'. With a prefix arg, save it in file FILE.
b3bf02fa
RS
483
484If you are calling this from Lisp, the two arguments are PREFIX-ARG
485and FILE, and if you just want it to write to the default file, then
486pass no arguments. Or pass in nil and FILE, and it will save in FILE
487instead. If you pass in one argument, and it is non-nil, then the
488user will be interactively queried for a file to save in.
489
11eb4275 490When you want to load in the bookmarks from a file, use
9aef3b21 491\`bookmark-load\', \\[bookmark-load]. That function will prompt you
11eb4275 492for a file, defaulting to the file defined by variable
9aef3b21 493`bookmark-file'."
b3bf02fa
RS
494 (interactive "P")
495 (cond
496 ((and (null parg) (null file))
497 ;;whether interactive or not, write to default file
498 (bookmark-write-file bookmark-file))
499 ((and (null parg) file)
500 ;;whether interactive or not, write to given file
501 (bookmark-write-file file))
502 ((and parg (not file))
503 ;;have been called interactively w/ prefix arg
504 (let ((file (read-file-name "File to save bookmarks in: ")))
505 (bookmark-write-file file)))
506 (t ; someone called us with prefix-arg *and* a file, so just write to file
507 (bookmark-write-file file)))
508 ;; signal that we have synced the bookmark file by setting this to
509 ;; 0. If there was an error at any point before, it will not get
510 ;; set, which is what we want.
511 (setq bookmark-alist-modification-count 0))
512
513(defun bookmark-write-file (file)
514 (save-excursion
515 (message (format "Saving bookmarks to file %s." file))
516 (set-buffer (find-file-noselect file))
517 (goto-char (point-min))
518 (delete-region (point-min) (point-max))
519 (print bookmark-alist (current-buffer))
520 (write-file file)
521 (kill-buffer (current-buffer))))
522
523(defun bookmark-load (file &optional revert no-msg)
9aef3b21
RS
524 "Load bookmarks from FILE (which must be in bookmark format).
525Appends loaded bookmarks to the front of the list of bookmarks. If
526optional second argument REVERT is non-nil, existing bookmarks are
527destroyed. Optional third arg NO-MSG means don't display any messages
528while loading.
b3bf02fa
RS
529
530If you load a file that doesn't contain a proper bookmark alist, you
9aef3b21 531will corrupt Emacs's bookmark list. Generally, you should only load
b3bf02fa 532in files that were created with the bookmark functions in the first
9aef3b21 533place. Your own personal bookmark file, `~/.emacs-bkmrks', is
8027e2ad 534maintained automatically by Emacs; you shouldn't need to load it
11eb4275 535explicitly."
b3bf02fa
RS
536 (interactive
537 (list (read-file-name
538 (format "Load bookmarks from: (%s) "
539 bookmark-file)
540 ;;Default might not be used often,
541 ;;but there's no better default, and
542 ;;I guess it's better than none at all.
543 "~/" bookmark-file 'confirm)))
544 (setq file (expand-file-name file))
545 (if (file-readable-p file)
546 (save-excursion
547 (if (null no-msg)
548 (message (format "Loading bookmarks from %s..." file)))
549 (set-buffer (find-file-noselect file))
550 (goto-char (point-min))
551 (let ((blist (car (read-from-string
552 (buffer-substring (point-min) (point-max))))))
553 (if (listp blist)
554 (progn
555 (if (not revert)
556 (setq bookmark-alist-modification-count
557 (1+ bookmark-alist-modification-count))
558 (setq bookmark-alist-modification-count 0))
559 (setq bookmark-alist
560 (append blist (if (not revert) bookmark-alist))))
561 (error (format "Invalid bookmark list in %s." file))))
562 (kill-buffer (current-buffer))
563 (if (null no-msg)
564 (message (format "Loading bookmarks from %s... done" file))))
565 (error (format "Cannot read bookmark file %s." file))))
566
11eb4275
RS
567;;;; bookmark menu bar stuff ;;;;
568
9aef3b21
RS
569(defvar bookmark-menu-bar-length 70
570 "*Maximum length of a bookmark name displayed on a popup menu.")
b3bf02fa 571
11eb4275 572(defvar bookmark-enable-menu-bar t
9aef3b21
RS
573 "*Non-nil means put a bookmark menu on the menu bar.
574\(Assuming that you are running Emacs under a windowing system, such
575as X.\)")
b3bf02fa 576
11eb4275 577(defun bookmark-make-menu-bar-alist ()
b3bf02fa
RS
578 (if (not bookmark-alist)
579 (if (file-readable-p bookmark-file)
580 (bookmark-load bookmark-file)))
581 (if bookmark-alist
582 (mapcar (lambda (cell)
583 (let ((str (car cell)))
584 (cons
11eb4275
RS
585 (if (> (length str) bookmark-menu-bar-length)
586 (substring str 0 bookmark-menu-bar-length)
b3bf02fa
RS
587 str)
588 str)))
589 bookmark-alist)
590 (error "No bookmarks currently set.")))
591
11eb4275
RS
592(defun bookmark-make-menu-bar-with-function (func-sym
593 menu-label
594 menu-str event)
b3bf02fa
RS
595 ;; help function for making menus that need to apply a bookmark
596 ;; function to a string.
11eb4275 597 (let* ((menu (bookmark-make-menu-bar-alist))
b3bf02fa
RS
598 (str (x-popup-menu event
599 (list menu-label
600 (cons menu-str
601 menu)))))
602 (if str
603 (apply func-sym (list str)))))
604
11eb4275 605(defun bookmark-menu-bar-insert (event)
9aef3b21
RS
606 "Insert the text of the file pointed to by bookmark BOOKMARK.
607You may have a problem using this function if the value of variable
608`bookmark-alist' is nil. If that happens, you need to load in some
609bookmarks. See help on function `bookmark-load' for more about
610this."
b3bf02fa 611 (interactive "e")
11eb4275 612 (bookmark-make-menu-bar-with-function 'bookmark-insert
b3bf02fa
RS
613 "Bookmark Insert Menu"
614 "--- Insert Contents ---"
615 event))
616
11eb4275 617(defun bookmark-menu-bar-jump (event)
9aef3b21
RS
618 "Jump to bookmark BOOKMARK (a point in some file).
619You may have a problem using this function if the value of variable
620`bookmark-alist' is nil. If that happens, you need to load in some
621bookmarks. See help on function `bookmark-load' for more about
622this."
b3bf02fa 623 (interactive "e")
11eb4275 624 (bookmark-make-menu-bar-with-function 'bookmark-jump
b3bf02fa
RS
625 "Bookmark Jump Menu"
626 "--- Jump to Bookmark ---"
627 event))
628
11eb4275 629(defun bookmark-menu-bar-locate (event)
9aef3b21
RS
630 "Insert the name of the file associated with BOOKMARK.
631\(This is not the same as the contents of that file\)."
b3bf02fa 632 (interactive "e")
11eb4275 633 (bookmark-make-menu-bar-with-function 'bookmark-locate
b3bf02fa
RS
634 "Bookmark Locate Menu"
635 "--- Insert Location ---"
636 event))
637
11eb4275 638(defun bookmark-menu-bar-rename (event)
9aef3b21
RS
639 "Change the name of BOOKMARK to NEWNAME.
640If called from keyboard, prompts for OLD and NEWNAME.
641If called from menubar, prompts for NEWNAME.
642If called from Lisp, prompts for NEWNAME if only BOOKMARK was passed
643as an argument. If called with two strings, then no prompting is
644done. You must pass at least BOOKMARK when calling from Lisp.
645
646While you are entering the new name, consecutive C-w's insert
647consectutive words from the text of the buffer into the new bookmark
648name, and C-v inserts the name of the file."
b3bf02fa 649 (interactive "e")
11eb4275 650 (bookmark-make-menu-bar-with-function 'bookmark-rename
b3bf02fa
RS
651 "Bookmark Rename Menu"
652 "--- Rename Bookmark ---"
653 event))
654
11eb4275 655(defun bookmark-menu-bar-delete (event)
9aef3b21
RS
656 "Delete the bookmark named NAME from the bookmark list.
657Removes only the first instance of a bookmark with that name. If
658there are one or more other bookmarks with the same name, they will
659not be deleted. Defaults to the \"current\" bookmark \(that is, the
660one most recently used in this file, if any\)."
b3bf02fa 661 (interactive "e")
11eb4275 662 (bookmark-make-menu-bar-with-function 'bookmark-delete
b3bf02fa
RS
663 "Bookmark Delete Menu"
664 "--- Delete Bookmark ---"
665 event))
666
11eb4275 667(if (and bookmark-enable-menu-bar window-system)
b3bf02fa
RS
668 (progn
669 (defvar menu-bar-bookmark-map
670 (make-sparse-keymap "Bookmark functions"))
671
672 ;; make bookmarks appear toward the right side of the menu.
673 (if (boundp 'menu-bar-final-items)
674 (if menu-bar-final-items
675 (setq menu-bar-final-items
676 (cons 'bookmark menu-bar-final-items)))
677 (setq menu-bar-final-items '(bookmark)))
678
679 (define-key global-map [menu-bar bookmark]
680 (cons "Bookmarks" menu-bar-bookmark-map))
681
682 (define-key menu-bar-bookmark-map [load]
683 '(" Load a bookmark file" . bookmark-load))
684
685 (define-key menu-bar-bookmark-map [write]
686 '("Write \(to another file\)" . bookmark-write))
687
688 (define-key menu-bar-bookmark-map [save]
11eb4275 689 '("Save \(in default file\)" . bookmark-save))
b3bf02fa 690
b3bf02fa 691 (define-key menu-bar-bookmark-map [delete]
11eb4275 692 '(" Delete a bookmark" . bookmark-menu-bar-delete))
b3bf02fa
RS
693
694 (define-key menu-bar-bookmark-map [rename]
11eb4275 695 '(" Rename bookmark" . bookmark-menu-bar-rename))
b3bf02fa
RS
696
697 (define-key menu-bar-bookmark-map [locate]
11eb4275 698 '(" Insert location" . bookmark-menu-bar-locate))
b3bf02fa
RS
699
700 (define-key menu-bar-bookmark-map [insert]
11eb4275 701 '(" Insert contents" . bookmark-menu-bar-insert))
b3bf02fa
RS
702
703 (define-key menu-bar-bookmark-map [set]
704 '(" Set bookmark" . bookmark-set))
705
706 (define-key menu-bar-bookmark-map [jump]
11eb4275 707 '(" Go to bookmark" . bookmark-menu-bar-jump))))
b3bf02fa
RS
708
709;; not using properties because they make the menu sluggish in coming
710;; up -- too many tests to make. Instead, choosing a useless menu
711;; item just gets you an error now (see
11eb4275 712;; bookmark-make-menu-bar-with-function)
b3bf02fa 713;;
11eb4275 714;; (put 'bookmark-menu-bar-jump 'menu-enable
b3bf02fa
RS
715;; '(or bookmark-alist
716;; (and (file-readable-p bookmark-file)
717;; (progn (bookmark-load bookmark-file)
718;; bookmark-alist))))
719;;
11eb4275 720;; (put 'bookmark-menu-bar-insert 'menu-enable
b3bf02fa
RS
721;; '(or bookmark-alist
722;; (and (file-readable-p bookmark-file)
723;; (progn (bookmark-load bookmark-file)
724;; bookmark-alist))))
725;;
11eb4275 726;; (put 'bookmark-menu-bar-locate 'menu-enable
b3bf02fa
RS
727;; '(or bookmark-alist
728;; (and (file-readable-p bookmark-file)
729;; (progn (bookmark-load bookmark-file)
730;; bookmark-alist))))
731;;
11eb4275 732;; (put 'bookmark-menu-bar-rename 'menu-enable
b3bf02fa
RS
733;; '(or bookmark-alist
734;; (and (file-readable-p bookmark-file)
735;; (progn (bookmark-load bookmark-file)
736;; bookmark-alist))))
737;;
11eb4275 738;; (put 'bookmark-menu-bar-delete 'menu-enable
b3bf02fa
RS
739;; '(or bookmark-alist
740;; (and (file-readable-p bookmark-file)
741;; (progn (bookmark-load bookmark-file)
742;; bookmark-alist))))
743;;
11eb4275 744;; (put 'bookmark-menu-bar-save 'menu-enable
b3bf02fa
RS
745;; '(or bookmark-alist
746;; (and (file-readable-p bookmark-file)
747;; (progn (bookmark-load bookmark-file)
748;; bookmark-alist))))
749;;
11eb4275 750;; (put 'bookmark-menu-bar-write 'menu-enable
b3bf02fa
RS
751;; '(or bookmark-alist
752;; (and (file-readable-p bookmark-file)
753;; (progn (bookmark-load bookmark-file)
754;; bookmark-alist))))
755
11eb4275 756;;;; end bookmark menu-bar stuff ;;;;
b3bf02fa
RS
757
758;; load the default bookmark file, if it exists, and the
759;; bookmark-alist is nil:
760(bookmark-try-default-file)
761
b3bf02fa
RS
762(provide 'bookmark)
763
11eb4275 764;;; bookmark.el ends here