|
| 1 | +;;; dashboard-bm.el --- Visual Bookmarks for Dashboard -*- lexical-binding: t; -*- |
| 2 | + |
| 3 | +;; Copyright (C) 2024 Jeffrey Phillips |
| 4 | + |
| 5 | +;; Author: Jeffrey Phillips <[email protected]> |
| 6 | +;; Maintainer: Jeffrey Phillips |
| 7 | +;; Shen, Jen-Chieh <[email protected]> |
| 8 | +;; URL: https://github.com/emacs-dashboard/dashboard-bm |
| 9 | +;; Version: 0.0.1 |
| 10 | +;; Package-Requires: ((emacs "26.1") (dashboard "1.2.5") (bm "0")) |
| 11 | +;; Keywords: tools |
| 12 | + |
| 13 | +;; This file is not part of GNU Emacs. |
| 14 | + |
| 15 | +;; This program is free software: you can redistribute it and/or modify |
| 16 | +;; it under the terms of the GNU General Public License as published by |
| 17 | +;; the Free Software Foundation, either version 3 of the License, or |
| 18 | +;; (at your option) any later version. |
| 19 | + |
| 20 | +;; This program is distributed in the hope that it will be useful, |
| 21 | +;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 22 | +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 23 | +;; GNU General Public License for more details. |
| 24 | + |
| 25 | +;; You should have received a copy of the GNU General Public License |
| 26 | +;; along with this program. If not, see <https://www.gnu.org/licenses/>. |
| 27 | + |
| 28 | +;;; Commentary: |
| 29 | +;; |
| 30 | +;; Visual Bookmarks for Dashboard. |
| 31 | +;; |
| 32 | + |
| 33 | +;;; Code: |
| 34 | + |
| 35 | +(require 'dashboard) |
| 36 | +(require 'bm) |
| 37 | + |
| 38 | +(defun dashboard-bm-show-bm-dash-action () |
| 39 | + (interactive) |
| 40 | + (let ((file (get-text-property (point) 'file)) |
| 41 | + (position (get-text-property (point) 'position))) |
| 42 | + (if (not file) |
| 43 | + (message "No bookmark at this line.")) |
| 44 | + (let ((buffer (find-file-noselect file))) |
| 45 | + (with-current-buffer buffer |
| 46 | + (pop-to-buffer buffer) |
| 47 | + (goto-char position))))) |
| 48 | + |
| 49 | +(defun dashboard-bm-insert-bm (list-size) |
| 50 | + (let ((bms '())) |
| 51 | + ;; Ensure we're fresh and synced by save and then load fresh, suppressing messages |
| 52 | + (cl-letf (((symbol-function 'message) #'ignore)) |
| 53 | + (bm-buffer-save-all) |
| 54 | + (bm-repository-save) |
| 55 | + (bm-repository-load)) |
| 56 | + (cl-loop for entry in bm-repository |
| 57 | + do |
| 58 | + (let* ((file (car entry)) |
| 59 | + (filename (f-filename file)) |
| 60 | + (buffer-data (assoc file bm-repository)) |
| 61 | + (bookmarks (cdr (assoc 'bookmarks buffer-data))) |
| 62 | + (new-keymap (make-sparse-keymap "+my/dashboard-actions"))) |
| 63 | + (keymap-set new-keymap "RET" #'dashboard-bm-show-bm-dash-action) |
| 64 | + (keymap-set new-keymap "<mouse-1>" #'dashboard-bm-show-bm-dash-action) |
| 65 | + (cl-loop for bookmark in bookmarks |
| 66 | + do |
| 67 | + (let* ((pos (cdr (assoc 'position bookmark))) |
| 68 | + (time (cdr (assoc 'time bookmark))) |
| 69 | + (annotation (cdr (assoc 'annotation bookmark))) |
| 70 | + (context-string |
| 71 | + (concat (cdr (assoc 'before-context-string bookmark)) |
| 72 | + (cdr (assoc 'after-context-string bookmark)))) |
| 73 | + (line |
| 74 | + (propertize |
| 75 | + (concat |
| 76 | + (dashboard-icon-for-file filename) |
| 77 | + (format " %-25s %-15s %s" |
| 78 | + (format "%s:%s" |
| 79 | + (propertize filename 'face |
| 80 | + 'dashboard-items-face) |
| 81 | + pos) |
| 82 | + (s-left 15 (or annotation "")) |
| 83 | + (replace-regexp-in-string |
| 84 | + "\n" " " context-string))) |
| 85 | + 'mouse-face 'highlight |
| 86 | + 'help-echo "Jump to bookmark")) |
| 87 | + (start 0) |
| 88 | + (end (length line))) |
| 89 | + (add-text-properties start end `(keymap ,new-keymap |
| 90 | + file ,file |
| 91 | + position ,pos) |
| 92 | + line) |
| 93 | + (push (cons time line) bms))))) |
| 94 | + (let ((section-name "BM's:") |
| 95 | + (shortcut "b") |
| 96 | + (icon (all-the-icons-faicon |
| 97 | + "bookmark-o" :height 1.2 :v-adjust 0.0 :face 'dashboard-heading))) |
| 98 | + (if (= (length bms) 0) |
| 99 | + (progn |
| 100 | + ;; Empty section, so no shortcut needed |
| 101 | + (keymap-unset dashboard-mode-map "b") |
| 102 | + (dashboard-insert-shortcut 'bm "" nil) |
| 103 | + (dashboard-insert-heading section-name nil icon) |
| 104 | + (insert "\n " |
| 105 | + (propertize "--- No items ---" 'face 'dashboard-no-items-face))) |
| 106 | + (let* ((size (min list-size (length bms))) |
| 107 | + (sorted (sort bms (lambda (a b) (time-less-p (car b) (car a)))))) |
| 108 | + (dashboard-insert-shortcut 'bm "b" "BM's") |
| 109 | + (dashboard-insert-heading section-name shortcut icon) |
| 110 | + (insert "\n " (mapconcat 'cdr (cl-subseq sorted 0 size) "\n "))))))) |
| 111 | + |
| 112 | +(push '(bm . dashboard-bm-insert-bm) dashboard-item-generators) |
| 113 | +(dashboard-modify-heading-icons '((bm . "bookmark-o"))) |
| 114 | + |
| 115 | +(provide 'dashboard-bm) |
| 116 | +;;; dashboard-bm.el ends here |
0 commit comments