mirror of
https://github.com/SqrtMinusOne/elfeed-summary.git
synced 2025-12-10 17:43:03 +03:00
feat: improve search handling
This commit is contained in:
parent
5006ef6432
commit
125e0f059d
1 changed files with 67 additions and 19 deletions
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
;; Author: Korytov Pavel <thexcloud@gmail.com>
|
;; Author: Korytov Pavel <thexcloud@gmail.com>
|
||||||
;; Maintainer: Korytov Pavel <thexcloud@gmail.com>
|
;; Maintainer: Korytov Pavel <thexcloud@gmail.com>
|
||||||
;; Version: 0.1.0
|
;; Version: 0.1.1
|
||||||
;; Package-Requires: ((emacs "27.1") (magit-section "3.3.0") (elfeed "3.4.1"))
|
;; Package-Requires: ((emacs "27.1") (magit-section "3.3.0") (elfeed "3.4.1"))
|
||||||
;; Homepage: https://github.com/SqrtMinusOne/elfeed-summary.el
|
;; Homepage: https://github.com/SqrtMinusOne/elfeed-summary.el
|
||||||
|
|
||||||
|
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;; The package provides a tree-based feed summary interface for
|
;; The package provides a tree-based feed summary interface for
|
||||||
;; elfeed. The tree can include individual feeds, searches, and
|
;; elfeed. The tree can include individual feeds, searches, and
|
||||||
;; groups. It mainly serves as an easier "jumping point" for elfeed,
|
;; groups. It mainly serves as an easier "jumping point" for elfeed,
|
||||||
;; so searching a subset of the elfeed database is one action away.
|
;; so searching a subset of the elfeed database is one action away.
|
||||||
;;
|
;;
|
||||||
;; `elfeed-summary' pops up the summary buffer. The buffer shows
|
;; `elfeed-summary' pops up the summary buffer. The buffer shows
|
||||||
|
|
@ -122,7 +122,9 @@
|
||||||
(string :tag "Filter title"))
|
(string :tag "Filter title"))
|
||||||
(cons :tag "Tags"
|
(cons :tag "Tags"
|
||||||
(const :tag "Tags" :tags)
|
(const :tag "Tags" :tags)
|
||||||
(repeat symbol)))))
|
(repeat symbol))
|
||||||
|
(cons (cons :tag "Add the default filter string" :add-default)
|
||||||
|
(boolean :tag "Add the default filter string")))))
|
||||||
(const :tag "Misc feeds" :misc))))
|
(const :tag "Misc feeds" :misc))))
|
||||||
|
|
||||||
(defgroup elfeed-summary ()
|
(defgroup elfeed-summary ()
|
||||||
|
|
@ -153,7 +155,7 @@ This is a list of these possible items:
|
||||||
|
|
||||||
`<group-params>' is an alist with the following keys:
|
`<group-params>' is an alist with the following keys:
|
||||||
- `:title' (mandatory)
|
- `:title' (mandatory)
|
||||||
- `:elements' (mandatory) - elements of the group. The structure is
|
- `:elements' (mandatory) - elements of the group. The structure is
|
||||||
the same as in the root definition.
|
the same as in the root definition.
|
||||||
- `:face' - group face. The default face is `elfeed-summary-group-face'.
|
- `:face' - group face. The default face is `elfeed-summary-group-face'.
|
||||||
- `:hide' - if non-nil, the group is collapsed by default.
|
- `:hide' - if non-nil, the group is collapsed by default.
|
||||||
|
|
@ -190,6 +192,8 @@ Query examples:
|
||||||
`elfeed-search-set-filter'
|
`elfeed-search-set-filter'
|
||||||
- `:title' (mandatory) title.
|
- `:title' (mandatory) title.
|
||||||
- `:tags' - list of tags to get the face of the entry.
|
- `:tags' - list of tags to get the face of the entry.
|
||||||
|
- `:add-default' - if t, prepend the filter with
|
||||||
|
`elfeed-summary-default-filter'.
|
||||||
|
|
||||||
Available special forms:
|
Available special forms:
|
||||||
- `:misc' - print out feeds, not found by any query above.
|
- `:misc' - print out feeds, not found by any query above.
|
||||||
|
|
@ -479,11 +483,17 @@ SEARCH is a `<search-params>' form as described in
|
||||||
`elfeed-summary-settings'.
|
`elfeed-summary-settings'.
|
||||||
|
|
||||||
Implented the same way as `elfeed-search--update-list'."
|
Implented the same way as `elfeed-search--update-list'."
|
||||||
(let* ((filter (elfeed-search-parse-filter (alist-get :filter search)))
|
(let* ((filter-str
|
||||||
|
(concat
|
||||||
|
(when (alist-get :add-default search)
|
||||||
|
elfeed-summary-default-filter)
|
||||||
|
(alist-get :filter search)))
|
||||||
|
(filter (elfeed-search-parse-filter filter-str))
|
||||||
(head (list nil))
|
(head (list nil))
|
||||||
(tail head)
|
(tail head)
|
||||||
(unread 0)
|
(unread 0)
|
||||||
(total 0))
|
(total 0)
|
||||||
|
unread-ids)
|
||||||
(if elfeed-search-compile-filter
|
(if elfeed-search-compile-filter
|
||||||
;; Force lexical bindings regardless of the current
|
;; Force lexical bindings regardless of the current
|
||||||
;; buffer-local value. Lexical scope uses the faster
|
;; buffer-local value. Lexical scope uses the faster
|
||||||
|
|
@ -496,18 +506,21 @@ Implented the same way as `elfeed-search--update-list'."
|
||||||
tail (cdr tail)
|
tail (cdr tail)
|
||||||
total (1+ total))
|
total (1+ total))
|
||||||
(when (member elfeed-summary-unread-tag (elfeed-entry-tags entry))
|
(when (member elfeed-summary-unread-tag (elfeed-entry-tags entry))
|
||||||
(setq unread (1+ unread))))))
|
(setq unread (1+ unread))
|
||||||
|
(push (elfeed-entry-id entry) unread-ids) ))))
|
||||||
(with-elfeed-db-visit (entry feed)
|
(with-elfeed-db-visit (entry feed)
|
||||||
(when (elfeed-search-filter filter entry feed total)
|
(when (elfeed-search-filter filter entry feed total)
|
||||||
(setf (cdr tail) (list entry)
|
(setf (cdr tail) (list entry)
|
||||||
tail (cdr tail)
|
tail (cdr tail)
|
||||||
total (1+ total))
|
total (1+ total))
|
||||||
(when (member elfeed-summary-unread-tag (elfeed-entry-tags entry))
|
(when (member elfeed-summary-unread-tag (elfeed-entry-tags entry))
|
||||||
(setq unread (1+ unread))))))
|
(setq unread (1+ unread))
|
||||||
|
(push (elfeed-entry-id entry) unread-ids)))))
|
||||||
`(search . ((params . ,(cdr search))
|
`(search . ((params . ,(cdr search))
|
||||||
(faces . ,(funcall elfeed-summary-search-face-fn
|
(faces . ,(funcall elfeed-summary-search-face-fn
|
||||||
(cdr search) unread total))
|
(cdr search) unread total))
|
||||||
(unread . ,unread)
|
(unread . ,unread)
|
||||||
|
(unread-ids . ,unread-ids)
|
||||||
(total . ,total)))))
|
(total . ,total)))))
|
||||||
|
|
||||||
(defun elfeed-summary--build-tree (params unread-count total-count misc-feeds)
|
(defun elfeed-summary--build-tree (params unread-count total-count misc-feeds)
|
||||||
|
|
@ -589,6 +602,7 @@ The return value is a list of alists of the following elements:
|
||||||
`elfeed-summary-settings'.
|
`elfeed-summary-settings'.
|
||||||
- `faces' - list of faces for the search entry.
|
- `faces' - list of faces for the search entry.
|
||||||
- `unread' - number of unread entries in the search results.
|
- `unread' - number of unread entries in the search results.
|
||||||
|
- `unread-ids' - ids of unread entries for marking them as read.
|
||||||
- `total' - total number of entries in the search results."
|
- `total' - total number of entries in the search results."
|
||||||
(let* ((feeds (elfeed-summary--extract-feeds
|
(let* ((feeds (elfeed-summary--extract-feeds
|
||||||
elfeed-summary-settings))
|
elfeed-summary-settings))
|
||||||
|
|
@ -671,10 +685,10 @@ The return value is a list of alists of the following elements:
|
||||||
|
|
||||||
If there's a widget at the point, pass the press event to the widget.
|
If there's a widget at the point, pass the press event to the widget.
|
||||||
That should result in the call to
|
That should result in the call to
|
||||||
`elfeed-summary--search-feed-notify'. Otherwise, if there's a group
|
`elfeed-summary--feed-notify'. Otherwise, if there's a group
|
||||||
section, run the corresponding action for the group.
|
section, run the corresponding action for the group.
|
||||||
|
|
||||||
The behavior of both `elfeed-summary--search-feed-notify' and
|
The behavior of both `elfeed-summary--feed-notify' and
|
||||||
`elfeed-summary--open-section' is modified by lexically scoped
|
`elfeed-summary--open-section' is modified by lexically scoped
|
||||||
variables `elfeed-summary--search-show-read' and
|
variables `elfeed-summary--search-show-read' and
|
||||||
`elfeed-summary--search-mark-read'.
|
`elfeed-summary--search-mark-read'.
|
||||||
|
|
@ -749,10 +763,10 @@ items."
|
||||||
"="
|
"="
|
||||||
(rx-to-string (elfeed-feed-id feed) t))))
|
(rx-to-string (elfeed-feed-id feed) t))))
|
||||||
|
|
||||||
(defun elfeed-summary--search-feed-notify (widget &rest _)
|
(defun elfeed-summary--feed-notify (widget &rest _)
|
||||||
"A function to run in `:notify' in a feed widget button.
|
"The function to run in `:notify' in a feed widget button.
|
||||||
|
|
||||||
WIDGET is an instance of the pressed widget."
|
WIDGET is the instance of the pressed widget."
|
||||||
(cond
|
(cond
|
||||||
(elfeed-summary--search-mark-read
|
(elfeed-summary--search-mark-read
|
||||||
(elfeed-summary--mark-read (list (widget-get widget :feed))))
|
(elfeed-summary--mark-read (list (widget-get widget :feed))))
|
||||||
|
|
@ -816,12 +830,46 @@ descent."
|
||||||
'elfeed-summary-count-face))
|
'elfeed-summary-count-face))
|
||||||
(propertize title 'face (alist-get 'faces data)))))
|
(propertize title 'face (alist-get 'faces data)))))
|
||||||
(widget-create 'push-button
|
(widget-create 'push-button
|
||||||
:notify #'elfeed-summary--search-feed-notify
|
:notify #'elfeed-summary--feed-notify
|
||||||
:feed feed
|
:feed feed
|
||||||
:only-read (= 0 (alist-get 'unread data))
|
:only-read (= 0 (alist-get 'unread data))
|
||||||
text)
|
text)
|
||||||
(insert "\n")))
|
(insert "\n")))
|
||||||
|
|
||||||
|
(defun elfeed-summary--mark-read-ids (ids)
|
||||||
|
"Mark elfeed entries with IDS as read."
|
||||||
|
(when (or (not elfeed-summary-confirm-mark-read)
|
||||||
|
(y-or-n-p "Mark all entries in feed as read? "))
|
||||||
|
(let ((ids-hash (make-hash-table)))
|
||||||
|
(dolist (id ids)
|
||||||
|
(puthash id t ids-hash))
|
||||||
|
(with-elfeed-db-visit (entry feed)
|
||||||
|
(when (and
|
||||||
|
(gethash (elfeed-entry-id entry) ids-hash nil)
|
||||||
|
(member elfeed-summary-unread-tag (elfeed-entry-tags entry)))
|
||||||
|
(setf (elfeed-entry-tags entry)
|
||||||
|
(seq-filter (lambda (tag) (not (eq elfeed-summary-unread-tag tag)))
|
||||||
|
(elfeed-entry-tags entry))))) )
|
||||||
|
(elfeed-summary--refresh)))
|
||||||
|
|
||||||
|
(defun elfeed-summary--search-notify (widget &rest _)
|
||||||
|
"The function to run in `:notify' in a search widget button.
|
||||||
|
|
||||||
|
WIDGET is the instance of the pressed widget."
|
||||||
|
(cond
|
||||||
|
(elfeed-summary--search-mark-read
|
||||||
|
(elfeed-summary--mark-read-ids
|
||||||
|
(widget-get widget :unread-ids)))
|
||||||
|
(t (elfeed-summary--open-elfeed)
|
||||||
|
(elfeed-search-set-filter
|
||||||
|
(concat
|
||||||
|
(when (widget-get widget :add-default)
|
||||||
|
elfeed-summary-default-filter)
|
||||||
|
(widget-get widget :filter)
|
||||||
|
(unless (or elfeed-summary--search-show-read
|
||||||
|
(widget-get widget :only-read))
|
||||||
|
(format " +%s " elfeed-summary-unread-tag)))))))
|
||||||
|
|
||||||
(defun elfeed-summary--render-search (data _level)
|
(defun elfeed-summary--render-search (data _level)
|
||||||
"Render a search item for the elfeed summary buffer.
|
"Render a search item for the elfeed summary buffer.
|
||||||
|
|
||||||
|
|
@ -846,11 +894,11 @@ descent."
|
||||||
'face
|
'face
|
||||||
(alist-get 'faces data)))))
|
(alist-get 'faces data)))))
|
||||||
(widget-create 'push-button
|
(widget-create 'push-button
|
||||||
:notify (lambda (widget &rest _)
|
:notify #'elfeed-summary--search-notify
|
||||||
(elfeed-summary--open-elfeed)
|
|
||||||
(elfeed-search-set-filter
|
|
||||||
(widget-get widget :filter)))
|
|
||||||
:filter (alist-get :filter search-data)
|
:filter (alist-get :filter search-data)
|
||||||
|
:only-read (= 0 (alist-get 'unread data))
|
||||||
|
:add-default (alist-get :add-default search-data)
|
||||||
|
:unread-ids (alist-get 'unread-ids data)
|
||||||
text)
|
text)
|
||||||
(widget-insert "\n")))
|
(widget-insert "\n")))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue