aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Emacs/.config/emacs/elisp/org-bookmark.el113
1 files changed, 77 insertions, 36 deletions
diff --git a/Emacs/.config/emacs/elisp/org-bookmark.el b/Emacs/.config/emacs/elisp/org-bookmark.el
index f606cde..192a75d 100644
--- a/Emacs/.config/emacs/elisp/org-bookmark.el
+++ b/Emacs/.config/emacs/elisp/org-bookmark.el
@@ -28,69 +28,110 @@
(defvar +bookmark/file (expand-file-name (concat org-directory "/bookmarks.org")))
(defvar +bookmark/mpv-args "--ytdl-raw-options=force-ipv4= --ytdl-format=22 -v")
-(defun +bookmark/--extract-heading ()
+(defun +bookmark/--get-heading-data ()
+ "In an org-mode buffer, with point on a heading: get the title,
+tags and url."
(let ((heading-components (org-heading-components))
- (tags (org-get-tags)))
- (message "%s" tags)
+ (tags (org-get-tags))
+ (url (org-entry-get (point-marker) "URL")))
(list
(nth 4 heading-components)
(cl-remove-if #'(lambda (tag) (string= tag "bookmark")) tags)
- (substring-no-properties
- (org-agenda-get-some-entry-text
- (point-marker)
- most-positive-fixnum)))))
+ url)))
-(defun +bookmark/--extract-all-heading-data ()
+(defun +bookmark/--get-all-heading-data ()
+ "In an org-mode buffer, get all the heading data (titles, tags and
+urls)."
(cl-remove-if
#'(lambda (x) (member "DONE" (nth 1 x)))
+ ;; Extract all headings with :bookmark: tag
(org-scan-tags
- #'+bookmark/--extract-heading
+ #'+bookmark/--get-heading-data
(cdr (org-make-tags-matcher ":bookmark:"))
nil)))
-(defun +bookmark/--heading->record (heading)
- (cl-destructuring-bind (name tags url) heading
+(defun +bookmark/--format-heading-data (data)
+ "Format the heading data extracted into a pair of (TITLE+TAG
+. URL)."
+ (cl-destructuring-bind (name tags url) data
(cons
- (concat name
- " "
+ (format "%s %s" name
(substring-no-properties
(cl-reduce #'(lambda (x y) (concat x ":" y))
tags
:initial-value "")))
url)))
+(defvar +bookmark/--cache nil
+ "Cached alist constructed from bookmarks file of form (TITLE+TAG
+. URL).")
+(defvar +bookmark/--cache-last-modified nil
+ "Last modified time for bookmarks file as a float.")
+
(defun +bookmark/bookmarks ()
+ "Get all bookmarks from +BOOKMARK/FILE in alist format. Results
+are cached for faster lookup."
(with-current-buffer (find-file-noselect +bookmark/file)
- (mapcar
- #'+bookmark/--heading->record
- (+bookmark/--extract-all-heading-data))))
+ (let ((cur-last-modified (float-time (visited-file-modtime))))
+ ;; If no cache, or no last-modified or the file has been modified
+ ;; since we've last cached then recache.
+ (when (or (null +bookmark/--cache)
+ (null +bookmark/--cache-last-modified)
+ (not (= cur-last-modified +bookmark/--cache-last-modified)))
+ (setq +bookmark/--cache-last-modified cur-last-modified
+ +bookmark/--cache (mapcar
+ #'+bookmark/--format-heading-data
+ (+bookmark/--get-all-heading-data))))))
+ +bookmark/--cache)
+
+(defun +bookmark/open-mpv (url)
+ (interactive)
+ (message "[bookmark]: Starting MPV process")
+ (with-current-buffer (get-buffer-create "*mpv*")
+ (ansi-color-for-comint-mode-on)
+ (comint-mode))
+ (set-process-filter (start-process-shell-command
+ "bookmark-mpv" "*mpv*"
+ (concat "mpv " +bookmark/mpv-args " \"" url "\""))
+ #'comint-output-filter))
+
+(defconst +bookmark/dispatch-list
+ '((("^https://\\(www.\\)?youtu\\(.\\)?be"
+ "\\.mp4$")
+ . +bookmark/open-mpv)
+ (otherwise . eww))
+ "List of pairs of type (PATTERNS . FUNC) which is used in
++BOOKMARK/OPEN-BOOKMARK to handle opening urls.
+
+PATTERNS is a list of one or more regexp patterns (as strings)
+which should match particular URLs. It can also be 'OTHERWISE
+which represents the default case if no previous patterns match
+the URL.
+
+FUNC is a callable or function which takes one parameter (the URL
+as a string) and produces some action of opening it.")
(defun +bookmark/open-bookmark ()
+ "Open a bookmark. Uses +BOOKMARK/DISPATCH-LIST to dispatch
+opening the url to some handler function."
(interactive)
(let* ((bookmarks (+bookmark/bookmarks))
- (choice (completing-read "Choose bookmark: "
- (mapcar #'car bookmarks)
- nil t))
+ (choice (completing-read "Choose bookmark: " (mapcar #'car bookmarks) nil t))
(pair (assoc choice bookmarks #'string=)))
(if (null pair)
(error (format "`%s' is not a valid bookmark" choice))
- (message "[bookmark]: Opening `%s`" (car pair))
- (cond
- ((or
- (string-match-p "^https://\\(www.\\)?youtu\\(.\\)?be" (cdr pair))
- (string-match-p "\\.mp4$" (cdr pair)))
- ;; Open MPV
- (message "[bookmark]: Starting MPV process")
- (with-current-buffer (get-buffer-create "*mpv*")
- (ansi-color-for-comint-mode-on)
- (comint-mode))
- (set-process-filter (start-process-shell-command
- "bookmark-mpv" "*mpv*"
- (concat "mpv " +bookmark/mpv-args " \"" (cdr pair) "\""))
- #'comint-output-filter))
- (t
- (message "[bookmark]: Starting eww")
- (eww (cdr pair)))))))
+ (message "[bookmark]: Opening `%s` (`%s`)" (car pair) (cdr pair))
+ (let* ((url (cdr pair))
+ (dispatch-choice
+ (cl-loop
+ for (patterns . func) in +bookmark/dispatch-list
+ if (or (eq patterns 'otherwise)
+ (cl-some
+ #'(lambda (pattern) (string-match pattern url))
+ patterns))
+ return func)))
+ (message "dispatch-choice=%S" dispatch-choice)
+ (funcall dispatch-choice (cdr pair))))))
(provide 'org-bookmark)
;;; bookmark.el ends here