### Customize Elfeed Search Buffer Entry Display Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Replace the default entry rendering function to customize how entries appear in the search buffer. This example shows how to add the score and format title and feed information. ```emacs-lisp ;; Custom entry printer: show score alongside standard info (defun my-elfeed-search-print (entry) (let* ((score (elfeed-meta entry :score 0)) (score-str (format "[%3d] " score)) (title (or (elfeed-meta--title entry) (elfeed-entry-link entry))) (feed (elfeed-entry-feed entry)) (feed-title (elfeed-meta--title feed))) (insert (propertize score-str 'face 'elfeed-search-date-face)) (insert (propertize (elfeed-format-column title 60 :left) 'face 'elfeed-search-title-face)) (when feed-title (insert " " (propertize feed-title 'face 'elfeed-search-feed-face))))) (setq elfeed-search-print-entry-function #'my-elfeed-search-print) ;; Customize the date display format (setq elfeed-search-date-format '("%Y-%m-%d" 10 :left)) ; default ;; Customize title column widths (setq elfeed-search-title-max-width 100) ; default 70 (setq elfeed-search-title-min-width 20) ; default 16 ;; Custom sort: group entries by feed (setq elfeed-search-sort-function #'elfeed-search-group-by-feed) ;; Sort oldest-first instead of newest-first (setq elfeed-search-sort-order 'ascending) ; default: descending ``` -------------------------------- ### Configure Elfeed Search Face Source: https://github.com/emacs-elfeed/elfeed/blob/main/README.org Customize the appearance of Elfeed search results by defining custom faces and adding them to `elfeed-search-face-alist`. This example makes entries tagged 'important' appear in red. ```emacs-lisp (defface important-elfeed-entry '((t :foreground "#f77")) "Marks an important Elfeed entry.") (push '(important important-elfeed-entry) elfeed-search-face-alist) ``` -------------------------------- ### Configure Elfeed cURL Backend Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Configure Elfeed to use cURL for HTTP fetches, enabling features like conditional GET and parallel downloads. You can disable cURL or specify its path. ```emacs-lisp ;; Check if curl is being used (set automatically if curl is found in PATH) elfeed-use-curl ; => t if curl found ``` ```emacs-lisp ;; Disable curl and fall back to url-retrieve (setq elfeed-use-curl nil) ``` ```emacs-lisp ;; Customize curl executable path (setq elfeed-curl-program-name "/usr/local/bin/curl") ``` ```emacs-lisp ;; Set custom user-agent string (setq elfeed-user-agent "MyElfeed/1.0") ``` ```emacs-lisp ;; Pass extra arguments to curl (e.g., proxy, client cert) (setq elfeed-curl-extra-arguments '("--proxy" "socks5://localhost:1080")) ``` ```emacs-lisp ;; In fetch callbacks, these buffer-local variables are available: ;; elfeed-curl-headers -- alist of response headers ;; elfeed-curl-status-code -- HTTP status integer ;; elfeed-curl-error-message -- error string on failure ;; elfeed-curl-location -- final URL after redirects ``` -------------------------------- ### Elfeed Entry Point Source: https://context7.com/emacs-elfeed/elfeed/llms.txt The main interactive entry point to open Elfeed. By default, it opens the `*elfeed-search*` buffer. This can be customized via `elfeed-entry-point`. ```emacs-lisp ;; Open Elfeed (M-x elfeed or bound key) (elfeed) ;; Customize the entry point (default: elfeed-search) (setq elfeed-entry-point 'elfeed-tree) ; use the tree view instead ;; Or call search/tree directly (elfeed-search) (elfeed-tree) ``` -------------------------------- ### Database Traversal Source: https://context7.com/emacs-elfeed/elfeed/llms.txt The `elfeed-db-visit` macro provides a primary low-level API for iterating over all database entries ordered by date (newest first). Use `elfeed-db-return` to exit early. Functions like `elfeed-feed-entries` and `elfeed-db-size` are also available. ```APIDOC ## Database Traversal — `elfeed-db-visit` Macro for iterating over all database entries ordered by date (newest first). Use `elfeed-db-return` to exit early. This is the primary low-level API for bulk entry processing. ```emacs-lisp ;; Collect all unread entry titles (let (titles) (elfeed-db-visit (entry) (when (elfeed-tagged-p 'unread entry) (push (elfeed-entry-title entry) titles))) titles) ;; Visit entries with feed access, stop at entries older than 30 days (let ((cutoff (- (float-time) (* 30 24 3600)))) (elfeed-db-visit (entry feed) (when (< (elfeed-entry-date entry) cutoff) (elfeed-db-return)) (message "%s: %s" (elfeed-feed-title feed) (elfeed-entry-title entry)))) ;; Strip content from old entries to save database space (defun my-elfeed-strip-old-content () (let ((limit (elfeed-float-time "60 days ago"))) (elfeed-db-visit (entry feed) (cond ((< (elfeed-entry-date entry) limit) (elfeed-db-return)) ; exit early, entries are sorted newest-first ((equal "https://www.youtube.com/feeds/videos.xml" (elfeed-feed-url feed)) (setf (elfeed-entry-content entry) nil)))))) ;; Get all entries for a specific feed (elfeed-feed-entries "https://nullprogram.com/feed/") ;; Get database size (number of entries) (elfeed-db-size) ``` ``` -------------------------------- ### Create Subset Feeds with Custom Tagging Source: https://github.com/emacs-elfeed/elfeed/blob/main/README.org Define a tagger to add 'junk' and remove 'unread' tags for entries from 'example.com' that do not match 'something interesting' in their title. ```emacs-lisp (add-hook 'elfeed-new-entry-hook (elfeed-make-tagger :feed-url "example\\.com" :entry-title '(not "something interesting") :add 'junk :remove 'unread)) ``` -------------------------------- ### Load elfeed-link and Configure Org-capture Templates Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Load the `elfeed-link` package to enable Elfeed integration with Org-mode. Configure `org-capture-templates` to create custom templates for capturing Elfeed entries, utilizing Elfeed's rich metadata properties. ```emacs-lisp (require 'elfeed-link) ;; From elfeed-show buffer: M-x org-store-link ;; Produces an org link like: [[elfeed:nullprogram.com#https://...][Post Title]] ;; Org-capture template using elfeed entry properties (setq org-capture-templates '(("e" "Elfeed entry" entry (file "~/org/feeds.org") "* TODO %:title :PROPERTIES: :URL: %:external-link :DATE: %:date-timestamp :FEED: %:feed-title :AUTHORS: %:authors :END: %:content "))) ``` -------------------------------- ### Import and Export Feeds with OPML Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Use `elfeed-load-opml` to import feed lists from OPML files and `elfeed-export-opml` to export the current feed list to an OPML file. Importing an OPML file can also save the subscriptions to the Elfeed customization file. ```emacs-lisp ;; Load feeds from an OPML file (interactive: also saves to customization file) (elfeed-load-opml "~/subscriptions.opml") ;; Export current elfeed-feeds to an OPML file (elfeed-export-opml "~/elfeed-export.opml") ;; The resulting OPML file looks like: ;; ;; ;; Elfeed Export ;; ;; ;; ... ;; ;; ``` -------------------------------- ### Manage Elfeed Database Persistence Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Explicitly manage database persistence using `elfeed-db-save`, `elfeed-db-load`, and `elfeed-db-compact`. The database is auto-saved on quit, but manual management is possible. `elfeed-db-compact` packs loose content files into a compressed archive and requires `gzip` in `PATH`. Add compaction to the `kill-emacs-hook` for automatic cleanup. ```emacs-lisp ;; Manually save the database index to disk (elfeed-db-save) ;; Compact the database (pack content + garbage collect unreferenced data) ;; Requires gzip in PATH. Good to run periodically or as kill-emacs-hook. (elfeed-db-compact) ;; Add compaction to Emacs shutdown hook (add-hook 'kill-emacs-hook #'elfeed-db-compact) ;; Unload the database (for external manipulation), then reload (elfeed-db-unload) (elfeed-db-load) ; called automatically on next elfeed-db-ensure ;; Change the database directory (set before first use) (setq elfeed-db-directory "~/Documents/elfeed-db/") ;; Query last update time (format-time-string "%Y-%m-%d %H:%M" (seconds-to-time (elfeed-db-last-update))) ``` -------------------------------- ### Manage Elfeed Metadata with setf Source: https://github.com/emacs-elfeed/elfeed/blob/main/README.org Use the `elfeed-meta` function and `setf` to store and retrieve arbitrary metadata for feed entries and feeds. Ensure `(require 'elfeed)` is present for macro expansion. ```emacs-lisp (require 'elfeed) ;; Necessary for macro expansion of (setf (elfeed-meta ...) ...) (setf (elfeed-meta entry :rating) 4) (elfeed-meta entry :rating) ;; => 4 (setf (elfeed-meta feed :title) "My Better Title") ``` -------------------------------- ### Entry Display - elfeed-show-entry Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Opens an elfeed entry in a dedicated buffer using `elfeed-show-mode`. The display function and switch behavior are customizable. This function is typically called from the search buffer via the RET key. ```APIDOC ## Entry Display — `elfeed-show-entry` Opens an elfeed entry in a dedicated buffer using `elfeed-show-mode`, rendered with Emacs' `shr` package (requires libxml2). The display function and switch behavior are customizable. ```emacs-lisp ;; Display an entry programmatically (normally called from search buffer via RET) (elfeed-show-entry entry) ;; Customize how the show buffer is opened (setq elfeed-show-entry-switch #'pop-to-buffer) ; open in another window (setq elfeed-show-entry-switch #'switch-to-buffer) ; default: same window ;; Allow multiple entry buffers simultaneously (setq elfeed-show-unique-buffers t) ;; Disable image loading if it causes slowdowns (setq shr-inhibit-images t) ;; Control display of author information (setq elfeed-show-entry-author t) ; default: show authors ;; Add a post-render hook to process entry display (add-hook 'elfeed-show-refresh-hook (lambda () (when (elfeed-tagged-p 'video elfeed-show-entry) (message "Tip: press 'b' to open in browser")))) ;; In show buffer key bindings: ;; n / p -- next/previous entry ;; b / B -- open in primary/secondary browser ;; y -- copy link URL to clipboard ;; + / - -- add/remove tags ;; m -- compose email about entry ;; d -- save enclosure ;; c -- copy link URL at point ``` ``` -------------------------------- ### Read and Write Entry Metadata with `elfeed-meta` Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Use `elfeed-meta` to access and modify persistent metadata on entries and feeds. Provide a default value when reading if the metadata is not set. Metadata is automatically persisted to the database. Use namespaced keys to prevent collisions with Elfeed's internal keys. ```emacs-lisp (require 'elfeed) ;; Read metadata (with optional default) (elfeed-meta entry :rating) (elfeed-meta entry :rating 0) ;; Write metadata (persisted to database on next save) (setf (elfeed-meta entry :rating) 4) (elfeed-meta entry :rating) ;; Use namespaced keys to avoid collision with Elfeed's own keys (setf (elfeed-meta entry :mypackage/processed) t) (setf (elfeed-meta feed :mypackage/custom-title) "My Better Title") ;; Override a feed's displayed title (setf (elfeed-meta (elfeed-db-get-feed "https://example.com/feed/") :title) "My Custom Feed Name") ``` -------------------------------- ### Configure Elfeed Feeds with Autotags Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Define feeds and their associated autotags directly in `elfeed-feeds`. Tags are applied to all new entries from the specified feed. Use `elfeed-apply-autotags-now` to apply tags to existing entries. ```emacs-lisp ;; Every entry from the blog feed gets tagged 'blog and 'emacs ;; Every entry from the comic feed gets tagged 'webcomic (setq elfeed-feeds '(("https://nullprogram.com/feed/" blog emacs) ("https://nedroid.com/feed/" webcomic) ("https://example.com/podcast.xml" podcast audio))) ;; Apply autotags to all already-existing entries in the database (elfeed-apply-autotags-now) ``` -------------------------------- ### Database Persistence Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Functions for explicitly managing the Elfeed database, including saving, loading, compacting, and setting the database directory. ```APIDOC ## Database Persistence — `elfeed-db-save` / `elfeed-db-load` / `elfeed-db-compact` Functions for explicitly managing database persistence. The database is auto-saved on quit, but can be managed manually. `elfeed-db-compact` packs the loose content files into a single compressed archive. ### Manual Save ```emacs-lisp ;; Manually save the database index to disk (elfeed-db-save) ``` ### Compact Database ```emacs-lisp ;; Compact the database (pack content + garbage collect unreferenced data) ;; Requires gzip in PATH. Good to run periodically or as kill-emacs-hook. (elfeed-db-compact) ;; Add compaction to Emacs shutdown hook (add-hook 'kill-emacs-hook #'elfeed-db-compact) ``` ### Unload and Reload Database ```emacs-lisp ;; Unload the database (for external manipulation), then reload (elfeed-db-unload) (elfeed-db-load) ; called automatically on next elfeed-db-ensure ``` ### Database Directory ```emacs-lisp ;; Change the database directory (set before first use) (setq elfeed-db-directory "~/Documents/elfeed-db/") ``` ### Query Last Update Time ```emacs-lisp ;; Query last update time (format-time-string "%Y-%m-%d %H:%M" (seconds-to-time (elfeed-db-last-update))) ;; => "2024-07-29 14:30" ``` ``` -------------------------------- ### Configure Elfeed Feeds Source: https://github.com/emacs-elfeed/elfeed/blob/main/README.org Define the list of feeds Elfeed should subscribe to. Add feed URLs to the `elfeed-feeds` variable in your Emacs configuration. ```emacs-lisp ;; Somewhere in your .emacs file (setq elfeed-feeds '("https://nullprogram.com/feed/" "https://planet.emacslife.com/atom.xml")) ``` -------------------------------- ### Traverse Elfeed Database Entries Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Iterate over database entries using `elfeed-db-visit`, ordered by date. Use `elfeed-db-return` to exit early. This is the primary low-level API for bulk entry processing. Functions like `elfeed-feed-entries` and `elfeed-db-size` provide access to feed-specific entries and database statistics. ```emacs-lisp ;; Collect all unread entry titles (let (titles) (elfeed-db-visit (entry) (when (elfeed-tagged-p 'unread entry) (push (elfeed-entry-title entry) titles))) titles) ``` ```emacs-lisp ;; Visit entries with feed access, stop at entries older than 30 days (let ((cutoff (- (float-time) (* 30 24 3600)))) (elfeed-db-visit (entry feed) (when (< (elfeed-entry-date entry) cutoff) (elfeed-db-return)) (message "%s: %s" (elfeed-feed-title feed) (elfeed-entry-title entry)))) ``` ```emacs-lisp ;; Strip content from old entries to save database space (defun my-elfeed-strip-old-content () (let ((limit (elfeed-float-time "60 days ago"))) (elfeed-db-visit (entry feed) (cond ((< (elfeed-entry-date entry) limit) (elfeed-db-return)) ; exit early, entries are sorted newest-first ((equal "https://www.youtube.com/feeds/videos.xml" (elfeed-feed-url feed)) (setf (elfeed-entry-content entry) nil)))))) ``` ```emacs-lisp ;; Get all entries for a specific feed (elfeed-feed-entries "https://nullprogram.com/feed/") ``` ```emacs-lisp ;; Get database size (number of entries) (elfeed-db-size) ``` -------------------------------- ### Configure Elfeed Feeds with Autotagging Source: https://github.com/emacs-elfeed/elfeed/blob/main/README.org Define a list of feeds, optionally including autotags for specific feeds. Autotags are applied to entries discovered in the specified feed. ```emacs-lisp (setq elfeed-feeds '(("https://nullprogram.com/feed/" blog emacs) "https://sachachua.com/blog/category/emacs-news/feed/" ;; no autotagging ("https://nedroid.com/feed/" webcomic))) ``` -------------------------------- ### Elfeed Hooks Reference Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Utilize Elfeed's hooks for extensibility at various lifecycle points. These hooks allow customization without needing to use Emacs' advice. ```emacs-lisp ;; Called for each new entry added to the database — primary extension point (add-hook 'elfeed-new-entry-hook (lambda (entry) (when (string-match-p "emacs" (or (elfeed-entry-title entry) "")) (elfeed-tag entry 'emacs)))) ``` ```emacs-lisp ;; Called after each new entry is parsed, with raw feed XML/JSON structure (add-hook 'elfeed-new-entry-parse-hook (lambda (type xml-or-json entry) ;; type is :atom, :rss, :rss1.0, or :json (when (eq type :atom) (message "Parsed atom entry: %s" (elfeed-entry-title entry))))) ``` ```emacs-lisp ;; Called on HTTP errors during feed fetching (add-hook 'elfeed-http-error-hooks (lambda (url status) (message "HTTP error %S fetching %s" status url))) ``` ```emacs-lisp ;; Called when feed XML/JSON parsing fails (add-hook 'elfeed-parse-error-hooks (lambda (url error) (message "Parse error for %s: %s" url error))) ``` ```emacs-lisp ;; Called any time the database has a major modification (add-hook 'elfeed-db-update-hook (lambda () (message "Elfeed DB updated at %s" (current-time-string)))) ``` ```emacs-lisp ;; Called when a feed update request completes (even with no new entries) (add-hook 'elfeed-update-hooks (lambda (url) (message "Finished updating: %s" url))) ``` ```emacs-lisp ;; Called when one or more feed updates have begun (add-hook 'elfeed-update-init-hooks (lambda () (message "Elfeed update started..."))) ``` -------------------------------- ### Feed-level Autotags Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Configure feeds with autotags directly in `elfeed-feeds`. Tags listed after a feed URL are applied to every new entry from that feed automatically. ```APIDOC ## Feed-level Autotags Tags listed after a feed URL in `elfeed-feeds` are applied to every new entry from that feed without needing a hook. ```emacs-lisp ;; Every entry from the blog feed gets tagged 'blog and 'emacs ;; Every entry from the comic feed gets tagged 'webcomic (setq elfeed-feeds '(("https://nullprogram.com/feed/" blog emacs) ("https://nedroid.com/feed/" webcomic) ("https://example.com/podcast.xml" podcast audio))) ;; Apply autotags to all already-existing entries in the database (elfeed-apply-autotags-now) ``` ``` -------------------------------- ### Customize Elfeed Entry Display Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Configure how Elfeed entries are displayed and rendered. Customize buffer switching, image loading, author information, and add post-render hooks. ```emacs-lisp ;; Display an entry programmatically (normally called from search buffer via RET) (elfeed-show-entry entry) ``` ```emacs-lisp ;; Customize how the show buffer is opened (setq elfeed-show-entry-switch #'pop-to-buffer) ; open in another window (setq elfeed-show-entry-switch #'switch-to-buffer) ; default: same window ``` ```emacs-lisp ;; Allow multiple entry buffers simultaneously (setq elfeed-show-unique-buffers t) ``` ```emacs-lisp ;; Disable image loading if it causes slowdowns (setq shr-inhibit-images t) ``` ```emacs-lisp ;; Control display of author information (setq elfeed-show-entry-author t) ; default: show authors ``` ```emacs-lisp ;; Add a post-render hook to process entry display (add-hook 'elfeed-show-refresh-hook (lambda () (when (elfeed-tagged-p 'video elfeed-show-entry) (message "Tip: press 'b' to open in browser")))) ``` ```emacs-lisp ;; In show buffer key bindings: ;; n / p -- next/previous entry ;; b / B -- open in primary/secondary browser ;; y -- copy link URL to clipboard ;; + / - -- add/remove tags ;; m -- compose email about entry ;; d -- save enclosure ;; c -- copy link URL at point ``` -------------------------------- ### Automatically Tag YouTube Entries Source: https://github.com/emacs-elfeed/elfeed/blob/main/README.org Use elfeed-new-entry-hook to automatically add 'video' and 'youtube' tags to entries from feeds containing 'youtube.com' in their URL. ```emacs-lisp (add-hook 'elfeed-new-entry-hook (elfeed-make-tagger :feed-url "youtube\\.com" :add '(video youtube))) ``` -------------------------------- ### Search Filter Syntax Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Utilize the powerful filter language in the Elfeed search buffer for `elfeed-search-set-filter` and `elfeed-search-live-filter`. Filters are space-separated tokens with specific syntax for tags, age, count limits, and feed matching. ```APIDOC ## Search Filter Syntax — `elfeed-search-set-filter` / `elfeed-search-live-filter` The search buffer supports a powerful filter language. Filters are space-separated tokens. Tags use `+` (required) or `-` (excluded). Age uses `@`. Count limits use `#`. Feed matchers use `=` (include) or `~` (exclude). All other tokens are regular expressions matched against title and link. ```emacs-lisp ;; Set a permanent default filter (shows last 6 months, unread only) (setq-default elfeed-search-filter "@6months +unread") ;; Programmatically set the filter from Elisp (elfeed-search-set-filter "+unread @1week") ;; Filter examples (use 's' key or M-x elfeed-search-set-filter): ;; ;; "@6months +unread" -- unread entries from last 6 months (default) ;; "linu[xs] @1year" -- Linux/Linus entries from past year ;; "-unread +youtube #10" -- 10 most recent read youtube entries ;; "+unread !x?emacs" -- unread, title/link doesn't match xemacs/emacs ;; "+emacs =https://example.org" -- emacs-tagged entries from one specific feed ;; "@2019-06-20--2019-06-24" -- entries in a specific date range ;; "@5days--1day" -- entries between 5 and 1 days ago ;; "#20" -- limit display to 20 entries ;; "~reddit\.com" -- exclude all reddit feeds ;; Parse a filter string into a structured plist (elfeed-search-parse-filter "@6months +unread") ;; => (:after 15897600.0 :must-have (unread)) ;; Reset to default filter (bound to 'c' in search buffer) (elfeed-search-clear-filter) ``` ``` -------------------------------- ### Save and Restore Elfeed Search Filters with Bookmarks Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Integrate Elfeed with Emacs' bookmark system to save and restore search filters. Use `M-x bookmark-set` in the search buffer to save the current filter. ```emacs-lisp ;; Example bookmark record created by elfeed: '("elfeed @6months +unread" (location . "@6months +unread") (tags . "unread") (handler . elfeed-search-bookmark-handler)) ``` ```emacs-lisp ;; Restore a saved search filter bookmark (elfeed-search-bookmark-handler '("elfeed +emacs" (location . "+emacs") (handler . elfeed-search-bookmark-handler))) ``` ```emacs-lisp ;; Bookmarks also work on individual entries in elfeed-show-mode ;; M-x bookmark-set in *elfeed-entry* buffer saves the entry + position ``` -------------------------------- ### Create Automatic Taggers Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Use `elfeed-make-tagger` to create functions for `elfeed-new-entry-hook` to apply or remove tags based on criteria like feed URL, entry title, or time bounds. ```emacs-lisp ;; Tag all YouTube entries with 'video and 'youtube (add-hook 'elfeed-new-entry-hook (elfeed-make-tagger :feed-url "youtube\.com" :add '(video youtube))) ;; Mark entries older than 2 weeks as read automatically (add-hook 'elfeed-new-entry-hook (elfeed-make-tagger :before "2 weeks ago" :remove 'unread)) ;; Junk uninteresting entries from a specific domain (add-hook 'elfeed-new-entry-hook (elfeed-make-tagger :feed-url "example\.com" :entry-title '(not "something interesting") :add 'junk :remove 'unread)) ;; Tag entries about Emacs from the last year (add-hook 'elfeed-new-entry-hook (elfeed-make-tagger :entry-title "emacs" :after "1 year ago" :add 'emacs)) ;; Apply elfeed-new-entry-hook retroactively to all existing entries (elfeed-apply-hooks-now) ``` -------------------------------- ### Elfeed Database Queries Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Access Elfeed's database directly using low-level functions to retrieve feed and entry information by their IDs. This is useful for advanced data manipulation. ```emacs-lisp ;; Get a feed struct by URL (creates it if not present) (let ((feed (elfeed-db-get-feed "https://nullprogram.com/feed/"))) (elfeed-feed-url feed) ; => "https://nullprogram.com/feed/" (elfeed-feed-title feed) ; => "null program" (after an update) (elfeed-meta feed :failures)) ; => 0 ``` ```emacs-lisp ;; Get an entry by its (namespace . id) cons cell ;; Entry IDs are (namespace . guid-or-link) pairs (let* ((entry (elfeed-db-get-entry '("nullprogram.com" . "https://nullprogram.com/blog/2024/"))) (when entry (elfeed-entry-title entry) ; => "Post Title" (elfeed-entry-link entry) ; => "https://nullprogram.com/blog/2024/" (elfeed-entry-date entry) ; => float epoch seconds (elfeed-entry-tags entry) ; => (unread blog emacs) (elfeed-entry-content-type entry); => html or nil (elfeed-deref (elfeed-entry-content entry)))) ; => HTML string ``` ```emacs-lisp ;; Get all tags present anywhere in the database (elfeed-db-get-all-tags) ;; => (blog emacs unread video webcomic youtube) ``` -------------------------------- ### Update Elfeed Feeds Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Functions to update feeds. `elfeed-update` fetches all feeds concurrently, while `elfeed-update-feed` updates a single feed. Both are asynchronous. Settings for concurrency and timeouts can be adjusted. ```emacs-lisp ;; Update all feeds (bound to "G" in search buffer) (elfeed-update) ;; Update a single specific feed (elfeed-update-feed "https://nullprogram.com/feed/") ;; Control concurrency and timeout (elfeed-set-max-connections 8) ; default is 16 (elfeed-set-timeout 60) ; seconds, default 30 ;; Query current settings (elfeed-get-max-connections) ; => 8 (elfeed-get-timeout) ; => 60 ;; Recover from a jammed connection pool (elfeed-unjam) ;; Add a new feed interactively and immediately fetch it (elfeed-add-feed "https://example.com/feed.xml" :save t) ;; Delete a feed and all its entries from the database (elfeed-delete-feed "https://example.com/feed.xml") ``` -------------------------------- ### Hooks Reference Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Elfeed exposes hooks at various lifecycle points for extensibility. These hooks allow users to add custom logic without modifying Elfeed's core code. ```APIDOC ## Hooks Reference Elfeed exposes hooks at all key lifecycle points for extensibility without needing advice. ```emacs-lisp ;; Called for each new entry added to the database — primary extension point (add-hook 'elfeed-new-entry-hook (lambda (entry) (when (string-match-p "emacs" (or (elfeed-entry-title entry) "")) (elfeed-tag entry 'emacs)))) ;; Called after each new entry is parsed, with raw feed XML/JSON structure (add-hook 'elfeed-new-entry-parse-hook (lambda (type xml-or-json entry) ;; type is :atom, :rss, :rss1.0, or :json (when (eq type :atom) (message "Parsed atom entry: %s" (elfeed-entry-title entry))))) ;; Called on HTTP errors during feed fetching (add-hook 'elfeed-http-error-hooks (lambda (url status) (message "HTTP error %S fetching %s" status url))) ;; Called when feed XML/JSON parsing fails (add-hook 'elfeed-parse-error-hooks (lambda (url error) (message "Parse error for %s: %s" url error))) ;; Called any time the database has a major modification (add-hook 'elfeed-db-update-hook (lambda () (message "Elfeed DB updated at %s" (current-time-string)))) ;; Called when a feed update request completes (even with no new entries) (add-hook 'elfeed-update-hooks (lambda (url) (message "Finished updating: %s" url))) ;; Called when one or more feed updates have begun (add-hook 'elfeed-update-init-hooks (lambda () (message "Elfeed update started..."))) ``` ``` -------------------------------- ### Global Keybinding for Elfeed Source: https://github.com/emacs-elfeed/elfeed/blob/main/README.org Set a global keybinding for the Elfeed function. This allows quick access to the feed reader from anywhere in Emacs. ```emacs-lisp (keymap-global-set "C-x w" #'elfeed) ``` -------------------------------- ### Custom Tag Faces Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Configure how tags are displayed in the search buffer by mapping tags to Emacs faces, allowing for visual highlighting of entries. ```APIDOC ## Custom Tag Faces — `elfeed-search-face-alist` Map tags to Emacs faces to visually highlight entries in the search buffer. The `unread` tag is pre-mapped to `elfeed-search-unread-title-face` (bold). All matching faces are applied cumulatively in order. ### Defining and Registering Faces ```emacs-lisp ;; Define a face for important entries (defface my-elfeed-important-face '((t :foreground "#f77" :weight bold)) "Face for important Elfeed entries.") ;; Define a face for video entries (defface my-elfeed-video-face '((t :foreground "#7af")) "Face for video Elfeed entries.") ;; Register the faces (prepend to take priority) (push '(important my-elfeed-important-face) elfeed-search-face-alist) (push '(video my-elfeed-video-face) elfeed-search-face-alist) ;; The default alist (unread entries appear bold) ;; elfeed-search-face-alist => '((unread elfeed-search-unread-title-face)) ``` ``` -------------------------------- ### Database Queries - elfeed-db-get-entry / elfeed-db-get-feed Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Low-level database accessor functions for looking up individual entries and feeds by their IDs. These functions provide direct access to the Elfeed database. ```APIDOC ## Database Queries — `elfeed-db-get-entry` / `elfeed-db-get-feed` Low-level database accessor functions for looking up individual entries and feeds by their IDs. ```emacs-lisp ;; Get a feed struct by URL (creates it if not present) (let ((feed (elfeed-db-get-feed "https://nullprogram.com/feed/"))) (elfeed-feed-url feed) ; => "https://nullprogram.com/feed/" (elfeed-feed-title feed) ; => "null program" (after an update) (elfeed-meta feed :failures)) ; => 0 ;; Get an entry by its (namespace . id) cons cell ;; Entry IDs are (namespace . guid-or-link) pairs (let* ((entry (elfeed-db-get-entry '("nullprogram.com" . "https://nullprogram.com/blog/2024/"))) (when entry (elfeed-entry-title entry) ; => "Post Title" (elfeed-entry-link entry) ; => "https://nullprogram.com/blog/2024/" (elfeed-entry-date entry) ; => float epoch seconds (elfeed-entry-tags entry) ; => (unread blog emacs) (elfeed-entry-content-type entry); => html or nil (elfeed-deref (elfeed-entry-content entry)))) ; => HTML string ;; Get all tags present anywhere in the database (elfeed-db-get-all-tags) ;; => (blog emacs unread video webcomic youtube) ``` ``` -------------------------------- ### Available Elfeed Capture Keywords Source: https://context7.com/emacs-elfeed/elfeed/llms.txt List of keywords available for use in Org-capture templates when capturing Elfeed entries. These keywords map to specific metadata fields of an Elfeed entry. ```emacs-lisp ;; Available capture keywords from elfeed-show buffer: ;; %:title -- entry title ;; %:external-link -- entry's original article URL ;; %:date -- publication date in ISO 8601 ;; %:date-timestamp -- Org active timestamp [2024-07-29 Mon 12:00] ;; %:authors -- comma-separated author names ;; %:tags -- Org tag format :blog:emacs: ;; %:content -- entry content (HTML entries wrapped in #+begin_export html) ;; %:feed-title -- name of the feed ``` -------------------------------- ### Elfeed Search Filter Syntax and Usage Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Utilize Elfeed's filter language for searching entries. Filters support tags, age, count limits, feed matching, and regular expressions. Use `elfeed-search-set-filter` to apply filters programmatically or interactively. ```emacs-lisp ;; Set a permanent default filter (shows last 6 months, unread only) (setq-default elfeed-search-filter "@6months +unread") ``` ```emacs-lisp ;; Programmatically set the filter from Elisp (elfeed-search-set-filter "+unread @1week") ``` ```emacs-lisp ;; Filter examples (use 's' key or M-x elfeed-search-set-filter): ;; ;; "@6months +unread" -- unread entries from last 6 months (default) ;; "linu[xs] @1year" -- Linux/Linus entries from past year ;; "-unread +youtube #10" -- 10 most recent read youtube entries ;; "+unread !x?emacs" -- unread, title/link doesn't match xemacs/emacs ;; "+emacs =https://example.org" -- emacs-tagged entries from one specific feed ;; "@2019-06-20--2019-06-24" -- entries in a specific date range ;; "@5days--1day" -- entries between 5 and 1 days ago ;; "#20" -- limit display to 20 entries ;; "~reddit\.com" -- exclude all reddit feeds ``` ```emacs-lisp ;; Parse a filter string into a structured plist (elfeed-search-parse-filter "@6months +unread") ;; => (:after 15897600.0 :must-have (unread)) ``` ```emacs-lisp ;; Reset to default filter (bound to 'c' in search buffer) (elfeed-search-clear-filter) ``` -------------------------------- ### OPML Import/Export Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Functions to import feed lists from OPML files and export the current feed list to an OPML file, facilitating portability between feed readers. ```APIDOC ## OPML Import/Export — `elfeed-load-opml` / `elfeed-export-opml` Load feed lists from OPML files (e.g., exported from other feed readers) or export the current feed list to OPML for portability. ### Load OPML ```emacs-lisp ;; Load feeds from an OPML file (interactive: also saves to customization file) (elfeed-load-opml "~/subscriptions.opml") ``` ### Export OPML ```emacs-lisp ;; Export current elfeed-feeds to an OPML file (elfeed-export-opml "~/elfeed-export.opml") ;; The resulting OPML file looks like: ;; ;; ;; Elfeed Export ;; ;; ;; ... ;; ;; ``` ``` -------------------------------- ### Customize Elfeed Search Faces with Tags Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Map custom tags to Emacs faces using `elfeed-search-face-alist` to visually highlight entries in the search buffer. Define new faces with `defface` and prepend them to the `elfeed-search-face-alist` to ensure they take priority. The `unread` tag is pre-mapped to `elfeed-search-unread-title-face`. ```emacs-lisp ;; Define a face for important entries (defface my-elfeed-important-face '((t :foreground "#f77" :weight bold)) "Face for important Elfeed entries.") ;; Define a face for video entries (defface my-elfeed-video-face '((t :foreground "#7af")) "Face for video Elfeed entries.") ;; Register the faces (prepend to take priority) (push '(important my-elfeed-important-face) elfeed-search-face-alist) (push '(video my-elfeed-video-face) elfeed-search-face-alist) ;; The default alist (unread entries appear bold) ;; elfeed-search-face-alist => '((unread elfeed-search-unread-title-face)) ``` -------------------------------- ### Manage Elfeed Entry Tags Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Use `elfeed-tag`, `elfeed-untag`, and `elfeed-tagged-p` to add, remove, and check tags on entries or feeds. These functions trigger `elfeed-tag-hooks` and `elfeed-untag-hooks` respectively. Tagging can be done on single entries, lists of entries, or interactively in the search buffer. ```emacs-lisp ;; Assuming `entry' is an elfeed-entry struct (e.g. from elfeed-db-visit) (elfeed-tag entry 'read 'important) ; add multiple tags at once (elfeed-untag entry 'unread) ; remove 'unread tag (elfeed-tagged-p 'unread entry) ; => nil (was just removed) (elfeed-tagged-p 'important entry) ; => t ``` ```emacs-lisp ;; Tag/untag a list of entries at once (let ((entries (list entry1 entry2 entry3))) (elfeed-tag entries 'archived) (elfeed-untag entries 'unread)) ``` ```emacs-lisp ;; In the search buffer: tag/untag selected entries interactively ;; "+" prompts for tag to add, "-" to remove ;; "r" marks selected as read (removes 'unread), "u" marks as unread ``` -------------------------------- ### Set Elfeed Fetch Timeout Source: https://github.com/emacs-elfeed/elfeed/blob/main/README.org Adjust the queue timeout for fetching feed updates. Increase this value if you encounter 'Queue timeout exceeded' errors. ```emacs-lisp (setf url-queue-timeout 30) ``` -------------------------------- ### Tagging Entries Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Core functions `elfeed-tag`, `elfeed-untag`, and `elfeed-tagged-p` to add, remove, and query tags on entry or feed objects. These functions also trigger `elfeed-tag-hooks` and `elfeed-untag-hooks` respectively. ```APIDOC ## Tagging Entries — `elfeed-tag` / `elfeed-untag` / `elfeed-tagged-p` Core functions to add, remove, and query tags on entry or feed objects. These fire `elfeed-tag-hooks` / `elfeed-untag-hooks` respectively. ```emacs-lisp ;; Assuming `entry' is an elfeed-entry struct (e.g. from elfeed-db-visit) (elfeed-tag entry 'read 'important) ; add multiple tags at once (elfeed-untag entry 'unread) ; remove 'unread tag (elfeed-tagged-p 'unread entry) ; => nil (was just removed) (elfeed-tagged-p 'important entry) ; => t ;; Tag/untag a list of entries at once (let ((entries (list entry1 entry2 entry3))) (elfeed-tag entries 'archived) (elfeed-untag entries 'unread)) ;; In the search buffer: tag/untag selected entries interactively ;; "+" prompts for tag to add, "-" to remove ;; "r" marks selected as read (removes 'unread), "u" marks as unread ``` ``` -------------------------------- ### Convert Time Representations with Elfeed Utilities Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Use `elfeed-float-time` to convert various date/time formats to epoch seconds and `elfeed-time-duration` to convert relative expressions into seconds. These are useful for custom filtering. ```emacs-lisp ;; Convert various time representations to float epoch seconds (elfeed-float-time "2024-07-29") ; => float epoch for that date (elfeed-float-time "Mon, 29 Jul 2024 12:00:00 GMT") ; RFC 2822 (elfeed-float-time 1722211200) ; already a number, returned as-is ``` ```emacs-lisp ;; Convert a relative time expression to a number of seconds (duration) (elfeed-time-duration "2 weeks ago") ; => 1209600.0 (elfeed-time-duration "6months") ; => 15897600.0 (elfeed-time-duration "1-year-old") ; => 31536000.0 (elfeed-time-duration "2019-06-24") ; duration from epoch to that date ``` ```emacs-lisp ;; Use in custom filtering: find entries from the past week (let ((cutoff (- (float-time) (elfeed-time-duration "1 week ago")))) (elfeed-db-visit (entry) (when (> (elfeed-entry-date entry) cutoff) (message "%s" (elfeed-entry-title entry))))) ``` -------------------------------- ### Mark Old Entries as Read Source: https://github.com/emacs-elfeed/elfeed/blob/main/README.org Configure elfeed-new-entry-hook to remove the 'unread' tag from entries older than two weeks, preventing them from being marked as unread. ```emacs-lisp (add-hook 'elfeed-new-entry-hook (elfeed-make-tagger :before "2 weeks ago" :remove 'unread)) ``` -------------------------------- ### Set Default Search Filter in Elfeed Source: https://github.com/emacs-elfeed/elfeed/blob/main/README.org Configure the default search filter for Elfeed. This setting is buffer-local and can be adjusted for easier quick searching. ```emacs-lisp (setq-default elfeed-search-filter "@1week +unread ") ``` -------------------------------- ### Entry Metadata Source: https://context7.com/emacs-elfeed/elfeed/llms.txt Access and modify persistent metadata associated with Elfeed entries and feeds. This allows for storing arbitrary Elisp data, which is automatically persisted to the database. ```APIDOC ## Entry Metadata — `elfeed-meta` A generalized accessor (setf-able) for reading and writing arbitrary persistent metadata on entry and feed structs. Values must be readable (printable) Elisp data. Metadata is stored in the database automatically. ### Reading Metadata ```emacs-lisp ;; Read metadata (with optional default) (elfeed-meta entry :rating) ; => nil if not set (elfeed-meta entry :rating 0) ; => 0 as default ``` ### Writing Metadata ```emacs-lisp ;; Write metadata (persisted to database on next save) (setf (elfeed-meta entry :rating) 4) (setf (elfeed-meta entry :rating) 4) (elfeed-meta entry :rating) ; => 4 ``` ### Namespaced Keys ```emacs-lisp ;; Use namespaced keys to avoid collision with Elfeed's own keys (setf (elfeed-meta entry :mypackage/processed) t) (setf (elfeed-meta feed :mypackage/custom-title) "My Better Title") ``` ### Built-in Metadata Keys - `:authors` -- list of author plists (:name :uri :email) - `:canonical-url` -- final URL after redirects - `:categories` -- feed-supplied categories for the entry - `:etag` -- HTTP ETag for conditional GETs - `:failures` -- count of failed updates for a feed - `:last-modified` -- HTTP Last-Modified header - `:title` -- overrides the feed-supplied display title ### Overriding Feed Title ```emacs-lisp ;; Override a feed's displayed title (setf (elfeed-meta (elfeed-db-get-feed "https://example.com/feed/") :title) "My Custom Feed Name") ``` ```