mirror of
https://github.com/SqrtMinusOne/elfeed-summary.git
synced 2025-12-11 18:13:03 +03:00
feat: add searches to settings
This commit is contained in:
parent
e9d4d59b41
commit
2d21f978c1
1 changed files with 105 additions and 39 deletions
|
|
@ -27,10 +27,13 @@
|
||||||
;; TODO
|
;; TODO
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
(require 'cl-lib)
|
||||||
(require 'elfeed)
|
(require 'elfeed)
|
||||||
(require 'elfeed-db)
|
(require 'elfeed-db)
|
||||||
(require 'widget)
|
(require 'elfeed-search)
|
||||||
|
(require 'magit-section)
|
||||||
(require 'seq)
|
(require 'seq)
|
||||||
|
(require 'widget)
|
||||||
|
|
||||||
(define-widget 'elfeed-summary-query 'lazy
|
(define-widget 'elfeed-summary-query 'lazy
|
||||||
"A query to extract a subset of elfeed feeds."
|
"A query to extract a subset of elfeed feeds."
|
||||||
|
|
@ -61,56 +64,76 @@
|
||||||
(const :tag "OR" or)
|
(const :tag "OR" or)
|
||||||
(repeat elfeed-summary-query))))
|
(repeat elfeed-summary-query))))
|
||||||
|
|
||||||
(define-widget 'elfeed-summary-group 'lazy
|
(define-widget 'elfeed-summary-setting-elements 'lazy
|
||||||
"A group of `elfeed-summary-query'"
|
"Type widget for `elfeed-summary-settings'"
|
||||||
:offset 4
|
:offset 4
|
||||||
:tag "Group"
|
:tag "Settings list"
|
||||||
:type '(repeat
|
:type '(repeat
|
||||||
(choice
|
(choice
|
||||||
(cons :tag "Group"
|
(cons :tag "Group"
|
||||||
(const group)
|
(const group)
|
||||||
(list :tag "Group params"
|
(repeat :tag "Group params"
|
||||||
(cons
|
(choice
|
||||||
(const :tag "Title" :title)
|
(cons
|
||||||
(string :tag "Title"))
|
(const :tag "Title" :title)
|
||||||
(cons
|
(string :tag "Title"))
|
||||||
(const :tag "Sort function" :sort-fn)
|
(cons
|
||||||
(choice
|
(const :tag "Sort function" :sort-fn)
|
||||||
function
|
(choice
|
||||||
(const :tag "None" nil)))
|
function
|
||||||
(cons
|
(const :tag "None" nil)))
|
||||||
(const :tag "Elements" :elements)
|
(cons
|
||||||
elfeed-summary-group)))
|
(const :tag "Elements" :elements)
|
||||||
elfeed-summary-query)))
|
elfeed-summary-setting-elements))))
|
||||||
|
(cons :tag "Query"
|
||||||
|
(const query)
|
||||||
|
elfeed-summary-query)
|
||||||
|
(cons :tag "Search"
|
||||||
|
(const search)
|
||||||
|
(repeat :tag "Search params"
|
||||||
|
(choice
|
||||||
|
(cons :tag "Filter"
|
||||||
|
(const :tag "Filter" :filter)
|
||||||
|
(string :tag "Filter string"))
|
||||||
|
(cons :tag "Title"
|
||||||
|
(const :tag "Title" :title)
|
||||||
|
(string :tag "Filter title")))))
|
||||||
|
(const :tag "Misc feeds" :misc))))
|
||||||
|
|
||||||
(defgroup elfeed-summary ()
|
(defgroup elfeed-summary ()
|
||||||
"Feed summary inteface for elfeed."
|
"Feed summary inteface for elfeed."
|
||||||
:group 'elfeed)
|
:group 'elfeed)
|
||||||
|
|
||||||
(defcustom elfeed-summary-settings '((group (:title . "All feeds")
|
(defcustom elfeed-summary-settings
|
||||||
(:sort-fn . string-lessp)
|
'((group (:title . "All feeds")
|
||||||
(:elements :all)))
|
(:sort-fn . string-lessp)
|
||||||
|
(:elements (query . :all)))
|
||||||
|
(group (:title . "Searches")
|
||||||
|
(:elements (search
|
||||||
|
(:filter . "@7-days-ago +unread")
|
||||||
|
(:title . "Unread entries this week"))
|
||||||
|
(search
|
||||||
|
(:filter . "@6-months-ago emacs")
|
||||||
|
(:title . "Something about Emacs")))))
|
||||||
"Elfeed summary buffer settings.
|
"Elfeed summary buffer settings.
|
||||||
|
|
||||||
This is a list of these possible items:
|
This is a list of these possible items:
|
||||||
- group
|
- Group `(group . <group-params>)'
|
||||||
- query
|
Groups are used to group elements under collapsible sections.
|
||||||
|
- Query `(query . <query-params>)'
|
||||||
|
Query extracts a subset of elfeed feeds based on the given criteria.
|
||||||
|
Each found feed will be represented as a line.
|
||||||
|
- Search `(search . <search-params>)'
|
||||||
|
Elfeed search, as defined by `elfeed-search-set-filter'.
|
||||||
- a few special forms
|
- a few special forms
|
||||||
|
|
||||||
Groups are used to group queries under collapsible sections.
|
`<group-params>' is an alist with the following keys:
|
||||||
|
|
||||||
A group is a cons cell like (group . <params>), where params are an
|
|
||||||
alist with the following attributes:
|
|
||||||
- `:title' (mandatory)
|
- `:title' (mandatory)
|
||||||
- `:elements' (mandatory) - also a list of groups and queries
|
- `:elements' (mandatory) - also a list of groups and queries
|
||||||
- `:sort-fn' - function used to sort titles of feeds, found by queries
|
- `:sort-fn' - function used to sort titles of feeds, found by queries
|
||||||
in `:elements'. E.g. `string-greaterp' for alphabetical order.
|
in `:elements'. E.g. `string-greaterp' for alphabetical order.
|
||||||
|
|
||||||
Query is a form that extract a subset of elfeed feeds based on
|
`<query-params>' can be:
|
||||||
some criteria. In the summary buffer, each feed found by the
|
|
||||||
query will be represented as a line.
|
|
||||||
|
|
||||||
Query can be:
|
|
||||||
- A symbol of a tag.
|
- A symbol of a tag.
|
||||||
A feed will be matched if it has that tag.
|
A feed will be matched if it has that tag.
|
||||||
- `:all'. Will match anything.
|
- `:all'. Will match anything.
|
||||||
|
|
@ -125,22 +148,27 @@ Query can be:
|
||||||
Match if any of the conditions 1, 2, ..., n match.
|
Match if any of the conditions 1, 2, ..., n match.
|
||||||
- `(not <query>)'
|
- `(not <query>)'
|
||||||
|
|
||||||
Feed tags are taken from `elfeed-feeds'.
|
Feed tags for query are taken from `elfeed-feeds'.
|
||||||
|
|
||||||
Query examples:
|
Query examples:
|
||||||
- `(emacs lisp)'
|
- `(emacs lisp)'
|
||||||
Return all feeds that have either \"emacs\" or \"lisp\" tags.
|
Return all feeds that have either \"emacs\" or \"lisp\" tags.
|
||||||
- `(and emacs lisp)'
|
- `(and emacs lisp)'
|
||||||
Return all feeds that have both \"emacs\" and \"lisp\" tags.
|
Return all feeds that have both \"emacs\" and \"lisp\" tags.
|
||||||
- `(and (title . \"Emacs\") (not planets))
|
- `(and (title . \"Emacs\") (not planets))'
|
||||||
Return all feeds that have \"Emacs\" in their title and don't have
|
Return all feeds that have \"Emacs\" in their title and don't have
|
||||||
the \"planets\" tag.
|
the \"planets\" tag.
|
||||||
|
|
||||||
|
`<search-params>` is an alist with the following keys:
|
||||||
|
- `:filter' (mandatory) filter string, as defined by
|
||||||
|
`elfeed-search-set-filter'
|
||||||
|
- `:title' (mandatory) title
|
||||||
|
|
||||||
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.
|
||||||
- `:unread' - a special feed of all unread entries."
|
- `:unread' - a special feed of all unread entries."
|
||||||
:group 'elfeed-summary
|
:group 'elfeed-summary
|
||||||
:type 'elfeed-summary-group)
|
:type 'elfeed-summary-setting-elements)
|
||||||
|
|
||||||
(defcustom elfeed-summary-look-back (* 60 60 24 180)
|
(defcustom elfeed-summary-look-back (* 60 60 24 180)
|
||||||
"TODO"
|
"TODO"
|
||||||
|
|
@ -157,6 +185,8 @@ Available special forms:
|
||||||
"Default face for the elfeed-summary group."
|
"Default face for the elfeed-summary group."
|
||||||
:group 'elfeed-summary)
|
:group 'elfeed-summary)
|
||||||
|
|
||||||
|
;;; Logic
|
||||||
|
|
||||||
(cl-defun elfeed-summary--match-tag (query &key tags title url author title-meta)
|
(cl-defun elfeed-summary--match-tag (query &key tags title url author title-meta)
|
||||||
"Check if attributes of elfeed feed match QUERY.
|
"Check if attributes of elfeed feed match QUERY.
|
||||||
|
|
||||||
|
|
@ -261,7 +291,8 @@ QUERY is described in `elfeed-summary-settings'."
|
||||||
if (and (listp param) (eq (car param) 'group))
|
if (and (listp param) (eq (car param) 'group))
|
||||||
append (elfeed-summary--extract-feeds
|
append (elfeed-summary--extract-feeds
|
||||||
(cdr (assoc :elements (cdr param))))
|
(cdr (assoc :elements (cdr param))))
|
||||||
else append (elfeed-summary--get-feeds param)))
|
else if (and (listp param) (eq (car param) 'query))
|
||||||
|
append (elfeed-summary--get-feeds (cdr param))))
|
||||||
|
|
||||||
(defun elfeed-summary--build-tree-feed (feed unread-count total-count)
|
(defun elfeed-summary--build-tree-feed (feed unread-count total-count)
|
||||||
(let* ((unread (or (gethash (elfeed-feed-id feed) unread-count) 0))
|
(let* ((unread (or (gethash (elfeed-feed-id feed) unread-count) 0))
|
||||||
|
|
@ -284,6 +315,33 @@ QUERY is described in `elfeed-summary-settings'."
|
||||||
(unread . ,unread)
|
(unread . ,unread)
|
||||||
(total . ,unread))))
|
(total . ,unread))))
|
||||||
|
|
||||||
|
(defun elfeed-summary--build-search (search)
|
||||||
|
"TODO
|
||||||
|
|
||||||
|
Implented the same way as `elfeed-search--update-list'."
|
||||||
|
(let* ((filter (elfeed-search-parse-filter (alist-get :filter search)))
|
||||||
|
(head (list nil))
|
||||||
|
(tail head)
|
||||||
|
(count 0))
|
||||||
|
(if elfeed-search-compile-filter
|
||||||
|
;; Force lexical bindings regardless of the current
|
||||||
|
;; buffer-local value. Lexical scope uses the faster
|
||||||
|
;; stack-ref opcode instead of the traditional varref opcode.
|
||||||
|
(let ((lexical-binding t)
|
||||||
|
(func (byte-compile (elfeed-search-compile-filter filter))))
|
||||||
|
(with-elfeed-db-visit (entry feed)
|
||||||
|
(when (funcall func entry feed count)
|
||||||
|
(setf (cdr tail) (list entry)
|
||||||
|
tail (cdr tail)
|
||||||
|
count (1+ count)))))
|
||||||
|
(with-elfeed-db-visit (entry feed)
|
||||||
|
(when (elfeed-search-filter filter entry feed count)
|
||||||
|
(setf (cdr tail) (list entry)
|
||||||
|
tail (cdr tail)
|
||||||
|
count (1+ count)))))
|
||||||
|
`((search . ,search)
|
||||||
|
(count . ,count))))
|
||||||
|
|
||||||
(defun elfeed-summary--build-tree (params unread-count total-count misc-feeds)
|
(defun elfeed-summary--build-tree (params unread-count total-count misc-feeds)
|
||||||
(cl-loop for param in params
|
(cl-loop for param in params
|
||||||
if (and (listp param) (eq (car param) 'group))
|
if (and (listp param) (eq (car param) 'group))
|
||||||
|
|
@ -291,16 +349,19 @@ QUERY is described in `elfeed-summary-settings'."
|
||||||
(children . ,(elfeed-summary--build-tree
|
(children . ,(elfeed-summary--build-tree
|
||||||
(cdr (assoc :elements (cdr param)))
|
(cdr (assoc :elements (cdr param)))
|
||||||
unread-count total-count misc-feeds)))
|
unread-count total-count misc-feeds)))
|
||||||
|
else if (and (listp param) (eq (car param) 'search))
|
||||||
|
collect (elfeed-summary--build-search param)
|
||||||
|
else if (and (listp param) (eq (car param) 'query))
|
||||||
|
append (cl-loop for feed in (elfeed-summary--get-feeds (cdr param))
|
||||||
|
collect (elfeed-summary--build-tree-feed
|
||||||
|
feed unread-count total-count))
|
||||||
else if (eq param :misc)
|
else if (eq param :misc)
|
||||||
append (cl-loop for feed in misc-feeds
|
append (cl-loop for feed in misc-feeds
|
||||||
collect (elfeed-summary--build-tree-feed
|
collect (elfeed-summary--build-tree-feed
|
||||||
feed unread-count total-count))
|
feed unread-count total-count))
|
||||||
else if (eq param :unread)
|
else if (eq param :unread)
|
||||||
collect (elfeed-summary--build-tree-unread unread-count)
|
collect (elfeed-summary--build-tree-unread unread-count)
|
||||||
else
|
else do (error "Can't parse: %s" (prin1-to-string param))))
|
||||||
append (cl-loop for feed in (elfeed-summary--get-feeds param)
|
|
||||||
collect (elfeed-summary--build-tree-feed
|
|
||||||
feed unread-count total-count))))
|
|
||||||
|
|
||||||
(defun elfeed-summary--get-data ()
|
(defun elfeed-summary--get-data ()
|
||||||
(let* ((feeds (elfeed-summary--extract-feeds
|
(let* ((feeds (elfeed-summary--extract-feeds
|
||||||
|
|
@ -328,5 +389,10 @@ QUERY is described in `elfeed-summary-settings'."
|
||||||
(elfeed-summary--build-tree elfeed-summary-settings
|
(elfeed-summary--build-tree elfeed-summary-settings
|
||||||
unread-count total-count misc-feeds)))
|
unread-count total-count misc-feeds)))
|
||||||
|
|
||||||
|
;;; View
|
||||||
|
|
||||||
|
(defun elfeed-summary--render (tree)
|
||||||
|
"TODO")
|
||||||
|
|
||||||
(provide 'elfeed-summary)
|
(provide 'elfeed-summary)
|
||||||
;;; elfeed-summary.el ends here
|
;;; elfeed-summary.el ends here
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue