bookmark.el でブックマーク名を自動入力

bookmark.el の使いづらいところと言えば、ブックマーク名を自分で入れなきゃらないところ。ブックマーク名を自動で入れればかなり便利になるんじゃないかと考え、「ファイル名:行数:関数名」と自動でブックマーク名を入れることにした。

which-functionというので、今いる関数の名前がわかるらしいので、これを利用する。

以下のような関数を定義し、

(require 'which-func)
(defun my-get-bookmark-name ()
  (interactive)
  (message "%s:%s:%s"
            (buffer-name)
            (line-number-at-pos (point)) (or (which-function) "")))

以下のhoge()で M-x my-get-bookmark-nameを実行すると

#include <stdio.h>
void hoge(void)
{
    return;
}

int main(int argc, char *argv[])
{
    hoge();
    return 0;
}

エコーバッファに「foo.c:4:hoge」と表示された。

これを使って関数を辿っていくのにどんどんブックマークをつけていったら、ブックマークが多くなって収集がつかなってきた。そこでブックマークの先頭に"!"が付いている場合は、次回起動時に読み込まないようにした。つまり、先頭に"!"とついているブックマークはテンポラリとする。


2011-05-26 オリジナルのbookmark.elに手を入れないと動かいなことがわかった。残念。

(require 'bookmark)

;; ブックマーク名を "!バッファ名:行数:関数名" にする。
;; オリジナルの bookmark-buffer-name 関数を上書き。
;; 後述するように、起動時に先頭が"!"となっているブックマークを削除することに注
;; 意。ブックマークを起動時に削除したくない場合は、ブックマーク登録時にミニバッ
;; ファで C-u を押して"!"を削除してから登録するか、 C-x r l で一覧表示して r を
;; 押して先頭の"!"を削除して登録しなおす。
(require 'which-func)
(defun bookmark-buffer-name ()
  (cond
   ((string-equal mode-name "Info") Info-current-node)
   ((and (boundp 'dired-directory) dired-directory)
    (format "%s" (buffer-name)))
   (t
    (format "!%s:%s:%s"
            (buffer-name)
            (line-number-at-pos (point)) (or (which-function) "")))))

;; 起動時に先頭が"!"となっているブックマークを削除する。 bookmark-default-file
;; を変更しているときは、事前に bookmark-default-file を設定しておく必要あり。
(require 'cl)
(bookmark-maybe-load-default-file)
(setq bookmark-alist
      (remove-if
       (lambda (x) (string-match "^!" (car x)) ) bookmark-alist))
(bookmark-save)

;; ブックマーク名に関数名を入れたことにより、ブックマーク名が長くなりがちなので、
;; 表示を伸ばす
(setq bookmark-bmenu-file-column 60)

;; オリジナルのbookmark-setに以下の変更を加える
;; elcファイルがあるときはバイトコンパイル必要なことに注意
;; diff -c bookmark.el bookmark.el.20110526-1635~ 
;; *** bookmark.el 2011-05-26 16:37:45.970516200 +0900
;; --- bookmark.el.20110526-1635~  2009-08-09 21:37:28.001000000 +0900
;; ***************
;; *** 761,769 ****
;;     (setq bookmark-yank-point (point))
;;     (setq bookmark-current-buffer (current-buffer))
;;
;; ! ;;   (let* ((default (or bookmark-current-bookmark
;; ! ;;                       (bookmark-buffer-name)))
;; !   (let* ((default (bookmark-buffer-name))
;;      (str
;;       (or name
;;                 (read-from-minibuffer
;; --- 761,768 ----
;;     (setq bookmark-yank-point (point))
;;     (setq bookmark-current-buffer (current-buffer))
;;
;; !   (let* ((default (or bookmark-current-bookmark
;; !                       (bookmark-buffer-name)))
;;      (str
;;       (or name
;;                 (read-from-minibu
;;                 ffer
補足

bm.el というのもあるそう。