読み込んでいないファイルのブックマークも一覧できる anything-bm-plusを作ってみた
bm.el と bookmark.el の両方を使い分けるのが面倒なので、bm.el のリポジトリファイルからブックマークのリスティングを行う anything-c-source を作ってみた。
これでもう bookmark.el は イラネ!!(*゚Д゚)ノ⌒゚ポィ
今回の試行錯誤で気がついたのだが、bm-bookmark-context-size のデフォルト値 16 では、ブックマーク箇所を誤認識する可能性が高い。
とりあえず ローカル環境では128 に設定しなおした。
しかし、まだ lisp は馴染んでなくて、コーディングがツライす。
何しろ定石がさっぱりなので、なんだか lisp っぽくないような気がする。。。
(require 'anything) (require 'bm) (require 'bm-ext) (defvar anything-bm-plus-item-separator "\0") ;; buffer ... ファイルを読み込んでいない時は nil (defun anything-bm-plus-item-line (filename buffer line-number annotation text) (format "%s%s%s%s%s%s%5d%s%s%s%s" ;; kind, file-name, buffer-name, line-number, annotation, text (if buffer "buffer" "file") anything-bm-plus-item-separator filename anything-bm-plus-item-separator (or buffer "") anything-bm-plus-item-separator line-number anything-bm-plus-item-separator annotation anything-bm-plus-item-separator text)) ;; (defun anything-bm-plus-item-lines-for-file (filename bookmarks expect-buffer-size) (let ( (item-lines '()) (start) (end) (annotation) (line-number) ) (save-excursion (with-output-to-temp-buffer " *anything-c-source-bm-plus*" (set-buffer standard-output) (insert-file filename) (while bookmarks (goto-char (point-min)) (let* ((bookmark (car bookmarks)) (is-buffer-size-match (equal (point-max) expect-buffer-size)) (start (if is-buffer-size-match (cdr (assoc 'position bookmark)) (bm-get-position-from-context bookmark))) (end) (line-number (line-number-at-pos start)) (annotation (or (cdr (assoc 'annotation bookmark)) "" )) ) (if start ;; start == nil is conflict data (progn (goto-char start) (setq end (point-at-eol)) (setq line (anything-bm-plus-item-line filename nil ; buffer line-number annotation (if (< (- end start) 1) ;; text ;; "\n" (buffer-substring start (1+ end))))) (setq item-lines (cons line item-lines))))) (setq bookmarks (cdr bookmarks))))) item-lines)) ;; (defun anything-bm-plus-opened-files () (delq nil (mapcar #'(lambda (buf) (with-current-buffer buf (let ((file-name (buffer-file-name))) (if file-name (cons (expand-file-name file-name) buf) nil)))) (buffer-list)))) (defun anything-bm-plus-format-line (bm) (let ((buf (overlay-buffer bm))) (with-current-buffer buf (anything-bm-plus-item-line (expand-file-name (buffer-file-name)) buf (line-number-at-pos (overlay-start bm)) (or (overlay-get bm 'annotation) "") (buffer-substring (overlay-start bm) (overlay-end bm)))))) (defun anything-bm-plus-insert-opened-bookmark-items () (let* ((bookmarks (bm-all-bookmarks)) (lines (mapconcat 'anything-bm-plus-format-line bookmarks ""))) (if (null bookmarks) (message "No bookmarks.") (insert lines)))) (defun anything-c-source-bm-plus-init () (with-current-buffer (anything-candidate-buffer 'global) (anything-bm-plus-insert-opened-bookmark-items) (let ((items bm-repository) (opend-files (anything-bm-plus-opened-files)) ) (while items (let* ( (filename (expand-file-name (car (car items)))) (buffer-data (assoc filename bm-repository)) (expect-buffer-size (cdr (assoc 'size buffer-data))) (bookmarks (cdr (assoc 'bookmarks buffer-data))) (item-lines) (buf (cdr (assoc filename opend-files))) ) (if buf nil (setq item-lines (anything-bm-plus-item-lines-for-file filename bookmarks expect-buffer-size))) (while item-lines (insert (car item-lines)) (setq item-lines (cdr item-lines))) ) (setq items (cdr items)))))) (defun anything-c-source-bm-plus-action (candidate) (let* ((kind (cdr (assoc 'kind candidate))) (buffername (cdr (assoc 'buffername candidate))) (filename (cdr (assoc 'filename candidate))) (line-number (cdr (assoc 'line-number candidate)))) (if (string= kind "buffer") (switch-to-buffer buffername) (find-file filename)) (goto-line line-number))) ;; (defun anything-c-source-bm-plus-transformer (candidates) (mapcar #'(lambda (candidate) (let* ((items (split-string candidate anything-bm-plus-item-separator)) (kind (car items)) (annotation-len-max 80) (annotation (fifth items)) (annotation (if (<= (length annotation) annotation-len-max) annotation (substring annotation 0 annotation-len-max))) (buffername (third items)) (buffername (if (= 0 (length buffername)) "none" buffername)) (buffername (concat "*" (concat buffername "*"))) ) (cons (if (string= kind "buffer") (progn (format "%-30s %s [%s] %s" buffername (fourth items) ;; line number annotation (sixth items)) ;; text ) (format "%-30s %s [%s] %s" (file-name-nondirectory (second items)) (fourth items) ;; line number annotation (sixth items)) ;; text ) (list (cons 'kind kind) (cons 'filename (second items)) (cons 'buffername (third items)) (cons 'line-number (string-to-number (fourth items))))))) candidates)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; (defvar anything-c-source-bm-plus '((name . "Visible Bookmarks Plus") (init . anything-c-source-bm-plus-init) (candidates-in-buffer) (candidate-transformer . anything-c-source-bm-plus-transformer) (action . (("Goto line" . anything-c-source-bm-plus-action))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; (defun anything-bm-select () (interactive) (anything '(anything-c-source-bm anything-c-source-bm-ext anything-c-source-bm-plus ))) (provide 'anything-bm-plus)