Skip to content

Commit

Permalink
adds elfeed
Browse files Browse the repository at this point in the history
  • Loading branch information
agzam committed Nov 16, 2022
1 parent 904a1c9 commit 896b72d
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 2 deletions.
5 changes: 3 additions & 2 deletions config.el
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@
(add-hook! 'prog-mode-hook #'hs-minor-mode)

;; disable visual-line-navigation in certain modes
(add-hook! (gh-notify-mode
grep-mode magit-log-mode
(add-hook! (elfeed-search-mode
gh-notify-mode grep-mode magit-log-mode
notmuch-hello-mode notmuch-search-mode notmuch-tree-mode
paradox-menu-mode yaml-mode)
(defun no-wrap-h ()
Expand Down Expand Up @@ -325,6 +325,7 @@
:desc "notmuch" "m" #'notmuch)
(:when (modulep! :custom web-browsing)
:desc "browser history" "b" #'browser-hist-search
:desc "elfeed" "e" #'elfeed
(:prefix ("h" . "HackerNews")
:desc "top" "t" #'hnreader-best
:desc "news" "n" #'hnreader-news))
Expand Down
157 changes: 157 additions & 0 deletions modules/custom/web-browsing/autoload/elfeed.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
;;; custom/web-browsing/autoload/elfeed.el -*- lexical-binding: t; -*-
(defvar +rss--wconf nil)

;;;###autoload
(defun =rss ()
"Activate (or switch to) `elfeed' in its workspace."
(interactive)
(if (modulep! :ui workspaces)
(progn
(+workspace-switch +rss-workspace-name t)
(unless (memq (buffer-local-value 'major-mode
(window-buffer
(selected-window)))
'(elfeed-show-mode
elfeed-search-mode))
(doom/switch-to-scratch-buffer)
(elfeed))
(+workspace/display))
(setq +rss--wconf (current-window-configuration))
(delete-other-windows)
(switch-to-buffer (doom-fallback-buffer))
(elfeed)))

;;;###autoload
(defun +rss/delete-pane ()
"Delete the *elfeed-entry* split pane."
(interactive)
(let* ((buf (get-buffer "*elfeed-entry*"))
(window (get-buffer-window buf)))
(delete-window window)
(when (buffer-live-p buf)
(kill-buffer buf))))

;;;###autoload
(defun +rss/open (entry)
"Display the currently selected item in a buffer."
(interactive (list (elfeed-search-selected :ignore-region)))
(when (elfeed-entry-p entry)
(elfeed-untag entry 'unread)
(elfeed-search-update-entry entry)
(elfeed-show-entry entry)))

;;;###autoload
(defun +rss/next ()
"Show the next item in the elfeed-search buffer."
(interactive)
(funcall elfeed-show-entry-delete)
(with-current-buffer (elfeed-search-buffer)
(forward-line)
(call-interactively '+rss/open)))

;;;###autoload
(defun +rss/previous ()
"Show the previous item in the elfeed-search buffer."
(interactive)
(funcall elfeed-show-entry-delete)
(with-current-buffer (elfeed-search-buffer)
(forward-line -1)
(call-interactively '+rss/open)))

;;;###autoload
(defun +rss/copy-link ()
"Copy current link to clipboard."
(interactive)
(let ((link (elfeed-entry-link elfeed-show-entry)))
(when link
(kill-new link)
(message "Copied %s to clipboard" link))))
;;
;; Hooks

;;;###autoload
(defun +rss-elfeed-wrap-h ()
"Enhances an elfeed entry's readability by wrapping it to a width of
`fill-column'."
(let ((inhibit-read-only t)
(inhibit-modification-hooks t))
(setq-local truncate-lines nil)
(setq-local shr-use-fonts nil)
(setq-local shr-width 85)
(set-buffer-modified-p nil)))

;;;###autoload
(defun +rss-cleanup-h ()
"Clean up after an elfeed session. Kills all elfeed and elfeed-org files."
(interactive)
;; `delete-file-projectile-remove-from-cache' slows down `elfeed-db-compact'
;; tremendously, so we disable the projectile cache:
(let (projectile-enable-caching)
(elfeed-db-compact))
(let ((buf (previous-buffer)))
(when (or (null buf) (not (doom-real-buffer-p buf)))
(switch-to-buffer (doom-fallback-buffer))))
(let ((search-buffers (doom-buffers-in-mode 'elfeed-search-mode))
(show-buffers (doom-buffers-in-mode 'elfeed-show-mode))
kill-buffer-query-functions)
(dolist (file (bound-and-true-p rmh-elfeed-org-files))
(when-let (buf (get-file-buffer (expand-file-name file org-directory)))
(kill-buffer buf)))
(dolist (b search-buffers)
(with-current-buffer b
(remove-hook 'kill-buffer-hook #'+rss-cleanup-h :local)
(kill-buffer b)))
(mapc #'kill-buffer show-buffers))
(if (and (modulep! :ui workspaces)
(+workspace-exists-p +rss-workspace-name))
(+workspace/delete +rss-workspace-name)
(when (window-configuration-p +rss--wconf)
(set-window-configuration +rss--wconf))
(setq +rss--wconf nil)
(previous-buffer)))

;;
;; Functions

;;;###autoload
(defun +rss-dead-feeds (&optional years)
"Return a list of feeds that haven't posted anything in YEARS."
(let* ((years (or years 1.0))
(living-feeds (make-hash-table :test 'equal))
(seconds (* years 365.0 24 60 60))
(threshold (- (float-time) seconds)))
(with-elfeed-db-visit (entry feed)
(let ((date (elfeed-entry-date entry)))
(when (> date threshold)
(setf (gethash (elfeed-feed-url feed) living-feeds) t))))
(cl-loop for url in (elfeed-feed-list)
unless (gethash url living-feeds)
collect url)))

;;;###autoload
(defun +rss-put-sliced-image-fn (spec alt &optional flags)
"TODO"
(letf! (defun insert-image (image &optional alt _area _slice)
(let ((height (cdr (image-size image t))))
(insert-sliced-image image alt nil (max 1 (/ height 20.0)) 1)))
(shr-put-image spec alt flags)))

;;;###autoload
(defun +rss-render-image-tag-without-underline-fn (dom &optional url)
"TODO"
(let ((start (point)))
(shr-tag-img dom url)
;; And remove underlines in case images are links, otherwise we get an
;; underline beneath every slice.
(put-text-property start (point) 'face '(:underline nil))))

;;;###autoload
(defun +process-elfeed-entry (entry)
"Process each type of entry differently.
e.g., you may want to open HN entries in eww."
(let ((url (elfeed-entry-link entry)))
(pcase url
((pred (string-match-p "https\\:\\/\\/www.youtube.com\\/watch"))
(youtube-sub-extractor-extract-subs url))
(_
(+eww-open-in-other-window url)))))
70 changes: 70 additions & 0 deletions modules/custom/web-browsing/config.el
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,73 @@

(use-package! browser-hist
:commands (browser-hist-search))

(use-package! elfeed
:commands elfeed
:init
(setq elfeed-db-directory (concat doom-local-dir "elfeed/db/")
elfeed-enclosure-default-dir (concat doom-local-dir "elfeed/enclosures/"))
:config
(setq elfeed-search-filter "@2-months-old "
elfeed-show-entry-switch #'switch-to-buffer
elfeed-show-entry-delete #'+rss/delete-pane
elfeed-search-title-max-width 80
shr-max-image-proportion 0.8)

(set-popup-rule! "^\\*elfeed-entry"
:size 0.75 :actions '(display-buffer-below-selected)
:select t :quit nil :ttl t)

(make-directory elfeed-db-directory t)

;; Ensure elfeed buffers are treated as real
(add-hook! 'doom-real-buffer-functions
(defun +rss-buffer-p (buf)
(string-match-p "^\\*elfeed" (buffer-name buf))))

;; Enhance readability of a post
(add-hook 'elfeed-show-mode-hook #'+rss-elfeed-wrap-h)
(add-hook! 'elfeed-search-mode-hook
(add-hook 'kill-buffer-hook #'+rss-cleanup-h nil 'local))

;; Large images are annoying to scroll through, because scrolling follows the
;; cursor, so we force shr to insert images in slices.
(setq-hook! 'elfeed-show-mode-hook
shr-put-image-function #'+rss-put-sliced-image-fn
shr-external-rendering-functions '((img . +rss-render-image-tag-without-underline-fn)))

;; Keybindings
(after! elfeed-show
(define-key! elfeed-show-mode-map
[remap next-buffer] #'+rss/next
[remap previous-buffer] #'+rss/previous))

(map! :map elfeed-search-mode-map
:n "q" #'elfeed-kill-buffer
(:localleader
"u" #'elfeed-update))

(map! :map elfeed-show-mode-map
:n "yy" #'+rss/copy-link)

;; (evil-define-key 'normal elfeed-search-mode-map
;; "q" #'elfeed-kill-buffer
;; "r" #'elfeed-search-update--force
;; (kbd "M-RET") #'elfeed-search-browse-url)

(advice-add 'elfeed-show-entry :after #'+process-elfeed-entry))

(use-package! elfeed-org
:after elfeed
:preface
(setq rmh-elfeed-org-files (list (concat doom-user-dir "elfeed.org")))
:config
(elfeed-org)
(defadvice! +rss-skip-missing-org-files-a (&rest _)
:before '(elfeed rmh-elfeed-org-mark-feed-ignore elfeed-org-export-opml)
(unless (file-name-absolute-p (car rmh-elfeed-org-files))
(let* ((default-directory org-directory)
(files (mapcar #'expand-file-name rmh-elfeed-org-files)))
(dolist (file (cl-remove-if #'file-exists-p files))
(message "elfeed-org: ignoring %S because it can't be read" file))
(setq rmh-elfeed-org-files (cl-remove-if-not #'file-exists-p files))))))
4 changes: 4 additions & 0 deletions modules/custom/web-browsing/packages.el
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@
(package! eww :built-in t)
(package! hnreader)
(package! browser-hist :recipe (:local-repo "browser-hist"))

(package! elfeed)
(package! elfeed-goodies)
(package! elfeed-org)

0 comments on commit 896b72d

Please sign in to comment.