summary refs log tree commit diff stats
path: root/lisp/+elfeed.el
blob: ef93347286c5504e52bfb7680479c4c6a8f115dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
;;; +elfeed.el -*- lexical-binding: t; -*-

;;; Code:

;; https://karthinks.com/software/lazy-elfeed/
(defun +elfeed-scroll-up-command (&optional arg)
  "Scroll up or go to next feed item in Elfeed"
  (interactive "^P")
  (let ((scroll-error-top-bottom nil))
    (condition-case-unless-debug nil
        (scroll-up-command arg)
      (error (elfeed-show-next)))))

(defun +elfeed-scroll-down-command (&optional arg)
  "Scroll up or go to next feed item in Elfeed"
  (interactive "^P")
  (let ((scroll-error-top-bottom nil))
    (condition-case-unless-debug nil
        (scroll-down-command arg)
      (error (elfeed-show-prev)))))

(defun +elfeed-search-browse-generic ()
  "Browse a url with `browse-url-generic-browser'."
  (interactive)
  (elfeed-search-browse-url t))

(defun +elfeed-show-browse-generic ()
  "Browse a url with `browse-url-generic-browser'."
  (interactive)
  (elfeed-show-visit t))

;;; Fetch feeds async
;; https://github.com/skeeto/elfeed/issues/367

(defun +elfeed--update-message ()
  (message "[Elfeed] Update in progress")
  'ignore)

(defvar +elfeed--update-running nil "Whether an update is currently running.")

(defun +elfeed-update-command ()
  (interactive)
  (let ((script (expand-file-name "~/.local/bin/elfeed")))
    (message "[Elfeed] Updating in the background.")
    (setq +elfeed--update-running t)
    (elfeed-db-save)
    (advice-add 'elfeed :override #'+elfeed--update-message)
    (ignore-errors (kill-buffer "*elfeed-search*"))
    (ignore-errors (kill-buffer "*elfeed-log*"))
    (elfeed-db-unload)
    (unless (file-exists-p script)
      (make-directory (file-name-directory script) :parents)
      (with-temp-buffer
        (insert "(progn\n"
                "  (load (locate-user-emacs-file \"early-init\"))\n"
                "  (straight-use-package 'elfeed)\n"
                "  (require 'elfeed)\n"
                "  (elfeed)\n"
                "  (elfeed-update)\n"
                "  (while (> (elfeed-queue-count-total) 0)\n"
                "    (sleep-for 5)\n"
                "    (message \"%s\" (elfeed-queue-count-total))\n"
                "    (accept-process-output))\n"
                "  (elfeed-db-save-safe)\n"
                "  (elfeed-db-gc-safe))")
        (write-file script)))
    (set-process-sentinel (start-process-shell-command
                           "Elfeed" nil (concat "emacs --script " script))
                          (lambda (a b)
                            (advice-remove 'elfeed #'+elfeed--update-message)
                            (setq +elfeed--update-running nil)
                            (message "[Elfeed] Background update %s."
                                     (string-trim b))))))

(defvar +elfeed--update-timer nil "Timer for `elfeed-update-command'.")
(defvar +elfeed--update-first-time 6 "How long to wait for the first time.")
(defvar +elfeed--update-repeat (* 60 15) "How long between updates.")

(defun +elfeed--cancel-update-timer ()
  "Cancel `+elfeed--update-timer'."
  (unless +elfeed--update-running
    (ignore-errors (cancel-timer +elfeed--update-timer))
    (setq +elfeed--update-timer nil)))

(defun +elfeed--reinstate-update-timer ()
  "Reinstate `+elfeed--update-timer'."
  (setq +elfeed--update-timer
        (run-at-time +elfeed--update-first-time
                     +elfeed--update-repeat
                     #'+elfeed-update-command)))

(define-minor-mode +elfeed-update-async-mode
  "Minor mode to update elfeed async-style every 15 minutes."
  :global t
  (if +elfeed-update-async-mode
      (progn                            ; enable
        (+elfeed--reinstate-update-timer)
        (advice-add 'elfeed :before '+elfeed--cancel-update-timer)
        (advice-add 'elfeed-search-quit-window :after '+elfeed--reinstate-update-timer))
    (progn                              ; disable
      (advice-remove 'elfeed '+elfeed--cancel-update-timer)
      (advice-remove 'elfeed-search-quit-window '+elfeed--reinstate-update-timer)
      (+elfeed--cancel-update-timer))))

(provide '+elfeed)
;;; +elfeed.el ends here