X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/a9269c187774dea6e939066a79901f23ae79641f..0877d0dc24ee792b9b14592869ea1aa0934aee58:/lisp/bookmark.el diff --git a/lisp/bookmark.el b/lisp/bookmark.el index bb7ad153e8..da6ffb3845 100644 --- a/lisp/bookmark.el +++ b/lisp/bookmark.el @@ -1,6 +1,6 @@ ;;; bookmark.el --- set bookmarks, maybe annotate them, jump to them later -;; Copyright (C) 1993-1997, 2001-2011 Free Software Foundation, Inc. +;; Copyright (C) 1993-1997, 2001-2013 Free Software Foundation, Inc. ;; Author: Karl Fogel ;; Maintainer: Karl Fogel @@ -33,7 +33,7 @@ ;;; Code: (require 'pp) -(eval-when-compile (require 'cl)) +(eval-when-compile (require 'cl-lib)) ;;; Misc comments: ;; @@ -65,7 +65,7 @@ --> t means save bookmarks when Emacs is killed. --> Otherwise, it should be a number that is the frequency with which the bookmark list is saved (i.e.: the number of times which - Emacs' bookmark list may be modified before it is automatically + Emacs's bookmark list may be modified before it is automatically saved.). If it is a number, Emacs will also automatically save bookmarks when it is killed. @@ -83,7 +83,7 @@ To specify the file in which to save them, modify the variable "The `.emacs.bmk' file used to be called this name.") -;; defvarred to avoid a compilation warning: +;; defvared to avoid a compilation warning: (defvar bookmark-file nil "Old name for `bookmark-default-file'.") @@ -99,12 +99,14 @@ To specify the file in which to save them, modify the variable (defcustom bookmark-version-control 'nospecial "Whether or not to make numbered backups of the bookmark file. -It can have four values: t, nil, `never', and `nospecial'. +It can have four values: t, nil, `never', or `nospecial'. The first three have the same meaning that they do for the -variable `version-control', and the final value `nospecial' means just -use the value of `version-control'." - :type '(choice (const nil) (const never) (const nospecial) - (other t)) +variable `version-control'; the value `nospecial' (the default) means +just use the value of `version-control'." + :type '(choice (const :tag "If existing" nil) + (const :tag "Never" never) + (const :tag "Use value of option `version-control'" nospecial) + (other :tag "Always" t)) :group 'bookmark) @@ -144,10 +146,7 @@ You can toggle whether files are shown with \\\\[bookma (defcustom bookmark-bmenu-toggle-filenames t "Non-nil means show filenames when listing bookmarks. -This may result in truncated bookmark names. To disable this, put the -following in your `.emacs' file: - -\(setq bookmark-bmenu-toggle-filenames nil)" +A non-nil value may result in truncated bookmark names." :type 'boolean :group 'bookmark) @@ -277,8 +276,8 @@ through a file easier.") (defvar bookmark-current-buffer nil "The buffer in which a bookmark is currently being set or renamed. Functions that insert strings into the minibuffer use this to know -the source buffer for that information; see `bookmark-yank-word' and -`bookmark-insert-current-bookmark' for example.") +the source buffer for that information; see `bookmark-yank-word' +for example.") (defvar bookmark-yank-point 0 @@ -434,7 +433,11 @@ the empty string." ": "))) (str (completing-read prompt - bookmark-alist + (lambda (string pred action) + (if (eq action 'metadata) + '(metadata (category . bookmark)) + (complete-with-action + action bookmark-alist string pred))) nil 0 nil @@ -473,6 +476,12 @@ equivalently just return ALIST without NAME.") (defun bookmark-make-record () "Return a new bookmark record (NAME . ALIST) for the current location." (let ((record (funcall bookmark-make-record-function))) + ;; Set up defaults. + (bookmark-prop-set + record 'defaults + (delq nil (delete-dups (append (bookmark-prop-get record 'defaults) + (list bookmark-current-bookmark + (bookmark-buffer-name)))))) ;; Set up default name. (if (stringp (car record)) ;; The function already provided a default name. @@ -738,10 +747,6 @@ This expects to be called from `point-min' in a bookmark file." (let ((map (make-sparse-keymap))) (set-keymap-parent map minibuffer-local-map) (define-key map "\C-w" 'bookmark-yank-word) - ;; This C-u binding might not be very useful any more now that we - ;; provide access to the default via the standard M-n binding. - ;; Maybe we should just remove it? --Stef-08 - (define-key map "\C-u" 'bookmark-insert-current-bookmark) map)) ;;;###autoload @@ -772,7 +777,19 @@ the list of bookmarks.)" (interactive (list nil current-prefix-arg)) (unwind-protect (let* ((record (bookmark-make-record)) - (default (car record))) + ;; `defaults' is a transient element of the + ;; extensible format described above in the section + ;; `File format stuff'. Bookmark record functions + ;; can use it to specify a list of default values + ;; accessible via M-n while reading a bookmark name. + (defaults (bookmark-prop-get record 'defaults)) + (default (if (consp defaults) (car defaults) defaults))) + + (if defaults + ;; Don't store default values in the record. + (setq record (assq-delete-all 'defaults record)) + ;; When no defaults in the record, use its first element. + (setq defaults (car record) default defaults)) (bookmark-maybe-load-default-file) ;; Don't set `bookmark-yank-point' and `bookmark-current-buffer' @@ -788,7 +805,7 @@ the list of bookmarks.)" (format "Set bookmark (%s): " default) nil bookmark-minibuffer-read-name-map - nil nil default)))) + nil nil defaults)))) (and (string-equal str "") (setq str default)) (bookmark-store str (cdr record) no-overwrite) @@ -828,11 +845,11 @@ annotations." "# Date: " (current-time-string) "\n")) +(define-obsolete-variable-alias 'bookmark-read-annotation-text-func + 'bookmark-edit-annotation-text-func "23.1") (defvar bookmark-edit-annotation-text-func 'bookmark-default-annotation-text "Function to return default text to use for a bookmark annotation. It takes one argument, the name of the bookmark, as a string.") -(define-obsolete-variable-alias 'bookmark-read-annotation-text-func - 'bookmark-edit-annotation-text-func "23.1") (defvar bookmark-edit-annotation-mode-map (let ((map (make-sparse-keymap))) @@ -888,18 +905,6 @@ Lines beginning with `#' are ignored." (bookmark-edit-annotation-mode bookmark-name-or-record)) -(defun bookmark-insert-current-bookmark () - "Insert into the bookmark name currently being set the value of -`bookmark-current-bookmark' in `bookmark-current-buffer', defaulting -to the buffer's file name if `bookmark-current-bookmark' is nil." - (interactive) - (let ((str - (with-current-buffer bookmark-current-buffer - (or bookmark-current-bookmark - (bookmark-buffer-name))))) - (insert str))) - - (defun bookmark-buffer-name () "Return the name of the current buffer in a form usable as a bookmark name. If the buffer is associated with a file or directory, use that name." @@ -1049,12 +1054,11 @@ The return value has the form (BUFFER . POINT). Note: this function is deprecated and is present for Emacs 22 compatibility only." + (declare (obsolete bookmark-handle-bookmark "23.1")) (save-excursion (bookmark-handle-bookmark bookmark) (cons (current-buffer) (point)))) -(make-obsolete 'bookmark-jump-noselect 'bookmark-handle-bookmark "23.1") - (defun bookmark-handle-bookmark (bookmark-name-or-record) "Call BOOKMARK-NAME-OR-RECORD's handler or `bookmark-default-handler' if it has none. This changes current buffer and point and returns nil, @@ -1359,7 +1363,12 @@ for a file, defaulting to the file defined by variable (goto-char (point-min)) (delete-region (point-min) (point-max)) (let ((print-length nil) - (print-level nil)) + (print-level nil) + ;; See bug #12503 for why we bind `print-circle'. Users + ;; can define their own bookmark types, which can result in + ;; arbitrary Lisp objects being stored in bookmark records, + ;; and some users create objects containing circularities. + (print-circle t)) (bookmark-insert-file-format-version-stamp) (insert "(") ;; Rather than a single call to `pp' we make one per bookmark. @@ -1539,7 +1548,7 @@ deletion, or > if it is flagged for displaying." (bookmark-maybe-load-default-file) (let ((buf (get-buffer-create "*Bookmark List*"))) (if (called-interactively-p 'interactive) - (pop-to-buffer-same-window buf) + (switch-to-buffer buf) (set-buffer buf))) (let ((inhibit-read-only t)) (erase-buffer) @@ -1864,10 +1873,8 @@ With a prefix arg, prompts for a file to save them in." The current window remains selected." (interactive) (let ((bookmark (bookmark-bmenu-bookmark)) - (pop-up-windows t) - same-window-buffer-names - same-window-regexps) - (bookmark--jump-via bookmark 'display-buffer))) + (fun (lambda (b) (display-buffer b t)))) + (bookmark--jump-via bookmark fun))) (defun bookmark-bmenu-other-window-with-mouse (event) "Select bookmark at the mouse pointer in other window, leaving bookmark menu visible." @@ -2005,38 +2012,12 @@ To carry out the deletions that you've marked, use \\\\ ;;; Bookmark-bmenu search -;; Store keyboard input for incremental search. -(defvar bookmark-search-pattern) - -(defun bookmark-read-search-input () - "Read each keyboard input and add it to `bookmark-search-pattern'." - (let ((prompt (propertize "Pattern: " 'face 'minibuffer-prompt)) - ;; (inhibit-quit t) ; inhibit-quit is evil. Use it with extreme care! - (tmp-list ())) - (while - (let ((char (read-key (concat prompt bookmark-search-pattern)))) - (case char - ((?\e ?\r) nil) ; RET or ESC break the search loop. - (?\C-g (setq bookmark-quit-flag t) nil) - (?\d (pop tmp-list) t) ; Delete last char of pattern with DEL - (t - (if (characterp char) - (push char tmp-list) - (setq unread-command-events - (nconc (mapcar 'identity - (this-single-command-raw-keys)) - unread-command-events)) - nil)))) - (setq bookmark-search-pattern - (apply 'string (reverse tmp-list)))))) - - (defun bookmark-bmenu-filter-alist-by-regexp (regexp) "Filter `bookmark-alist' with bookmarks matching REGEXP and rebuild list." (let ((bookmark-alist - (loop for i in bookmark-alist - when (string-match regexp (car i)) collect i into new - finally return new))) + (cl-loop for i in bookmark-alist + when (string-match regexp (car i)) collect i into new + finally return new))) (bookmark-bmenu-list))) @@ -2045,19 +2026,23 @@ To carry out the deletions that you've marked, use \\\\ "Incremental search of bookmarks, hiding the non-matches as we go." (interactive) (let ((bmk (bookmark-bmenu-bookmark)) - (bookmark-search-pattern "") - (timer (run-with-idle-timer - bookmark-search-delay 'repeat - #'(lambda () - (bookmark-bmenu-filter-alist-by-regexp - bookmark-search-pattern))))) + (timer nil)) (unwind-protect - (bookmark-read-search-input) - (cancel-timer timer) - (message nil) - (when bookmark-quit-flag ; C-g hit restore menu list. - (bookmark-bmenu-list) (bookmark-bmenu-goto-bookmark bmk)) - (setq bookmark-quit-flag nil)))) + (minibuffer-with-setup-hook + (lambda () + (setq timer (run-with-idle-timer + bookmark-search-delay 'repeat + #'(lambda (buf) + (with-current-buffer buf + (bookmark-bmenu-filter-alist-by-regexp + (minibuffer-contents)))) + (current-buffer)))) + (read-string "Pattern: ") + (when timer (cancel-timer timer) (setq timer nil))) + (when timer ;; Signalled an error or a `quit'. + (cancel-timer timer) + (bookmark-bmenu-list) + (bookmark-bmenu-goto-bookmark bmk))))) (defun bookmark-bmenu-goto-bookmark (name) "Move point to bookmark with name NAME." @@ -2115,36 +2100,36 @@ strings returned are not." ;;;###autoload (defvar menu-bar-bookmark-map (let ((map (make-sparse-keymap "Bookmark functions"))) - (define-key map [load] - `(menu-item ,(purecopy "Load a Bookmark File...") bookmark-load - :help ,(purecopy "Load bookmarks from a bookmark file)"))) - (define-key map [write] - `(menu-item ,(purecopy "Save Bookmarks As...") bookmark-write - :help ,(purecopy "Write bookmarks to a file (reading the file name with the minibuffer)"))) - (define-key map [save] - `(menu-item ,(purecopy "Save Bookmarks") bookmark-save - :help ,(purecopy "Save currently defined bookmarks"))) - (define-key map [edit] - `(menu-item ,(purecopy "Edit Bookmark List") bookmark-bmenu-list - :help ,(purecopy "Display a list of existing bookmarks"))) - (define-key map [delete] - `(menu-item ,(purecopy "Delete Bookmark...") bookmark-delete - :help ,(purecopy "Delete a bookmark from the bookmark list"))) - (define-key map [rename] - `(menu-item ,(purecopy "Rename Bookmark...") bookmark-rename - :help ,(purecopy "Change the name of a bookmark"))) - (define-key map [locate] - `(menu-item ,(purecopy "Insert Location...") bookmark-locate - :help ,(purecopy "Insert the name of the file associated with a bookmark"))) - (define-key map [insert] - `(menu-item ,(purecopy "Insert Contents...") bookmark-insert - :help ,(purecopy "Insert the text of the file pointed to by a bookmark"))) - (define-key map [set] - `(menu-item ,(purecopy "Set Bookmark...") bookmark-set - :help ,(purecopy "Set a bookmark named inside a file."))) - (define-key map [jump] - `(menu-item ,(purecopy "Jump to Bookmark...") bookmark-jump - :help ,(purecopy "Jump to a bookmark (a point in some file)"))) + (bindings--define-key map [load] + '(menu-item "Load a Bookmark File..." bookmark-load + :help "Load bookmarks from a bookmark file)")) + (bindings--define-key map [write] + '(menu-item "Save Bookmarks As..." bookmark-write + :help "Write bookmarks to a file (reading the file name with the minibuffer)")) + (bindings--define-key map [save] + '(menu-item "Save Bookmarks" bookmark-save + :help "Save currently defined bookmarks")) + (bindings--define-key map [edit] + '(menu-item "Edit Bookmark List" bookmark-bmenu-list + :help "Display a list of existing bookmarks")) + (bindings--define-key map [delete] + '(menu-item "Delete Bookmark..." bookmark-delete + :help "Delete a bookmark from the bookmark list")) + (bindings--define-key map [rename] + '(menu-item "Rename Bookmark..." bookmark-rename + :help "Change the name of a bookmark")) + (bindings--define-key map [locate] + '(menu-item "Insert Location..." bookmark-locate + :help "Insert the name of the file associated with a bookmark")) + (bindings--define-key map [insert] + '(menu-item "Insert Contents..." bookmark-insert + :help "Insert the text of the file pointed to by a bookmark")) + (bindings--define-key map [set] + '(menu-item "Set Bookmark..." bookmark-set + :help "Set a bookmark named inside a file.")) + (bindings--define-key map [jump] + '(menu-item "Jump to Bookmark..." bookmark-jump + :help "Jump to a bookmark (a point in some file)")) map)) ;;;###autoload @@ -2164,11 +2149,11 @@ strings returned are not." "Hook run at the end of loading library `bookmark.el'.") ;; Exit Hook, called from kill-emacs-hook +(define-obsolete-variable-alias 'bookmark-exit-hooks + 'bookmark-exit-hook "22.1") (defvar bookmark-exit-hook nil "Hook run when Emacs exits.") -(define-obsolete-variable-alias 'bookmark-exit-hooks 'bookmark-exit-hook "22.1") - (defun bookmark-exit-hook-internal () "Save bookmark state, if necessary, at Emacs exit time. This also runs `bookmark-exit-hook'."