Fetching contributors…
Cannot retrieve contributors at this time
302 lines (262 sloc) 11.2 KB
;;; helm-bookmark.el --- Helm for Emacs regular Bookmarks.
;; Copyright (C) 2012 Thierry Volpiatto <>
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <>.
;;; Code:
(eval-when-compile (require 'cl))
(eval-when-compile (require 'bookmark))
(require 'helm)
(require 'helm-utils)
(require 'helm-info)
(require 'helm-adaptative)
(defgroup helm-bookmark nil
"Predefined configurations for `helm.el'."
:group 'helm)
(defface helm-bookmarks-su
'((t (:foreground "red")))
"Face for su/sudo bookmarks."
:group 'helm-bookmark)
(defface helm-bookmark-info
'((t (:foreground "green")))
"Face used for W3m Emacs bookmarks (not w3m bookmarks)."
:group 'helm-bookmark)
(defface helm-bookmark-w3m
'((t (:foreground "yellow")))
"Face used for W3m Emacs bookmarks (not w3m bookmarks)."
:group 'helm-bookmark)
(defface helm-bookmark-gnus
'((t (:foreground "magenta")))
"Face used for Gnus bookmarks."
:group 'helm-bookmark)
(defface helm-bookmark-man
'((t (:foreground "Orange4")))
"Face used for Woman/man bookmarks."
:group 'helm-bookmark)
(defface helm-bookmark-file
'((t (:foreground "Deepskyblue2")))
"Face used for file bookmarks."
:group 'helm-bookmark)
(defface helm-bookmark-directory
'((t (:inherit helm-ff-directory)))
"Face used for file bookmarks."
:group 'helm-bookmark)
(defvar helm-c-bookmark-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map helm-map)
(define-key map (kbd "C-c o") 'helm-c-bookmark-run-jump-other-window)
(define-key map (kbd "C-d") 'helm-c-bookmark-run-delete)
(when (locate-library "bookmark-extensions")
(define-key map (kbd "M-e") 'helm-c-bmkext-run-edit))
(define-key map (kbd "C-c ?") 'helm-c-bookmark-help)
(delq nil map))
"Generic Keymap for emacs bookmark sources.")
(defvar helm-c-source-bookmarks
`((name . "Bookmarks")
(init . (lambda ()
(require 'bookmark)
"*hbookmark list*" (bookmark-all-names))))
(type . bookmark))
"See (info \"(emacs)Bookmarks\").")
;;; bookmark-set
(defvar helm-c-source-bookmark-set
'((name . "Set Bookmark")
(action . bookmark-set))
"See (info \"(emacs)Bookmarks\").")
;;; Special bookmarks
(defvar helm-c-source-bookmarks-ssh
'((name . "Bookmarks-ssh")
(init . (lambda ()
(require 'bookmark)
"*hbookmark list*" (helm-c-collect-bookmarks :ssh t))))
(type . bookmark))
"See (info \"(emacs)Bookmarks\").")
(defvar helm-c-source-bookmarks-su
'((name . "Bookmarks-root")
(init . (lambda ()
(require 'bookmark)
"*hbookmark list*" (helm-c-collect-bookmarks :su t))))
(filtered-candidate-transformer . helm-c-highlight-bookmark-su)
(type . bookmark))
"See (info \"(emacs)Bookmarks\").")
(defvar helm-c-source-bookmarks-local
'((name . "Bookmarks-Local")
(init . (lambda ()
(require 'bookmark)
"*hlbookmark list*" (helm-c-collect-bookmarks :local t))))
(type . bookmark))
"See (info \"(emacs)Bookmarks\").")
(defun* helm-c-collect-bookmarks (&key local su sudo ssh)
(let* ((lis-all (bookmark-all-names))
(lis-loc (cond (local (loop for i in lis-all
unless (string-match "^(ssh)\\|^(su)" i)
collect i))
(su (loop for i in lis-all
when (string-match "^(su)" i)
collect i))
(sudo (loop for i in lis-all
when (string-match "^(sudo)" i)
collect i))
(ssh (loop for i in lis-all
when (string-match "^(ssh)" i)
collect i)))))
(sort lis-loc 'string-lessp)))
(defun helm-c-bookmark-root-logged-p ()
(catch 'break
(dolist (i (mapcar #'buffer-name (buffer-list)))
(when (string-match (format "*tramp/%s ." helm-su-or-sudo) i)
(throw 'break t)))))
(defun helm-c-highlight-bookmark-su (files source)
(if (helm-c-bookmark-root-logged-p)
(helm-c-highlight-bookmark files source)
(helm-c-highlight-not-logged files source)))
(defun helm-c-highlight-not-logged (files source)
(loop for i in files
collect (propertize i 'face 'helm-bookmarks-su)))
(defun helm-c-highlight-bookmark (bookmarks source)
"Used as `candidate-transformer' to colorize bookmarks.
Work both with standard Emacs bookmarks and bookmark-extensions.el."
(let ((non-essential t))
(loop for i in bookmarks
for isfile = (bookmark-get-filename i)
for bufp = (and (fboundp 'bmkext-get-buffer-name)
(bmkext-get-buffer-name i))
for handlerp = (and (fboundp 'bookmark-get-handler)
(bookmark-get-handler i))
for isw3m = (and (fboundp 'bmkext-w3m-bookmark-p)
(bmkext-w3m-bookmark-p i))
for isgnus = (and (fboundp 'bmkext-gnus-bookmark-p)
(bmkext-gnus-bookmark-p i))
for isman = (and (fboundp 'bmkext-man-bookmark-p) ; Man
(bmkext-man-bookmark-p i))
for iswoman = (and (fboundp 'bmkext-woman-bookmark-p) ; Woman
(bmkext-woman-bookmark-p i))
for handlerp = (bookmark-get-handler i)
for isannotation = (bookmark-get-annotation i)
for isabook = (string= (bookmark-prop-get i 'type) "addressbook")
for isinfo = (eq handlerp 'Info-bookmark-jump)
;; Add a * if bookmark have annotation
if (and isannotation (not (string-equal isannotation "")))
do (setq i (concat "*" i))
collect (cond ( ;; info buffers
(propertize i 'face 'helm-bookmark-info 'help-echo isfile))
( ;; w3m buffers
(propertize i 'face 'helm-bookmark-w3m 'help-echo isfile))
( ;; gnus buffers
(propertize i 'face 'helm-bookmark-gnus 'help-echo isfile))
( ;; Man Woman
(or iswoman isman)
(propertize i 'face 'helm-bookmark-man 'help-echo isfile))
( ;; Addressbook
(propertize i 'face '((:foreground "Tomato"))))
( ;; directories
(and isfile
;; This is needed because `non-essential'
;; is not working on Emacs-24.2 and the behavior
;; of tramp seems to have changed since previous
;; versions (Need to reenter password even if a first
;; connection have been established, probably when host
;; is named differently i.e machine/localhost)
(not (file-remote-p isfile))
(file-directory-p isfile))
(propertize i 'face 'helm-bookmark-directory 'help-echo isfile))
( ;; regular files
(propertize i 'face 'helm-bookmark-file 'help-echo isfile))))))
(defun helm-c-bookmark-jump (candidate)
"Jump to bookmark from keyboard."
(let ((current-prefix-arg helm-current-prefix-arg))
(bookmark-jump candidate)))
(define-helm-type-attribute 'bookmark
`((coerce . helm-bookmark-get-bookmark-from-name)
("Jump to bookmark" . helm-c-bookmark-jump)
("Jump to BM other window" . bookmark-jump-other-window)
("Bookmark edit annotation" . bookmark-edit-annotation)
("Bookmark show annotation" . bookmark-show-annotation)
("Delete bookmark(s)" . helm-delete-marked-bookmarks)
,@(and (locate-library "bookmark-extensions")
`(("Edit Bookmark" . bmkext-edit-bookmark)))
("Rename bookmark" . bookmark-rename)
("Relocate bookmark" . bookmark-relocate))
(keymap . ,helm-c-bookmark-map)
(mode-line . helm-bookmark-mode-line-string))
"Bookmark name.")
(defun helm-c-bookmark-run-jump-other-window ()
"Jump to bookmark from keyboard."
(helm-c-quit-and-execute-action 'bookmark-jump-other-window))
(defun helm-c-bookmark-run-delete ()
"Delete bookmark from keyboard."
(when (y-or-n-p "Delete bookmark?")
(helm-c-quit-and-execute-action 'helm-delete-marked-bookmarks)))
(defun helm-bookmark-get-bookmark-from-name (bmk)
"Return bookmark name even if it is a bookmark with annotation.
e.g prepended with *.
Return nil if bmk is not a valid bookmark."
(let ((bookmark (replace-regexp-in-string "\*" "" bmk)))
(if (assoc bookmark bookmark-alist)
(when (assoc bmk bookmark-alist)
(defun helm-delete-marked-bookmarks (ignore)
"Delete this bookmark or all marked bookmarks."
(dolist (i (helm-marked-candidates))
(bookmark-delete (helm-bookmark-get-bookmark-from-name i)
(defun helm-bookmarks ()
"Preconfigured `helm' for bookmarks."
(helm :sources '(helm-c-source-bookmarks
:buffer "*helm bookmarks*"
:default (buffer-name helm-current-buffer)))
(defun helm-c-pp-bookmarks ()
"Preconfigured `helm' for bookmarks (pretty-printed)."
(helm :sources '(helm-c-source-bookmarks-local
:buffer "*helm pp bookmarks*"
:default (buffer-name helm-current-buffer)))
(provide 'helm-bookmark)
;; Local Variables:
;; byte-compile-warnings: (not cl-functions obsolete)
;; coding: utf-8
;; indent-tabs-mode: nil
;; End:
;;; helm-bookmark.el ends here