fix: transfer-to-global uses .bookmarks, remove old Plan file fns
This commit is contained in:
@@ -1,170 +0,0 @@
|
|||||||
;;; gortium-bookmarks.el — ExoKortex Project Bookmarks
|
|
||||||
;;; Loaded from README.org via (require 'gortium-bookmarks nil t)
|
|
||||||
|
|
||||||
(defvar gortium/project-bookmark-names nil
|
|
||||||
"Bookmark names currently in the Plan file for the active project.")
|
|
||||||
|
|
||||||
(defun gortium//project-plan-file ()
|
|
||||||
"Return the first .org file under 1-Plan/ at the project root, or nil."
|
|
||||||
(when-let* ((root (projectile-project-root)))
|
|
||||||
(car (directory-files (expand-file-name "1-Plan" root) t "\\.org\\'" t))))
|
|
||||||
|
|
||||||
(defun gortium//project-tag ()
|
|
||||||
"Read the project tag from .dir-locals.el in the current project."
|
|
||||||
(when (projectile-project-p)
|
|
||||||
(let ((default-directory (projectile-project-root)))
|
|
||||||
(gortium/read-dir-local 'gortium/project-tag))))
|
|
||||||
|
|
||||||
(defun gortium//read-plan-bookmarks ()
|
|
||||||
"Parse * Bookmarks from the Plan file.
|
|
||||||
Returns alist ((NAME . URL) ...) where URL is the link target."
|
|
||||||
(when-let* ((plan-file (gortium//project-plan-file))
|
|
||||||
(_ (file-exists-p plan-file)))
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert-file-contents plan-file)
|
|
||||||
(goto-char (point-min))
|
|
||||||
(when (re-search-forward "^\\* Bookmarks" nil t)
|
|
||||||
(forward-line 1)
|
|
||||||
(let ((bookmarks '()))
|
|
||||||
(while (not (or (eobp) (looking-at "^\\* ")))
|
|
||||||
(cond
|
|
||||||
((looking-at "^\\*\\* \\(.+\\)\n\\[\\[file:\\(.+\\)\\]\\[\\(.+\\)\\]\\]")
|
|
||||||
(push (cons (match-string 1) (match-string 2)) bookmarks)
|
|
||||||
(forward-line 2))
|
|
||||||
((looking-at "\\[\\[\\(.+\\)\\]\\[\\(.+\\)\\]\\]")
|
|
||||||
(unless (string-prefix-p "mu4e:" (match-string 1))
|
|
||||||
(push (cons (match-string 2) (match-string 1)) bookmarks))
|
|
||||||
(forward-line 1))
|
|
||||||
(t (forward-line 1))))
|
|
||||||
(setq gortium/project-bookmark-names (mapcar #'car bookmarks))
|
|
||||||
(nreverse bookmarks))))))
|
|
||||||
|
|
||||||
(defun gortium//append-bookmark-to-plan (name url)
|
|
||||||
"Append a bookmark as [[url][name]] under * Bookmarks in the Plan file.
|
|
||||||
NAME is the display name, URL is the link target (file path or web URL)."
|
|
||||||
(when-let* ((plan-file (gortium//project-plan-file)))
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert-file-contents plan-file)
|
|
||||||
(goto-char (point-min))
|
|
||||||
(if (re-search-forward "^\\* Bookmarks" nil t)
|
|
||||||
(forward-line 1)
|
|
||||||
(goto-char (point-max))
|
|
||||||
(insert "\n* Bookmarks\n"))
|
|
||||||
(insert (format "[[%s][%s]]\n" url name))
|
|
||||||
(write-region (point-min) (point-max) plan-file nil 'silent)
|
|
||||||
(message "Bookmark added to %s" (file-name-nondirectory plan-file))
|
|
||||||
(push name gortium/project-bookmark-names))))
|
|
||||||
|
|
||||||
(defun gortium//remove-bookmark-from-plan (name)
|
|
||||||
"Remove a bookmark entry from * Bookmarks in the Plan file."
|
|
||||||
(when-let* ((plan-file (gortium//project-plan-file)))
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert-file-contents plan-file)
|
|
||||||
(goto-char (point-min))
|
|
||||||
(when (re-search-forward (format "^\\*\\* %s\n" (regexp-quote name)) nil t)
|
|
||||||
(forward-line -1)
|
|
||||||
(let ((start (point)))
|
|
||||||
(forward-line 2)
|
|
||||||
(delete-region start (point)))
|
|
||||||
(write-region (point-min) (point-max) plan-file nil 'silent)
|
|
||||||
(message "Bookmark '%s' removed from Plan file" name)
|
|
||||||
(setq gortium/project-bookmark-names
|
|
||||||
(delete name gortium/project-bookmark-names))))))
|
|
||||||
|
|
||||||
(defun gortium/bookmark-set ()
|
|
||||||
"Save a bookmark. Prompts: (g)lobal or (p)roject.
|
|
||||||
Project bookmarks go to * Bookmarks in the Plan file.
|
|
||||||
The prompt shows the project tag so you can verify the target."
|
|
||||||
(interactive)
|
|
||||||
(let ((choice (read-char-choice "Save: (g)lobal / (p)roject? " '(?g ?p))))
|
|
||||||
(pcase choice
|
|
||||||
(?g (call-interactively 'bookmark-set))
|
|
||||||
(?p
|
|
||||||
(if (projectile-project-p)
|
|
||||||
(let* ((tag (or (gortium//project-tag) "project"))
|
|
||||||
(name (read-string (format "[%s] Bookmark name: " tag)))
|
|
||||||
(file (buffer-file-name)))
|
|
||||||
(gortium//append-bookmark-to-plan name file)
|
|
||||||
(message "Project bookmark saved to Plan file."))
|
|
||||||
(user-error "Not in a Projectile project"))))))
|
|
||||||
|
|
||||||
(defun gortium/list-project-bookmarks ()
|
|
||||||
"Show project bookmarks in the bookmark menu (with categories).
|
|
||||||
Temporarily replaces bookmark-alist so the menu shows project bookmarks
|
|
||||||
in their native categories. On quit, restores global bookmarks."
|
|
||||||
(interactive)
|
|
||||||
(let* ((bookmarks (gortium//read-plan-bookmarks))
|
|
||||||
(names (mapcar #'car bookmarks)))
|
|
||||||
(if (not names)
|
|
||||||
(message "No bookmarks found in this project's Plan file.")
|
|
||||||
(let ((saved-alist (copy-tree bookmark-alist)))
|
|
||||||
(setq bookmark-alist nil)
|
|
||||||
(dolist (bm (nreverse (copy-tree bookmarks)))
|
|
||||||
(bookmark-store (car bm) `((filename . ,(cdr bm))) nil))
|
|
||||||
(bookmark-bmenu-list)
|
|
||||||
(with-current-buffer "*Bookmark List*"
|
|
||||||
(add-hook 'kill-buffer-hook
|
|
||||||
(lambda ()
|
|
||||||
(setq bookmark-alist saved-alist)
|
|
||||||
(when-let* ((plan-file (gortium//project-plan-file))
|
|
||||||
(entries (bookmark-maybe-sort-alist bookmark-alist)))
|
|
||||||
(gortium//sync-plan-to-bookmark-file
|
|
||||||
(mapcar (lambda (e)
|
|
||||||
(cons (car e)
|
|
||||||
(alist-get 'filename (cdr e))))
|
|
||||||
entries))))
|
|
||||||
nil t))))))
|
|
||||||
|
|
||||||
(defun gortium//sync-plan-to-bookmark-file (bookmarks)
|
|
||||||
"Write BOOKMARKS alist back to the Plan file under * Bookmarks."
|
|
||||||
(when-let* ((plan-file (gortium//project-plan-file)))
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert-file-contents plan-file)
|
|
||||||
(when (re-search-forward "^\\* Bookmarks" nil t)
|
|
||||||
(forward-line 1)
|
|
||||||
(let ((start (point)))
|
|
||||||
(if (re-search-forward "^\\* " nil t)
|
|
||||||
(forward-line -1)
|
|
||||||
(goto-char (point-max)))
|
|
||||||
(delete-region start (point)))
|
|
||||||
(dolist (bm (nreverse (copy-tree bookmarks)))
|
|
||||||
(insert (format "[[%s][%s]]\n" (cdr bm) (car bm))))
|
|
||||||
(write-region (point-min) (point-max) plan-file nil 'silent)))))
|
|
||||||
|
|
||||||
(defun gortium/transfer-to-project ()
|
|
||||||
"Transfer a global bookmark to the current project's Plan file."
|
|
||||||
(interactive)
|
|
||||||
(if (projectile-project-p)
|
|
||||||
(let* ((name (completing-read "Transfer to project: " (bookmark-all-names) nil t))
|
|
||||||
(file (bookmark-location name)))
|
|
||||||
(when (and name file (y-or-n-p (format "Transfer '%s' to project? " name)))
|
|
||||||
(gortium//append-bookmark-to-plan name file)
|
|
||||||
(bookmark-delete name)
|
|
||||||
(bookmark-save)
|
|
||||||
(message "Transferred '%s' to project %s" name
|
|
||||||
(or (gortium//project-tag) ""))))
|
|
||||||
(user-error "Not in a Projectile project")))
|
|
||||||
|
|
||||||
(defun gortium/transfer-to-global ()
|
|
||||||
"Transfer a project bookmark to the global bookmarks list."
|
|
||||||
(interactive)
|
|
||||||
(let* ((bookmarks (gortium//read-plan-bookmarks))
|
|
||||||
(names (mapcar #'car bookmarks)))
|
|
||||||
(if names
|
|
||||||
(let* ((name (completing-read "Transfer to global: " names nil t))
|
|
||||||
(url (cdr (assoc name bookmarks))))
|
|
||||||
(when (and name url (y-or-n-p (format "Transfer '%s' to global? " name)))
|
|
||||||
(bookmark-store name `((filename . ,url)) t)
|
|
||||||
(bookmark-save)
|
|
||||||
(gortium//remove-bookmark-from-plan name)
|
|
||||||
(message "Transferred '%s' to global" name)))
|
|
||||||
(message "No project bookmarks to transfer."))))
|
|
||||||
|
|
||||||
;; Bindings
|
|
||||||
(map! :leader
|
|
||||||
:desc "Set bookmark (global/project)"
|
|
||||||
"b m" #'gortium/bookmark-set
|
|
||||||
:desc "Jump to project bookmark"
|
|
||||||
"p RET" #'gortium/list-project-bookmarks)
|
|
||||||
|
|
||||||
(provide 'gortium-bookmarks)
|
|
||||||
Reference in New Issue
Block a user