dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

README.md (16443B)


      1 # Elfeed Emacs Web Feed Reader
      2 
      3 Elfeed is an extensible web feed reader for Emacs, supporting both
      4 Atom and RSS. It requires Emacs 24.3 and is available for download
      5 from [MELPA](http://melpa.milkbox.net/) or
      6 [el-get](https://github.com/dimitri/el-get). Elfeed was inspired by
      7 [notmuch](http://notmuchmail.org/).
      8 
      9 For a longer overview,
     10 
     11  * [Introducing Elfeed, an Emacs Web Feed Reader](http://nullprogram.com/blog/2013/09/04/).
     12  * [Tips and Tricks](http://nullprogram.com/blog/2013/11/26/)
     13  * [Read your RSS feeds in Emacs with Elfeed
     14 ](http://pragmaticemacs.com/emacs/read-your-rss-feeds-in-emacs-with-elfeed/)
     15  * [Scoring Elfeed articles](http://kitchingroup.cheme.cmu.edu/blog/2017/01/05/Scoring-elfeed-articles/)
     16  * [Using Emacs 29](https://www.youtube.com/watch?v=pOFqzK1Ymr4),
     17    [30](https://www.youtube.com/watch?v=tjnK1rkO7RU),
     18    [31](https://www.youtube.com/watch?v=5zuSUbAHH8c)
     19  * [Take Elfeed everywhere: Mobile rss reading Emacs-style (for free/cheap)](http://babbagefiles.blogspot.com/2017/03/take-elfeed-everywhere-mobile-rss.html)
     20  * [Elfeed Rules!](https://noonker.github.io/posts/2020-04-22-elfeed/) ([reddit](https://old.reddit.com/r/emacs/comments/g6oowz/elfeed_rules/))
     21  * [Elfeed with Tiny Tiny RSS](https://codingquark.com/emacs/2020/04/19/elfeed-protocol-ttrss.html) ([hn](https://news.ycombinator.com/item?id=22915200))
     22  * [Open Emacs elfeed links in the background](http://xenodium.com/open-emacs-elfeed-links-in-background/)
     23  * [Using Emacs 72](https://cestlaz.github.io/post/using-emacs-72-customizing-elfeed/)
     24  * [Lazy Elfeed](https://karthinks.com/blog/lazy-elfeed/)
     25  * [Using Elfeed to View Videos](https://joshrollinswrites.com/help-desk-head-desk/20200611/)
     26  * [Manage podcasts in Emacs with Elfeed and Bongo](https://protesilaos.com/codelog/2020-09-11-emacs-elfeed-bongo/)
     27  * [... more ...](http://nullprogram.com/tags/elfeed/)
     28  * [... and more ...](http://pragmaticemacs.com/category/elfeed/)
     29 
     30 [![](http://i.imgur.com/kxgF5AH.png)](http://i.imgur.com/kxgF5AH.png)
     31 
     32 The database format is stable and is never expected to change.
     33 
     34 ## Prerequisites
     35 
     36 **It is *strongly* recommended you have cURL installed**, either in
     37 your PATH or configured via `elfeed-curl-program-name`. Elfeed will
     38 prefer it to Emacs' own URL-fetching mechanism, `url-retrieve`. It's
     39 also essential for running Elfeed on Windows, where `url-retrieve` is
     40 broken. Updates using cURL are significantly faster than the built-in
     41 method, both for you and the feed hosts.
     42 
     43 If this is giving you problems, fetching with cURL can be disabled by
     44 setting `elfeed-use-curl` to nil.
     45 
     46 ## Extensions
     47 
     48 These projects extend Elfeed with additional features:
     49 
     50 * [elfeed-org](https://github.com/remyhonig/elfeed-org)
     51 * [elfeed-goodies](https://github.com/algernon/elfeed-goodies)
     52 * [elfeed-protocol](https://github.com/fasheng/elfeed-protocol)
     53 * [elfeed-score](https://github.com/sp1ff/elfeed-score)
     54 * [Elfeed Android interface](https://github.com/areina/elfeed-cljsrn)
     55   ([Google Play](https://play.google.com/store/apps/details?id=com.elfeedcljsrn))
     56 * [elfeed-dashboard](https://github.com/Manoj321/elfeed-dashboard)
     57 
     58 ## Getting Started
     59 
     60 Elfeed is broken into a multiple source files, so if you manually
     61 install it you will need to add the Elfeed package directory to your
     62 `load-path`. If installed via package.el or el-get, this will be done
     63 automatically.
     64 
     65 It is recommended that you make a global binding for `elfeed`.
     66 
     67 ```el
     68 (global-set-key (kbd "C-x w") 'elfeed)
     69 ```
     70 
     71 Running the interactive function `elfeed` will pop up the
     72 `*elfeed-search*` buffer, which will display feed items.
     73 
     74  * <kbd>g</kbd>: refresh view of the feed listing
     75  * <kbd>G</kbd>: fetch feed updates from the servers
     76  * <kbd>s</kbd>: update the search filter (see tags)
     77  * <kbd>c</kbd>: clear the search filter
     78 
     79 This buffer will be empty until you add your feeds to the
     80 `elfeed-feeds` list and initiate an update with `M-x elfeed-update`
     81 (or <kbd>G</kbd> in the Elfeed buffer). This will populate the Elfeed
     82 database with entries.
     83 
     84 ```el
     85 ;; Somewhere in your .emacs file
     86 (setq elfeed-feeds
     87       '("http://nullprogram.com/feed/"
     88         "http://planet.emacsen.org/atom.xml"))
     89 ```
     90 
     91 Another option for providing a feed list is with an OPML file. Running
     92 `M-x elfeed-load-opml` will fill `elfeed-feeds` with feeds listed in
     93 an OPML file. When `elfeed-load-opml` is called interactively, it will
     94 automatically save the feedlist to your customization file, so you
     95 will only need to do this once.
     96 
     97 If there are a lot of feeds, the initial update will take noticeably
     98 longer than normal operation because of the large amount of
     99 information being written the database. Future updates will only need
    100 to write new or changed data. If updating feeds slows down Emacs too
    101 much for you, reduce the number of concurrent fetches via
    102 `elfeed-set-max-connections`.
    103 
    104 If you're getting many "Queue timeout exceeded" errors, increase the
    105 fetch timeout via `elfeed-set-timeout`.
    106 
    107 ~~~el
    108 (setf url-queue-timeout 30)
    109 ~~~
    110 
    111 From the search buffer there are a number of ways to interact with
    112 entries. Entries are selected by placing the point over an entry.
    113 Multiple entries are selected at once by using an active region.
    114 
    115  * <kbd>RET</kbd>: view selected entry in a buffer
    116  * <kbd>b</kbd>: open selected entries in your browser (`browse-url`)
    117  * <kbd>y</kbd>: copy selected entries URL to the clipboard
    118  * <kbd>r</kbd>: mark selected entries as read
    119  * <kbd>u</kbd>: mark selected entries as unread
    120  * <kbd>+</kbd>: add a specific tag to selected entries
    121  * <kbd>-</kbd>: remove a specific tag from selected entries
    122 
    123 ## Tags
    124 
    125 Elfeed maintains a list of arbitrary tags -- symbols attached to an
    126 entry. The tag `unread` is treated specially by default, with unread
    127 entries appearing in bold.
    128 
    129 ### Autotagging
    130 
    131 Tags can automatically be applied to entries discovered in specific
    132 feeds through extra syntax in `elfeed-feeds`. Normally this is a list
    133 of strings, but an item can also be a list, providing set of
    134 "autotags" for a feed's entries.
    135 
    136 ```el
    137 (setq elfeed-feeds
    138       '(("http://nullprogram.com/feed/" blog emacs)
    139         "http://www.50ply.com/atom.xml"  ; no autotagging
    140         ("http://nedroid.com/feed/" webcomic)))
    141 ```
    142 
    143 ### Filter Syntax
    144 
    145 To make tags useful, the Elfeed entry listing buffer can be filtered
    146 by tags. Use `elfeed-search-set-filter` (or <kbd>s</kbd>) to update
    147 the filter. Use `elfeed-search-clear-filter` to restore the default.
    148 
    149 Any component of the search string beginning with a `+` or
    150 a `-` is treated like a tag. `+` means the tag is required, `-` means
    151 the tag must not be present.
    152 
    153 A component beginning with a `@` indicates an age or a date range. An
    154 age is a relative time expression or an absolute date expression.
    155 Entries older than this age are filtered out. The age description
    156 accepts plain English, but cannot have spaces, so use dashes. For
    157 example, `"@2-years-old"`, `"@3-days-ago"` or `"@2019-06-24"`. A date
    158 range are two ages seperated by a `--`, e.g.
    159 `"@2019-06-20--2019-06-24"` or `"@5-days-ago--1-day-ago"`. The entry
    160 must be newer than the first expression but older than the second. The
    161 database is date-oriented, so **filters that include an age
    162 restriction are significantly more efficient.**
    163 
    164 A component beginning with a `!` is treated as an "inverse" regular
    165 expression. This means that any entry matching this regular expression
    166 will be filtered out. The regular expression begins *after* the `!`
    167 character. You can read this as "entry not matching `foo`".
    168 
    169 A component beginning with a `#` limits the total number of entries
    170 displayed to the number immediately following the symbol. For example,
    171 to limit the display to 20 entries: `#20`.
    172 
    173 A component beginning with a `=` is a regular expression matching the
    174 entry's feed (title or URL). Only entries belonging to a feed that
    175 matches at least one of the `=` expressions will be shown.
    176 
    177 A component beginning with a `~` is a regular expression matching the
    178 entry's feed (title or URL). Only entries belonging to a feed that
    179 matches none of the `~` expressions will be shown.
    180 
    181 All other components are treated as a regular expression, and only
    182 entries matching it (title or URL) will be shown.
    183 
    184 Here are some example filters.
    185 
    186  * `@6-months-ago +unread`
    187 
    188 Only show unread entries of the last six months. This is the default filter.
    189 
    190  * `linu[xs] @1-year-old`
    191 
    192 Only show entries about Linux or Linus from the last year.
    193 
    194  * `-unread +youtube #10`
    195 
    196 Only show the most recent 10 previously-read entries tagged as
    197 `youtube`.
    198 
    199  * `+unread !x?emacs`
    200 
    201 Only show unread entries not having `emacs` or `xemacs` in the title
    202 or link.
    203 
    204 * `+emacs =http://example.org/feed/`
    205 
    206 Only show entries tagged as `emacs` from a specific feed.
    207 
    208 #### Default Search Filter
    209 
    210 You can set your default search filter by changing the default value
    211 of `elfeed-search-filter`. It only changes buffer-locally when you're
    212 adjusting the filter within Elfeed. For example, some users prefer to
    213 have a space on the end for easier quick searching.
    214 
    215     (setq-default elfeed-search-filter "@1-week-ago +unread ")
    216 
    217 ### Tag Hooks
    218 
    219 The last example assumes you've tagged posts with `youtube`. You
    220 probably want to do this sort of thing automatically, either through
    221 the "autotags" feature mentioned above, or with the
    222 `elfeed-new-entry-hook`. Functions in this hook are called with new
    223 entries, allowing them to be manipulated, such as adding tags.
    224 
    225 ```el
    226 ;; Mark all YouTube entries
    227 (add-hook 'elfeed-new-entry-hook
    228           (elfeed-make-tagger :feed-url "youtube\\.com"
    229                               :add '(video youtube)))
    230 ```
    231 
    232 Avoiding tagging old entries as `unread`:
    233 
    234 ```el
    235 ;; Entries older than 2 weeks are marked as read
    236 (add-hook 'elfeed-new-entry-hook
    237           (elfeed-make-tagger :before "2 weeks ago"
    238                               :remove 'unread))
    239 ```
    240 
    241 Or building your own subset feeds:
    242 
    243 ```el
    244 (add-hook 'elfeed-new-entry-hook
    245           (elfeed-make-tagger :feed-url "example\\.com"
    246                               :entry-title '(not "something interesting")
    247                               :add 'junk
    248                               :remove 'unread))
    249 ```
    250 
    251 Use `M-x elfeed-apply-hooks-now` to apply `elfeed-new-entry-hook` to
    252 all existing entries. Otherwise hooks will only apply to new entries
    253 on discovery.
    254 
    255 ### Custom Tag Faces
    256 
    257 By default, entries marked `unread` will have bolded titles in the
    258 `*elfeed-search*` listing. You can customize how tags affect an
    259 entry's appearance by customizing `elfeed-search-face-alist`. For
    260 example, this configuration makes entries tagged `important` stand out
    261 in red.
    262 
    263 ~~~el
    264 (defface important-elfeed-entry
    265   '((t :foreground "#f77"))
    266   "Marks an important Elfeed entry.")
    267 
    268 (push '(important important-elfeed-entry)
    269       elfeed-search-face-alist)
    270 ~~~
    271 
    272 All faces from all tags will be applied to the entry title. The faces
    273 will be ordered as they appear in `elfeed-search-face-alist`.
    274 
    275 ## Bookmarks
    276 
    277 Filters can be saved and restored using Emacs' built-in [bookmarks
    278 feature][bm]. While in the search buffer, use `M-x bookmark-set` to
    279 save the current filter, and `M-x bookmark-jump` to restore a saved
    280 filter. Emacs automatically persists bookmarks across sessions.
    281 
    282 [bm]: https://www.gnu.org/software/emacs/manual/html_node/emacs/Bookmarks.html
    283 
    284 ## Metadata Plist
    285 
    286 All feed and entry objects have plist where you can store your own
    287 arbitrary, [readable values][rd]. These values are automatically
    288 persisted in the database. This metadata is accessed using the
    289 polymorphic `elfeed-meta` function. It's setf-able.
    290 
    291 ~~~el
    292 (setf (elfeed-meta entry :rating) 4)
    293 (elfeed-meta entry :rating)
    294 ;; => 4
    295 
    296 (setf (elfeed-meta feed :title) "My Better Title")
    297 ~~~
    298 
    299 Elfeed itself adds some entries to this plist, some for your use, some
    300 for its own use. Here are the properties that Elfeed uses:
    301 
    302 * `:authors` : A list of author plists (`:name`, `:uri`, `:email`).
    303 * `:canonical-url` : The final URL for the feed after all redirects.
    304 * `:categories` : The feed-supplied categories for this entry.
    305 * `:etag` : HTTP Etag header, for conditional GETs.
    306 * `:failures` : Number of times this feed has failed to update.
    307 * `:last-modified` : HTTP Last-Modified header, for conditional GETs.
    308 * `:title` : Overrides the feed-supplied title for display purposes,
    309   both for feeds and entries. See also `elfeed-search-set-feed-title`
    310   and `elfeed-search-set-entry-title`.
    311 
    312 This list will grow in time, so you might consider namespacing your
    313 own properties to avoid collisions (e.g. `:xyz/rating`), or simply not
    314 using keywords as keys. Elfeed will always use keywords without a
    315 slash.
    316 
    317 [rd]: http://nullprogram.com/blog/2013/12/30/
    318 
    319 ## Hooks
    320 
    321 A number of hooks are available to customize the behavior of Elfeed at
    322 key points without resorting to advice.
    323 
    324 * `elfeed-new-entry-hook` : Called each time a new entry it added to
    325   the database, allowing for automating tagging and such.
    326 * `elfeed-new-entry-parse-hook` : Called with each new entry and the
    327   full XML structure from which it was parsed, allowing for additional
    328   information to be drawn from the original feed XML.
    329 * `elfeed-http-error-hooks` : Allows for special behavior when HTTP
    330   errors occur, beyond simply logging the error to `*elfeed-log*` .
    331 * `elfeed-parse-error-hooks` : Allows for special behavior when feed
    332   parsing fails, beyond logging.
    333 * `elfeed-db-update-hook` : Called any time the database has had a
    334   major modification.
    335 
    336 ## Viewing Entries
    337 
    338 Entries are viewed locally in Emacs by typing `RET` while over an
    339 entry in the search listing. The content will be displayed in a
    340 separate buffer using `elfeed-show-mode`, rendered using Emacs'
    341 built-in shr package. This requires an Emacs compiled with `libxml2`
    342 bindings, which provides the necessary HTML parser.
    343 
    344 Sometimes displaying images can slow down or even crash Emacs. Set
    345 `shr-inhibit-images` to disable images if this is a problem.
    346 
    347 ## Web Interface
    348 
    349 Elfeed includes a demonstration/toy web interface for remote network
    350 access. It's a single-page web application that follows the database
    351 live as new entries arrive. It's packaged separately as `elfeed-web`.
    352 To fire it up, run `M-x elfeed-web-start` and visit
    353 http://localhost:8080/elfeed/ (check your `httpd-port`) with a
    354 browser. See the `elfeed-web.el` header for endpoint documentation if
    355 you'd like to access the Elfeed database through the web API.
    356 
    357 It's rough and unfinished -- no keyboard shortcuts, read-only, no
    358 authentication, and a narrow entry viewer. This is basically Elfeed's
    359 "mobile" interface. Patches welcome.
    360 
    361 ## Platform Support
    362 
    363 Summary: Install cURL and most problems disappear for all platforms.
    364 
    365 I personally only use Elfeed on Linux, but it's occasionally tested on
    366 Windows. Unfortunately the Windows port of Emacs is a bit too unstable
    367 for parallel feed downloads with `url-retrieve`, not to mention the
    368 [tiny, hard-coded, 512 open descriptor limitation][files], so it
    369 limits itself to one feed at a time on this platform.
    370 
    371 [files]: http://msdn.microsoft.com/en-us/library/kdfaxaay%28vs.71%29.aspx
    372 
    373 If you fetch HTTPS feeds without cURL on *any* platform, it's
    374 essential that Emacs is built with the `--with-gnutls` option.
    375 Otherwise Emacs runs gnutls in an inferior process, which rarely works
    376 well.
    377 
    378 ## Database Management
    379 
    380 The database should keep itself under control without any manual
    381 intervention, but steps can be taken to minimize the database size if
    382 desired. The simplest option is to run the `elfeed-db-compact`
    383 command, which will pack the loose-file content database into a single
    384 compressed file. This function works well in `kill-emacs-hook`.
    385 
    386 Going further, a function could be added to `elfeed-new-entry-hook` to
    387 strip unwanted/unneeded content from select entries before being
    388 stored in the database. For example, for YouTube videos only the entry
    389 link is of interest and the regularly-changing entry content could be
    390 tossed to save time and storage.
    391 
    392 ## Status and Roadmap
    393 
    394 Elfeed is to the point where it can serve 100% of my own web feed
    395 needs. My personal selection of about 150 feeds has been acting as my
    396 test case as I optimize and add features.
    397 
    398 Some things I still might want to add:
    399 
    400 * Database synchronization between computers
    401 * Parallel feed fetching via separate Emacs subprocesses
    402 
    403 ## Motivation
    404 
    405 As far as I know, outside of Elfeed there does not exist an
    406 extensible, text-file configured, power-user web feed client that can
    407 handle a reasonable number of feeds. The existing clients I've tried
    408 are missing some important capability that limits its usefulness to
    409 me.